diff --git a/DEPS b/DEPS index 0c35ba34..bdb4bfb7 100644 --- a/DEPS +++ b/DEPS
@@ -129,11 +129,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'f82158fb7fdc233ea32598d795a656e7a08adb1e', + 'skia_revision': 'd521ce39e99f99651be0ff2ba46376b60b6bc7d9', # 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': 'ba65b118eb24c527a0669d3ce40031b124e6fb20', + 'v8_revision': 'c6fbb279f3137a8cdc09ae48eb0b84744004079a', # 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. @@ -196,7 +196,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'ed5998919f4b97464cb0f6cd640ad78f101a498d', + 'catapult_revision': 'd7f22e29c4a1be844b5eb8153cb3b95775f2af7e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -252,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': 'b68af7ca8e027c54341dfc9b19c3df80fa07a78e', + 'spv_tools_revision': 'dca3ea5e1719ef996111fa53582fc592d5f891ed', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -268,7 +268,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '8e97b4c8a5126a36ff03b7f6581b45b6d322a331', + 'dawn_revision': '15d4c2e63b7281d622eba063c615be73358af260', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -1183,7 +1183,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '5ee4ec84de3c8760a2982824262803caca10e1b3', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '999374532cec467910846b6af52df01aae7278ea', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1354,7 +1354,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6f0b34abee8dba611c253738d955c59f703c147a', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '637bed5f8d90c6990687b4de03350609cf907783', + Var('webrtc_git') + '/src.git' + '@' + 'e670fd97951a967283f74ff9b313dc16aa19e7af', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1395,7 +1395,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@352cf25552e6945de83f895ddc9f821bfa27304e', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@75c4cbfa717ae8cb1a946886dce1c863bfc7833b', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/gfx/parent_output_surface.cc b/android_webview/browser/gfx/parent_output_surface.cc index 24b3e718..4b4c44f 100644 --- a/android_webview/browser/gfx/parent_output_surface.cc +++ b/android_webview/browser/gfx/parent_output_surface.cc
@@ -113,4 +113,7 @@ return 0; } +void ParentOutputSurface::SetUpdateVSyncParametersCallback( + viz::UpdateVSyncParametersCallback callback) {} + } // namespace android_webview
diff --git a/android_webview/browser/gfx/parent_output_surface.h b/android_webview/browser/gfx/parent_output_surface.h index 95d60d9..12bda6e 100644 --- a/android_webview/browser/gfx/parent_output_surface.h +++ b/android_webview/browser/gfx/parent_output_surface.h
@@ -45,6 +45,8 @@ unsigned GetOverlayTextureId() const override; gfx::BufferFormat GetOverlayBufferFormat() const override; unsigned UpdateGpuFence() override; + void SetUpdateVSyncParametersCallback( + viz::UpdateVSyncParametersCallback callback) override; private: void OnPresentation(const gfx::PresentationFeedback& feedback);
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index f4156f3b..1234f9cf 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1205,6 +1205,8 @@ "wm/tablet_mode/tablet_mode_window_state.h", "wm/top_level_window_factory.cc", "wm/top_level_window_factory.h", + "wm/toplevel_window_event_handler.cc", + "wm/toplevel_window_event_handler.h", "wm/video_detector.cc", "wm/video_detector.h", "wm/widget_finder.cc", @@ -1242,8 +1244,6 @@ "wm/wm_shadow_controller_delegate.h", "wm/wm_snap_to_pixel_layout_manager.cc", "wm/wm_snap_to_pixel_layout_manager.h", - "wm/wm_toplevel_window_event_handler.cc", - "wm/wm_toplevel_window_event_handler.h", "wm/wm_window_animations.cc", "wm/wm_window_animations.h", "wm/work_area_insets.cc",
diff --git a/ash/shell.cc b/ash/shell.cc index 87e6738..a46c6e7 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -155,6 +155,7 @@ #include "ash/wm/system_modal_container_layout_manager.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/tablet_mode/tablet_mode_window_manager.h" +#include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/video_detector.h" #include "ash/wm/window_animations.h" #include "ash/wm/window_cycle_controller.h" @@ -162,7 +163,6 @@ #include "ash/wm/window_properties.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_shadow_controller_delegate.h" -#include "ash/wm/wm_toplevel_window_event_handler.h" #include "ash/wm/workspace_controller.h" #include "ash/ws/ax_ash_window_utils.h" #include "ash/ws/window_service_owner.h"
diff --git a/ash/system/power/power_event_observer.cc b/ash/system/power/power_event_observer.cc index 7959a9ca..fc1f4a1 100644 --- a/ash/system/power/power_event_observer.cc +++ b/ash/system/power/power_event_observer.cc
@@ -30,9 +30,8 @@ namespace { -void OnSuspendDisplaysCompleted(base::OnceClosure suspend_callback, - bool status) { - std::move(suspend_callback).Run(); +void OnSuspendDisplaysCompleted(base::UnguessableToken token, bool status) { + chromeos::PowerManagerClient::Get()->UnblockSuspend(token); } // Returns whether the screen should be locked when device is suspended. @@ -233,7 +232,7 @@ // If suspending, run pending animations to the end immediately, as there is // no point in waiting for them to finish given that the device is suspending. - if (displays_suspended_callback_) + if (block_suspend_token_) EndPendingWallpaperAnimations(); // The |compositor_watcher_| is owned by this, and the callback passed to it @@ -248,9 +247,9 @@ power_manager::SuspendImminent::Reason reason) { suspend_in_progress_ = true; - displays_suspended_callback_ = - chromeos::PowerManagerClient::Get()->GetSuspendReadinessCallback( - FROM_HERE); + block_suspend_token_ = base::UnguessableToken::Create(); + chromeos::PowerManagerClient::Get()->BlockSuspend(block_suspend_token_, + "PowerEventObserver"); // Stop compositing immediately if // * the screen lock flow has already completed @@ -284,7 +283,7 @@ // animation to complete, clear the blocker since the suspend has already // completed. This prevents rendering requests from being blocked after a // resume if the lock screen took too long to show. - displays_suspended_callback_.Reset(); + block_suspend_token_ = {}; StartRootWindowCompositors(); } @@ -295,11 +294,10 @@ // The screen is now locked but the pending suspend, if any, will be blocked // until all the animations have completed. - if (displays_suspended_callback_) { + if (block_suspend_token_) VLOG(1) << "Screen locked due to suspend"; - } else { + else VLOG(1) << "Screen locked without suspend"; - } } else { lock_state_ = LockState::kUnlocked; compositor_watcher_.reset(); @@ -314,7 +312,7 @@ if (ShouldLockOnSuspend()) { lock_state_ = LockState::kLocking; Shell::Get()->lock_state_controller()->LockWithoutAnimation(); - } else if (displays_suspended_callback_) { + } else if (block_suspend_token_) { StopCompositingAndSuspendDisplays(); } } @@ -330,7 +328,7 @@ } void PowerEventObserver::StopCompositingAndSuspendDisplays() { - DCHECK(displays_suspended_callback_); + DCHECK(block_suspend_token_); DCHECK(!compositor_watcher_.get()); for (aura::Window* window : Shell::GetAllRootWindows()) { ui::Compositor* compositor = window->GetHost()->compositor(); @@ -340,8 +338,8 @@ ui::UserActivityDetector::Get()->OnDisplayPowerChanging(); Shell::Get()->display_configurator()->SuspendDisplays( - base::Bind(&OnSuspendDisplaysCompleted, - base::Passed(&displays_suspended_callback_))); + base::Bind(&OnSuspendDisplaysCompleted, block_suspend_token_)); + block_suspend_token_ = {}; } void PowerEventObserver::EndPendingWallpaperAnimations() { @@ -357,7 +355,7 @@ compositor_watcher_.reset(); lock_state_ = LockState::kLocked; - if (displays_suspended_callback_) + if (block_suspend_token_) StopCompositingAndSuspendDisplays(); }
diff --git a/ash/system/power/power_event_observer.h b/ash/system/power/power_event_observer.h index 0f1a0b0..4c49d21 100644 --- a/ash/system/power/power_event_observer.h +++ b/ash/system/power/power_event_observer.h
@@ -9,9 +9,9 @@ #include "ash/ash_export.h" #include "ash/session/session_observer.h" -#include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/unguessable_token.h" #include "chromeos/dbus/power/power_manager_client.h" namespace ui { @@ -78,11 +78,11 @@ void StartRootWindowCompositors(); // Sets all root window compositors' visibility to false, and then suspends - // displays. It will run |display_suspended_callback_| once displays are - // suspended. - // This should only be called when it's safe to stop compositing - - // either if the screen is not expected to get locked, or all compositors - // have gone through compositing cycle after the screen was locked. + // displays. It will run unblock suspend via |block_suspend_token_| once + // displays are suspended. This should only be called when it's safe to stop + // compositing - either if the screen is not expected to get locked, or all + // compositors have gone through compositing cycle after the screen was + // locked. void StopCompositingAndSuspendDisplays(); // If any of the root windows have pending wallpaper animations, it stops @@ -106,13 +106,13 @@ // compositors are in state in which it's safe to proceed with suspend. std::unique_ptr<ui::CompositorObserver> compositor_watcher_; - // Callback set when device suspend is delayed due to a screen lock - suspend + // Token set when device suspend is delayed due to a screen lock - suspend // should be continued when the screen lock finishes showing and display // compositors pick up screen lock changes. All compositors should be stopped - // prior to calling this - call StopCompositingAndSuspendDisplays() instead of - // runnig this callback directly. - // This will only be set while the device is suspending. - base::OnceClosure displays_suspended_callback_; + // prior to unblocking and clearing this - call + // StopCompositingAndSuspendDisplays(). This will only be set while the device + // is suspending. + base::UnguessableToken block_suspend_token_; DISALLOW_COPY_AND_ASSIGN(PowerEventObserver); };
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_controller.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_controller.cc index 2ebf639a..b69dd01 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_controller.cc
@@ -7,8 +7,8 @@ #include "ash/shell.h" #include "ash/wm/tablet_mode/tablet_mode_browser_window_drag_delegate.h" #include "ash/wm/tablet_mode/tablet_mode_window_drag_metrics.h" +#include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/window_util.h" -#include "ash/wm/wm_toplevel_window_event_handler.h" #include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/cursor_manager.h"
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.h b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.h index 3acfcc9..1e66a6c 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.h +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.h
@@ -10,7 +10,7 @@ #include "ash/public/cpp/presentation_time_recorder.h" #include "ash/public/cpp/window_properties.h" #include "ash/wm/splitview/split_view_controller.h" -#include "ash/wm/wm_toplevel_window_event_handler.h" +#include "ash/wm/toplevel_window_event_handler.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "ui/aura/window_occlusion_tracker.h"
diff --git a/ash/wm/wm_toplevel_window_event_handler.cc b/ash/wm/toplevel_window_event_handler.cc similarity index 99% rename from ash/wm/wm_toplevel_window_event_handler.cc rename to ash/wm/toplevel_window_event_handler.cc index eddb86c..11e22b1 100644 --- a/ash/wm/wm_toplevel_window_event_handler.cc +++ b/ash/wm/toplevel_window_event_handler.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 "ash/wm/wm_toplevel_window_event_handler.h" +#include "ash/wm/toplevel_window_event_handler.h" #include "ash/public/cpp/app_types.h" #include "ash/shell.h"
diff --git a/ash/wm/wm_toplevel_window_event_handler.h b/ash/wm/toplevel_window_event_handler.h similarity index 97% rename from ash/wm/wm_toplevel_window_event_handler.h rename to ash/wm/toplevel_window_event_handler.h index 9ba0d5a..a9c48be 100644 --- a/ash/wm/wm_toplevel_window_event_handler.h +++ b/ash/wm/toplevel_window_event_handler.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 ASH_WM_WM_TOPLEVEL_WINDOW_EVENT_HANDLER_H_ -#define ASH_WM_WM_TOPLEVEL_WINDOW_EVENT_HANDLER_H_ +#ifndef ASH_WM_TOPLEVEL_WINDOW_EVENT_HANDLER_H_ +#define ASH_WM_TOPLEVEL_WINDOW_EVENT_HANDLER_H_ #include <memory> @@ -177,4 +177,4 @@ } // namespace ash -#endif // ASH_WM_WM_TOPLEVEL_WINDOW_EVENT_HANDLER_H_ +#endif // ASH_WM_TOPLEVEL_WINDOW_EVENT_HANDLER_H_
diff --git a/ash/wm/toplevel_window_event_handler_unittest.cc b/ash/wm/toplevel_window_event_handler_unittest.cc index 8faec88..96d3ddb9 100644 --- a/ash/wm/toplevel_window_event_handler_unittest.cc +++ b/ash/wm/toplevel_window_event_handler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ash/wm/wm_toplevel_window_event_handler.h" +#include "ash/wm/toplevel_window_event_handler.h" #include "ash/display/screen_orientation_controller.h" #include "ash/display/screen_orientation_controller_test_api.h"
diff --git a/ash/ws/window_service_delegate_impl.cc b/ash/ws/window_service_delegate_impl.cc index 14e8379..c217e4f 100644 --- a/ash/ws/window_service_delegate_impl.cc +++ b/ash/ws/window_service_delegate_impl.cc
@@ -14,9 +14,9 @@ #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 "ash/wm/wm_toplevel_window_event_handler.h" #include "ash/ws/ash_window_manager.h" #include "ash/ws/multi_user_window_manager_bridge.h" #include "base/bind.h"
diff --git a/ash/ws/window_service_delegate_impl_unittest.cc b/ash/ws/window_service_delegate_impl_unittest.cc index ff4f83db..2062c425 100644 --- a/ash/ws/window_service_delegate_impl_unittest.cc +++ b/ash/ws/window_service_delegate_impl_unittest.cc
@@ -9,8 +9,8 @@ #include "ash/wm/desks/desks_util.h" #include "ash/wm/resize_shadow.h" #include "ash/wm/resize_shadow_controller.h" +#include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/window_state.h" -#include "ash/wm/wm_toplevel_window_event_handler.h" #include "ash/ws/window_service_owner.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h"
diff --git a/base/callback_helpers.h b/base/callback_helpers.h index c695adf..c0ca4db 100644 --- a/base/callback_helpers.h +++ b/base/callback_helpers.h
@@ -10,6 +10,7 @@ #ifndef BASE_CALLBACK_HELPERS_H_ #define BASE_CALLBACK_HELPERS_H_ +#include <type_traits> #include <utility> #include "base/atomicops.h" @@ -21,16 +22,39 @@ namespace base { -// Prefer std::move() over ResetAndReturn(). -template <typename Functor> -OnceCallback<Functor> ResetAndReturn(OnceCallback<Functor>* cb) { - auto ret = std::move(*cb); - DCHECK(!*cb); - return ret; -} +namespace internal { -template <typename Functor> -RepeatingCallback<Functor> ResetAndReturn(RepeatingCallback<Functor>* cb) { +template <typename T> +struct IsBaseCallbackImpl : std::false_type {}; + +template <typename R, typename... Args> +struct IsBaseCallbackImpl<OnceCallback<R(Args...)>> : std::true_type {}; + +template <typename R, typename... Args> +struct IsBaseCallbackImpl<RepeatingCallback<R(Args...)>> : std::true_type {}; + +} // namespace internal + +template <typename T> +using IsBaseCallback = internal::IsBaseCallbackImpl<std::decay_t<T>>; + +// SFINAE friendly enabler allowing to overload methods for both Repeating and +// OnceCallbacks. +// +// Usage: +// template <template <typename> class CallbackType, +// ... other template args ..., +// typename = EnableIfIsBaseCallback<CallbackType>> +// void DoStuff(CallbackType<...> cb, ...); +template <template <typename> class CallbackType> +using EnableIfIsBaseCallback = + std::enable_if_t<IsBaseCallback<CallbackType<void()>>::value>; + +// Prefer std::move() over ResetAndReturn(). +template <template <typename> class CallbackType, + typename RunType, + typename = EnableIfIsBaseCallback<CallbackType>> +CallbackType<RunType> ResetAndReturn(CallbackType<RunType>* cb) { auto ret = std::move(*cb); DCHECK(!*cb); return ret;
diff --git a/base/callback_helpers_unittest.cc b/base/callback_helpers_unittest.cc index 1c1102d..c8f0b95b 100644 --- a/base/callback_helpers_unittest.cc +++ b/base/callback_helpers_unittest.cc
@@ -4,12 +4,45 @@ #include "base/callback_helpers.h" +#include <functional> + #include "base/bind.h" #include "base/callback.h" #include "testing/gtest/include/gtest/gtest.h" namespace { +TEST(CallbackHelpersTest, IsBaseCallback) { + // Check that base::Closures and references to them are considered + // base::Callbacks. + static_assert(base::IsBaseCallback<base::OnceClosure>::value, ""); + static_assert(base::IsBaseCallback<base::RepeatingClosure>::value, ""); + static_assert(base::IsBaseCallback<base::OnceClosure&&>::value, ""); + static_assert(base::IsBaseCallback<const base::RepeatingClosure&>::value, ""); + + // Check that base::Callbacks with a given RunType and references to them are + // considered base::Callbacks. + static_assert(base::IsBaseCallback<base::OnceCallback<int(int)>>::value, ""); + static_assert(base::IsBaseCallback<base::RepeatingCallback<int(int)>>::value, + ""); + static_assert(base::IsBaseCallback<base::OnceCallback<int(int)>&&>::value, + ""); + static_assert( + base::IsBaseCallback<const base::RepeatingCallback<int(int)>&>::value, + ""); + + // Check that POD types are not considered base::Callbacks. + static_assert(!base::IsBaseCallback<bool>::value, ""); + static_assert(!base::IsBaseCallback<int>::value, ""); + static_assert(!base::IsBaseCallback<double>::value, ""); + + // Check that the closely related std::function is not considered a + // base::Callback. + static_assert(!base::IsBaseCallback<std::function<void()>>::value, ""); + static_assert(!base::IsBaseCallback<const std::function<void()>&>::value, ""); + static_assert(!base::IsBaseCallback<std::function<void()>&&>::value, ""); +} + void Increment(int* value) { (*value)++; }
diff --git a/base/files/file_util.h b/base/files/file_util.h index 75f0785..860d885 100644 --- a/base/files/file_util.h +++ b/base/files/file_util.h
@@ -375,6 +375,14 @@ // Appends |data| to |fd|. Does not close |fd| when done. Returns true iff // |size| bytes of |data| were written to |fd|. BASE_EXPORT bool WriteFileDescriptor(const int fd, const char* data, int size); + +// Allocates disk space for the file referred to by |fd| for the byte range +// starting at |offset| and continuing for |size| bytes. The file size will be +// changed if |offset|+|len| is greater than the file size. Zeros will fill the +// new space. +// After a successful call, subsequent writes into the specified range are +// guaranteed not to fail because of lack of disk space. +BASE_EXPORT bool AllocateFileRegion(File* file, int64_t offset, size_t size); #endif // Appends |data| to |filename|. Returns true iff |size| bytes of |data| were
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index 17b984e..c05a09bd 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc
@@ -22,6 +22,7 @@ #include <unistd.h> #include "base/base_switches.h" +#include "base/bits.h" #include "base/command_line.h" #include "base/containers/stack.h" #include "base/environment.h" @@ -870,6 +871,78 @@ return true; } +bool AllocateFileRegion(File* file, int64_t offset, size_t size) { + DCHECK(file); + + // Explicitly extend |file| to the maximum size. Zeros will fill the new + // space. It is assumed that the existing file is fully realized as + // otherwise the entire file would have to be read and possibly written. + const int64_t original_file_len = file->GetLength(); + if (original_file_len < 0) { + DPLOG(ERROR) << "fstat " << file->GetPlatformFile(); + return false; + } + + // Increase the actual length of the file, if necessary. This can fail if + // the disk is full and the OS doesn't support sparse files. + const int64_t new_file_len = offset + size; + if (!file->SetLength(std::max(original_file_len, new_file_len))) { + DPLOG(ERROR) << "ftruncate " << file->GetPlatformFile(); + return false; + } + + // Realize the extent of the file so that it can't fail (and crash) later + // when trying to write to a memory page that can't be created. This can + // fail if the disk is full and the file is sparse. + + // First try the more effective platform-specific way of allocating the disk + // space. It can fail because the filesystem doesn't support it. In that case, + // use the manual method below. + +#if defined(OS_LINUX) + if (HANDLE_EINTR(fallocate(file->GetPlatformFile(), 0, offset, size)) != -1) + return true; + DPLOG(ERROR) << "fallocate"; +#elif defined(OS_MACOSX) + // MacOS doesn't support fallocate even though their new APFS filesystem + // does support sparse files. It does, however, have the functionality + // available via fcntl. + // See also: https://openradar.appspot.com/32720223 + fstore_t params = {F_ALLOCATEALL, F_PEOFPOSMODE, offset, size, 0}; + if (fcntl(file->GetPlatformFile(), F_PREALLOCATE, ¶ms) != -1) + return true; + DPLOG(ERROR) << "F_PREALLOCATE"; +#endif + + // Manually realize the extended file by writing bytes to it at intervals. + int64_t block_size = 512; // Start with something safe. + struct stat statbuf; + if (fstat(file->GetPlatformFile(), &statbuf) == 0 && statbuf.st_blksize > 0 && + base::bits::IsPowerOfTwo(statbuf.st_blksize)) { + block_size = statbuf.st_blksize; + } + + // Write starting at the next block boundary after the old file length. + const int64_t extension_start = + base::bits::Align(original_file_len, block_size); + for (int64_t i = extension_start; i < new_file_len; i += block_size) { + char existing_byte; + if (HANDLE_EINTR(pread(file->GetPlatformFile(), &existing_byte, 1, i)) != + 1) { + return false; // Can't read? Not viable. + } + if (existing_byte != 0) { + continue; // Block has data so must already exist. + } + if (HANDLE_EINTR(pwrite(file->GetPlatformFile(), &existing_byte, 1, i)) != + 1) { + return false; // Can't write? Not viable. + } + } + + return true; +} + #if !defined(OS_NACL_NONSFI) bool AppendToFile(const FilePath& filename, const char* data, int size) {
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc index 35f9056a..26fd381 100644 --- a/base/files/file_util_unittest.cc +++ b/base/files/file_util_unittest.cc
@@ -2522,6 +2522,75 @@ EXPECT_TRUE(GetShmemTempDir(false, &dir)); EXPECT_TRUE(DirectoryExists(dir)); } + +TEST_F(FileUtilTest, AllocateFileRegionTest_ZeroOffset) { + const int kTestFileLength = 9; + char test_data[] = "test_data"; + FilePath file_path = temp_dir_.GetPath().Append( + FILE_PATH_LITERAL("allocate_file_region_test_zero_offset")); + WriteFile(file_path, test_data, kTestFileLength); + + File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_WRITE); + ASSERT_TRUE(file.IsValid()); + ASSERT_EQ(file.GetLength(), kTestFileLength); + + const int kExtendedFileLength = 23; + ASSERT_TRUE(AllocateFileRegion(&file, 0, kExtendedFileLength)); + EXPECT_EQ(file.GetLength(), kExtendedFileLength); + + char data_read[32]; + int bytes_read = file.Read(0, data_read, kExtendedFileLength); + EXPECT_EQ(bytes_read, kExtendedFileLength); + for (int i = 0; i < kTestFileLength; ++i) + EXPECT_EQ(test_data[i], data_read[i]); + for (int i = kTestFileLength; i < kExtendedFileLength; ++i) + EXPECT_EQ(0, data_read[i]); +} + +TEST_F(FileUtilTest, AllocateFileRegionTest_NonZeroOffset) { + const int kTestFileLength = 9; + char test_data[] = "test_data"; + FilePath file_path = temp_dir_.GetPath().Append( + FILE_PATH_LITERAL("allocate_file_region_test_non_zero_offset")); + WriteFile(file_path, test_data, kTestFileLength); + + File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_WRITE); + ASSERT_TRUE(file.IsValid()); + ASSERT_EQ(file.GetLength(), kTestFileLength); + + const int kExtensionOffset = 5; + const int kExtensionSize = 10; + ASSERT_TRUE(AllocateFileRegion(&file, kExtensionOffset, kExtensionSize)); + const int kExtendedFileLength = kExtensionOffset + kExtensionSize; + EXPECT_EQ(file.GetLength(), kExtendedFileLength); + + char data_read[32]; + int bytes_read = file.Read(0, data_read, kExtendedFileLength); + EXPECT_EQ(bytes_read, kExtendedFileLength); + for (int i = 0; i < kTestFileLength; ++i) + EXPECT_EQ(test_data[i], data_read[i]); + for (int i = kTestFileLength; i < kExtendedFileLength; ++i) + EXPECT_EQ(0, data_read[i]); +} + +TEST_F(FileUtilTest, AllocateFileRegionTest_DontTruncate) { + const int kTestFileLength = 9; + char test_data[] = "test_data"; + FilePath file_path = temp_dir_.GetPath().Append( + FILE_PATH_LITERAL("allocate_file_region_test_dont_truncate")); + WriteFile(file_path, test_data, kTestFileLength); + + File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ | + base::File::FLAG_WRITE); + ASSERT_TRUE(file.IsValid()); + ASSERT_EQ(file.GetLength(), kTestFileLength); + + const int kTruncatedFileLength = 4; + ASSERT_TRUE(AllocateFileRegion(&file, 0, kTruncatedFileLength)); + EXPECT_EQ(file.GetLength(), kTestFileLength); +} #endif TEST_F(FileUtilTest, GetHomeDirTest) {
diff --git a/base/files/memory_mapped_file_posix.cc b/base/files/memory_mapped_file_posix.cc index c9cdd56..fb7d6fa8 100644 --- a/base/files/memory_mapped_file_posix.cc +++ b/base/files/memory_mapped_file_posix.cc
@@ -11,15 +11,12 @@ #include <sys/stat.h> #include <unistd.h> +#include "base/files/file_util.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/threading/scoped_blocking_call.h" #include "build/build_config.h" -#if defined(OS_ANDROID) -#include <android/api-level.h> -#endif - namespace base { MemoryMappedFile::MemoryMappedFile() : data_(nullptr), length_(0) {} @@ -82,79 +79,8 @@ case READ_WRITE_EXTEND: flags |= PROT_READ | PROT_WRITE; - const int64_t new_file_len = region.offset + region.size; - - // POSIX won't auto-extend the file when it is written so it must first - // be explicitly extended to the maximum size. Zeros will fill the new - // space. It is assumed that the existing file is fully realized as - // otherwise the entire file would have to be read and possibly written. - const int64_t original_file_len = file_.GetLength(); - if (original_file_len < 0) { - DPLOG(ERROR) << "fstat " << file_.GetPlatformFile(); + if (!AllocateFileRegion(&file_, region.offset, region.size)) return false; - } - - // Increase the actual length of the file, if necessary. This can fail if - // the disk is full and the OS doesn't support sparse files. - if (!file_.SetLength(std::max(original_file_len, new_file_len))) { - DPLOG(ERROR) << "ftruncate " << file_.GetPlatformFile(); - return false; - } - - // Realize the extent of the file so that it can't fail (and crash) later - // when trying to write to a memory page that can't be created. This can - // fail if the disk is full and the file is sparse. - bool do_manual_extension = false; - -#if defined(OS_ANDROID) && __ANDROID_API__ < 21 - // Only Android API>=21 supports the fallocate call. Older versions need - // to manually extend the file by writing zeros at block intervals. - do_manual_extension = true; -#elif defined(OS_MACOSX) - // MacOS doesn't support fallocate even though their new APFS filesystem - // does support sparse files. It does, however, have the functionality - // available via fcntl. - // See also: https://openradar.appspot.com/32720223 - fstore_t params = {F_ALLOCATEALL, F_PEOFPOSMODE, region.offset, - region.size, 0}; - if (fcntl(file_.GetPlatformFile(), F_PREALLOCATE, ¶ms) != 0) { - DPLOG(ERROR) << "F_PREALLOCATE"; - // This can fail because the filesystem doesn't support it so don't - // give up just yet. Try the manual method below. - do_manual_extension = true; - } -#else - if (posix_fallocate(file_.GetPlatformFile(), region.offset, - region.size) != 0) { - DPLOG(ERROR) << "posix_fallocate"; - // This can fail because the filesystem doesn't support it so don't - // give up just yet. Try the manual method below. - do_manual_extension = true; - } -#endif - - // Manually realize the extended file by writing bytes to it at intervals. - if (do_manual_extension) { - int64_t block_size = 512; // Start with something safe. - struct stat statbuf; - if (fstat(file_.GetPlatformFile(), &statbuf) == 0 && - statbuf.st_blksize > 0) { - block_size = statbuf.st_blksize; - } - - // Write starting at the next block boundary after the old file length. - const int64_t extension_start = - (original_file_len + block_size - 1) & ~(block_size - 1); - for (int64_t i = extension_start; i < new_file_len; i += block_size) { - char existing_byte; - if (pread(file_.GetPlatformFile(), &existing_byte, 1, i) != 1) - return false; // Can't read? Not viable. - if (existing_byte != 0) - continue; // Block has data so must already exist. - if (pwrite(file_.GetPlatformFile(), &existing_byte, 1, i) != 1) - return false; // Can't write? Not viable. - } - } break; }
diff --git a/base/memory/platform_shared_memory_region_posix.cc b/base/memory/platform_shared_memory_region_posix.cc index f577c81..0b9c36a 100644 --- a/base/memory/platform_shared_memory_region_posix.cc +++ b/base/memory/platform_shared_memory_region_posix.cc
@@ -8,6 +8,7 @@ #include <sys/mman.h> #include <sys/stat.h> +#include "base/files/file.h" #include "base/files/file_util.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" @@ -229,11 +230,10 @@ if (!GetShmemTempDir(false /* executable */, &directory)) return {}; - ScopedFD fd; FilePath path; - fd.reset(CreateAndOpenFdForTemporaryFileInDir(directory, &path)); + File shm_file(CreateAndOpenFdForTemporaryFileInDir(directory, &path)); - if (!fd.is_valid()) { + if (!shm_file.IsValid()) { PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed"; FilePath dir = path.DirName(); if (access(dir.value().c_str(), W_OK | X_OK) < 0) { @@ -261,24 +261,12 @@ } } -#if defined(OS_LINUX) - // Unlike ftruncate(), fallocate() always allocates disk space, so we get an - // error if the disk is full. https://crbug.com/951431 - if (HANDLE_EINTR(fallocate(fd.get(), 0, 0, size)) != 0) { - PLOG(ERROR) << "Failed to reserve " << size << " bytes for shared memory."; + if (!AllocateFileRegion(&shm_file, 0, size)) return {}; - } -#else - // fallocate() is a Linux-specific syscall, fallback to ftruncate(). - if (HANDLE_EINTR(ftruncate(fd.get(), size)) != 0) { - DPLOG(ERROR) << "ftruncate() failed"; - return {}; - } -#endif if (readonly_fd.is_valid()) { struct stat stat = {}; - if (fstat(fd.get(), &stat) != 0) { + if (fstat(shm_file.GetPlatformFile(), &stat) != 0) { DPLOG(ERROR) << "fstat(fd) failed"; return {}; } @@ -296,8 +284,9 @@ } } - return PlatformSharedMemoryRegion({std::move(fd), std::move(readonly_fd)}, - mode, size, UnguessableToken::Create()); + return PlatformSharedMemoryRegion( + {ScopedFD(shm_file.TakePlatformFile()), std::move(readonly_fd)}, mode, + size, UnguessableToken::Create()); #endif // !defined(OS_NACL) }
diff --git a/base/task/cancelable_task_tracker.h b/base/task/cancelable_task_tracker.h index 1ccd1fd..f2fc970 100644 --- a/base/task/cancelable_task_tracker.h +++ b/base/task/cancelable_task_tracker.h
@@ -44,6 +44,7 @@ #include "base/base_export.h" #include "base/bind.h" #include "base/callback.h" +#include "base/callback_helpers.h" #include "base/containers/small_map.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -79,11 +80,19 @@ OnceClosure task, OnceClosure reply); - template <typename TaskReturnType, typename ReplyArgType> + // Though RepeatingCallback is convertible to OnceCallback, we need a + // CallbackType template since we can not use template deduction and object + // conversion at once on the overload resolution. + // TODO(crbug.com/714018): Update all callers of the RepeatingCallback version + // to use OnceCallback and remove the CallbackType template. + template <template <typename> class CallbackType, + typename TaskReturnType, + typename ReplyArgType, + typename = EnableIfIsBaseCallback<CallbackType>> TaskId PostTaskAndReplyWithResult(TaskRunner* task_runner, const Location& from_here, - OnceCallback<TaskReturnType()> task, - OnceCallback<void(ReplyArgType)> reply) { + CallbackType<TaskReturnType()> task, + CallbackType<void(ReplyArgType)> reply) { auto* result = new std::unique_ptr<TaskReturnType>(); return PostTaskAndReply( task_runner, from_here, @@ -93,24 +102,6 @@ std::move(reply), Owned(result))); } - // RepeatingCallback version of PostTaskWithTraitsAndReplyWithResult above. - // Though RepeatingCallback is convertible to OnceCallback, we need this since - // we can not use template deduction and object conversion at once on the - // overload resolution. - // TODO(tzik): Update all callers of the RepeatingCallback version to use - // OnceCallback. - template <typename TaskReturnType, typename ReplyArgType> - TaskId PostTaskAndReplyWithResult( - TaskRunner* task_runner, - const Location& from_here, - RepeatingCallback<TaskReturnType()> task, - RepeatingCallback<void(ReplyArgType)> reply) { - return PostTaskAndReplyWithResult( - task_runner, from_here, - static_cast<OnceCallback<TaskReturnType()>>(std::move(task)), - static_cast<OnceCallback<void(ReplyArgType)>>(std::move(reply))); - } - // Creates a tracked TaskId and an associated IsCanceledCallback. Client can // later call TryCancel() with the returned TaskId, and run |is_canceled_cb| // from any thread to check whether the TaskId is canceled.
diff --git a/base/task/post_task.h b/base/task/post_task.h index c646cd5..bdb1f9d 100644 --- a/base/task/post_task.h +++ b/base/task/post_task.h
@@ -11,6 +11,7 @@ #include "base/base_export.h" #include "base/bind.h" #include "base/callback.h" +#include "base/callback_helpers.h" #include "base/location.h" #include "base/memory/ref_counted.h" #include "base/post_task_and_reply_with_result_internal.h" @@ -94,29 +95,23 @@ // Equivalent to calling PostTaskWithTraitsAndReplyWithResult with default // TaskTraits. -template <typename TaskReturnType, typename ReplyArgType> +// +// Though RepeatingCallback is convertible to OnceCallback, we need a +// CallbackType template since we can not use template deduction and object +// conversion at once on the overload resolution. +// TODO(crbug.com/714018): Update all callers of the RepeatingCallback version +// to use OnceCallback and remove the CallbackType template. +template <template <typename> class CallbackType, + typename TaskReturnType, + typename ReplyArgType, + typename = EnableIfIsBaseCallback<CallbackType>> bool PostTaskAndReplyWithResult(const Location& from_here, - OnceCallback<TaskReturnType()> task, - OnceCallback<void(ReplyArgType)> reply) { + CallbackType<TaskReturnType()> task, + CallbackType<void(ReplyArgType)> reply) { return PostTaskWithTraitsAndReplyWithResult( from_here, TaskTraits(), std::move(task), std::move(reply)); } -// RepeatingCallback version of PostTaskAndReplyWithResult above. -// Though RepeatingCallback is convertible to OnceCallback, we need this since -// we can not use template deduction and object conversion at once on the -// overload resolution. -// TODO(tzik): Update all callers of the RepeatingCallback version to use -// OnceCallback. -template <typename TaskReturnType, typename ReplyArgType> -bool PostTaskAndReplyWithResult(const Location& from_here, - RepeatingCallback<TaskReturnType()> task, - RepeatingCallback<void(ReplyArgType)> reply) { - return PostTaskAndReplyWithResult( - from_here, OnceCallback<TaskReturnType()>(std::move(task)), - OnceCallback<void(ReplyArgType)>(std::move(reply))); -} - // Posts |task| with specific |traits|. Returns false if the task definitely // won't run because of current shutdown state. BASE_EXPORT bool PostTaskWithTraits(const Location& from_here, @@ -149,12 +144,21 @@ // or thread and same TaskTraits if applicable) when |task| completes. Returns // false if the task definitely won't run because of current shutdown state. Can // only be called when SequencedTaskRunnerHandle::IsSet(). -template <typename TaskReturnType, typename ReplyArgType> +// +// Though RepeatingCallback is convertible to OnceCallback, we need a +// CallbackType template since we can not use template deduction and object +// conversion at once on the overload resolution. +// TODO(crbug.com/714018): Update all callers of the RepeatingCallback version +// to use OnceCallback and remove the CallbackType template. +template <template <typename> class CallbackType, + typename TaskReturnType, + typename ReplyArgType, + typename = EnableIfIsBaseCallback<CallbackType>> bool PostTaskWithTraitsAndReplyWithResult( const Location& from_here, const TaskTraits& traits, - OnceCallback<TaskReturnType()> task, - OnceCallback<void(ReplyArgType)> reply) { + CallbackType<TaskReturnType()> task, + CallbackType<void(ReplyArgType)> reply) { auto* result = new std::unique_ptr<TaskReturnType>(); return PostTaskWithTraitsAndReply( from_here, traits, @@ -164,23 +168,6 @@ std::move(reply), Owned(result))); } -// RepeatingCallback version of PostTaskWithTraitsAndReplyWithResult above. -// Though RepeatingCallback is convertible to OnceCallback, we need this since -// we can not use template deduction and object conversion at once on the -// overload resolution. -// TODO(tzik): Update all callers of the RepeatingCallback version to use -// OnceCallback. -template <typename TaskReturnType, typename ReplyArgType> -bool PostTaskWithTraitsAndReplyWithResult( - const Location& from_here, - const TaskTraits& traits, - RepeatingCallback<TaskReturnType()> task, - RepeatingCallback<void(ReplyArgType)> reply) { - return PostTaskWithTraitsAndReplyWithResult( - from_here, traits, OnceCallback<TaskReturnType()>(std::move(task)), - OnceCallback<void(ReplyArgType)>(std::move(reply))); -} - // Returns a TaskRunner whose PostTask invocations result in scheduling tasks // using |traits|. Tasks may run in any order and in parallel. BASE_EXPORT scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits(
diff --git a/base/task_runner_util.h b/base/task_runner_util.h index 14c536d..05894ab 100644 --- a/base/task_runner_util.h +++ b/base/task_runner_util.h
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" +#include "base/callback_helpers.h" #include "base/logging.h" #include "base/post_task_and_reply_with_result_internal.h" #include "base/task_runner.h" @@ -31,11 +32,20 @@ // FROM_HERE, // BindOnce(&DoWorkAndReturn), // BindOnce(&Callback)); -template <typename TaskReturnType, typename ReplyArgType> +// +// Though RepeatingCallback is convertible to OnceCallback, we need a +// CallbackType template since we can not use template deduction and object +// conversion at once on the overload resolution. +// TODO(crbug.com/714018): Update all callers of the RepeatingCallback version +// to use OnceCallback and remove the CallbackType template. +template <template <typename> class CallbackType, + typename TaskReturnType, + typename ReplyArgType, + typename = EnableIfIsBaseCallback<CallbackType>> bool PostTaskAndReplyWithResult(TaskRunner* task_runner, const Location& from_here, - OnceCallback<TaskReturnType()> task, - OnceCallback<void(ReplyArgType)> reply) { + CallbackType<TaskReturnType()> task, + CallbackType<void(ReplyArgType)> reply) { DCHECK(task); DCHECK(reply); // std::unique_ptr used to avoid the need of a default constructor. @@ -48,22 +58,6 @@ std::move(reply), Owned(result))); } -// RepeatingCallback version of PostTaskAndReplyWithResult above. -// Though RepeatingCallback is convertible to OnceCallback, we need this since -// we cannot use template deduction and object conversion at once on the -// overload resolution. -// TODO(crbug.com/714018): Update all callers of the RepeatingCallback version -// to use OnceCallback. -template <typename TaskReturnType, typename ReplyArgType> -bool PostTaskAndReplyWithResult(TaskRunner* task_runner, - const Location& from_here, - RepeatingCallback<TaskReturnType()> task, - RepeatingCallback<void(ReplyArgType)> reply) { - return PostTaskAndReplyWithResult( - task_runner, from_here, OnceCallback<TaskReturnType()>(std::move(task)), - OnceCallback<void(ReplyArgType)>(std::move(reply))); -} - } // namespace base #endif // BASE_TASK_RUNNER_UTIL_H_
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index d62699e..2181b63 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8915146190128167296 \ No newline at end of file +8915116829918854048 \ No newline at end of file
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 36a262b3..5d4c278 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -514,6 +514,12 @@ } gfx::Size LayerImpl::bounds() const { + // As an optimization, we do not need to include the viewport bounds delta if + // the layer is not a viewport layer. + if (viewport_layer_type_ == NOT_VIEWPORT_LAYER) { + DCHECK(ViewportBoundsDelta().IsZero()); + return bounds_; + } auto viewport_bounds_delta = gfx::ToCeiledVector2d(ViewportBoundsDelta()); return gfx::Size(bounds_.width() + viewport_bounds_delta.x(), bounds_.height() + viewport_bounds_delta.y());
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index 7c047cd1..22d86d8 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc
@@ -1261,11 +1261,26 @@ canvas->drawImage(decoded_image.image().get(), op->left, op->top, &paint); } -// TODO(xidachen): ensure paint worklet generated images are correctly handled. void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op, const PaintFlags* flags, SkCanvas* canvas, const PlaybackParams& params) { + // TODO(crbug.com/931704): make sure to support the case where paint worklet + // generated images are used in other raster work such as canvas2d. + if (op->image.IsPaintWorklet()) { + DCHECK(params.image_provider); + ImageProvider::ScopedResult result = + params.image_provider->GetRasterContent(DrawImage(op->image)); + + DCHECK(IsScaleAdjustmentIdentity(op->scale_adjustment)); + SkAutoCanvasRestore save_restore(canvas, true); + canvas->concat( + SkMatrix::MakeRectToRect(op->src, op->dst, SkMatrix::kFill_ScaleToFit)); + canvas->clipRect(op->src); + result.paint_record()->Playback(canvas, params); + return; + } + // TODO(enne): Probably PaintCanvas should just use the skia enum directly. SkCanvas::SrcRectConstraint skconstraint = static_cast<SkCanvas::SrcRectConstraint>(op->constraint);
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc index 0f6f7b74..25f96990 100644 --- a/cc/paint/paint_op_buffer_unittest.cc +++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -439,6 +439,18 @@ EXPECT_TRUE(buffer.HasDiscardableImages()); } +TEST(PaintOpBufferTest, DiscardableImagesTracking_PaintWorkletImageRect) { + scoped_refptr<TestPaintWorkletInput> input = + base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(32.0f, 32.0f)); + PaintOpBuffer buffer; + PaintImage image = CreatePaintWorkletPaintImage(input); + SkRect src = SkRect::MakeEmpty(); + SkRect dst = SkRect::MakeEmpty(); + buffer.push<DrawImageRectOp>(image, src, dst, nullptr, + PaintCanvas::kStrict_SrcRectConstraint); + EXPECT_TRUE(buffer.HasDiscardableImages()); +} + TEST(PaintOpBufferTest, DiscardableImagesTracking_DrawImageRect) { PaintOpBuffer buffer; PaintImage image = CreateDiscardablePaintImage(gfx::Size(100, 100)); @@ -2916,6 +2928,172 @@ blink_buffer.Playback(&canvas, PlaybackParams(&provider)); } +TEST(PaintOpBufferTest, RasterPaintWorkletImageRectBasicCase) { + sk_sp<PaintOpBuffer> paint_worklet_buffer = sk_make_sp<PaintOpBuffer>(); + PaintFlags noop_flags; + SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 100, 100); + paint_worklet_buffer->push<TranslateOp>(8.0f, 8.0f); + paint_worklet_buffer->push<SaveLayerOp>(&savelayer_rect, &noop_flags); + PaintFlags draw_flags; + draw_flags.setColor(0u); + SkRect rect = SkRect::MakeXYWH(0, 0, 100, 100); + paint_worklet_buffer->push<DrawRectOp>(rect, draw_flags); + + MockImageProvider provider; + provider.SetRecord(paint_worklet_buffer); + + PaintOpBuffer blink_buffer; + scoped_refptr<TestPaintWorkletInput> input = + base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(100, 100)); + PaintImage image = CreatePaintWorkletPaintImage(input); + SkRect src = SkRect::MakeXYWH(0, 0, 100, 100); + SkRect dst = SkRect::MakeXYWH(0, 0, 100, 100); + blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr, + PaintCanvas::kStrict_SrcRectConstraint); + + testing::StrictMock<MockCanvas> canvas; + testing::Sequence s; + + EXPECT_CALL(canvas, willSave()).InSequence(s); + EXPECT_CALL(canvas, willSave()).InSequence(s); + EXPECT_CALL(canvas, didConcat(SkMatrix::MakeTrans(8.0f, 8.0f))); + EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s); + EXPECT_CALL(canvas, OnDrawRectWithColor(0u)); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + + blink_buffer.Playback(&canvas, PlaybackParams(&provider)); +} + +TEST(PaintOpBufferTest, RasterPaintWorkletImageRectTranslated) { + sk_sp<PaintOpBuffer> paint_worklet_buffer = sk_make_sp<PaintOpBuffer>(); + PaintFlags noop_flags; + SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 10, 10); + paint_worklet_buffer->push<SaveLayerOp>(&savelayer_rect, &noop_flags); + PaintFlags draw_flags; + draw_flags.setFilterQuality(kLow_SkFilterQuality); + PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10)); + paint_worklet_buffer->push<DrawImageOp>(paint_image, 0.0f, 0.0f, &draw_flags); + + std::vector<SkSize> src_rect_offset = {SkSize::MakeEmpty()}; + std::vector<SkSize> scale_adjustment = {SkSize::Make(0.2f, 0.2f)}; + std::vector<SkFilterQuality> quality = {kHigh_SkFilterQuality}; + MockImageProvider provider(src_rect_offset, scale_adjustment, quality); + provider.SetRecord(paint_worklet_buffer); + + PaintOpBuffer blink_buffer; + scoped_refptr<TestPaintWorkletInput> input = + base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(100, 100)); + PaintImage image = CreatePaintWorkletPaintImage(input); + SkRect src = SkRect::MakeXYWH(0, 0, 100, 100); + SkRect dst = SkRect::MakeXYWH(5, 7, 100, 100); + blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr, + PaintCanvas::kStrict_SrcRectConstraint); + + testing::StrictMock<MockCanvas> canvas; + testing::Sequence s; + + EXPECT_CALL(canvas, willSave()).InSequence(s); + EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s); + EXPECT_CALL(canvas, didConcat(SkMatrix::MakeTrans(5.0f, 7.0f))); + EXPECT_CALL(canvas, willSave()).InSequence(s); + EXPECT_CALL(canvas, didConcat(MatchesInvScale(scale_adjustment[0]))); + EXPECT_CALL(canvas, onDrawImage(NonLazyImage(), 0.0f, 0.0f, + MatchesQuality(quality[0]))); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + + blink_buffer.Playback(&canvas, PlaybackParams(&provider)); +} + +TEST(PaintOpBufferTest, RasterPaintWorkletImageRectScaled) { + sk_sp<PaintOpBuffer> paint_worklet_buffer = sk_make_sp<PaintOpBuffer>(); + PaintFlags noop_flags; + SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 10, 10); + paint_worklet_buffer->push<SaveLayerOp>(&savelayer_rect, &noop_flags); + PaintFlags draw_flags; + draw_flags.setFilterQuality(kLow_SkFilterQuality); + PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10)); + paint_worklet_buffer->push<DrawImageOp>(paint_image, 0.0f, 0.0f, &draw_flags); + + std::vector<SkSize> src_rect_offset = {SkSize::MakeEmpty()}; + std::vector<SkSize> scale_adjustment = {SkSize::Make(0.2f, 0.2f)}; + std::vector<SkFilterQuality> quality = {kHigh_SkFilterQuality}; + MockImageProvider provider(src_rect_offset, scale_adjustment, quality); + provider.SetRecord(paint_worklet_buffer); + + PaintOpBuffer blink_buffer; + scoped_refptr<TestPaintWorkletInput> input = + base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(100, 100)); + PaintImage image = CreatePaintWorkletPaintImage(input); + SkRect src = SkRect::MakeXYWH(0, 0, 100, 100); + SkRect dst = SkRect::MakeXYWH(0, 0, 200, 150); + blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr, + PaintCanvas::kStrict_SrcRectConstraint); + + testing::StrictMock<MockCanvas> canvas; + testing::Sequence s; + + EXPECT_CALL(canvas, willSave()).InSequence(s); + EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s); + EXPECT_CALL(canvas, didConcat(SkMatrix::MakeScale(2.f, 1.5f))); + EXPECT_CALL(canvas, willSave()).InSequence(s); + EXPECT_CALL(canvas, didConcat(MatchesInvScale(scale_adjustment[0]))); + EXPECT_CALL(canvas, onDrawImage(NonLazyImage(), 0.0f, 0.0f, + MatchesQuality(quality[0]))); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + + blink_buffer.Playback(&canvas, PlaybackParams(&provider)); +} + +TEST(PaintOpBufferTest, RasterPaintWorkletImageRectClipped) { + sk_sp<PaintOpBuffer> paint_worklet_buffer = sk_make_sp<PaintOpBuffer>(); + PaintFlags noop_flags; + SkRect savelayer_rect = SkRect::MakeXYWH(0, 0, 60, 60); + paint_worklet_buffer->push<SaveLayerOp>(&savelayer_rect, &noop_flags); + PaintFlags draw_flags; + draw_flags.setFilterQuality(kLow_SkFilterQuality); + PaintImage paint_image = CreateDiscardablePaintImage(gfx::Size(10, 10)); + // One rect inside the src-rect, one outside. + paint_worklet_buffer->push<DrawImageOp>(paint_image, 0.0f, 0.0f, &draw_flags); + paint_worklet_buffer->push<DrawImageOp>(paint_image, 50.0f, 50.0f, + &draw_flags); + + std::vector<SkSize> src_rect_offset = {SkSize::MakeEmpty()}; + std::vector<SkSize> scale_adjustment = {SkSize::Make(0.2f, 0.2f)}; + std::vector<SkFilterQuality> quality = {kHigh_SkFilterQuality}; + MockImageProvider provider(src_rect_offset, scale_adjustment, quality); + provider.SetRecord(paint_worklet_buffer); + + PaintOpBuffer blink_buffer; + scoped_refptr<TestPaintWorkletInput> input = + base::MakeRefCounted<TestPaintWorkletInput>(gfx::SizeF(100, 100)); + PaintImage image = CreatePaintWorkletPaintImage(input); + SkRect src = SkRect::MakeXYWH(0, 0, 20, 20); + SkRect dst = SkRect::MakeXYWH(0, 0, 20, 20); + blink_buffer.push<DrawImageRectOp>(image, src, dst, nullptr, + PaintCanvas::kStrict_SrcRectConstraint); + + testing::StrictMock<MockCanvas> canvas; + testing::Sequence s; + + EXPECT_CALL(canvas, willSave()).InSequence(s); + EXPECT_CALL(canvas, OnSaveLayer()).InSequence(s); + EXPECT_CALL(canvas, willSave()).InSequence(s); + EXPECT_CALL(canvas, didConcat(MatchesInvScale(scale_adjustment[0]))); + EXPECT_CALL(canvas, onDrawImage(NonLazyImage(), 0.0f, 0.0f, + MatchesQuality(quality[0]))); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + EXPECT_CALL(canvas, willRestore()).InSequence(s); + + blink_buffer.Playback(&canvas, PlaybackParams(&provider)); +} + TEST(PaintOpBufferTest, ReplacesImagesFromProvider) { std::vector<SkSize> src_rect_offset = { SkSize::MakeEmpty(), SkSize::Make(2.0f, 2.0f), SkSize::Make(3.0f, 3.0f)};
diff --git a/cc/paint/render_surface_filters.cc b/cc/paint/render_surface_filters.cc index d82fdd06..0a9cb8b 100644 --- a/cc/paint/render_surface_filters.cc +++ b/cc/paint/render_surface_filters.cc
@@ -11,6 +11,7 @@ #include "cc/paint/filter_operation.h" #include "cc/paint/filter_operations.h" #include "cc/paint/paint_filter.h" +#include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkRegion.h" #include "third_party/skia/include/effects/SkAlphaThresholdFilter.h" @@ -26,31 +27,31 @@ namespace { -void GetBrightnessMatrix(float amount, SkScalar matrix[20]) { +void GetBrightnessMatrix(float amount, float matrix[20]) { // Spec implementation // (http://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquivalent) // <feFunc[R|G|B] type="linear" slope="[amount]"> - memset(matrix, 0, 20 * sizeof(SkScalar)); + memset(matrix, 0, 20 * sizeof(float)); matrix[0] = matrix[6] = matrix[12] = amount; matrix[18] = 1.f; } -void GetSaturatingBrightnessMatrix(float amount, SkScalar matrix[20]) { +void GetSaturatingBrightnessMatrix(float amount, float matrix[20]) { // Legacy implementation used by internal clients. // <feFunc[R|G|B] type="linear" intercept="[amount]"/> - memset(matrix, 0, 20 * sizeof(SkScalar)); + memset(matrix, 0, 20 * sizeof(float)); matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f; - matrix[4] = matrix[9] = matrix[14] = amount * 255.f; + matrix[4] = matrix[9] = matrix[14] = amount; } -void GetContrastMatrix(float amount, SkScalar matrix[20]) { - memset(matrix, 0, 20 * sizeof(SkScalar)); +void GetContrastMatrix(float amount, float matrix[20]) { + memset(matrix, 0, 20 * sizeof(float)); matrix[0] = matrix[6] = matrix[12] = amount; - matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f) * 255.f; + matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f); matrix[18] = 1.f; } -void GetSaturateMatrix(float amount, SkScalar matrix[20]) { +void GetSaturateMatrix(float amount, float matrix[20]) { // Note, these values are computed to ensure MatrixNeedsClamping is false // for amount in [0..1] matrix[0] = 0.213f + 0.787f * amount; @@ -69,7 +70,7 @@ matrix[18] = 1.f; } -void GetHueRotateMatrix(float hue, SkScalar matrix[20]) { +void GetHueRotateMatrix(float hue, float matrix[20]) { float cos_hue = cosf(hue * base::kPiFloat / 180.f); float sin_hue = sinf(hue * base::kPiFloat / 180.f); matrix[0] = 0.213f + cos_hue * 0.787f - sin_hue * 0.213f; @@ -89,20 +90,20 @@ matrix[19] = 0.f; } -void GetInvertMatrix(float amount, SkScalar matrix[20]) { - memset(matrix, 0, 20 * sizeof(SkScalar)); +void GetInvertMatrix(float amount, float matrix[20]) { + memset(matrix, 0, 20 * sizeof(float)); matrix[0] = matrix[6] = matrix[12] = 1.f - 2.f * amount; - matrix[4] = matrix[9] = matrix[14] = amount * 255.f; + matrix[4] = matrix[9] = matrix[14] = amount; matrix[18] = 1.f; } -void GetOpacityMatrix(float amount, SkScalar matrix[20]) { - memset(matrix, 0, 20 * sizeof(SkScalar)); +void GetOpacityMatrix(float amount, float matrix[20]) { + memset(matrix, 0, 20 * sizeof(float)); matrix[0] = matrix[6] = matrix[12] = 1.f; matrix[18] = amount; } -void GetGrayscaleMatrix(float amount, SkScalar matrix[20]) { +void GetGrayscaleMatrix(float amount, float matrix[20]) { // Note, these values are computed to ensure MatrixNeedsClamping is false // for amount in [0..1] matrix[0] = 0.2126f + 0.7874f * amount; @@ -124,7 +125,7 @@ matrix[18] = 1.f; } -void GetSepiaMatrix(float amount, SkScalar matrix[20]) { +void GetSepiaMatrix(float amount, float matrix[20]) { matrix[0] = 0.393f + 0.607f * amount; matrix[1] = 0.769f - 0.769f * amount; matrix[2] = 0.189f - 0.189f * amount; @@ -144,10 +145,10 @@ matrix[18] = 1.f; } -sk_sp<PaintFilter> CreateMatrixImageFilter(const SkScalar matrix[20], +sk_sp<PaintFilter> CreateMatrixImageFilter(const float matrix[20], sk_sp<PaintFilter> input) { - return sk_make_sp<ColorFilterPaintFilter>( - SkColorFilters::MatrixRowMajor255(matrix), std::move(input)); + return sk_make_sp<ColorFilterPaintFilter>(SkColorFilters::Matrix(matrix), + std::move(input)); } } // namespace @@ -157,7 +158,7 @@ const gfx::SizeF& size, const gfx::Vector2dF& offset) { sk_sp<PaintFilter> image_filter; - SkScalar matrix[20]; + float matrix[20]; for (size_t i = 0; i < filters.size(); ++i) { const FilterOperation& op = filters.at(i); switch (op.type()) { @@ -271,7 +272,7 @@ has_input = !!color_paint_filter->input(); } - if (cf && cf->asColorMatrix(matrix) && !has_input) { + if (cf && cf->asAColorMatrix(matrix) && !has_input) { image_filter = CreateMatrixImageFilter(matrix, std::move(image_filter)); } else if (image_filter) {
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index fa4412f..39e438b6f 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc
@@ -20,7 +20,6 @@ #include "cc/test/pixel_test_utils.h" #include "cc/test/test_in_process_context_provider.h" #include "components/viz/client/client_resource_provider.h" -#include "components/viz/common/display/update_vsync_parameters_callback.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" @@ -69,7 +68,6 @@ bool flipped_output_surface) : SkiaOutputSurfaceImpl(gpu_service, surface_handle, - viz::UpdateVSyncParametersCallback(), renderer_settings), flipped_output_surface_(flipped_output_surface) {} @@ -182,7 +180,15 @@ SkImageInfo::MakeN32Premul(result_bitmap_->width(), result_bitmap_->height()), ref_pixels->data(), result_bitmap_->width() * sizeof(SkColor)); - return comparator.Compare(*result_bitmap_, ref_pixels_bitmap); + bool result = comparator.Compare(*result_bitmap_, ref_pixels_bitmap); + if (!result) { + std::string res_bmp_data_url = GetPNGDataUrl(*result_bitmap_); + std::string ref_bmp_data_url = GetPNGDataUrl(ref_pixels_bitmap); + LOG(ERROR) << "Pixels do not match!"; + LOG(ERROR) << "Actual: " << res_bmp_data_url; + LOG(ERROR) << "Expected: " << ref_bmp_data_url; + } + return result; } void PixelTest::ReadbackResult(base::OnceClosure quit_run_loop,
diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc index 24040f13..d8d58f1 100644 --- a/cc/test/pixel_test_output_surface.cc +++ b/cc/test/pixel_test_output_surface.cc
@@ -110,4 +110,7 @@ return 0; } +void PixelTestOutputSurface::SetUpdateVSyncParametersCallback( + viz::UpdateVSyncParametersCallback callback) {} + } // namespace cc
diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h index 8b2acd3..215c11c9 100644 --- a/cc/test/pixel_test_output_surface.h +++ b/cc/test/pixel_test_output_surface.h
@@ -39,6 +39,8 @@ gfx::BufferFormat GetOverlayBufferFormat() const override; uint32_t GetFramebufferCopyTextureFormat() override; unsigned UpdateGpuFence() override; + void SetUpdateVSyncParametersCallback( + viz::UpdateVSyncParametersCallback callback) override; void set_has_external_stencil_test(bool has_test) { external_stencil_test_ = has_test;
diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc index 32c04b5..12ee8775 100644 --- a/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -54,17 +54,17 @@ // This matrix swaps the red and green channels, and has a slight // translation in the alpha component, so that it affects transparent // pixels. - SkScalar matrix[20] = { + float matrix[20] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 20.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 20 / 255.0f, }; FilterOperations filters; SkImageFilter::CropRect cropRect( SkRect::MakeXYWH(-40000, -40000, 80000, 80000)); filters.Append(FilterOperation::CreateReferenceFilter( - sk_make_sp<ColorFilterPaintFilter>( - SkColorFilters::MatrixRowMajor255(matrix), nullptr, &cropRect))); + sk_make_sp<ColorFilterPaintFilter>(SkColorFilters::Matrix(matrix), + nullptr, &cropRect))); filter_layer->SetFilters(filters); background->SetMasksToBounds(masks_to_bounds); background->AddChild(filter_layer); @@ -381,16 +381,16 @@ CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorRED); background->AddChild(foreground); - SkScalar matrix[20]; + float matrix[20]; memset(matrix, 0, 20 * sizeof(matrix[0])); // This filter does a red-blue swap, so the foreground becomes blue. - matrix[2] = matrix[6] = matrix[10] = matrix[18] = SK_Scalar1; + matrix[2] = matrix[6] = matrix[10] = matrix[18] = 1.0f; // We filter only the bottom 200x100 pixels of the foreground. SkImageFilter::CropRect crop_rect(SkRect::MakeXYWH(0, 100, 200, 100)); FilterOperations filters; filters.Append( FilterOperation::CreateReferenceFilter(sk_make_sp<ColorFilterPaintFilter>( - SkColorFilters::MatrixRowMajor255(matrix), nullptr, &crop_rect))); + SkColorFilters::Matrix(matrix), nullptr, &crop_rect))); // Make the foreground layer's render surface be clipped by the background // layer. @@ -417,16 +417,16 @@ CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorRED); background->AddChild(foreground); - SkScalar matrix[20]; + float matrix[20]; memset(matrix, 0, 20 * sizeof(matrix[0])); // This filter does a red-blue swap, so the foreground becomes blue. - matrix[2] = matrix[6] = matrix[10] = matrix[18] = SK_Scalar1; + matrix[2] = matrix[6] = matrix[10] = matrix[18] = 1.0f; // Set up a crop rec to filter the bottom 200x100 pixels of the foreground. SkImageFilter::CropRect crop_rect(SkRect::MakeXYWH(0, 100, 200, 100)); FilterOperations filters; filters.Append( FilterOperation::CreateReferenceFilter(sk_make_sp<ColorFilterPaintFilter>( - SkColorFilters::MatrixRowMajor255(matrix), nullptr, &crop_rect))); + SkColorFilters::Matrix(matrix), nullptr, &crop_rect))); // Make the foreground layer's render surface be clipped by the background // layer.
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 734a2f75..6a959cd 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -351,7 +351,8 @@ // No single thread test because the commit goes directly to the active tree in // single thread mode, so notify ready to activate is skipped. -MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty); +// Flaky: https://crbug.com/947673 +// MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty); // Test if the LTHI receives ReadyToDraw notifications from the TileManager when // no raster tasks get scheduled.
diff --git a/chrome/android/features/keyboard_accessory/BUILD.gn b/chrome/android/features/keyboard_accessory/BUILD.gn index d03685c..bd670cc 100644 --- a/chrome/android/features/keyboard_accessory/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/BUILD.gn
@@ -8,6 +8,7 @@ sources = [ "internal/java/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryViewBridge.java", "internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java", + "public/java/src/org/chromium/chrome/browser/keyboard_accessory/data/UserInfoField.java", ] jni_package = "chrome" }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java index c002353c..6419e5d 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java
@@ -16,6 +16,7 @@ import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.FooterCommand; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.UserInfo; import org.chromium.chrome.browser.keyboard_accessory.data.PropertyProvider; +import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; @@ -115,19 +116,19 @@ @CalledByNative private void addFieldToUserInfo(Object objUserInfo, String displayText, String a11yDescription, boolean isObfuscated, boolean selectable) { - Callback<UserInfo.Field> callback = null; + Callback<UserInfoField> callback = null; if (selectable) { callback = (field) -> { assert mNativeView != 0 : "Controller was destroyed but the bridge wasn't!"; ManualFillingMetricsRecorder.recordSuggestionSelected(AccessoryTabType.PASSWORDS, field.isObfuscated() ? AccessorySuggestionType.PASSWORD : AccessorySuggestionType.USERNAME); - nativeOnFillingTriggered(mNativeView, field.isObfuscated(), field.getDisplayText()); + nativeOnFillingTriggered(mNativeView, field.isObfuscated(), field); }; } ((UserInfo) objUserInfo) .getFields() - .add(new UserInfo.Field(displayText, a11yDescription, isObfuscated, callback)); + .add(new UserInfoField(displayText, a11yDescription, isObfuscated, callback)); } @CalledByNative @@ -155,7 +156,7 @@ private native void nativeOnFaviconRequested(long nativeManualFillingViewAndroid, int desiredSizeInPx, Callback<Bitmap> faviconCallback); private native void nativeOnFillingTriggered( - long nativeManualFillingViewAndroid, boolean isObfuscated, String textToFill); + long nativeManualFillingViewAndroid, boolean isObfuscated, UserInfoField userInfoField); private native void nativeOnOptionSelected( long nativeManualFillingViewAndroid, String selectedOption); private native void nativeOnGenerationRequested(long nativeManualFillingViewAndroid);
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AccessorySheetTabMetricsRecorder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AccessorySheetTabMetricsRecorder.java index 891eb93..5b6bdcc 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AccessorySheetTabMetricsRecorder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AccessorySheetTabMetricsRecorder.java
@@ -11,6 +11,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.keyboard_accessory.AccessoryTabType; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.UserInfo; +import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.ui.modelutil.ListModel; /** @@ -39,7 +40,7 @@ for (int i = 0; i < suggestionList.size(); ++i) { if (getType(suggestionList.get(i)) == PASSWORD_INFO) { UserInfo info = (UserInfo) suggestionList.get(i).getDataPiece(); - for (UserInfo.Field field : info.getFields()) { + for (UserInfoField field : info.getFields()) { if (field.isSelectable()) ++interactiveSuggestions; } }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java index 014a9af9..c706c1b 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewBinder.java
@@ -10,6 +10,7 @@ import org.chromium.chrome.browser.keyboard_accessory.R; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; +import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabViewBinder.ElementViewHolder; import org.chromium.ui.modelutil.ListModel; @@ -57,7 +58,7 @@ } } - void bindChipView(ChipView chip, KeyboardAccessoryData.UserInfo.Field field) { + void bindChipView(ChipView chip, UserInfoField field) { chip.getPrimaryTextView().setTransformationMethod( field.isObfuscated() ? new PasswordTransformationMethod() : null); chip.getPrimaryTextView().setText(field.getDisplayText());
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewBinder.java index d33e000a..73e0119 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewBinder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewBinder.java
@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.keyboard_accessory.R; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.FooterCommand; +import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabViewBinder.ElementViewHolder; import org.chromium.ui.modelutil.ListModel; @@ -113,7 +114,7 @@ ViewCompat.setPaddingRelative(password, 2 * mPadding + mIconSize, 0, mPadding, 0); } - private void bindTextView(TextView text, KeyboardAccessoryData.UserInfo.Field field) { + private void bindTextView(TextView text, UserInfoField field) { text.setTransformationMethod( field.isObfuscated() ? new PasswordTransformationMethod() : null); // With transformation, the character set forces a LTR gravity. Therefore, invert it:
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java index dd4fac4..12d8579f 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetModernViewTest.java
@@ -30,6 +30,7 @@ import org.chromium.chrome.browser.keyboard_accessory.R; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.UserInfo; +import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -112,9 +113,9 @@ assertThat(mView.get().getChildCount(), is(0)); UserInfo testInfo = new UserInfo(null); - testInfo.addField(new UserInfo.Field( + testInfo.addField(new UserInfoField( "Name Suggestion", "Name Suggestion", false, item -> clicked.set(true))); - testInfo.addField(new UserInfo.Field( + testInfo.addField(new UserInfoField( "Password Suggestion", "Password Suggestion", true, item -> clicked.set(true))); TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.add(new AccessorySheetDataPiece(
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java index 07558b5..dbd5836 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetViewTest.java
@@ -31,6 +31,7 @@ import org.chromium.chrome.browser.keyboard_accessory.R; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.UserInfo; +import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AccessorySheetTabModel.AccessorySheetDataPiece; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -124,9 +125,9 @@ assertThat(mView.get().getChildCount(), is(0)); UserInfo testInfo = new UserInfo(null); - testInfo.addField(new UserInfo.Field( + testInfo.addField(new UserInfoField( "Name Suggestion", "Name Suggestion", false, item -> clicked.set(true))); - testInfo.addField(new UserInfo.Field( + testInfo.addField(new UserInfoField( "Password Suggestion", "Password Suggestion", true, item -> clicked.set(true))); TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.add(new AccessorySheetDataPiece(
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java index 3510106..dccd860 100644 --- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java +++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingControllerTest.java
@@ -69,6 +69,7 @@ import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.Action; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.UserInfo; import org.chromium.chrome.browser.keyboard_accessory.data.PropertyProvider; +import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.chrome.browser.keyboard_accessory.sheet_component.AccessorySheetCoordinator; import org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.PasswordAccessorySheetCoordinator; import org.chromium.chrome.browser.tab.Tab; @@ -189,8 +190,8 @@ AccessorySheetData sheetData = new AccessorySheetData(FallbackSheetType.PASSWORD, "Passwords"); UserInfo userInfo = new UserInfo(null); - userInfo.addField(new UserInfo.Field("(No username)", "No username", false, null)); - userInfo.addField(new UserInfo.Field(passwordString, "Password", true, null)); + userInfo.addField(new UserInfoField("(No username)", "No username", false, null)); + userInfo.addField(new UserInfoField(passwordString, "Password", true, null)); sheetData.getUserInfoList().add(userInfo); mAccessorySheetDataProvider.notifyObservers(sheetData); }
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java index 63840b1..2a6ba34 100644 --- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java +++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/PasswordAccessorySheetControllerTest.java
@@ -44,6 +44,7 @@ import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.FooterCommand; import org.chromium.chrome.browser.keyboard_accessory.data.KeyboardAccessoryData.UserInfo; import org.chromium.chrome.browser.keyboard_accessory.data.PropertyProvider; +import org.chromium.chrome.browser.keyboard_accessory.data.UserInfoField; import org.chromium.ui.modelutil.ListObservable; import java.util.HashMap; @@ -126,9 +127,9 @@ final AccessorySheetData testData = new AccessorySheetData(FallbackSheetType.PASSWORD, "Passwords for this site"); testData.getUserInfoList().add(new UserInfo(null)); - testData.getUserInfoList().get(0).addField(new UserInfo.Field("Name", "Name", false, null)); + testData.getUserInfoList().get(0).addField(new UserInfoField("Name", "Name", false, null)); testData.getUserInfoList().get(0).addField( - new UserInfo.Field("Password", "Password for Name", true, field -> {})); + new UserInfoField("Password", "Password for Name", true, field -> {})); testData.getFooterCommands().add(new FooterCommand("Manage passwords", result -> {})); mCoordinator.registerDataProvider(testProvider); @@ -162,9 +163,9 @@ // As soon UserInfo is available, discard the title. testData.getUserInfoList().add(new UserInfo(null)); - testData.getUserInfoList().get(0).addField(new UserInfo.Field("Name", "Name", false, null)); + testData.getUserInfoList().get(0).addField(new UserInfoField("Name", "Name", false, null)); testData.getUserInfoList().get(0).addField( - new UserInfo.Field("Password", "Password for Name", true, field -> {})); + new UserInfoField("Password", "Password for Name", true, field -> {})); testProvider.notifyObservers(testData); assertThat(mSheetDataPieces.size(), is(2)); @@ -205,16 +206,16 @@ // If the tab is shown with X interactive item, record "X" samples. UserInfo userInfo1 = new UserInfo(null); - userInfo1.addField(new UserInfo.Field("Interactive 1", "", false, (v) -> {})); - userInfo1.addField(new UserInfo.Field("Non-Interactive 1", "", true, null)); + userInfo1.addField(new UserInfoField("Interactive 1", "", false, (v) -> {})); + userInfo1.addField(new UserInfoField("Non-Interactive 1", "", true, null)); accessorySheetData.getUserInfoList().add(userInfo1); UserInfo userInfo2 = new UserInfo(null); - userInfo2.addField(new UserInfo.Field("Interactive 2", "", false, (v) -> {})); - userInfo2.addField(new UserInfo.Field("Non-Interactive 2", "", true, null)); + userInfo2.addField(new UserInfoField("Interactive 2", "", false, (v) -> {})); + userInfo2.addField(new UserInfoField("Non-Interactive 2", "", true, null)); accessorySheetData.getUserInfoList().add(userInfo2); UserInfo userInfo3 = new UserInfo(null); - userInfo3.addField(new UserInfo.Field("Interactive 3", "", false, (v) -> {})); - userInfo3.addField(new UserInfo.Field("Non-Interactive 3", "", true, null)); + userInfo3.addField(new UserInfoField("Interactive 3", "", false, (v) -> {})); + userInfo3.addField(new UserInfoField("Non-Interactive 3", "", true, null)); accessorySheetData.getUserInfoList().add(userInfo3); testProvider.notifyObservers(accessorySheetData); mCoordinator.onTabShown();
diff --git a/chrome/android/features/keyboard_accessory/public/BUILD.gn b/chrome/android/features/keyboard_accessory/public/BUILD.gn index d9371680..2bc922b 100644 --- a/chrome/android/features/keyboard_accessory/public/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/public/BUILD.gn
@@ -13,9 +13,10 @@ ] java_files = [ "java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java", + "java/src/org/chromium/chrome/browser/keyboard_accessory/data/KeyboardAccessoryData.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/data/Provider.java", "java/src/org/chromium/chrome/browser/keyboard_accessory/data/PropertyProvider.java", - "java/src/org/chromium/chrome/browser/keyboard_accessory/data/KeyboardAccessoryData.java", + "java/src/org/chromium/chrome/browser/keyboard_accessory/data/UserInfoField.java", ] srcjar_deps = [ ":java_enums_srcjar" ] }
diff --git a/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/data/KeyboardAccessoryData.java b/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/data/KeyboardAccessoryData.java index 2a828fe..9c80b76 100644 --- a/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/data/KeyboardAccessoryData.java +++ b/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/data/KeyboardAccessoryData.java
@@ -176,7 +176,7 @@ * (username + password), to be shown on the manual fallback UI. */ public final static class UserInfo { - private final List<Field> mFields = new ArrayList<>(); + private final List<UserInfoField> mFields = new ArrayList<>(); private final @Nullable FaviconProvider mFaviconProvider; /** @@ -191,69 +191,6 @@ void fetchFavicon(@Px int desiredSize, Callback<Bitmap> favicon); } - /** - * Represents an item (either selectable or not) presented on the UI, such as the username - * or a credit card number. - */ - public final static class Field { - private final String mDisplayText; - private final String mA11yDescription; - private final boolean mIsObfuscated; - private final Callback<Field> mCallback; - - /** - * Creates a new Field. - * @param displayText The text to display. Plain text if |isObfuscated| is false. - * @param a11yDescription The description used for accessibility. - * @param isObfuscated If true, the displayed caption is transformed into stars. - * @param callback Called when the user taps the suggestions. - */ - public Field(String displayText, String a11yDescription, boolean isObfuscated, - Callback<Field> callback) { - mDisplayText = displayText; - mA11yDescription = a11yDescription; - mIsObfuscated = isObfuscated; - mCallback = callback; - } - - /** - * Returns the text to be displayed on the UI. - */ - public String getDisplayText() { - return mDisplayText; - } - - /** - * Returns a translated description that can be used for accessibility. - */ - public String getA11yDescription() { - return mA11yDescription; - } - - /** - * Returns whether the user can interact with the selected suggestion. For example, - * this is false if this is a password suggestion on a non-password input field. - */ - public boolean isSelectable() { - return mCallback != null; - } - - /** - * Returns true if obfuscation should be applied to the item's caption, for example to - * hide passwords. - */ - public boolean isObfuscated() { - return mIsObfuscated; - } - - /** - * The delegate is called when the Item is selected by a user. - */ - public void triggerSelection() { - if (mCallback != null) mCallback.onResult(this); - } - } - public UserInfo(@Nullable FaviconProvider faviconProvider) { mFaviconProvider = faviconProvider; } @@ -262,14 +199,14 @@ * Adds a new field to the group. * @param field The field to be added. */ - public void addField(Field field) { + public void addField(UserInfoField field) { mFields.add(field); } /** * Returns the list of fields in this group. */ - public List<Field> getFields() { + public List<UserInfoField> getFields() { return mFields; }
diff --git a/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/data/UserInfoField.java b/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/data/UserInfoField.java new file mode 100644 index 0000000..0e44b3a --- /dev/null +++ b/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/data/UserInfoField.java
@@ -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. + +package org.chromium.chrome.browser.keyboard_accessory.data; + +import org.chromium.base.Callback; +import org.chromium.base.annotations.CalledByNative; + +/** + * Represents an item (either selectable or not) presented on the UI, such as the username + * or a credit card number. + */ +public final class UserInfoField { + private final String mDisplayText; + private final String mA11yDescription; + private final boolean mIsObfuscated; + private final Callback<UserInfoField> mCallback; + + /** + * @param displayText The text to display. Plain text if |isObfuscated| is false. + * @param a11yDescription The description used for accessibility. + * @param isObfuscated If true, the displayed caption is transformed into stars. + * @param callback Called when the user taps the suggestions. + */ + public UserInfoField(String displayText, String a11yDescription, boolean isObfuscated, + Callback<UserInfoField> callback) { + mDisplayText = displayText; + mA11yDescription = a11yDescription; + mIsObfuscated = isObfuscated; + mCallback = callback; + } + + /** + * Returns the text to be displayed on the UI. + */ + @CalledByNative + public String getDisplayText() { + return mDisplayText; + } + + /** + * Returns a translated description that can be used for accessibility. + */ + @CalledByNative + public String getA11yDescription() { + return mA11yDescription; + } + + /** + * Returns whether the user can interact with the selected suggestion. For example, + * this is false if this is a password suggestion on a non-password input field. + */ + @CalledByNative + public boolean isSelectable() { + return mCallback != null; + } + + /** + * Returns true if obfuscation should be applied to the item's caption, for example to + * hide passwords. + */ + @CalledByNative + public boolean isObfuscated() { + return mIsObfuscated; + } + + /** + * The delegate is called when the Item is selected by a user. + */ + public void triggerSelection() { + if (mCallback != null) mCallback.onResult(this); + } +}
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index b22fce0..8e21108 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -5,6 +5,14 @@ import("//build/config/android/rules.gni") import("//chrome/common/features.gni") +android_resources("java_resources") { + resource_dirs = [ "java/res" ] + deps = [ + "//chrome/android:chrome_app_java_resources", + ] + custom_package = "org.chromium.chrome.tab_ui" +} + android_library("java") { java_files = [ "java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupUtils.java", @@ -38,6 +46,10 @@ "java/src/org/chromium/chrome/browser/tasks/tab_management/TabListFaviconProvider.java", ] + deps = [ + ":java_resources", + ] + classpath_deps = [ "//base:base_java", "//chrome/android:chrome_java",
diff --git a/chrome/android/java/res/drawable-hdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-hdpi/tabstrip_selected.png similarity index 100% rename from chrome/android/java/res/drawable-hdpi/tabstrip_selected.png rename to chrome/android/features/tab_ui/java/res/drawable-hdpi/tabstrip_selected.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-mdpi/tabstrip_selected.png similarity index 100% rename from chrome/android/java/res/drawable-mdpi/tabstrip_selected.png rename to chrome/android/features/tab_ui/java/res/drawable-mdpi/tabstrip_selected.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-xhdpi/tabstrip_selected.png similarity index 100% rename from chrome/android/java/res/drawable-xhdpi/tabstrip_selected.png rename to chrome/android/features/tab_ui/java/res/drawable-xhdpi/tabstrip_selected.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-xxhdpi/tabstrip_selected.png similarity index 100% rename from chrome/android/java/res/drawable-xxhdpi/tabstrip_selected.png rename to chrome/android/features/tab_ui/java/res/drawable-xxhdpi/tabstrip_selected.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/tabstrip_selected.png b/chrome/android/features/tab_ui/java/res/drawable-xxxhdpi/tabstrip_selected.png similarity index 100% rename from chrome/android/java/res/drawable-xxxhdpi/tabstrip_selected.png rename to chrome/android/features/tab_ui/java/res/drawable-xxxhdpi/tabstrip_selected.png Binary files differ
diff --git a/chrome/android/java/res/drawable/selected_tab_background.xml b/chrome/android/features/tab_ui/java/res/drawable/selected_tab_background.xml similarity index 100% rename from chrome/android/java/res/drawable/selected_tab_background.xml rename to chrome/android/features/tab_ui/java/res/drawable/selected_tab_background.xml
diff --git a/chrome/android/java/res/drawable/tab_grid_card_background.xml b/chrome/android/features/tab_ui/java/res/drawable/tab_grid_card_background.xml similarity index 100% rename from chrome/android/java/res/drawable/tab_grid_card_background.xml rename to chrome/android/features/tab_ui/java/res/drawable/tab_grid_card_background.xml
diff --git a/chrome/android/java/res/drawable/tabstrip_favicon_background.xml b/chrome/android/features/tab_ui/java/res/drawable/tabstrip_favicon_background.xml similarity index 100% rename from chrome/android/java/res/drawable/tabstrip_favicon_background.xml rename to chrome/android/features/tab_ui/java/res/drawable/tabstrip_favicon_background.xml
diff --git a/chrome/android/java/res/layout/bottom_tab_grid_toolbar.xml b/chrome/android/features/tab_ui/java/res/layout/bottom_tab_grid_toolbar.xml similarity index 100% rename from chrome/android/java/res/layout/bottom_tab_grid_toolbar.xml rename to chrome/android/features/tab_ui/java/res/layout/bottom_tab_grid_toolbar.xml
diff --git a/chrome/android/java/res/layout/bottom_tab_strip_toolbar.xml b/chrome/android/features/tab_ui/java/res/layout/bottom_tab_strip_toolbar.xml similarity index 100% rename from chrome/android/java/res/layout/bottom_tab_strip_toolbar.xml rename to chrome/android/features/tab_ui/java/res/layout/bottom_tab_strip_toolbar.xml
diff --git a/chrome/android/java/res/layout/tab_grid_card_item.xml b/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml similarity index 100% rename from chrome/android/java/res/layout/tab_grid_card_item.xml rename to chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml
diff --git a/chrome/android/java/res/layout/tab_list_recycler_view_layout.xml b/chrome/android/features/tab_ui/java/res/layout/tab_list_recycler_view_layout.xml similarity index 100% rename from chrome/android/java/res/layout/tab_list_recycler_view_layout.xml rename to chrome/android/features/tab_ui/java/res/layout/tab_list_recycler_view_layout.xml
diff --git a/chrome/android/java/res/layout/tab_strip_item.xml b/chrome/android/features/tab_ui/java/res/layout/tab_strip_item.xml similarity index 100% rename from chrome/android/java/res/layout/tab_strip_item.xml rename to chrome/android/features/tab_ui/java/res/layout/tab_strip_item.xml
diff --git a/chrome/android/features/tab_ui/java/res/values/dimens.xml b/chrome/android/features/tab_ui/java/res/values/dimens.xml new file mode 100644 index 0000000..487a5fc --- /dev/null +++ b/chrome/android/features/tab_ui/java/res/values/dimens.xml
@@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> +<resources xmlns:tools="http://schemas.android.com/tools"> + <dimen name="tab_grid_favicon_size">32dp</dimen> + <dimen name="tab_list_selected_inset">7dp</dimen> + <dimen name="tab_list_selected_inset_kitkat">2dp</dimen> + <dimen name="tab_list_card_padding">8dp</dimen> + <dimen name="tab_list_mini_card_radius">4dp</dimen> + <dimen name="tab_list_mini_card_frame_size">1dp</dimen> + <dimen name="tab_grid_thumbnail_card_default_size">152dp</dimen> + <dimen name="tab_grid_thumbnail_favicon_frame_padding">16dp</dimen> + <dimen name="tab_grid_thumbnail_favicon_padding">24dp</dimen> + <dimen name="tab_grid_thumbnail_favicon_background_radius">3dp</dimen> + <dimen name="tab_grid_thumbnail_favicon_background_padding">2dp</dimen> + <dimen name="tab_grid_thumbnail_favicon_background_down_shift">2dp</dimen> + <dimen name="swipe_to_dismiss_threshold">72dp</dimen> +</resources>
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java index c5eeaa7..74745363 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java
@@ -18,11 +18,11 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; import org.chromium.base.task.PostTask; -import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.tab_ui.R; import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; @@ -183,21 +183,21 @@ // Initialize Paints to use. mEmptyThumbnailPaint = new Paint(); mEmptyThumbnailPaint.setStyle(Paint.Style.FILL); - mEmptyThumbnailPaint.setColor( - ApiCompatibilityUtils.getColor(context.getResources(), R.color.modern_grey_100)); + mEmptyThumbnailPaint.setColor(ApiCompatibilityUtils.getColor( + context.getResources(), org.chromium.chrome.R.color.modern_grey_100)); mEmptyThumbnailPaint.setAntiAlias(true); mThumbnailFramePaint = new Paint(); mThumbnailFramePaint.setStyle(Paint.Style.STROKE); mThumbnailFramePaint.setStrokeWidth( context.getResources().getDimension(R.dimen.tab_list_mini_card_frame_size)); - mThumbnailFramePaint.setColor( - ApiCompatibilityUtils.getColor(context.getResources(), R.color.modern_grey_300)); + mThumbnailFramePaint.setColor(ApiCompatibilityUtils.getColor( + context.getResources(), org.chromium.chrome.R.color.modern_grey_300)); mThumbnailFramePaint.setAntiAlias(true); mTextPaint = new Paint(); - mTextPaint.setTextSize( - context.getResources().getDimension(R.dimen.compositor_tab_title_text_size)); + mTextPaint.setTextSize(context.getResources().getDimension( + org.chromium.chrome.R.dimen.compositor_tab_title_text_size)); mTextPaint.setFakeBoldText(true); mTextPaint.setAntiAlias(true); mTextPaint.setTextAlign(Paint.Align.CENTER); @@ -212,7 +212,8 @@ 0, context.getResources().getDimension( R.dimen.tab_grid_thumbnail_favicon_background_down_shift), - context.getResources().getColor(R.color.modern_grey_800_alpha_38)); + context.getResources().getColor( + org.chromium.chrome.R.color.modern_grey_800_alpha_38)); // Initialize Rects for thumbnails. float thumbnailPadding = context.getResources().getDimension(R.dimen.tab_list_card_padding);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SilenceLintErrors.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SilenceLintErrors.java index e3714ddd..0035890 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SilenceLintErrors.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SilenceLintErrors.java
@@ -11,30 +11,21 @@ */ /* package */ class SilenceLintErrors { // TODO(yusufo): Add these resources to the DFM - private int[] mRes = new int[] {R.dimen.tab_grid_favicon_size, - R.string.tab_management_module_title, + private int[] mRes = new int[] { R.string.iph_tab_groups_quickly_compare_pages_text, R.string.iph_tab_groups_tap_to_see_another_tab_text, - R.string.iph_tab_groups_your_tabs_together_text, R.string.bottom_tab_grid_description, - R.string.bottom_tab_grid_opened_half, R.string.bottom_tab_grid_opened_full, - R.string.bottom_tab_grid_closed, R.dimen.tab_list_selected_inset, - R.layout.tab_strip_item, R.drawable.selected_tab_background, - R.drawable.tab_grid_card_background, R.layout.tab_grid_card_item, - R.layout.tab_list_recycler_view_layout, R.layout.bottom_tab_grid_toolbar, - R.string.bottom_tab_grid_new_tab, R.string.bottom_tab_grid_new_tab, + R.string.iph_tab_groups_your_tabs_together_text, + R.string.bottom_tab_grid_description, + R.string.bottom_tab_grid_opened_half, + R.string.bottom_tab_grid_opened_full, + R.string.bottom_tab_grid_closed, + R.string.bottom_tab_grid_new_tab, + R.string.bottom_tab_grid_new_tab, R.plurals.bottom_tab_grid_title_placeholder, R.string.iph_tab_groups_tap_to_see_another_tab_accessibility_text, R.string.accessibility_bottom_tab_strip_expand_tab_sheet, - R.layout.bottom_tab_strip_toolbar, R.drawable.tabstrip_selected, - R.dimen.tab_list_card_padding, R.dimen.tab_list_mini_card_text_size, - R.dimen.tab_list_mini_card_frame_size, R.dimen.tab_list_mini_card_radius, - R.drawable.tabstrip_favicon_background, R.dimen.swipe_to_dismiss_threshold, - R.dimen.tab_grid_thumbnail_card_default_size, R.dimen.tab_list_selected_inset_kitkat, - R.dimen.tab_grid_thumbnail_favicon_padding, - R.dimen.tab_grid_thumbnail_favicon_frame_padding, - R.dimen.tab_grid_thumbnail_favicon_background_radius, - R.dimen.tab_grid_thumbnail_favicon_background_padding, - R.dimen.tab_grid_thumbnail_favicon_background_down_shift}; + R.string.accessibility_bottom_tab_grid_close_tab_sheet, + }; private SilenceLintErrors() {} }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetToolbarCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetToolbarCoordinator.java index 6548ef3..557c080 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetToolbarCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridSheetToolbarCoordinator.java
@@ -9,8 +9,8 @@ import android.view.View; import android.view.ViewGroup; -import org.chromium.chrome.R; import org.chromium.chrome.browser.lifecycle.Destroyable; +import org.chromium.chrome.tab_ui.R; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java index 96050bc..250e20ef 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -15,7 +15,7 @@ import android.view.View; import org.chromium.base.Callback; -import org.chromium.chrome.R; +import org.chromium.chrome.tab_ui.R; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -41,7 +41,7 @@ String title = item.get(TabProperties.TITLE); holder.title.setText(title); holder.closeButton.setContentDescription(holder.itemView.getResources().getString( - R.string.accessibility_tabstrip_btn_close_tab, title)); + org.chromium.chrome.R.string.accessibility_tabstrip_btn_close_tab, title)); } else if (TabProperties.IS_SELECTED == propertyKey) { Resources res = holder.itemView.getResources(); Resources.Theme theme = holder.itemView.getContext().getTheme();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewHolder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewHolder.java index 18a89e2..39e270b 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewHolder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewHolder.java
@@ -13,7 +13,7 @@ import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.chrome.R; +import org.chromium.chrome.tab_ui.R; import org.chromium.ui.widget.ButtonCompat; /** @@ -36,15 +36,15 @@ this.favicon = itemView.findViewById(R.id.tab_favicon); this.closeButton = itemView.findViewById(R.id.close_button); DrawableCompat.setTint(this.closeButton.getDrawable(), - ApiCompatibilityUtils.getColor(itemView.getResources(), R.color.light_icon_color)); + ApiCompatibilityUtils.getColor( + itemView.getResources(), org.chromium.chrome.R.color.light_icon_color)); this.createGroupButton = itemView.findViewById(R.id.create_group_button); this.backgroundView = itemView.findViewById(R.id.background_view); } public static TabGridViewHolder create(ViewGroup parent, int itemViewType) { - View view = - LayoutInflater.from(parent.getContext()) - .inflate(org.chromium.chrome.R.layout.tab_grid_card_item, parent, false); + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.tab_grid_card_item, parent, false); return new TabGridViewHolder(view); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiToolbarView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiToolbarView.java index a2ec9d73..87657a0 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiToolbarView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiToolbarView.java
@@ -13,7 +13,7 @@ import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.chrome.R; +import org.chromium.chrome.tab_ui.R; import org.chromium.ui.widget.ChromeImageView; /**
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java index d202496..12fcb47 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -15,12 +15,12 @@ import android.view.LayoutInflater; import android.view.ViewGroup; -import org.chromium.chrome.R; import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupUtils; +import org.chromium.chrome.tab_ui.R; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripToolbarCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripToolbarCoordinator.java index a69b64a..f819ccd 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripToolbarCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripToolbarCoordinator.java
@@ -9,8 +9,8 @@ import android.view.View; import android.view.ViewGroup; -import org.chromium.chrome.R; import org.chromium.chrome.browser.lifecycle.Destroyable; +import org.chromium.chrome.tab_ui.R; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java index a26896a..72c89ae 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java
@@ -10,7 +10,7 @@ import android.support.v7.widget.RecyclerView.ViewHolder; import android.widget.FrameLayout; -import org.chromium.chrome.R; +import org.chromium.chrome.tab_ui.R; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -45,13 +45,13 @@ item.get(TabProperties.TAB_CLOSED_LISTENER).run(holder.getTabId()); }); holder.button.setContentDescription(holder.itemView.getContext().getString( - R.string.accessibility_tabstrip_btn_close_tab, title)); + org.chromium.chrome.R.string.accessibility_tabstrip_btn_close_tab, title)); } else { holder.button.setOnClickListener(view -> { item.get(TabProperties.TAB_SELECTED_LISTENER).run(holder.getTabId()); }); holder.button.setContentDescription(holder.itemView.getContext().getString( - R.string.accessibility_tabstrip_tab, title)); + org.chromium.chrome.R.string.accessibility_tabstrip_tab, title)); } } else if (TabProperties.FAVICON == propertyKey) { Drawable faviconDrawable = item.get(TabProperties.FAVICON);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewHolder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewHolder.java index d199c08..0a1c9550 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewHolder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewHolder.java
@@ -10,7 +10,7 @@ import android.view.ViewGroup; import android.widget.ImageButton; -import org.chromium.chrome.R; +import org.chromium.chrome.tab_ui.R; /** * {@link RecyclerView.ViewHolder} for tab strip.
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinderTest.java index fd6613b..c4c968fe 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinderTest.java
@@ -22,7 +22,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.DisabledTest; -import org.chromium.chrome.R; +import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ui.DummyUiActivity; import org.chromium.chrome.test.ui.DummyUiActivityTestCase; @@ -207,14 +207,14 @@ mContainerModel.set(TabListContainerProperties.IS_INCOGNITO, true); assertThat(mRecyclerView.getBackground(), instanceOf(ColorDrawable.class)); assertThat(((ColorDrawable) mRecyclerView.getBackground()).getColor(), - equalTo(ApiCompatibilityUtils.getColor( - mRecyclerView.getResources(), R.color.incognito_modern_primary_color))); + equalTo(ApiCompatibilityUtils.getColor(mRecyclerView.getResources(), + org.chromium.chrome.R.color.incognito_modern_primary_color))); mContainerModel.set(TabListContainerProperties.IS_INCOGNITO, false); assertThat(mRecyclerView.getBackground(), instanceOf(ColorDrawable.class)); assertThat(((ColorDrawable) mRecyclerView.getBackground()).getColor(), - equalTo(ApiCompatibilityUtils.getColor( - mRecyclerView.getResources(), R.color.modern_primary_color))); + equalTo(ApiCompatibilityUtils.getColor(mRecyclerView.getResources(), + org.chromium.chrome.R.color.modern_primary_color))); } @Test
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java index ad0092fe..19a7c2a 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
@@ -23,8 +23,8 @@ import org.junit.runner.RunWith; import org.chromium.base.Callback; -import org.chromium.chrome.R; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ui.DummyUiActivityTestCase; import org.chromium.content_public.browser.test.util.TestThreadUtils;
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index ecbe8a6..16544e7 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -597,22 +597,6 @@ <!-- Explicit Language Ask Prompt dimensions --> <dimen name="explicit_ask_checkbox_end_padding">4dp</dimen> - <!-- Tab List dimensions --> - <dimen name="tab_grid_favicon_size">32dp</dimen> - <dimen name="tab_list_selected_inset">7dp</dimen> - <dimen name="tab_list_selected_inset_kitkat">2dp</dimen> - <dimen name="tab_list_card_padding">8dp</dimen> - <dimen name="tab_list_mini_card_radius">4dp</dimen> - <dimen name="tab_list_mini_card_frame_size">1dp</dimen> - <dimen name="tab_list_mini_card_text_size">12sp</dimen> - <dimen name="tab_grid_thumbnail_card_default_size">152dp</dimen> - <dimen name="tab_grid_thumbnail_favicon_frame_padding">16dp</dimen> - <dimen name="tab_grid_thumbnail_favicon_padding">24dp</dimen> - <dimen name="tab_grid_thumbnail_favicon_background_radius">3dp</dimen> - <dimen name="tab_grid_thumbnail_favicon_background_padding">2dp</dimen> - <dimen name="tab_grid_thumbnail_favicon_background_down_shift">2dp</dimen> - <dimen name="swipe_to_dismiss_threshold">72dp</dimen> - <!-- RadioButtonWithDescription dimensions --> <dimen name="radio_button_with_description_lateral_padding">16dp</dimen> <dimen name="radio_button_with_description_vertical_padding">10dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java index 85bedb5..019bb97 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java
@@ -118,6 +118,7 @@ || (!monthInput.isFocused() && didFocusOnMonth)) { return ErrorType.EXPIRATION_MONTH; } + // If year was focused before, proceed to check if year is valid. if (!didFocusOnYear) { return ErrorType.NOT_ENOUGH_INFO; } @@ -131,7 +132,10 @@ } return ErrorType.NOT_ENOUGH_INFO; } - + // Year is valid but month is still being edited. + if (month == -1) { + return ErrorType.NOT_ENOUGH_INFO; + } if (year == thisYear && month < thisMonth) { return ErrorType.EXPIRATION_DATE; }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/AutofillUiUtilsTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/AutofillUiUtilsTest.java index c43e899f..9611a50 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/AutofillUiUtilsTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/AutofillUiUtilsTest.java
@@ -148,6 +148,32 @@ @Test @SmallTest @SuppressLint("SetTextI18n") + public void testExpirationDateErrorWithMonthBeingEditedAndValidYearReturnsNotEnoughInfo() { + mMonthInput.setText(""); + mMonthInput.requestFocus(); + mYearInput.setText(String.valueOf(mTwoDigitThisYear + 1)); + + int errorType = getExpirationDateErrorForUserEnteredMonthAndYear(); + + Assert.assertEquals(ErrorType.NOT_ENOUGH_INFO, errorType); + } + + @Test + @SmallTest + @SuppressLint("SetTextI18n") + public void testExpirationDateErrorWithMonthSetToZeroAndValidYearReturnsNotEnoughInfo() { + mMonthInput.setText("0"); + mMonthInput.requestFocus(); + mYearInput.setText(String.valueOf(mTwoDigitThisYear + 1)); + + int errorType = getExpirationDateErrorForUserEnteredMonthAndYear(); + + Assert.assertEquals(ErrorType.NOT_ENOUGH_INFO, errorType); + } + + @Test + @SmallTest + @SuppressLint("SetTextI18n") public void testGetMonthWithNonNumericInputReturnsNegativeOne() { mMonthInput.setText("MM");
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/OWNERS b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/OWNERS new file mode 100644 index 0000000..b946bf67 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/OWNERS
@@ -0,0 +1 @@ +file://chrome/android/java/src/org/chromium/chrome/browser/autofill/OWNERS \ No newline at end of file
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 92e1fb8..e1cac02 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-76.0.3776.0_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-76.0.3777.0_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5e268e4..fd54901 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2573,6 +2573,7 @@ "android/webapps/webapp_registry.h", "android/widget/thumbnail_generator.cc", "android/widget/thumbnail_generator.h", + "autofill/accessory_controller.h", "autofill/android/personal_data_manager_android.cc", "autofill/android/personal_data_manager_android.h", "autofill/android/phone_number_util_android.cc", @@ -2581,6 +2582,8 @@ "autofill/manual_filling_controller.h", "autofill/manual_filling_controller_impl.cc", "autofill/manual_filling_controller_impl.h", + "autofill/manual_filling_utils.cc", + "autofill/manual_filling_utils.h", "autofill/manual_filling_view_interface.h", "banners/app_banner_infobar_delegate_android.cc", "banners/app_banner_infobar_delegate_android.h",
diff --git a/chrome/browser/autofill/accessory_controller.h b/chrome/browser/autofill/accessory_controller.h new file mode 100644 index 0000000..a96f8ef5 --- /dev/null +++ b/chrome/browser/autofill/accessory_controller.h
@@ -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. + +#ifndef CHROME_BROWSER_AUTOFILL_ACCESSORY_CONTROLLER_H_ +#define CHROME_BROWSER_AUTOFILL_ACCESSORY_CONTROLLER_H_ + +#include <vector> + +#include "components/autofill/core/browser/accessory_sheet_data.h" + +// Interface for the portions of type-specific manual filling controllers (e.g., +// password, credit card) which interact with the generic +// ManualFillingController. +class AccessoryController { + public: + virtual ~AccessoryController() = default; + + // Triggered when a user selects an item for filling. This handler is + // responsible for propagating it so that it ultimately ends up in the form + // in the content area. + virtual void OnFillingTriggered( + const autofill::UserInfo::Field& selection) = 0; +}; + +#endif // CHROME_BROWSER_AUTOFILL_ACCESSORY_CONTROLLER_H_
diff --git a/chrome/browser/autofill/manual_filling_controller.h b/chrome/browser/autofill/manual_filling_controller.h index 28eec4e..261b19fa1 100644 --- a/chrome/browser/autofill/manual_filling_controller.h +++ b/chrome/browser/autofill/manual_filling_controller.h
@@ -91,8 +91,8 @@ // Called by the UI code to request that |text_to_fill| is to be filled into // the currently focused field. Forwards the request to a type-specific // accessory controller. - virtual void OnFillingTriggered(bool is_password, - const base::string16& text_to_fill) = 0; + virtual void OnFillingTriggered( + const autofill::UserInfo::Field& selection) = 0; // Called by the UI code because a user triggered the |selected_option|, // such as "Manage passwords..."
diff --git a/chrome/browser/autofill/manual_filling_controller_impl.cc b/chrome/browser/autofill/manual_filling_controller_impl.cc index c5575bd..ac859f4 100644 --- a/chrome/browser/autofill/manual_filling_controller_impl.cc +++ b/chrome/browser/autofill/manual_filling_controller_impl.cc
@@ -98,10 +98,9 @@ } void ManualFillingControllerImpl::OnFillingTriggered( - bool is_password, - const base::string16& text_to_fill) { + const autofill::UserInfo::Field& selection) { DCHECK(pwd_controller_); - pwd_controller_->OnFillingTriggered(is_password, text_to_fill); + pwd_controller_->OnFillingTriggered(selection); } void ManualFillingControllerImpl::OnOptionSelected(
diff --git a/chrome/browser/autofill/manual_filling_controller_impl.h b/chrome/browser/autofill/manual_filling_controller_impl.h index 2dc04c3e..04eaf5e 100644 --- a/chrome/browser/autofill/manual_filling_controller_impl.h +++ b/chrome/browser/autofill/manual_filling_controller_impl.h
@@ -32,8 +32,7 @@ void ShowWhenKeyboardIsVisible(FillingSource source) override; void Hide(FillingSource source) override; void OnAutomaticGenerationStatusChanged(bool available) override; - void OnFillingTriggered(bool is_password, - const base::string16& text_to_fill) override; + void OnFillingTriggered(const autofill::UserInfo::Field& selection) override; void OnOptionSelected(const base::string16& selected_option) const override; void OnGenerationRequested() override; void GetFavicon(
diff --git a/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc b/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc index c3037b4c..50c8fe16 100644 --- a/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc +++ b/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc
@@ -41,7 +41,7 @@ MOCK_METHOD0(DidNavigateMainFrame, void()); MOCK_METHOD2(GetFavicon, void(int, base::OnceCallback<void(const gfx::Image&)>)); - MOCK_METHOD2(OnFillingTriggered, void(bool, const base::string16&)); + MOCK_METHOD1(OnFillingTriggered, void(const autofill::UserInfo::Field&)); MOCK_CONST_METHOD1(OnOptionSelected, void(const base::string16&)); }; @@ -68,7 +68,7 @@ MockPasswordAccessoryView() = default; MOCK_METHOD1(OnItemsAvailable, void(const autofill::AccessorySheetData&)); - MOCK_METHOD1(OnFillingTriggered, void(const base::string16&)); + MOCK_METHOD1(OnFillingTriggered, void(const autofill::UserInfo::Field&)); MOCK_METHOD0(OnViewDestroyed, void()); MOCK_METHOD1(OnAutomaticGenerationStatusChanged, void(bool)); MOCK_METHOD0(CloseAccessorySheet, void()); @@ -202,12 +202,11 @@ TEST_F(ManualFillingControllerTest, OnFillingTriggered) { const char kTextToFill[] = "TextToFill"; const base::string16 text_to_fill(base::ASCIIToUTF16(kTextToFill)); + const autofill::UserInfo::Field field(text_to_fill, text_to_fill, false, + true); - EXPECT_CALL(mock_pwd_controller_, OnFillingTriggered(true, text_to_fill)); - controller()->OnFillingTriggered(true, text_to_fill); - - EXPECT_CALL(mock_pwd_controller_, OnFillingTriggered(false, text_to_fill)); - controller()->OnFillingTriggered(false, text_to_fill); + EXPECT_CALL(mock_pwd_controller_, OnFillingTriggered(field)); + controller()->OnFillingTriggered(field); } TEST_F(ManualFillingControllerTest, OnGenerationRequested) {
diff --git a/chrome/browser/autofill/manual_filling_utils.cc b/chrome/browser/autofill/manual_filling_utils.cc new file mode 100644 index 0000000..28eaa679 --- /dev/null +++ b/chrome/browser/autofill/manual_filling_utils.cc
@@ -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. + +#include "chrome/browser/autofill/manual_filling_utils.h" + +#include <utility> + +#include "chrome/grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" + +namespace autofill { + +AccessorySheetData CreateAccessorySheetData(base::string16 title, + std::vector<UserInfo> user_info) { + // TODO(crbug.com/902425): Remove hard-coded enum value + AccessorySheetData data(FallbackSheetType::PASSWORD, std::move(title)); + for (auto& i : user_info) { + data.add_user_info(std::move(i)); + } + + // TODO(crbug.com/902425): Generalize options (both adding to footer, and + // handling selection). + base::string16 manage_passwords_title = l10n_util::GetStringUTF16( + IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK); + data.add_footer_command(FooterCommand(manage_passwords_title)); + + return data; +} + +} // namespace autofill
diff --git a/chrome/browser/autofill/manual_filling_utils.h b/chrome/browser/autofill/manual_filling_utils.h new file mode 100644 index 0000000..1dbcf3d --- /dev/null +++ b/chrome/browser/autofill/manual_filling_utils.h
@@ -0,0 +1,19 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_UTILS_H_ +#define CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_UTILS_H_ + +#include "components/autofill/core/browser/accessory_sheet_data.h" + +namespace autofill { + +// Creates an AccessorySheetData defining the data to be shown in the filling +// UI. +AccessorySheetData CreateAccessorySheetData(base::string16 title, + std::vector<UserInfo> user_info); + +} // namespace autofill + +#endif // CHROME_BROWSER_AUTOFILL_MANUAL_FILLING_UTILS_H_
diff --git a/chrome/browser/autofill/mock_manual_filling_controller.h b/chrome/browser/autofill/mock_manual_filling_controller.h index 98d84da..c7407ff9 100644 --- a/chrome/browser/autofill/mock_manual_filling_controller.h +++ b/chrome/browser/autofill/mock_manual_filling_controller.h
@@ -24,8 +24,7 @@ MOCK_METHOD1(Hide, void(ManualFillingController::FillingSource)); MOCK_METHOD2(GetFavicon, void(int, base::OnceCallback<void(const gfx::Image&)>)); - MOCK_METHOD2(OnFillingTriggered, - void(bool is_password, const base::string16&)); + MOCK_METHOD1(OnFillingTriggered, void(const autofill::UserInfo::Field&)); MOCK_CONST_METHOD1(OnOptionSelected, void(const base::string16&)); MOCK_METHOD0(OnGenerationRequested, void()); MOCK_CONST_METHOD0(container_view, gfx::NativeView());
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 f3f9e679..376b6ee5 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
@@ -1100,8 +1100,7 @@ void OnRequest(RequestDetails details) override { NOTREACHED(); } - void QueueSignedExchangeReport( - const SignedExchangeReportDetails& details) override { + void QueueSignedExchangeReport(SignedExchangeReportDetails details) override { NOTREACHED(); }
diff --git a/chrome/browser/chromeos/app_mode/app_session.cc b/chrome/browser/chromeos/app_mode/app_session.cc index 15e1adda..5f37e50a 100644 --- a/chrome/browser/chromeos/app_mode/app_session.cc +++ b/chrome/browser/chromeos/app_mode/app_session.cc
@@ -29,10 +29,9 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/pref_names.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" +#include "chromeos/services/power/public/cpp/power_manager_mojo_client.h" #include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_child_process_host_iterator.h" @@ -46,7 +45,6 @@ #include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/guest_view/web_view/web_view_guest.h" -#include "third_party/cros_system_api/dbus/service_constants.h" using extensions::AppWindow; using extensions::AppWindowRegistry; @@ -63,7 +61,7 @@ } void RebootDevice() { - PowerManagerClient::Get()->RequestRestart( + PowerManagerMojoClient::Get()->RequestRestart( power_manager::REQUEST_RESTART_OTHER, "kiosk app session"); }
diff --git a/chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.cc b/chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.cc index ff676377..a6738928 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/common/chrome_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/services/power/public/cpp/power_manager_mojo_client.h" #include "components/user_manager/user_manager.h" #include "extensions/browser/extension_system.h" #include "ui/base/user_activity/user_activity_detector.h" @@ -63,7 +64,7 @@ if (user_activity_detector && user_activity_detector->HasObserver(this)) user_activity_detector->RemoveObserver(this); - auto* power_manager = chromeos::PowerManagerClient::Get(); + auto* power_manager = chromeos::PowerManagerMojoClient::Get(); if (power_manager && power_manager->HasObserver(this)) power_manager->RemoveObserver(this); } @@ -109,7 +110,7 @@ void KioskModeIdleAppNameNotification::Start() { if (!ui::UserActivityDetector::Get()->HasObserver(this)) { ui::UserActivityDetector::Get()->AddObserver(this); - chromeos::PowerManagerClient::Get()->AddObserver(this); + chromeos::PowerManagerMojoClient::Get()->AddObserver(this); } ResetTimer(); }
diff --git a/chrome/browser/chromeos/fileapi/external_file_url_util.cc b/chrome/browser/chromeos/fileapi/external_file_url_util.cc index d2354cd..822c3f70 100644 --- a/chrome/browser/chromeos/fileapi/external_file_url_util.cc +++ b/chrome/browser/chromeos/fileapi/external_file_url_util.cc
@@ -28,7 +28,8 @@ return type == storage::kFileSystemTypeDrive || type == storage::kFileSystemTypeDeviceMediaAsFileStorage || type == storage::kFileSystemTypeProvided || - type == storage::kFileSystemTypeArcContent || force; + type == storage::kFileSystemTypeArcContent || + type == storage::kFileSystemTypeArcDocumentsProvider || force; } GURL FileSystemURLToExternalFileURL(
diff --git a/chrome/browser/chromeos/kiosk_next_home/intent_config_helper.cc b/chrome/browser/chromeos/kiosk_next_home/intent_config_helper.cc index 0fc9a1a..b16d86b 100644 --- a/chrome/browser/chromeos/kiosk_next_home/intent_config_helper.cc +++ b/chrome/browser/chromeos/kiosk_next_home/intent_config_helper.cc
@@ -83,8 +83,7 @@ : ready_(false) { base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, - {base::MayBlock(), base::TaskPriority::USER_VISIBLE, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, + {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, base::BindOnce( [](std::unique_ptr<Delegate> read_config_delegate) { return read_config_delegate->GetJsonConfig();
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc index cca7279..765dfc69 100644 --- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc +++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -723,6 +723,14 @@ SetJsonDevicePolicy(key::kDeviceUpdateStagingSchedule, container.staging_schedule(), policies); } + + if (container.has_device_quick_fix_build_token()) { + policies->Set(key::kDeviceQuickFixBuildToken, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, + std::make_unique<base::Value>( + container.device_quick_fix_build_token()), + nullptr); + } } if (policy.has_allow_kiosk_app_control_chrome_version()) {
diff --git a/chrome/browser/chromeos/power/extension_event_observer.cc b/chrome/browser/chromeos/power/extension_event_observer.cc index be2aa07..09a1e21 100644 --- a/chrome/browser/chromeos/power/extension_event_observer.cc +++ b/chrome/browser/chromeos/power/extension_event_observer.cc
@@ -63,7 +63,6 @@ ExtensionEventObserver::ExtensionEventObserver() : should_delay_suspend_(true), - suspend_is_pending_(false), suspend_keepalive_count_(0), weak_factory_(this) { registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED, @@ -95,11 +94,11 @@ void ExtensionEventObserver::SetShouldDelaySuspend(bool should_delay) { should_delay_suspend_ = should_delay; - if (!should_delay_suspend_ && suspend_is_pending_) { + if (!should_delay_suspend_ && block_suspend_token_) { // There is a suspend attempt pending but this class should no longer be // delaying it. Immediately report readiness. - suspend_is_pending_ = false; - std::move(power_manager_callback_).Run(); + PowerManagerClient::Get()->UnblockSuspend(block_suspend_token_); + block_suspend_token_ = {}; suspend_readiness_callback_.Cancel(); } } @@ -216,8 +215,7 @@ } void ExtensionEventObserver::SuspendDone(const base::TimeDelta& duration) { - suspend_is_pending_ = false; - power_manager_callback_.Reset(); + block_suspend_token_ = {}; suspend_readiness_callback_.Cancel(); } @@ -236,14 +234,13 @@ } void ExtensionEventObserver::OnSuspendImminent(bool dark_suspend) { - if (suspend_is_pending_) { - LOG(WARNING) << "OnSuspendImminent called while previous suspend attempt " - << "is still pending."; - } + DCHECK(block_suspend_token_.is_empty()) + << "OnSuspendImminent called while previous suspend attempt " + << "is still pending."; - suspend_is_pending_ = true; - power_manager_callback_ = - PowerManagerClient::Get()->GetSuspendReadinessCallback(FROM_HERE); + block_suspend_token_ = base::UnguessableToken::Create(); + PowerManagerClient::Get()->BlockSuspend(block_suspend_token_, + "ExtensionEventObserver"); suspend_readiness_callback_.Reset( base::Bind(&ExtensionEventObserver::MaybeReportSuspendReadiness, @@ -263,12 +260,11 @@ } void ExtensionEventObserver::MaybeReportSuspendReadiness() { - if (!suspend_is_pending_ || suspend_keepalive_count_ > 0 || - power_manager_callback_.is_null()) + if (suspend_keepalive_count_ > 0 || block_suspend_token_.is_empty()) return; - suspend_is_pending_ = false; - std::move(power_manager_callback_).Run(); + PowerManagerClient::Get()->UnblockSuspend(block_suspend_token_); + block_suspend_token_ = {}; } } // namespace chromeos
diff --git a/chrome/browser/chromeos/power/extension_event_observer.h b/chrome/browser/chromeos/power/extension_event_observer.h index d4fe0272..f3de4a1f 100644 --- a/chrome/browser/chromeos/power/extension_event_observer.h +++ b/chrome/browser/chromeos/power/extension_event_observer.h
@@ -17,6 +17,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" +#include "base/unguessable_token.h" #include "chromeos/dbus/power/power_manager_client.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_observer.h" @@ -122,9 +123,12 @@ std::set<Profile*> active_profiles_; bool should_delay_suspend_; - bool suspend_is_pending_; int suspend_keepalive_count_; - base::OnceClosure power_manager_callback_; + + // |this| blocks Power Manager suspend with this token. When the token is + // empty, |this| isn't blocking suspend. + base::UnguessableToken block_suspend_token_; + base::CancelableClosure suspend_readiness_callback_; content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index 5843368e0..7c3059a 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -946,8 +946,9 @@ CloseAppWindow(app_window); } +// https://crbug.com/956870 IN_PROC_BROWSER_TEST_F(ExtensionWindowLastFocusedTest, - NoTabIdForDevToolsAndAppWindows) { + DISABLED_NoTabIdForDevToolsAndAppWindows) { Browser* normal_browser = CreateBrowserWithEmptyTab(false); { ActivateBrowserWindow(normal_browser);
diff --git a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc index 7ee710e..945a7eb 100644 --- a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc +++ b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win.cc
@@ -320,7 +320,7 @@ DCHECK(!device_location.empty()); base::string16* pnp_device_id = new base::string16; base::string16* storage_object_id = new base::string16; - base::PostTaskWithTraitsAndReplyWithResult<bool>( + base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {content::BrowserThread::UI}, base::Bind(&GetStorageInfoOnUIThread, device_location, base::Unretained(pnp_device_id),
diff --git a/chrome/browser/notifications/OWNERS b/chrome/browser/notifications/OWNERS index 82f60d8f..02152be 100644 --- a/chrome/browser/notifications/OWNERS +++ b/chrome/browser/notifications/OWNERS
@@ -1,5 +1,6 @@ dewittj@chromium.org dimich@chromium.org +knollr@chromium.org mukai@chromium.org peter@chromium.org stevenjb@chromium.org
diff --git a/chrome/browser/password_manager/password_accessory_controller.h b/chrome/browser/password_manager/password_accessory_controller.h index c17752a..29792ff 100644 --- a/chrome/browser/password_manager/password_accessory_controller.h +++ b/chrome/browser/password_manager/password_accessory_controller.h
@@ -7,11 +7,13 @@ #include <map> #include <memory> +#include <utility> #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" +#include "chrome/browser/autofill/accessory_controller.h" #include "components/autofill/core/common/filling_status.h" #include "components/autofill/core/common/password_generation_util.h" #include "content/public/browser/web_contents_user_data.h" @@ -30,10 +32,11 @@ // On the first call, an instance is attached to |web_contents|, so it can be // returned by subsequent calls. class PasswordAccessoryController - : public base::SupportsWeakPtr<PasswordAccessoryController> { + : public base::SupportsWeakPtr<PasswordAccessoryController>, + public AccessoryController { public: PasswordAccessoryController() = default; - virtual ~PasswordAccessoryController() = default; + ~PasswordAccessoryController() override = default; // Returns true if the accessory controller may exist for |web_contents|. // Otherwise (e.g. if VR is enabled), it returns false. @@ -88,11 +91,6 @@ int desired_size_in_pixel, base::OnceCallback<void(const gfx::Image&)> icon_callback) = 0; - // Called by the UI code to request that |text_to_fill| is to be filled into - // the currently focused field. - virtual void OnFillingTriggered(bool is_password, - const base::string16& text_to_fill) = 0; - // Called by the UI code because a user triggered the |selected_option|, // such as "Manage passwords..." // TODO(crbug.com/905669): Replace the string param with an enum to indicate
diff --git a/chrome/browser/password_manager/password_accessory_controller_impl.cc b/chrome/browser/password_manager/password_accessory_controller_impl.cc index b793a9d..d312374c 100644 --- a/chrome/browser/password_manager/password_accessory_controller_impl.cc +++ b/chrome/browser/password_manager/password_accessory_controller_impl.cc
@@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/android/preferences/preferences_launcher.h" #include "chrome/browser/autofill/manual_filling_controller.h" +#include "chrome/browser/autofill/manual_filling_utils.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/password_manager/password_accessory_metrics_util.h" #include "chrome/browser/profiles/profile.h" @@ -26,6 +27,7 @@ #include "components/password_manager/content/browser/content_password_manager_driver_factory.h" #include "components/password_manager/core/browser/password_manager_driver.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "components/url_formatter/elide_url.h" #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" @@ -35,8 +37,64 @@ using autofill::UserInfo; using FillingSource = ManualFillingController::FillingSource; +namespace { + +autofill::UserInfo Translate(bool current_field_is_password, + const PasswordAccessorySuggestion& data) { + UserInfo user_info; + + user_info.add_field(UserInfo::Field( + data.username, data.username, /*is_password=*/false, + /*selectable=*/data.username_selectable && !current_field_is_password)); + + user_info.add_field(UserInfo::Field( + data.password, + l10n_util::GetStringFUTF16( + IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_DESCRIPTION, data.username), + /*is_password=*/true, /*selectable=*/current_field_is_password)); + + return user_info; +} + +base::string16 GetTitle(bool has_suggestions, const url::Origin& origin) { + const base::string16 elided_url = + url_formatter::FormatOriginForSecurityDisplay( + origin, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC); + return l10n_util::GetStringFUTF16( + has_suggestions + ? IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_TITLE + : IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_EMPTY_MESSAGE, + elided_url); +} + +} // namespace + PasswordAccessoryControllerImpl::~PasswordAccessoryControllerImpl() = default; +void PasswordAccessoryControllerImpl::OnFillingTriggered( + const autofill::UserInfo::Field& selection) { + if (!AppearsInSuggestions(selection.display_text(), selection.is_obfuscated(), + GetFocusedFrameOrigin())) { + NOTREACHED() << "Tried to fill '" << selection.display_text() << "' into " + << GetFocusedFrameOrigin(); + return; // Never fill across different origins! + } + + password_manager::ContentPasswordManagerDriverFactory* factory = + password_manager::ContentPasswordManagerDriverFactory::FromWebContents( + web_contents_); + DCHECK(factory); + password_manager::ContentPasswordManagerDriver* driver = + factory->GetDriverForFrame(web_contents_->GetFocusedFrame()); + if (!driver) { + return; + } // |driver| can be NULL if the tab is being closed. + driver->FillIntoFocusedField( + selection.is_obfuscated(), selection.display_text(), + base::BindOnce(&PasswordAccessoryControllerImpl::OnFilledIntoFocusedField, + base::AsWeakPtr<PasswordAccessoryControllerImpl>(this))); +} + // static bool PasswordAccessoryController::AllowedForWebContents( content::WebContents* web_contents) { @@ -63,24 +121,6 @@ return PasswordAccessoryControllerImpl::FromWebContents(web_contents); } -struct PasswordAccessoryControllerImpl::SuggestionElementData { - SuggestionElementData(base::string16 password, - base::string16 username, - bool username_selectable) - : password(password), - username(username), - username_selectable(username_selectable) {} - - // Password string to be used for this credential. - base::string16 password; - - // Username string to be used for this credential. - base::string16 username; - - // Decides whether the username is interactive (i.e. empty ones are not). - bool username_selectable; -}; - struct PasswordAccessoryControllerImpl::FaviconRequestData { // List of requests waiting for favicons to be available. std::vector<base::OnceCallback<void(const gfx::Image&)>> pending_requests; @@ -107,7 +147,7 @@ void PasswordAccessoryControllerImpl::SavePasswordsForOrigin( const std::map<base::string16, const PasswordForm*>& best_matches, const url::Origin& origin) { - std::vector<SuggestionElementData>* suggestions = + std::vector<PasswordAccessorySuggestion>* suggestions = &origin_suggestions_[origin]; suggestions->clear(); for (const auto& pair : best_matches) { @@ -142,13 +182,25 @@ const url::Origin& origin, bool is_fillable, bool is_password_field) { - current_origin_ = is_fillable ? origin : url::Origin(); + std::vector<UserInfo> info_to_add; + + if (is_fillable) { + const std::vector<PasswordAccessorySuggestion> suggestions = + GetSuggestions(); + info_to_add.resize(suggestions.size()); + std::transform(suggestions.begin(), suggestions.end(), info_to_add.begin(), + [is_password_field](const auto& x) { + return Translate(is_password_field, x); + }); + } + + bool has_suggestions = !info_to_add.empty(); + GetManualFillingController()->RefreshSuggestionsForField( - is_fillable, CreateAccessorySheetData( - origin, - is_fillable ? origin_suggestions_[origin] - : std::vector<SuggestionElementData>(), - is_password_field)); + is_fillable, autofill::CreateAccessorySheetData( + GetTitle(has_suggestions, GetFocusedFrameOrigin()), + std::move(info_to_add))); + if (is_password_field) { GetManualFillingController()->ShowWhenKeyboardIsVisible( FillingSource::PASSWORD_FALLBACKS); @@ -159,7 +211,6 @@ void PasswordAccessoryControllerImpl::DidNavigateMainFrame() { favicon_tracker_.TryCancelAll(); // If there is a request pending, cancel it. - current_origin_ = url::Origin(); icons_request_data_.clear(); origin_suggestions_.clear(); } @@ -167,7 +218,8 @@ void PasswordAccessoryControllerImpl::GetFavicon( int desired_size_in_pixel, base::OnceCallback<void(const gfx::Image&)> icon_callback) { - url::Origin origin = current_origin_; // Copy origin in case it changes. + url::Origin origin = + GetFocusedFrameOrigin(); // Copy origin in case it changes. // Check whether this request can be immediately answered with a cached icon. // It is empty if there wasn't at least one request that found an icon yet. FaviconRequestData* icon_request = &icons_request_data_[origin]; @@ -198,32 +250,6 @@ &favicon_tracker_); } -void PasswordAccessoryControllerImpl::OnFillingTriggered( - bool is_password, - const base::string16& text_to_fill) { - content::RenderFrameHost* target = web_contents_->GetFocusedFrame(); - - const url::Origin& origin = target->GetLastCommittedOrigin(); - if (!AppearsInSuggestions(text_to_fill, is_password, origin)) { - NOTREACHED() << "Tried to fill '" << text_to_fill << "' into " << origin; - return; // Never fill across different origins! - } - - password_manager::ContentPasswordManagerDriverFactory* factory = - password_manager::ContentPasswordManagerDriverFactory::FromWebContents( - web_contents_); - DCHECK(factory); - password_manager::ContentPasswordManagerDriver* driver = - factory->GetDriverForFrame(target); - if (!driver) { - return; - } // |driver| can be NULL if the tab is being closed. - driver->FillIntoFocusedField( - is_password, text_to_fill, - base::BindOnce(&PasswordAccessoryControllerImpl::OnFilledIntoFocusedField, - base::AsWeakPtr<PasswordAccessoryControllerImpl>(this))); -} - PasswordAccessoryControllerImpl::PasswordAccessoryControllerImpl( content::WebContents* web_contents) : web_contents_(web_contents), @@ -241,46 +267,6 @@ mf_controller_(std::move(mf_controller)), favicon_service_(favicon_service) {} -// static -AccessorySheetData PasswordAccessoryControllerImpl::CreateAccessorySheetData( - const url::Origin& origin, - const std::vector<SuggestionElementData>& suggestions, - bool is_password_field) { - // Create the title element - base::string16 passwords_title_str = l10n_util::GetStringFUTF16( - suggestions.empty() - ? IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_EMPTY_MESSAGE - : IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_LIST_TITLE, - base::ASCIIToUTF16(origin.host())); - AccessorySheetData data(autofill::FallbackSheetType::PASSWORD, - passwords_title_str); - - // Create a username and a password element for every suggestion. - for (const SuggestionElementData& suggestion : suggestions) { - UserInfo user_info; - - user_info.add_field(UserInfo::Field( - suggestion.username, suggestion.username, /*is_password=*/false, - /*selectable=*/suggestion.username_selectable && !is_password_field)); - - user_info.add_field(UserInfo::Field( - suggestion.password, - l10n_util::GetStringFUTF16( - IDS_PASSWORD_MANAGER_ACCESSORY_PASSWORD_DESCRIPTION, - suggestion.username), - /*is_password=*/true, /*selectable=*/is_password_field)); - - data.add_user_info(std::move(user_info)); - } - - // Create the link to all passwords. - base::string16 manage_passwords_title = l10n_util::GetStringUTF16( - IDS_PASSWORD_MANAGER_ACCESSORY_ALL_PASSWORDS_LINK); - data.add_footer_command(FooterCommand(manage_passwords_title)); - - return data; -} - void PasswordAccessoryControllerImpl::OnImageFetched( url::Origin origin, const favicon_base::FaviconRawBitmapResult& bitmap_result) { @@ -293,7 +279,7 @@ } icon_request->cached_icon = image_result.image; // Only trigger all the callbacks if they still affect a displayed origin. - if (origin == current_origin_) { + if (origin == GetFocusedFrameOrigin()) { for (auto& callback : icon_request->pending_requests) { std::move(callback).Run(icon_request->cached_icon); } @@ -305,7 +291,8 @@ const base::string16& suggestion, bool is_password, const url::Origin& origin) const { - for (const SuggestionElementData& element : origin_suggestions_.at(origin)) { + for (const PasswordAccessorySuggestion& element : + origin_suggestions_.at(origin)) { const base::string16& candidate = is_password ? element.password : element.username; if (candidate == suggestion) @@ -322,4 +309,16 @@ return mf_controller_; } +url::Origin PasswordAccessoryControllerImpl::GetFocusedFrameOrigin() const { + return web_contents_->GetFocusedFrame()->GetLastCommittedOrigin(); +} + +std::vector<PasswordAccessorySuggestion> +PasswordAccessoryControllerImpl::GetSuggestions() const { + auto it = origin_suggestions_.find(GetFocusedFrameOrigin()); + return it == origin_suggestions_.end() + ? std::vector<PasswordAccessorySuggestion>() + : it->second; +} + WEB_CONTENTS_USER_DATA_KEY_IMPL(PasswordAccessoryControllerImpl)
diff --git a/chrome/browser/password_manager/password_accessory_controller_impl.h b/chrome/browser/password_manager/password_accessory_controller_impl.h index 2c3bd8572..0db305a 100644 --- a/chrome/browser/password_manager/password_accessory_controller_impl.h +++ b/chrome/browser/password_manager/password_accessory_controller_impl.h
@@ -30,6 +30,24 @@ class ManualFillingController; +// Encapsulates the data needed from the password manager backend to +// eventually render a username/password in the manual filling frontend. +// TODO(crbug.com/941654): It's probably cleanest to use PasswordForm directly +// instead of PasswordAccessorySuggestion as the type for the +// AccessoryController. +struct PasswordAccessorySuggestion { + PasswordAccessorySuggestion(base::string16 password, + base::string16 username, + bool username_selectable) + : password(std::move(password)), + username(std::move(username)), + username_selectable(username_selectable) {} + + base::string16 password; + base::string16 username; + bool username_selectable; +}; + // Use either PasswordAccessoryController::GetOrCreate or // PasswordAccessoryController::GetIfExisting to obtain instances of this class. // This class exists for every tab and should never store state based on the @@ -40,6 +58,9 @@ public: ~PasswordAccessoryControllerImpl() override; + // AccessoryController: + void OnFillingTriggered(const autofill::UserInfo::Field& selection) override; + // PasswordAccessoryController: void SavePasswordsForOrigin( const std::map<base::string16, const autofill::PasswordForm*>& @@ -53,8 +74,6 @@ void GetFavicon( int desired_size_in_pixel, base::OnceCallback<void(const gfx::Image&)> icon_callback) override; - void OnFillingTriggered(bool is_password, - const base::string16& text_to_fill) override; void OnOptionSelected(const base::string16& selected_option) const override; // Like |CreateForWebContents|, it creates the controller and attaches it to @@ -66,9 +85,6 @@ favicon::FaviconService* favicon_service); private: - // Data for a credential pair that is transformed into a suggestion. - struct SuggestionElementData; - // Data allowing to cache favicons and favicon-related requests. struct FaviconRequestData; @@ -83,13 +99,6 @@ base::WeakPtr<ManualFillingController> mf_controller, favicon::FaviconService* favicon_service); - // Creates the view items based on the given |suggestions|. - // If |is_password_field| is false, password suggestions won't be interactive. - static autofill::AccessorySheetData CreateAccessorySheetData( - const url::Origin& origin, - const std::vector<SuggestionElementData>& suggestions, - bool is_password_field); - // Handles a favicon response requested by |GetFavicon| and responds to // pending favicon requests with a (possibly empty) icon bitmap. void OnImageFetched( @@ -105,21 +114,20 @@ // |web_contents_|. The lazy initialization allows injecting mocks for tests. base::WeakPtr<ManualFillingController> GetManualFillingController(); + url::Origin GetFocusedFrameOrigin() const; + std::vector<PasswordAccessorySuggestion> GetSuggestions() const; + // ------------------------------------------------------------------------ // Members - Make sure to NEVER store state related to a single frame here! // ------------------------------------------------------------------------ // Contains the last set of credentials by origin. - std::map<url::Origin, std::vector<SuggestionElementData>> origin_suggestions_; + std::map<url::Origin, std::vector<PasswordAccessorySuggestion>> + origin_suggestions_; // The tab for which this class is scoped. content::WebContents* web_contents_; - // TODO(fhorschig): Make sure this works across frames - // The origin of the currently focused frame. It's used to ensure that - // favicons are not displayed across origins. - url::Origin current_origin_; - // TODO(fhorschig): Find a way to use unordered_map with origin keys. // A cache for all favicons that were requested. This includes all iframes // for which the accessory was displayed.
diff --git a/chrome/browser/password_manager/password_accessory_controller_impl_unittest.cc b/chrome/browser/password_manager/password_accessory_controller_impl_unittest.cc index c7055ece..c4c212a 100644 --- a/chrome/browser/password_manager/password_accessory_controller_impl_unittest.cc +++ b/chrome/browser/password_manager/password_accessory_controller_impl_unittest.cc
@@ -205,6 +205,12 @@ void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); NavigateAndCommit(GURL(kExampleSite)); + FocusWebContentsOnMainFrame(); + + ASSERT_TRUE(web_contents()->GetFocusedFrame()); + ASSERT_EQ(url::Origin::Create(GURL(kExampleSite)), + web_contents()->GetFocusedFrame()->GetLastCommittedOrigin()); + PasswordAccessoryControllerImpl::CreateForWebContentsForTesting( web_contents(), mock_manual_filling_controller_.AsWeakPtr(), favicon_service()); @@ -663,12 +669,21 @@ controller()->RefreshSuggestionsForField( url::Origin::Create(GURL(kExampleSite)), true, false); - // Right after starting the favicon request for example.com, another frame on - // the same site is focused. Even if the request is completed, the callback - // should not be called because the origin of the suggestions has changed. + // Right after starting the favicon request for example.com, a navigation + // changes the URL of the focused frame. Even if the request is completed, + // the callback should not be called because the origin of the suggestions + // has changed. EXPECT_CALL(*favicon_service(), GetRawFaviconForPageURL(GURL(kExampleSite), _, kIconSize, _, _, _)) - .WillOnce(favicon::PostReply<6>(favicon_base::FaviconRawBitmapResult())); + .WillOnce(testing::DoAll( + // Triggering a navigation at this moment ensures that the focused + // frame origin changes after the original origin has been sent to the + // favicon service, but before checking whether the origins match (and + // maybe invoking the callback). + testing::InvokeWithoutArgs([this]() { + this->NavigateAndCommit(GURL("https://other.frame.com/")); + }), + favicon::PostReply<6>(favicon_base::FaviconRawBitmapResult()))); EXPECT_CALL(mock_callback, Run).Times(0); controller()->GetFavicon(kIconSize, mock_callback.Get()); EXPECT_CALL(mock_manual_filling_controller_,
diff --git a/chrome/browser/previews/previews_lite_page_decider.cc b/chrome/browser/previews/previews_lite_page_decider.cc index de12c60..036d3af6 100644 --- a/chrome/browser/previews/previews_lite_page_decider.cc +++ b/chrome/browser/previews/previews_lite_page_decider.cc
@@ -50,7 +50,7 @@ // Cleans up the given host blacklist by removing all stale (expiry has passed) // entries. If after removing all stale entries, the blacklist is still over // capacity, then remove the entry with the closest expiration. -void RemoveStaleEntries(base::DictionaryValue* dict) { +void RemoveStaleBlacklistEntries(base::DictionaryValue* dict) { std::vector<std::string> keys_to_delete; base::Time min_value = base::Time::Max(); @@ -405,7 +405,7 @@ host_bypass_blacklist_->SetKey( host, base::Value((base::Time::Now() + duration).ToDoubleT())); - RemoveStaleEntries(host_bypass_blacklist_.get()); + RemoveStaleBlacklistEntries(host_bypass_blacklist_.get()); if (pref_service_) pref_service_->Set(kHostBlacklist, *host_bypass_blacklist_); }
diff --git a/chrome/browser/previews/previews_offline_helper.cc b/chrome/browser/previews/previews_offline_helper.cc index d9cd2a21..977b2bd 100644 --- a/chrome/browser/previews/previews_offline_helper.cc +++ b/chrome/browser/previews/previews_offline_helper.cc
@@ -51,7 +51,7 @@ // Cleans up the given dictionary by removing all stale (expiry has passed) // entries. -void RemoveStaleEntries(base::DictionaryValue* dict) { +void RemoveStaleOfflinePageEntries(base::DictionaryValue* dict) { base::Time earliest_expiry = base::Time::Max(); std::string earliest_key; std::vector<std::string> keys_to_delete; @@ -85,8 +85,8 @@ for (const std::string& key : keys_to_delete) dict->RemoveKey(key); - // RemoveStaleEntries is called for every new added page, so it's fine to just - // remove one at a time to keep the pref size below a threshold. + // RemoveStaleOfflinePageEntries is called for every new added page, so it's + // fine to just remove one at a time to keep the pref size below a threshold. if (dict->DictSize() > previews::params::OfflinePreviewsHelperMaxPrefSize()) { dict->RemoveKey(earliest_key); } @@ -109,7 +109,7 @@ // Tidy up the pref in case it's been a while since the last stale item // removal. - RemoveStaleEntries(available_pages_.get()); + RemoveStaleOfflinePageEntries(available_pages_.get()); UpdatePref(); #if BUILDFLAG(ENABLE_OFFLINE_PAGES) @@ -196,7 +196,7 @@ base::Value(TimeToDictionaryValue(added_page.creation_time))); } - RemoveStaleEntries(available_pages_.get()); + RemoveStaleOfflinePageEntries(available_pages_.get()); UpdatePref(); } @@ -207,7 +207,7 @@ // Has no effect if the url was never in the dictionary. available_pages_->RemoveKey(HashURL(page_info.url)); - RemoveStaleEntries(available_pages_.get()); + RemoveStaleOfflinePageEntries(available_pages_.get()); UpdatePref(); }
diff --git a/chrome/browser/resources/chromeos/camera/src/css/main.css b/chrome/browser/resources/chromeos/camera/src/css/main.css index b852569d..0b2128c 100644 --- a/chrome/browser/resources/chromeos/camera/src/css/main.css +++ b/chrome/browser/resources/chromeos/camera/src/css/main.css
@@ -230,18 +230,20 @@ } .mode-item { - margin: 4px 0; + flex: 0 0 48px; position: relative; } -label.mode-item>span { +div.mode-item>span { border-radius: 13px / 50%; color: white; display: inline-block; font-family: 'Roboto', sans-serif; font-size: 14px; font-weight: 500; - padding: 8px 12px; + line-height: 32px; + margin: 8px 0; + padding: 0 12px; text-shadow: 2px 3px 3px rgba(32, 33, 36, 0.3); } @@ -492,7 +494,7 @@ #camera { --big-icon: 48px; --bottom-line: 56px; - --modes-height: 130px; + --modes-height: 140px; --modes-bottom: calc((var(--bottom-line) + (var(--big-icon) / 2)) + 24px); --small-icon: 40px; }
diff --git a/chrome/browser/resources/chromeos/camera/src/views/main.html b/chrome/browser/resources/chromeos/camera/src/views/main.html index 63b6508b..8c36c92 100644 --- a/chrome/browser/resources/chromeos/camera/src/views/main.html +++ b/chrome/browser/resources/chromeos/camera/src/views/main.html
@@ -57,34 +57,34 @@ <div class="centered-overlay" id="camera-mode"></div> </div> <div id="modes-group" class="buttons right-stripe"> - <label class="mode-item"> + <div class="mode-item"> <input type="radio" name="mode" data-mode="video-mode" tabindex="0" i18n-aria="switch_record_video_button"> <span i18n-content="label_switch_record_video_button" aria-hidden="true"></span> - </label> - <label class="mode-item"> + </div> + <div class="mode-item"> <input type="radio" name="mode" data-mode="photo-mode" tabindex="0" i18n-aria="switch_take_photo_button"> <span i18n-content="label_switch_take_photo_button" aria-hidden="true"></span> - </label> - <label class="mode-item"> + </div> + <div class="mode-item"> <input type="radio" name="mode" data-mode="square-mode" tabindex="0" i18n-aria="switch_take_square_photo_button"> <span i18n-content="label_switch_take_square_photo_button" aria-hidden="true"></span> - </label> - <label class="mode-item"> + </div> + <div class="mode-item"> <input type="radio" name="mode" data-mode="portrait-mode" tabindex="0" i18n-aria="switch_take_portrait_photo_button"> <span i18n-content="label_switch_take_portrait_photo_button" aria-hidden="true"></span> - </label> + </div> </div> <div id="shutters-group" class="buttons right-stripe circle"> <button id="start-recordvideo" class="shutter" tabindex="0"
diff --git a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc index 31cbce9..6c9dbd73 100644 --- a/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_apps_sync_test.cc
@@ -67,7 +67,8 @@ ~TwoClientAppsSyncTest() override {} - bool TestUsesSelfNotifications() override { return false; } + // Needed for AwaitQuiescence(). + bool TestUsesSelfNotifications() override { return true; } private: DISALLOW_COPY_AND_ASSIGN(TwoClientAppsSyncTest); @@ -311,6 +312,8 @@ // have the same launch type values for the CWS. IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, E2E_ENABLED(UpdateLaunchType)) { ASSERT_TRUE(SetupSync()); + // Wait until sync settles before we override the apps below. + ASSERT_TRUE(AwaitQuiescence()); ASSERT_TRUE(AppsMatchChecker().Wait()); // Change the launch type to window. @@ -337,6 +340,8 @@ IN_PROC_BROWSER_TEST_P(TwoClientAppsSyncTest, UnexpectedLaunchType) { ASSERT_TRUE(SetupSync()); + // Wait until sync settles before we override the apps below. + ASSERT_TRUE(AwaitQuiescence()); ASSERT_TRUE(AllProfilesHaveSameApps()); extensions::SetLaunchType(GetProfile(1), extensions::kWebStoreAppId,
diff --git a/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc b/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc index be2b2f2..28628ed 100644 --- a/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" #include "chrome/browser/sync/test/integration/sync_test.h" +#include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "components/sync/base/sync_base_switches.h" #include "components/sync/engine/sync_engine_switches.h" #include "testing/gtest/include/gtest/gtest.h" @@ -91,16 +92,8 @@ EXPECT_TRUE(WaitForBookmarksToMatchVerifier()); } -#if defined(OS_CHROMEOS) -// https://crbug.com/956012 -#define MAYBE_SetPassphraseAndThenSetupSync \ - DISABLED_SetPassphraseAndThenSetupSync -#else -#define MAYBE_SetPassphraseAndThenSetupSync SetPassphraseAndThenSetupSync -#endif - IN_PROC_BROWSER_TEST_F(TwoClientCustomPassphraseSyncTest, - MAYBE_SetPassphraseAndThenSetupSync) { + SetPassphraseAndThenSetupSync) { ASSERT_TRUE(SetupClients()); ASSERT_TRUE(GetClient(kEncryptingClientId)->SetupSync()); @@ -111,6 +104,9 @@ ASSERT_TRUE( PassphraseAcceptedChecker(GetSyncService(kEncryptingClientId)).Wait()); AddTestBookmarksToClient(kEncryptingClientId); + // Wait for the client to commit the update. + ASSERT_TRUE( + UpdatedProgressMarkerChecker(GetSyncService(kEncryptingClientId)).Wait()); // Set up a new sync client. ASSERT_TRUE(
diff --git a/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc index e21a2fe7..e50358d 100644 --- a/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc
@@ -291,10 +291,6 @@ // Flaky on TSAN: crbug.com/915219 #define MAYBE_SetPassphraseAndThenSetupSync \ DISABLED_SetPassphraseAndThenSetupSync -#elif defined(OS_CHROMEOS) -// https://crbug.com/956012 -#define MAYBE_SetPassphraseAndThenSetupSync \ - DISABLED_SetPassphraseAndThenSetupSync #else #define MAYBE_SetPassphraseAndThenSetupSync SetPassphraseAndThenSetupSync #endif @@ -306,6 +302,8 @@ GetSyncService(0)->GetUserSettings()->SetEncryptionPassphrase( kValidPassphrase); ASSERT_TRUE(PassphraseAcceptedChecker(GetSyncService(0)).Wait()); + // Wait for the client to commit the updates. + ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); // When client 1 hits a passphrase required state, we can infer that // client 0's passphrase has been committed. to the server.
diff --git a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc index 10f3ab60..06042542 100644 --- a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
@@ -40,7 +40,8 @@ SyncTest(TWO_CLIENT) {} ~TwoClientPreferencesSyncTest() override {} - bool TestUsesSelfNotifications() override { return false; } + // Needed for AwaitQuiescence(). + bool TestUsesSelfNotifications() override { return true; } private: DISALLOW_COPY_AND_ASSIGN(TwoClientPreferencesSyncTest); @@ -49,6 +50,8 @@ IN_PROC_BROWSER_TEST_P(TwoClientPreferencesSyncTest, E2E_ENABLED(Sanity)) { DisableVerifier(); ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + // Wait until sync settles before we override the prefs below. + ASSERT_TRUE(AwaitQuiescence()); ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait()); const std::string new_home_page = base::StringPrintf( "https://example.com/%s", base::GenerateGUID().c_str());
diff --git a/chrome/browser/sync/test/integration/two_client_themes_sync_test.cc b/chrome/browser/sync/test/integration/two_client_themes_sync_test.cc index a1d92816..a38d771 100644 --- a/chrome/browser/sync/test/integration/two_client_themes_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_themes_sync_test.cc
@@ -27,7 +27,8 @@ : FeatureToggler(switches::kSyncPseudoUSSThemes), SyncTest(TWO_CLIENT) {} ~TwoClientThemesSyncTest() override {} - bool TestUsesSelfNotifications() override { return false; } + // Needed for AwaitQuiescence(). + bool TestUsesSelfNotifications() override { return true; } private: DISALLOW_COPY_AND_ASSIGN(TwoClientThemesSyncTest); @@ -39,6 +40,8 @@ IN_PROC_BROWSER_TEST_P(TwoClientThemesSyncTest, E2E_ENABLED(DefaultThenSyncCustom)) { ASSERT_TRUE(SetupSync()); + // Wait until sync settles before we override the theme below. + AwaitQuiescence(); ASSERT_FALSE(UsingCustomTheme(GetProfile(0))); ASSERT_FALSE(UsingCustomTheme(GetProfile(1))); @@ -66,6 +69,8 @@ SetCustomTheme(GetProfile(1)); ASSERT_TRUE(SetupSync()); + // Wait until sync settles before we override the theme below. + AwaitQuiescence(); UseSystemTheme(GetProfile(0)); ASSERT_TRUE(UsingSystemTheme(GetProfile(0))); @@ -86,6 +91,8 @@ SetCustomTheme(GetProfile(1)); ASSERT_TRUE(SetupSync()); + // Wait until sync settles before we override the theme below. + AwaitQuiescence(); UseDefaultTheme(GetProfile(0)); EXPECT_TRUE(UsingDefaultTheme(GetProfile(0))); @@ -101,6 +108,8 @@ // is intended to test steady-state scenarios. IN_PROC_BROWSER_TEST_P(TwoClientThemesSyncTest, E2E_ENABLED(CycleOptions)) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + // Wait until sync settles before we override the theme below. + AwaitQuiescence(); SetCustomTheme(GetProfile(0));
diff --git a/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc b/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc index 2e3e3843..a780fda 100644 --- a/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" #include "chrome/browser/sync/test/integration/sync_test.h" +#include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "chrome/browser/sync/test/integration/user_events_helper.h" #include "chrome/browser/sync/user_event_service_factory.h" #include "components/sync/protocol/user_event_specifics.pb.h" @@ -61,8 +62,12 @@ GetSyncService(kEncryptingClientId) ->GetUserSettings() ->SetEncryptionPassphrase("hunter2"); + UpdatedProgressMarkerChecker update_checker( + GetSyncService(kEncryptingClientId)); ASSERT_TRUE( PassphraseAcceptedChecker(GetSyncService(kEncryptingClientId)).Wait()); + // Make sure the updates are committed before proceeding with the test. + ASSERT_TRUE(update_checker.Wait()); // Record a user event on the second client before setting up sync (before // knowing it will be encrypted). This event should not get recorded while
diff --git a/chrome/browser/sync/test/integration/two_client_wallet_sync_test.cc b/chrome/browser/sync/test/integration/two_client_wallet_sync_test.cc index 67ea5eb..17ae71c 100644 --- a/chrome/browser/sync/test/integration/two_client_wallet_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_wallet_sync_test.cc
@@ -60,7 +60,8 @@ } ~TwoClientWalletSyncTest() override {} - bool TestUsesSelfNotifications() override { return false; } + // Needed for AwaitQuiescence(). + bool TestUsesSelfNotifications() override { return true; } bool SetupSync() override { test_clock_.SetNow(kArbitraryDefaultTime); @@ -505,6 +506,9 @@ CreateSyncWalletAddress(/*name=*/"address-1", /*company=*/"Company-1"), CreateDefaultSyncPaymentsCustomerData()}); ASSERT_TRUE(SetupSync()); + // Wait until sync settles (for the wallet metadata) before we change the + // data again. + ASSERT_TRUE(AwaitQuiescence()); // Grab the current address on the first client. std::vector<AutofillProfile*> server_addresses = GetServerProfiles(0); @@ -553,6 +557,9 @@ CreateSyncWalletAddress(/*name=*/"address-1", /*company=*/"Company-1"), CreateDefaultSyncPaymentsCustomerData()}); ASSERT_TRUE(SetupSync()); + // Wait until sync settles (for the wallet metadata) before we change the + // data again. + ASSERT_TRUE(AwaitQuiescence()); // Grab the current card on the first client. std::vector<CreditCard*> credit_cards = GetServerCreditCards(0);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 23e65c09..ce02205c 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -450,6 +450,7 @@ "//components/password_manager/content/browser", "//components/password_manager/core/browser", "//components/payments/content:utils", + "//components/payments/content/icon", "//components/pdf/browser", "//components/policy/core/browser", "//components/pref_registry",
diff --git a/chrome/browser/ui/android/passwords/manual_filling_view_android.cc b/chrome/browser/ui/android/passwords/manual_filling_view_android.cc index ed05d00..3e43edd 100644 --- a/chrome/browser/ui/android/passwords/manual_filling_view_android.cc +++ b/chrome/browser/ui/android/passwords/manual_filling_view_android.cc
@@ -23,6 +23,7 @@ #include "components/autofill/core/browser/accessory_sheet_data.h" #include "components/autofill/core/common/password_form.h" #include "jni/ManualFillingComponentBridge_jni.h" +#include "jni/UserInfoField_jni.h" #include "ui/android/view_android.h" #include "ui/android/window_android.h" #include "ui/gfx/android/java_bitmap.h" @@ -31,7 +32,9 @@ using autofill::AccessorySheetData; using autofill::FooterCommand; using autofill::UserInfo; +using base::android::ConvertJavaStringToUTF16; using base::android::ConvertUTF16ToJavaString; +using base::android::JavaRef; using base::android::ScopedJavaLocalRef; ManualFillingViewAndroid::ManualFillingViewAndroid( @@ -107,9 +110,9 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jboolean isPassword, - const base::android::JavaParamRef<_jstring*>& textToFill) { + const base::android::JavaParamRef<jobject>& j_user_info_field) { controller_->OnFillingTriggered( - isPassword, base::android::ConvertJavaStringToUTF16(textToFill)); + ConvertJavaUserInfoField(env, j_user_info_field)); } void ManualFillingViewAndroid::OnOptionSelected( @@ -166,6 +169,19 @@ return j_tab_data; } +UserInfo::Field ManualFillingViewAndroid::ConvertJavaUserInfoField( + JNIEnv* env, + const JavaRef<jobject>& j_field_to_convert) { + base::string16 display_text = ConvertJavaStringToUTF16( + env, Java_UserInfoField_getDisplayText(env, j_field_to_convert)); + base::string16 a11y_description = ConvertJavaStringToUTF16( + env, Java_UserInfoField_getA11yDescription(env, j_field_to_convert)); + bool is_obfuscated = Java_UserInfoField_isObfuscated(env, j_field_to_convert); + bool selectable = Java_UserInfoField_isSelectable(env, j_field_to_convert); + return UserInfo::Field(display_text, a11y_description, is_obfuscated, + selectable); +} + // static void JNI_ManualFillingComponentBridge_CachePasswordSheetDataForTesting( JNIEnv* env,
diff --git a/chrome/browser/ui/android/passwords/manual_filling_view_android.h b/chrome/browser/ui/android/passwords/manual_filling_view_android.h index 4decce8..093393dd 100644 --- a/chrome/browser/ui/android/passwords/manual_filling_view_android.h +++ b/chrome/browser/ui/android/passwords/manual_filling_view_android.h
@@ -9,6 +9,7 @@ #include "base/android/scoped_java_ref.h" #include "chrome/browser/autofill/manual_filling_view_interface.h" +#include "components/autofill/core/browser/accessory_sheet_data.h" namespace gfx { class Image; @@ -43,7 +44,7 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jboolean isPassword, - const base::android::JavaParamRef<jstring>& textToFill); + const base::android::JavaParamRef<jobject>& j_user_info_field); void OnOptionSelected( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, @@ -61,6 +62,10 @@ JNIEnv* env, const autofill::AccessorySheetData& tab_data); + autofill::UserInfo::Field ConvertJavaUserInfoField( + JNIEnv* env, + const base::android::JavaRef<jobject>& j_field_to_convert); + // The controller provides data for this view and owns it. ManualFillingController* controller_;
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc index 2376598..b880021 100644 --- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" #include "chrome/browser/ui/views/payments/payment_request_views_util.h" #include "chrome/grit/generated_resources.h" +#include "components/payments/content/icon/icon_size.h" #include "components/payments/content/origin_security_checker.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" @@ -114,18 +115,19 @@ top_level_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 1.0, views::GridLayout::USE_PREF, 0, 0); - // Payment handler icon should be 32 pixels tall. - constexpr int kPaymentHandlerIconHeight = 32; const bool has_icon = icon_image_skia.width() && icon_image_skia.height(); float adjusted_width = base::checked_cast<float>(icon_image_skia.width()); if (has_icon) { adjusted_width = - adjusted_width * kPaymentHandlerIconHeight / icon_image_skia.height(); + adjusted_width * + IconSizeCalculator::kPaymentAppDeviceIndependentIdealIconHeight / + icon_image_skia.height(); // A column for the instrument icon. top_level_columns->AddColumn( views::GridLayout::LEADING, views::GridLayout::FILL, views::GridLayout::kFixedSize, views::GridLayout::FIXED, - adjusted_width, kPaymentHandlerIconHeight); + adjusted_width, + IconSizeCalculator::kPaymentAppDeviceIndependentIdealIconHeight); top_level_columns->AddPaddingColumn(views::GridLayout::kFixedSize, 8); } @@ -135,8 +137,11 @@ std::unique_ptr<views::ImageView> instrument_icon_view = CreateInstrumentIconView(/*icon_id=*/0, icon_image_skia, /*label=*/page_title); - instrument_icon_view->SetImageSize( - gfx::Size(adjusted_width, kPaymentHandlerIconHeight)); + // We should set image size in density independent pixels here, since + // views::ImageView objects are rastered at the device scale factor. + instrument_icon_view->SetImageSize(gfx::Size( + adjusted_width, + IconSizeCalculator::kPaymentAppDeviceIndependentIdealIconHeight)); top_level_layout->AddView(instrument_icon_view.release()); } }
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index 4176b3e6..1ce4ad3 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -20,6 +20,7 @@ #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/phone_number_i18n.h" +#include "components/payments/content/icon/icon_size.h" #include "components/payments/core/payment_options_provider.h" #include "components/payments/core/payment_request_data_util.h" #include "components/payments/core/payments_profile_comparator.h" @@ -249,11 +250,11 @@ float ratio = 1; if (width && height) ratio = width / height; - // Other instrument icons should be 32 pixels high while preserving the - // image ratio. - constexpr int kPaymentHandlerIconHeight = 32; - icon_view->SetImageSize(gfx::Size(ratio * kPaymentHandlerIconHeight, - kPaymentHandlerIconHeight)); + // We should set image size in density indepent pixels here, since + // views::ImageView objects are rastered at the device scale factor. + icon_view->SetImageSize(gfx::Size( + ratio * IconSizeCalculator::kPaymentAppDeviceIndependentIdealIconHeight, + IconSizeCalculator::kPaymentAppDeviceIndependentIdealIconHeight)); } else { icon_view->SetImage(ui::ResourceBundle::GetSharedInstance() .GetImageNamed(icon_resource_id)
diff --git a/chrome/browser/unified_consent/unified_consent_browsertest.cc b/chrome/browser/unified_consent/unified_consent_browsertest.cc index caa7078..97d414e 100644 --- a/chrome/browser/unified_consent/unified_consent_browsertest.cc +++ b/chrome/browser/unified_consent/unified_consent_browsertest.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_test.h" +#include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/unified_consent/unified_consent_service_factory.h" #include "chrome/common/pref_names.h" @@ -118,9 +119,8 @@ "UnifiedConsent.SyncAndGoogleServicesSettings", 1); } -// Flakes on all platforms. http://crbug.com/954167 IN_PROC_BROWSER_TEST_F(UnifiedConsentBrowserTest, - DISABLED_SettingsOptInTakeOverServicePrefChanges) { + SettingsOptInTakeOverServicePrefChanges) { std::string pref_A = prefs::kSearchSuggestEnabled; std::string pref_B = prefs::kAlternateErrorPagesEnabled; @@ -130,6 +130,8 @@ // both prefs will be "off". GetProfile(0)->GetPrefs()->SetBoolean(pref_A, false); GetProfile(0)->GetPrefs()->SetBoolean(pref_B, false); + // Make sure the updates are committed before proceeding with the test. + ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); // Second client: Turn off both prefs while sync is off. GetProfile(1)->GetPrefs()->SetBoolean(pref_A, false);
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 809b181..daa5cfe 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -160,7 +160,11 @@ "https://www.chrome.com/manage"; const char kManagedUiLearnMoreUrl[] = +#if defined(OS_CHROMEOS) "https://support.google.com/chromebook/?p=is_chrome_managed"; +#else + "https://support.google.com/chrome/?p=is_chrome_managed"; +#endif const char kMyActivityUrlInClearBrowsingData[] = "https://myactivity.google.com/myactivity/?utm_source=chrome_cbd";
diff --git a/chromeos/components/power/dark_resume_controller.cc b/chromeos/components/power/dark_resume_controller.cc index 0782ee9..891a977 100644 --- a/chromeos/components/power/dark_resume_controller.cc +++ b/chromeos/components/power/dark_resume_controller.cc
@@ -31,8 +31,9 @@ void DarkResumeController::DarkSuspendImminent() { DVLOG(1) << __func__; - suspend_readiness_cb_ = - PowerManagerClient::Get()->GetSuspendReadinessCallback(FROM_HERE); + block_suspend_token_ = base::UnguessableToken::Create(); + PowerManagerClient::Get()->BlockSuspend(block_suspend_token_, + "DarkResumeController"); // Schedule task that will check for any wake locks acquired in dark resume. DCHECK(!wake_lock_check_timer_.IsRunning()); wake_lock_check_timer_.Start( @@ -59,20 +60,20 @@ // with dark resume. DVLOG(1) << __func__; // The observer is only registered once dark resume starts. - DCHECK(suspend_readiness_cb_); - std::move(suspend_readiness_cb_).Run(); + DCHECK(block_suspend_token_); + PowerManagerClient::Get()->UnblockSuspend(block_suspend_token_); + block_suspend_token_ = {}; ClearDarkResumeState(); } bool DarkResumeController::IsDarkResumeStateSetForTesting() const { - return !suspend_readiness_cb_.is_null() && - wake_lock_observer_binding_.is_bound(); + return block_suspend_token_ && wake_lock_observer_binding_.is_bound(); } bool DarkResumeController::IsDarkResumeStateClearedForTesting() const { return !weak_ptr_factory_.HasWeakPtrs() && !wake_lock_check_timer_.IsRunning() && - !hard_timeout_timer_.IsRunning() && suspend_readiness_cb_.is_null() && + !hard_timeout_timer_.IsRunning() && !block_suspend_token_ && !wake_lock_observer_binding_.is_bound(); } @@ -104,16 +105,17 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(dark_resume_tasks_sequence_checker_); hard_timeout_timer_.Stop(); // Enough is enough. Tell power daemon it's okay to suspend. - DCHECK(suspend_readiness_cb_); - std::move(suspend_readiness_cb_).Run(); + DCHECK(block_suspend_token_); + PowerManagerClient::Get()->UnblockSuspend(block_suspend_token_); + block_suspend_token_ = {}; ClearDarkResumeState(); } void DarkResumeController::ClearDarkResumeState() { DVLOG(1) << __func__; - // Reset the callback that is used to trigger a re-suspend. Won't be needed + // Reset the token that is used to trigger a re-suspend. Won't be needed // if the dark resume state machine is ending. - suspend_readiness_cb_.Reset(); + block_suspend_token_ = {}; // This automatically invalidates any WakeLockObserver and associated callback // in this case OnDeactivation.
diff --git a/chromeos/components/power/dark_resume_controller.h b/chromeos/components/power/dark_resume_controller.h index 9655795..9853321 100644 --- a/chromeos/components/power/dark_resume_controller.h +++ b/chromeos/components/power/dark_resume_controller.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" +#include "base/unguessable_token.h" #include "chromeos/dbus/power/power_manager_client.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/device/public/mojom/wake_lock.mojom.h" @@ -68,11 +69,11 @@ void OnWakeLockDeactivated(device::mojom::WakeLockType type) override; // Return true iff all dark resume related state is set i.e the suspend - // readiness callback is set and wake lock release event has observers. + // readiness token is set and wake lock release event has observers. bool IsDarkResumeStateSetForTesting() const; // Return true iff all dark resume related state is reset i.e. suspend - // readiness callback is null, wake lock release event has no observers, + // readiness token is empty, wake lock release event has no observers, // wake lock check timer is reset, hard timeout timer is reset and there are // no in flight tasks. This should be true when device exits dark resume // either by re-suspending or transitioning to full resume. @@ -98,9 +99,9 @@ // Not owned by this instance. service_manager::Connector* const connector_; - // Called when system is ready to supend after a DarkSupendImminent i.e. + // Used when system is ready to suspend after a DarkSupendImminent i.e. // after a dark resume. - base::OnceClosure suspend_readiness_cb_; + base::UnguessableToken block_suspend_token_; // The binding used to implement device::mojom::WakeLockObserver. mojo::Binding<device::mojom::WakeLockObserver> wake_lock_observer_binding_;
diff --git a/chromeos/dbus/power/fake_power_manager_client.cc b/chromeos/dbus/power/fake_power_manager_client.cc index 9bf45d85..487c9abae 100644 --- a/chromeos/dbus/power/fake_power_manager_client.cc +++ b/chromeos/dbus/power/fake_power_manager_client.cc
@@ -249,11 +249,16 @@ FROM_HERE, base::BindOnce(std::move(callback), inactivity_delays_)); } -base::OnceClosure FakePowerManagerClient::GetSuspendReadinessCallback( - const base::Location& from_where) { +void FakePowerManagerClient::BlockSuspend(const base::UnguessableToken& token, + const std::string& debug_info) { ++num_pending_suspend_readiness_callbacks_; - return base::BindOnce(&FakePowerManagerClient::HandleSuspendReadiness, - base::Unretained(this)); +} + +void FakePowerManagerClient::UnblockSuspend( + const base::UnguessableToken& token) { + CHECK_GT(num_pending_suspend_readiness_callbacks_, 0); + + --num_pending_suspend_readiness_callbacks_; } void FakePowerManagerClient::CreateArcTimers( @@ -423,12 +428,6 @@ observer.PowerChanged(*props_); } -void FakePowerManagerClient::HandleSuspendReadiness() { - CHECK_GT(num_pending_suspend_readiness_callbacks_, 0); - - --num_pending_suspend_readiness_callbacks_; -} - void FakePowerManagerClient::DeleteArcTimersInternal(const std::string& tag) { // Retrieve all timer ids associated with |tag|. Delete all timers associated // with these timer ids.
diff --git a/chromeos/dbus/power/fake_power_manager_client.h b/chromeos/dbus/power/fake_power_manager_client.h index 1a376e55..c3a0a70 100644 --- a/chromeos/dbus/power/fake_power_manager_client.h +++ b/chromeos/dbus/power/fake_power_manager_client.h
@@ -111,8 +111,9 @@ void GetInactivityDelays( DBusMethodCallback<power_manager::PowerManagementPolicy::Delays> callback) override; - base::OnceClosure GetSuspendReadinessCallback( - const base::Location& from_where) override; + void BlockSuspend(const base::UnguessableToken& token, + const std::string& debug_info) override; + void UnblockSuspend(const base::UnguessableToken& token) override; void CreateArcTimers( const std::string& tag, std::vector<std::pair<clockid_t, base::ScopedFD>> arc_timer_requests, @@ -186,10 +187,6 @@ } private: - // Callback that will be run by asynchronous suspend delays to report - // readiness. - void HandleSuspendReadiness(); - // Notifies |observers_| that |props_| has been updated. void NotifyObservers();
diff --git a/chromeos/dbus/power/power_manager_client.cc b/chromeos/dbus/power/power_manager_client.cc index b94b799..f6b9d9c 100644 --- a/chromeos/dbus/power/power_manager_client.cc +++ b/chromeos/dbus/power/power_manager_client.cc
@@ -23,6 +23,7 @@ #include "base/strings/stringprintf.h" #include "base/threading/platform_thread.h" #include "base/timer/timer.h" +#include "base/unguessable_token.h" #include "chromeos/dbus/power/fake_power_manager_client.h" #include "chromeos/dbus/power_manager/backlight.pb.h" #include "chromeos/dbus/power_manager/idle.pb.h" @@ -452,17 +453,30 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } - base::OnceClosure GetSuspendReadinessCallback( - const base::Location& from_where) override { + void BlockSuspend(const base::UnguessableToken& token, + const std::string& debug_info) override { DCHECK(OnOriginThread()); DCHECK(suspend_is_pending_); + DCHECK(token); - const int callback_id = next_suspend_readiness_callback_id_++; - pending_suspend_readiness_callbacks_[callback_id] = from_where; - return base::BindOnce( - &PowerManagerClientImpl::HandleObserverSuspendReadiness, - weak_ptr_factory_.GetWeakPtr(), pending_suspend_id_, - suspending_from_dark_resume_, callback_id); + suspend_readiness_registry_[token.ToString()] = { + pending_suspend_id_, suspending_from_dark_resume_, debug_info}; + } + + void UnblockSuspend(const base::UnguessableToken& token) override { + DCHECK(OnOriginThread()); + auto registration = suspend_readiness_registry_.find(token.ToString()); + + if (registration == suspend_readiness_registry_.end() || + registration->second.suspend_id != pending_suspend_id_ || + registration->second.suspending_from_dark_resume != + suspending_from_dark_resume_ || + !suspend_is_pending_) { + return; + } + + suspend_readiness_registry_.erase(registration); + MaybeReportSuspendReadiness(); } void CreateArcTimers( @@ -843,12 +857,11 @@ pending_suspend_id_ = proto.suspend_id(); suspend_is_pending_ = true; suspending_from_dark_resume_ = in_dark_resume; - pending_suspend_readiness_callbacks_.clear(); + suspend_readiness_registry_.clear(); // Record the fact that observers are being notified to ensure that we don't - // report readiness prematurely if one of them calls - // GetSuspendReadinessCallback() and then runs the callback synchonously - // instead of asynchronously. + // report readiness prematurely if one of them calls BlockSuspend() and then + // runs UnblockSuspend() synchonously instead of asynchronously. notifying_observers_about_suspend_imminent_ = true; if (suspending_from_dark_resume_) { for (auto& observer : observers_) @@ -897,11 +910,11 @@ // powerd gives clients a limited amount of time to report suspend // readiness. Log the stragglers within Chrome to aid in debugging. - for (const auto it : pending_suspend_readiness_callbacks_) { + for (const auto it : suspend_readiness_registry_) { LOG(WARNING) << "Didn't report suspend readiness due to " - << it.second.ToString(); + << it.second.debug_info; } - pending_suspend_readiness_callbacks_.clear(); + suspend_readiness_registry_.clear(); for (auto& observer : observers_) observer.SuspendDone(duration); @@ -1032,22 +1045,6 @@ power_manager::kRegisterDarkSuspendDelayMethod)); } - // Records the fact that an observer has finished doing asynchronous work - // that was blocking a pending suspend attempt and possibly reports - // suspend readiness to powerd. Called by callbacks returned via - // GetSuspendReadinessCallback(). - void HandleObserverSuspendReadiness(int32_t suspend_id, - bool in_dark_resume, - int callback_id) { - DCHECK(OnOriginThread()); - if (!suspend_is_pending_ || suspend_id != pending_suspend_id_ || - in_dark_resume != suspending_from_dark_resume_) - return; - - pending_suspend_readiness_callbacks_.erase(callback_id); - MaybeReportSuspendReadiness(); - } - // Reports suspend readiness to powerd if no observers are still holding // suspend readiness callbacks. void MaybeReportSuspendReadiness() { @@ -1058,7 +1055,7 @@ if (notifying_observers_about_suspend_imminent_) return; - if (!pending_suspend_readiness_callbacks_.empty()) + if (!suspend_readiness_registry_.empty()) return; std::string method_name; @@ -1123,13 +1120,15 @@ // helps distinguish the context within which these variables are being used. bool suspending_from_dark_resume_ = false; - // Next ID to be assigned to a callback returned via - // GetSuspendReadinessCallback(). - int next_suspend_readiness_callback_id_ = 1; + struct SuspendInfo { + int32_t suspend_id; + bool suspending_from_dark_resume; + std::string debug_info; + }; - // Map from suspend readiness callback ID to the location of the code that - // requested the callback. - std::map<int, base::Location> pending_suspend_readiness_callbacks_; + // A map that holds BlockSuspend() registrations. It maps from the token (in + // string form) to details about the suspend. + std::unordered_map<std::string, SuspendInfo> suspend_readiness_registry_; // Inspected by MaybeReportSuspendReadiness() to avoid prematurely notifying // powerd about suspend readiness while |observers_|' SuspendImminent()
diff --git a/chromeos/dbus/power/power_manager_client.h b/chromeos/dbus/power/power_manager_client.h index 5ea004b..b6f3a967a 100644 --- a/chromeos/dbus/power/power_manager_client.h +++ b/chromeos/dbus/power/power_manager_client.h
@@ -24,6 +24,10 @@ #include "chromeos/dbus/power_manager/suspend.pb.h" #include "third_party/cros_system_api/dbus/service_constants.h" +namespace base { +class UnguessableToken; +} + namespace dbus { class Bus; } @@ -108,9 +112,9 @@ // all observers' implementations of this method have finished running. // // If an observer wishes to asynchronously delay suspend, - // PowerManagerClient::GetSuspendReadinessCallback() may be called from - // within SuspendImminent(). The returned callback must be called once - // the observer is ready for suspend. + // PowerManagerClient::BlockSuspend() may be called from within + // SuspendImminent(). UnblockSuspend() must be called once the observer is + // ready for suspend. virtual void SuspendImminent( power_manager::SuspendImminent::Reason reason) {} @@ -122,8 +126,8 @@ // Called when the system is about to resuspend from a dark resume. Like // SuspendImminent(), the suspend will be deferred until all observers have // finished running and those observers that wish to asynchronously delay - // the suspend should call PowerManagerClient::GetSuspendReadinessCallback() - // from within this method. The returned callback should be run once the + // the suspend should call PowerManagerClient::BlockSuspend() + // from within this method. UnblockSuspend() must be called once the // observer is ready for suspend. virtual void DarkSuspendImminent() {} @@ -275,10 +279,17 @@ DBusMethodCallback<power_manager::PowerManagementPolicy::Delays> callback) = 0; - // Returns a callback that can be called by an observer to report readiness - // for suspend. See Observer::SuspendImminent(). - virtual base::OnceClosure GetSuspendReadinessCallback( - const base::Location& from_where) = 0; + // Used by client code to temporarily block an imminent suspend (for up to + // kSuspendDelayTimeoutMs, i.e. 5 seconds). See Observer::SuspendImminent. + // |debug_info| should be a human-readable string that assists in determining + // what code called BlockSuspend(). Afterwards, callers must release the block + // via UnblockSuspend. + virtual void BlockSuspend(const base::UnguessableToken& token, + const std::string& debug_info) = 0; + + // Used to indicate that the client code which passed |token| before is now + // ready for a suspend. + virtual void UnblockSuspend(const base::UnguessableToken& token) = 0; // Creates timers corresponding to clocks present in |arc_timer_requests|. // ScopedFDs are used to indicate timer expiration as described in
diff --git a/chromeos/dbus/power/power_manager_client_unittest.cc b/chromeos/dbus/power/power_manager_client_unittest.cc index 181ad5c..51aeaec1 100644 --- a/chromeos/dbus/power/power_manager_client_unittest.cc +++ b/chromeos/dbus/power/power_manager_client_unittest.cc
@@ -16,6 +16,7 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/unguessable_token.h" #include "chromeos/dbus/power_manager/suspend.pb.h" #include "dbus/mock_bus.h" #include "dbus/mock_object_proxy.h" @@ -92,47 +93,47 @@ int num_suspend_imminent() const { return num_suspend_imminent_; } int num_suspend_done() const { return num_suspend_done_; } int num_dark_suspend_imminent() const { return num_dark_suspend_imminent_; } - base::OnceClosure suspend_readiness_callback() { - return std::move(suspend_readiness_callback_); + const base::UnguessableToken& block_suspend_token() const { + return block_suspend_token_; } - void set_take_suspend_readiness_callback(bool take_callback) { - take_suspend_readiness_callback_ = take_callback; + void set_should_block_suspend(bool take_callback) { + should_block_suspend_ = take_callback; } - void set_run_suspend_readiness_callback_immediately(bool run) { - run_suspend_readiness_callback_immediately_ = run; + void set_run_unblock_suspend_immediately(bool run) { + run_unblock_suspend_immediately_ = run; } - // Runs |suspend_readiness_callback_|. - bool RunSuspendReadinessCallback() WARN_UNUSED_RESULT { - if (suspend_readiness_callback_.is_null()) + // Runs |block_suspend_token_|. + bool UnblockSuspend() WARN_UNUSED_RESULT { + if (block_suspend_token_.is_empty()) return false; - std::move(suspend_readiness_callback_).Run(); + client_->UnblockSuspend(block_suspend_token_); return true; } // PowerManagerClient::Observer: void SuspendImminent(power_manager::SuspendImminent::Reason reason) override { num_suspend_imminent_++; - if (take_suspend_readiness_callback_) { - suspend_readiness_callback_ = - client_->GetSuspendReadinessCallback(FROM_HERE); + if (should_block_suspend_) { + block_suspend_token_ = base::UnguessableToken::Create(); + client_->BlockSuspend(block_suspend_token_, FROM_HERE.ToString()); } - if (run_suspend_readiness_callback_immediately_) - CHECK(RunSuspendReadinessCallback()); + if (run_unblock_suspend_immediately_) + CHECK(UnblockSuspend()); } void SuspendDone(const base::TimeDelta& sleep_duration) override { num_suspend_done_++; } void DarkSuspendImminent() override { num_dark_suspend_imminent_++; - if (take_suspend_readiness_callback_) { - suspend_readiness_callback_ = - client_->GetSuspendReadinessCallback(FROM_HERE); + if (should_block_suspend_) { + block_suspend_token_ = base::UnguessableToken::Create(); + client_->BlockSuspend(block_suspend_token_, FROM_HERE.ToString()); } - if (run_suspend_readiness_callback_immediately_) - CHECK(RunSuspendReadinessCallback()); + if (run_unblock_suspend_immediately_) + CHECK(UnblockSuspend()); } private: @@ -145,16 +146,16 @@ int num_dark_suspend_imminent_ = 0; // Should SuspendImminent() and DarkSuspendImminent() call |client_|'s - // GetSuspendReadinessCallback() method? - bool take_suspend_readiness_callback_ = false; + // BlockSuspend() method? + bool should_block_suspend_ = false; - // Should SuspendImminent() and DarkSuspendImminent() run the suspend - // readiness callback synchronously after taking it? Only has an effect if - // |take_suspend_readiness_callback_| is true. - bool run_suspend_readiness_callback_immediately_ = false; + // Should SuspendImminent() and DarkSuspendImminent() unblock the suspend + // synchronously after blocking itit? Only has an effect if + // |should_block_suspend_| is true. + bool run_unblock_suspend_immediately_ = false; - // Callback returned by |client_|'s GetSuspendReadinessCallback() method. - base::OnceClosure suspend_readiness_callback_; + // When non-empty, the token for the outstanding block-suspend registration. + base::UnguessableToken block_suspend_token_; DISALLOW_COPY_AND_ASSIGN(TestObserver); }; @@ -386,9 +387,9 @@ // callbacks. TEST_F(PowerManagerClientTest, ReportSuspendReadinessWithCallbacks) { TestObserver observer_1(client_); - observer_1.set_take_suspend_readiness_callback(true); + observer_1.set_should_block_suspend(true); TestObserver observer_2(client_); - observer_2.set_take_suspend_readiness_callback(true); + observer_2.set_should_block_suspend(true); TestObserver observer_3(client_); // When observers call GetSuspendReadinessCallback() from their @@ -396,9 +397,9 @@ // deferred until all callbacks are run. const int kSuspendId = 1; EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); - EXPECT_TRUE(observer_1.RunSuspendReadinessCallback()); + EXPECT_TRUE(observer_1.UnblockSuspend()); ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); - EXPECT_TRUE(observer_2.RunSuspendReadinessCallback()); + EXPECT_TRUE(observer_2.UnblockSuspend()); EmitSuspendDoneSignal(kSuspendId); EXPECT_EQ(1, observer_1.num_suspend_done()); EXPECT_EQ(1, observer_2.num_suspend_done()); @@ -409,7 +410,7 @@ TEST_F(PowerManagerClientTest, NotifyRenderProcessManagerDelegate) { TestDelegate delegate(client_); TestObserver observer(client_); - observer.set_take_suspend_readiness_callback(true); + observer.set_should_block_suspend(true); const int kSuspendId = 1; EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); @@ -419,7 +420,7 @@ // The RenderProcessManagerDelegate should be notified that suspend is // imminent only after observers have reported readiness. ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); - EXPECT_TRUE(observer.RunSuspendReadinessCallback()); + EXPECT_TRUE(observer.UnblockSuspend()); EXPECT_EQ(1, delegate.num_suspend_imminent()); EXPECT_EQ(0, delegate.num_suspend_done()); @@ -434,7 +435,7 @@ TEST_F(PowerManagerClientTest, ReportDarkSuspendReadiness) { TestDelegate delegate(client_); TestObserver observer(client_); - observer.set_take_suspend_readiness_callback(true); + observer.set_should_block_suspend(true); const int kSuspendId = 1; EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); @@ -442,7 +443,7 @@ EXPECT_EQ(0, delegate.num_suspend_imminent()); ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); - EXPECT_TRUE(observer.RunSuspendReadinessCallback()); + EXPECT_TRUE(observer.UnblockSuspend()); EXPECT_EQ(1, delegate.num_suspend_imminent()); // The RenderProcessManagerDelegate shouldn't be notified about dark suspend @@ -455,7 +456,7 @@ ExpectSuspendReadiness(kHandleDarkSuspendReadiness, kDarkSuspendId, kDarkSuspendDelayId); - EXPECT_TRUE(observer.RunSuspendReadinessCallback()); + EXPECT_TRUE(observer.UnblockSuspend()); EXPECT_EQ(0, delegate.num_suspend_done()); EmitSuspendDoneSignal(kSuspendId); @@ -468,7 +469,7 @@ TEST_F(PowerManagerClientTest, SuspendCancelledWhileCallbackPending) { TestDelegate delegate(client_); TestObserver observer(client_); - observer.set_take_suspend_readiness_callback(true); + observer.set_should_block_suspend(true); const int kSuspendId = 1; EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); @@ -487,7 +488,7 @@ // leave the renderers in a frozen state (http://crbug.com/646912). There's an // implicit expectation that powerd doesn't get notified about readiness here, // too. - EXPECT_TRUE(observer.RunSuspendReadinessCallback()); + EXPECT_TRUE(observer.UnblockSuspend()); EXPECT_EQ(0, delegate.num_suspend_imminent()); EXPECT_EQ(0, delegate.num_suspend_done()); } @@ -497,12 +498,12 @@ TEST_F(PowerManagerClientTest, SuspendDoneWhileDarkSuspendCallbackPending) { TestDelegate delegate(client_); TestObserver observer(client_); - observer.set_take_suspend_readiness_callback(true); + observer.set_should_block_suspend(true); const int kSuspendId = 1; EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); - EXPECT_TRUE(observer.RunSuspendReadinessCallback()); + EXPECT_TRUE(observer.UnblockSuspend()); EXPECT_EQ(1, delegate.num_suspend_imminent()); const int kDarkSuspendId = 5; @@ -517,7 +518,7 @@ // Dark suspend readiness shouldn't be reported even if the callback runs at // this point, since the suspend attempt is already done. The delegate also // shouldn't receive any more calls. - EXPECT_TRUE(observer.RunSuspendReadinessCallback()); + EXPECT_TRUE(observer.UnblockSuspend()); EXPECT_EQ(1, delegate.num_suspend_imminent()); EXPECT_EQ(1, delegate.num_suspend_done()); } @@ -527,27 +528,27 @@ TEST_F(PowerManagerClientTest, DarkSuspendImminentWhileCallbackPending) { TestDelegate delegate(client_); TestObserver observer(client_); - observer.set_take_suspend_readiness_callback(true); + observer.set_should_block_suspend(true); // Announce that suspend is imminent and grab, but don't run, the readiness // callback. const int kSuspendId = 1; EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); EXPECT_EQ(1, observer.num_suspend_imminent()); - base::OnceClosure regular_callback = observer.suspend_readiness_callback(); + base::UnguessableToken regular_token = observer.block_suspend_token(); // Before readiness is reported, announce that dark suspend is imminent. const int kDarkSuspendId = 1; EmitSuspendImminentSignal(kDarkSuspendImminent, kDarkSuspendId); EXPECT_EQ(1, observer.num_dark_suspend_imminent()); - base::OnceClosure dark_callback = observer.suspend_readiness_callback(); + base::UnguessableToken dark_token = observer.block_suspend_token(); // Complete the suspend attempt and run both of the earlier callbacks. Neither // should result in readiness being reported. EmitSuspendDoneSignal(kSuspendId); EXPECT_EQ(1, observer.num_suspend_done()); - std::move(regular_callback).Run(); - std::move(dark_callback).Run(); + client_->UnblockSuspend(regular_token); + client_->UnblockSuspend(dark_token); } // Tests that PowerManagerClient handles a single observer that requests a @@ -556,8 +557,8 @@ // http://crosbug.com/p/58295 TEST_F(PowerManagerClientTest, SyncCallbackWithSingleObserver) { TestObserver observer(client_); - observer.set_take_suspend_readiness_callback(true); - observer.set_run_suspend_readiness_callback_immediately(true); + observer.set_should_block_suspend(true); + observer.set_run_unblock_suspend_immediately(true); const int kSuspendId = 1; ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); @@ -571,16 +572,16 @@ // been notified and confirmed readiness. TEST_F(PowerManagerClientTest, SyncCallbackWithMultipleObservers) { TestObserver observer1(client_); - observer1.set_take_suspend_readiness_callback(true); - observer1.set_run_suspend_readiness_callback_immediately(true); + observer1.set_should_block_suspend(true); + observer1.set_run_unblock_suspend_immediately(true); TestObserver observer2(client_); - observer2.set_take_suspend_readiness_callback(true); + observer2.set_should_block_suspend(true); const int kSuspendId = 1; EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); - EXPECT_TRUE(observer2.RunSuspendReadinessCallback()); + EXPECT_TRUE(observer2.UnblockSuspend()); EmitSuspendDoneSignal(kSuspendId); }
diff --git a/chromeos/disks/suspend_unmount_manager.cc b/chromeos/disks/suspend_unmount_manager.cc index f17cbf9..ddf6721 100644 --- a/chromeos/disks/suspend_unmount_manager.cc +++ b/chromeos/disks/suspend_unmount_manager.cc
@@ -25,8 +25,8 @@ SuspendUnmountManager::~SuspendUnmountManager() { PowerManagerClient::Get()->RemoveObserver(this); - if (!suspend_readiness_callback_.is_null()) - std::move(suspend_readiness_callback_).Run(); + if (block_suspend_token_) + PowerManagerClient::Get()->UnblockSuspend(block_suspend_token_); } void SuspendUnmountManager::SuspendImminent( @@ -43,9 +43,10 @@ } } for (const auto& mount_path : mount_paths) { - if (suspend_readiness_callback_.is_null()) { - suspend_readiness_callback_ = - PowerManagerClient::Get()->GetSuspendReadinessCallback(FROM_HERE); + if (block_suspend_token_.is_empty()) { + block_suspend_token_ = base::UnguessableToken::Create(); + PowerManagerClient::Get()->BlockSuspend(block_suspend_token_, + "SuspendUnmountManager"); } disk_mount_manager_->UnmountPath( mount_path, UNMOUNT_OPTIONS_NONE, @@ -61,7 +62,7 @@ unmounting_paths_.clear(); disk_mount_manager_->EnsureMountInfoRefreshed( base::BindOnce(&OnRefreshCompleted), true /* force */); - suspend_readiness_callback_.Reset(); + block_suspend_token_ = {}; } void SuspendUnmountManager::OnUnmountComplete(const std::string& mount_path, @@ -69,8 +70,10 @@ // This can happen when unmount completes after suspend done is called. if (unmounting_paths_.erase(mount_path) != 1) return; - if (unmounting_paths_.empty() && !suspend_readiness_callback_.is_null()) - std::move(suspend_readiness_callback_).Run(); + if (unmounting_paths_.empty() && block_suspend_token_) { + PowerManagerClient::Get()->UnblockSuspend(block_suspend_token_); + block_suspend_token_ = {}; + } } } // namespace disks
diff --git a/chromeos/disks/suspend_unmount_manager.h b/chromeos/disks/suspend_unmount_manager.h index 48714d9..e29cb08 100644 --- a/chromeos/disks/suspend_unmount_manager.h +++ b/chromeos/disks/suspend_unmount_manager.h
@@ -10,6 +10,7 @@ #include "base/component_export.h" #include "base/macros.h" +#include "base/unguessable_token.h" #include "chromeos/dbus/cros_disks_client.h" #include "chromeos/dbus/power/power_manager_client.h" @@ -40,7 +41,7 @@ // The paths that the manager currently tries to unmount for suspend. std::set<std::string> unmounting_paths_; - base::OnceClosure suspend_readiness_callback_; + base::UnguessableToken block_suspend_token_; base::WeakPtrFactory<SuspendUnmountManager> weak_ptr_factory_;
diff --git a/chromeos/services/power/public/cpp/power_manager_mojo_client.cc b/chromeos/services/power/public/cpp/power_manager_mojo_client.cc index cd88ec6..6220cf3 100644 --- a/chromeos/services/power/public/cpp/power_manager_mojo_client.cc +++ b/chromeos/services/power/public/cpp/power_manager_mojo_client.cc
@@ -82,7 +82,9 @@ void PowerManagerMojoClient::RequestRestart( power_manager::RequestRestartReason reason, - const std::string& description) {} + const std::string& description) { + controller_->RequestRestart(reason, description); +} void PowerManagerMojoClient::RequestShutdown( power_manager::RequestShutdownReason reason, @@ -114,10 +116,11 @@ DBusMethodCallback<power_manager::PowerManagementPolicy::Delays> callback) { } -base::OnceClosure PowerManagerMojoClient::GetSuspendReadinessCallback( - const base::Location& from_where) { - return base::OnceClosure(); -} +void PowerManagerMojoClient::BlockSuspend(const base::UnguessableToken& token, + const std::string& debug_info) {} + +void PowerManagerMojoClient::UnblockSuspend( + const base::UnguessableToken& token) {} void PowerManagerMojoClient::CreateArcTimers( const std::string& tag, @@ -152,6 +155,11 @@ observer.KeyboardBrightnessChanged(change); } +void PowerManagerMojoClient::SuspendDone(base::TimeDelta sleep_duration) { + for (auto& observer : observers_) + observer.SuspendDone(sleep_duration); +} + void PowerManagerMojoClient::InitAfterInterfaceBound() { DCHECK(controller_.is_bound()); power::mojom::PowerManagerObserverAssociatedPtrInfo ptr_info;
diff --git a/chromeos/services/power/public/cpp/power_manager_mojo_client.h b/chromeos/services/power/public/cpp/power_manager_mojo_client.h index bfffe88..f97f350a 100644 --- a/chromeos/services/power/public/cpp/power_manager_mojo_client.h +++ b/chromeos/services/power/public/cpp/power_manager_mojo_client.h
@@ -59,8 +59,9 @@ void GetInactivityDelays( DBusMethodCallback<power_manager::PowerManagementPolicy::Delays> callback) override; - base::OnceClosure GetSuspendReadinessCallback( - const base::Location& from_where) override; + void BlockSuspend(const base::UnguessableToken& token, + const std::string& debug_info) override; + void UnblockSuspend(const base::UnguessableToken& token) override; void CreateArcTimers( const std::string& tag, std::vector<std::pair<clockid_t, base::ScopedFD>> arc_timer_requests, @@ -78,6 +79,7 @@ const power_manager::BacklightBrightnessChange& change) override; void KeyboardBrightnessChanged( const power_manager::BacklightBrightnessChange& change) override; + void SuspendDone(base::TimeDelta sleep_duration) override; power::mojom::PowerManagerControllerPtr* interface_ptr() { return &controller_;
diff --git a/chromeos/services/power/public/cpp/power_manager_mojo_controller.cc b/chromeos/services/power/public/cpp/power_manager_mojo_controller.cc index 9954591..8be21bd 100644 --- a/chromeos/services/power/public/cpp/power_manager_mojo_controller.cc +++ b/chromeos/services/power/public/cpp/power_manager_mojo_controller.cc
@@ -48,6 +48,12 @@ std::move(callback))); } +void PowerManagerMojoController::RequestRestart( + power_manager::RequestRestartReason reason, + const std::string& description) { + PowerManagerClient::Get()->RequestRestart(reason, description); +} + void PowerManagerMojoController::PowerManagerBecameAvailable(bool available) { client_->PowerManagerBecameAvailable(available); } @@ -62,4 +68,9 @@ client_->KeyboardBrightnessChanged(change); } +void PowerManagerMojoController::SuspendDone( + const base::TimeDelta& sleep_duration) { + client_->SuspendDone(sleep_duration); +} + } // namespace chromeos
diff --git a/chromeos/services/power/public/cpp/power_manager_mojo_controller.h b/chromeos/services/power/public/cpp/power_manager_mojo_controller.h index 5e549345..b770bae 100644 --- a/chromeos/services/power/public/cpp/power_manager_mojo_controller.h +++ b/chromeos/services/power/public/cpp/power_manager_mojo_controller.h
@@ -32,6 +32,8 @@ const power_manager::SetBacklightBrightnessRequest& request) override; void GetScreenBrightnessPercent( GetScreenBrightnessPercentCallback callback) override; + void RequestRestart(power_manager::RequestRestartReason reason, + const std::string& description) override; // PowerManagerClient::Observer: void PowerManagerBecameAvailable(bool available) override; @@ -39,6 +41,7 @@ const power_manager::BacklightBrightnessChange& change) override; void KeyboardBrightnessChanged( const power_manager::BacklightBrightnessChange& change) override; + void SuspendDone(const base::TimeDelta& sleep_duration) override; private: mojo::BindingSet<power::mojom::PowerManagerController> binding_set_;
diff --git a/chromeos/services/power/public/mojom/mojom_traits.cc b/chromeos/services/power/public/mojom/mojom_traits.cc index 7533904..da5f2ca 100644 --- a/chromeos/services/power/public/mojom/mojom_traits.cc +++ b/chromeos/services/power/public/mojom/mojom_traits.cc
@@ -7,6 +7,7 @@ namespace mojo { using chromeos::power::mojom::BacklightBrightnessChangeCause; +using chromeos::power::mojom::RequestRestartReason; using chromeos::power::mojom::SetBacklightBrightnessRequestCause; using chromeos::power::mojom::SetBacklightBrightnessRequestTransition; @@ -199,4 +200,38 @@ return true; } +// static +RequestRestartReason +EnumTraits<RequestRestartReason, power_manager::RequestRestartReason>::ToMojom( + power_manager::RequestRestartReason reason) { + switch (reason) { + case power_manager::REQUEST_RESTART_FOR_USER: + return RequestRestartReason::kForUser; + case power_manager::REQUEST_RESTART_FOR_UPDATE: + return RequestRestartReason::kForUpdate; + case power_manager::REQUEST_RESTART_OTHER: + return RequestRestartReason::kOther; + } +} + +// static +bool EnumTraits<RequestRestartReason, power_manager::RequestRestartReason>:: + FromMojom(chromeos::power::mojom::RequestRestartReason reason, + power_manager::RequestRestartReason* out) { + switch (reason) { + case RequestRestartReason::kForUser: + *out = power_manager::REQUEST_RESTART_FOR_USER; + return true; + case RequestRestartReason::kForUpdate: + *out = power_manager::REQUEST_RESTART_FOR_UPDATE; + return true; + case RequestRestartReason::kOther: + *out = power_manager::REQUEST_RESTART_OTHER; + return true; + } + + NOTREACHED(); + return false; +} + } // namespace mojo
diff --git a/chromeos/services/power/public/mojom/mojom_traits.h b/chromeos/services/power/public/mojom/mojom_traits.h index 3c0f3c5..47c205f 100644 --- a/chromeos/services/power/public/mojom/mojom_traits.h +++ b/chromeos/services/power/public/mojom/mojom_traits.h
@@ -9,6 +9,7 @@ #include "chromeos/services/power/public/mojom/power_manager.mojom-shared.h" #include "chromeos/services/power/public/mojom/power_manager.mojom.h" #include "mojo/public/cpp/bindings/enum_traits.h" +#include "third_party/cros_system_api/dbus/power_manager/dbus-constants.h" namespace mojo { @@ -83,6 +84,16 @@ power_manager::BacklightBrightnessChange* out); }; +template <> +struct EnumTraits<chromeos::power::mojom::RequestRestartReason, + power_manager::RequestRestartReason> { + static chromeos::power::mojom::RequestRestartReason ToMojom( + power_manager::RequestRestartReason reason); + + static bool FromMojom(chromeos::power::mojom::RequestRestartReason reason, + power_manager::RequestRestartReason* out); +}; + } // namespace mojo #endif // CHROMEOS_SERVICES_POWER_PUBLIC_MOJOM_MOJOM_TRAITS_H_
diff --git a/chromeos/services/power/public/mojom/power_manager.mojom b/chromeos/services/power/public/mojom/power_manager.mojom index 6f6e18a..9c4d4ab 100644 --- a/chromeos/services/power/public/mojom/power_manager.mojom +++ b/chromeos/services/power/public/mojom/power_manager.mojom
@@ -4,6 +4,8 @@ module chromeos.power.mojom; +import "mojo/public/mojom/base/time.mojom"; + enum SetBacklightBrightnessRequestTransition { kGradual, kInstant, @@ -50,6 +52,12 @@ BacklightBrightnessChangeCause cause; }; +enum RequestRestartReason { + kForUser, + kForUpdate, + kOther, +}; + // The interface for handling out-of-process calls that query or adjust power // related state. The implementation relays calls to the D-Bus client, which // uses D-Bus to communicate with the Power Manager daemon. In Mash, this lives @@ -61,6 +69,7 @@ // PowerManagerClient interface. Refer to that for documentation. SetScreenBrightness(SetBacklightBrightnessRequest request); GetScreenBrightnessPercent() => (Brightness? brightness); + RequestRestart(RequestRestartReason reason, string description); }; // An interface for observing changes to power state. The changes are dispatched @@ -71,4 +80,5 @@ PowerManagerBecameAvailable(bool available); ScreenBrightnessChanged(BacklightBrightnessChange change); KeyboardBrightnessChanged(BacklightBrightnessChange change); + SuspendDone(mojo_base.mojom.TimeDelta sleep_duration); };
diff --git a/chromeos/services/power/public/mojom/power_types.typemap b/chromeos/services/power/public/mojom/power_types.typemap index bc7ae7bc9..d9d3599e 100644 --- a/chromeos/services/power/public/mojom/power_types.typemap +++ b/chromeos/services/power/public/mojom/power_types.typemap
@@ -3,7 +3,10 @@ # found in the LICENSE file. mojom = "//chromeos/services/power/public/mojom/power_manager.mojom" -public_headers = [ "chromeos/dbus/power_manager/backlight.pb.h" ] +public_headers = [ + "chromeos/dbus/power_manager/backlight.pb.h", + "third_party/cros_system_api/dbus/power_manager/dbus-constants.h", +] traits_headers = [ "//chromeos/services/power/public/mojom/mojom_traits.h" ] sources = [ "//chromeos/services/power/public/mojom/mojom_traits.cc", @@ -15,6 +18,7 @@ type_mappings = [ "chromeos.power.mojom.BacklightBrightnessChange=power_manager::BacklightBrightnessChange", "chromeos.power.mojom.BacklightBrightnessChangeCause=power_manager::BacklightBrightnessChange_Cause", + "chromeos.power.mojom.RequestRestartReason=power_manager::RequestRestartReason", "chromeos.power.mojom.SetBacklightBrightnessRequest=power_manager::SetBacklightBrightnessRequest", "chromeos.power.mojom.SetBacklightBrightnessRequestCause=power_manager::SetBacklightBrightnessRequest_Cause", "chromeos.power.mojom.SetBacklightBrightnessRequestTransition=power_manager::SetBacklightBrightnessRequest_Transition",
diff --git a/components/arc/common/net.mojom b/components/arc/common/net.mojom index 8932523..731445ab 100644 --- a/components/arc/common/net.mojom +++ b/components/arc/common/net.mojom
@@ -167,13 +167,18 @@ // The physical network types exposed to ARC by the host, // corresponding to a subset of shill technology types defined // in platform2/system_api/dbus/shill/dbus-constants.h. +// The missing shill technology types are: +// - WiMAX: obsolete WiFi standard, deprecated in Chrome OS in Q2 2019. +// - Bluetooth: ARC does not support host IP networks over Bluetooth. +// - PPPoE: ARC does not support host Point to Point networks. +// Next Enum ID: 5 +// ID 4 was previously assigned to WiMAX. [Extensible] enum NetworkType { - CELLULAR, - ETHERNET, - VPN, - WIFI, - WIMAX, + CELLULAR = 0, + ETHERNET = 1, + VPN = 2, + WIFI = 3, }; // Used by ARC to request a network configuration to be created on the host.
diff --git a/components/arc/net/arc_net_host_impl.cc b/components/arc/net/arc_net_host_impl.cc index 1cf4fd78..19e5528 100644 --- a/components/arc/net/arc_net_host_impl.cc +++ b/components/arc/net/arc_net_host_impl.cc
@@ -264,8 +264,6 @@ DCHECK(wifi_dict); mojo->wifi = TranslateONCWifi(wifi_dict); mojo->tethering_client_state = GetWifiTetheringClientState(wifi_dict); - } else if (type == onc::network_type::kWimax) { - mojo->type = arc::mojom::NetworkType::WIMAX; } else { NOTREACHED() << "Unknown network type: " << type; }
diff --git a/components/arc/power/arc_power_bridge.cc b/components/arc/power/arc_power_bridge.cc index ece21ae..b1768d0 100644 --- a/components/arc/power/arc_power_bridge.cc +++ b/components/arc/power/arc_power_bridge.cc
@@ -174,9 +174,13 @@ if (!power_instance) return; - power_instance->Suspend( - chromeos::PowerManagerClient::Get()->GetSuspendReadinessCallback( - FROM_HERE)); + auto token = base::UnguessableToken::Create(); + chromeos::PowerManagerClient::Get()->BlockSuspend(token, "ArcPowerBridge"); + power_instance->Suspend(base::BindOnce( + [](base::UnguessableToken token) { + chromeos::PowerManagerClient::Get()->UnblockSuspend(token); + }, + token)); } void ArcPowerBridge::SuspendDone(const base::TimeDelta& sleep_duration) {
diff --git a/components/autofill/core/browser/accessory_sheet_data.cc b/components/autofill/core/browser/accessory_sheet_data.cc index 75cce7f..e4ceb61 100644 --- a/components/autofill/core/browser/accessory_sheet_data.cc +++ b/components/autofill/core/browser/accessory_sheet_data.cc
@@ -85,7 +85,8 @@ default; bool AccessorySheetData::operator==(const AccessorySheetData& data) const { - return title_ == data.title_ && user_info_list_ == data.user_info_list_ && + return sheet_type_ == data.sheet_type_ && title_ == data.title_ && + user_info_list_ == data.user_info_list_ && footer_commands_ == data.footer_commands_; }
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc index 9960067..a711bc69 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
@@ -660,9 +660,15 @@ break; } case EntityChange::ACTION_DELETE: { - cache_.erase(change->storage_key()); - is_any_local_modified |= RemoveServerMetadata( - table, parsed_storage_key.type, parsed_storage_key.metadata_id); + // We intentionally ignore remote deletions in order to avoid + // delete-create ping pongs (if we delete metadata for address data + // entity that still locally exists, PDM will think the server address + // has not been converted to a local address yet and will trigger + // conversion that in turn triggers creating and committing the metadata + // entity again). + // This is safe because this client will delete the wallet_metadata + // entity locally as soon as the wallet_data entity gets deleted. + // Corner cases are handled by DeleteOldOrphanMetadata(). break; } }
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc index 6d10220e..47c76e9 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
@@ -1034,9 +1034,9 @@ EqualsSpecifics(remote_card))); } -// Test that remote deletions are properly propagated into the local database. +// Test that remote deletions are ignored. TEST_F(AutofillWalletMetadataSyncBridgeTest, - RemoteDeletion_ShouldDeleteExistingLocalData) { + RemoteDeletion_ShouldNotDeleteExistingLocalData) { // Perform initial sync to create sync data & metadata. ResetBridge(/*initial_sync_done=*/false); WalletMetadataSpecifics profile = @@ -1053,87 +1053,19 @@ ASSERT_THAT(GetLocalSyncMetadataStorageKeys(), UnorderedElementsAre(kAddr1StorageKey, kCard1StorageKey)); - // Now delete the profile. Changes should happen in the local database. + // Now delete the profile. + // We still need to commit the updated progress marker and sync metadata. EXPECT_CALL(*backend(), CommitChanges()); - EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()); - ReceiveTombstones({profile, card}); - - // Verify that both data and sync metadata is gone. - EXPECT_FALSE(real_processor()->IsTrackingEntityForTest(kAddr1StorageKey)); - EXPECT_FALSE(real_processor()->IsTrackingEntityForTest(kCard1StorageKey)); - EXPECT_THAT(GetLocalSyncMetadataStorageKeys(), IsEmpty()); - EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty()); -} - -// Test that remote deletions are properly handled even when the local data is -// already deleted. We should still delete sync metadata both from the DB and -// from the processor internal memory. -TEST_F(AutofillWalletMetadataSyncBridgeTest, - RemoteDeletion_ShouldNotNotifyChangesWhenLocalDataIsGone) { - // Perform initial sync to create sync data & metadata. - ResetBridge(/*initial_sync_done=*/false); - WalletMetadataSpecifics profile = - CreateWalletMetadataSpecificsForAddressWithDetails( - kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20); - WalletMetadataSpecifics card = - CreateWalletMetadataSpecificsForCardWithDetails( - kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40); - StartSyncing({profile, card}); - - // Clear the data from the local DB, sync metadata stays untouched both in the - // processor and in the local DB. - table()->SetServerProfiles({}); - table()->SetServerCreditCards({}); - ASSERT_TRUE(real_processor()->IsTrackingEntityForTest(kAddr1StorageKey)); - ASSERT_TRUE(real_processor()->IsTrackingEntityForTest(kCard1StorageKey)); - ASSERT_THAT(GetLocalSyncMetadataStorageKeys(), - UnorderedElementsAre(kAddr1StorageKey, kCard1StorageKey)); - - // Send deletions from the server. We should commit to write the new progress - // marker down. - EXPECT_CALL(*backend(), CommitChanges()); - // Since the data is already deleted, it should not notify about changes. The - // entities should however get deleted from the processor. + // Changes should _not_ happen in the local autofill database. EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0); ReceiveTombstones({profile, card}); - // Verify that sync metadata is gone from both the processor and local DB. + // Verify that even though the processor does not track these entities any + // more and the sync metadata is gone, the actual data entities still exist in + // the local DB. EXPECT_FALSE(real_processor()->IsTrackingEntityForTest(kAddr1StorageKey)); EXPECT_FALSE(real_processor()->IsTrackingEntityForTest(kCard1StorageKey)); EXPECT_THAT(GetLocalSyncMetadataStorageKeys(), IsEmpty()); - EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty()); -} - -// Test that remote deletions are ignored if there is no sync metadata for the -// entity. -TEST_F(AutofillWalletMetadataSyncBridgeTest, - RemoteDeletion_ShouldNotDeleteLocalDataWithoutSyncMetadata) { - WalletMetadataSpecifics profile = - CreateWalletMetadataSpecificsForAddressWithDetails( - kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20); - WalletMetadataSpecifics card = - CreateWalletMetadataSpecificsForCardWithDetails( - kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40); - - table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)}); - table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)}); - - // Do not perform initial sync. This way, no sync metadata gets created, the - // processor does not know about the entities and thus, it should not delete - // them. - ResetBridge(/*initial_sync_done=*/true); - StartSyncing({}); - ASSERT_FALSE(real_processor()->IsTrackingEntityForTest(kAddr1StorageKey)); - ASSERT_FALSE(real_processor()->IsTrackingEntityForTest(kCard1StorageKey)); - ASSERT_THAT(GetLocalSyncMetadataStorageKeys(), IsEmpty()); - - // Send deletions from the server. We should commit to write the new progress - // marker down. - EXPECT_CALL(*backend(), CommitChanges()); - // The actual deletion should get ignored. - EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0); - ReceiveTombstones({profile, card}); - EXPECT_THAT( GetAllLocalDataInclRestart(), UnorderedElementsAre(EqualsSpecifics(profile), EqualsSpecifics(card)));
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc index 10620ba..47362955 100644 --- a/components/exo/client_controlled_shell_surface.cc +++ b/components/exo/client_controlled_shell_surface.cc
@@ -22,12 +22,12 @@ #include "ash/shell.h" #include "ash/wm/client_controlled_state.h" #include "ash/wm/drag_details.h" +#include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_properties.h" #include "ash/wm/window_state.h" #include "ash/wm/window_state_delegate.h" #include "ash/wm/window_util.h" -#include "ash/wm/wm_toplevel_window_event_handler.h" #include "base/logging.h" #include "base/no_destructor.h" #include "base/strings/utf_string_conversions.h"
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc index d037cd7..c5bcfff2 100644 --- a/components/exo/shell_surface.cc +++ b/components/exo/shell_surface.cc
@@ -8,9 +8,9 @@ #include "ash/public/cpp/window_state_type.h" #include "ash/shell.h" #include "ash/wm/desks/desks_util.h" +#include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/window_resizer.h" #include "ash/wm/window_state.h" -#include "ash/wm/wm_toplevel_window_event_handler.h" #include "base/bind.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h"
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h index fb30af25..aea3623 100644 --- a/components/exo/shell_surface.h +++ b/components/exo/shell_surface.h
@@ -5,8 +5,8 @@ #ifndef COMPONENTS_EXO_SHELL_SURFACE_H_ #define COMPONENTS_EXO_SHELL_SURFACE_H_ +#include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/window_state_observer.h" -#include "ash/wm/wm_toplevel_window_event_handler.h" #include "base/containers/circular_deque.h" #include "base/macros.h" #include "components/exo/shell_surface_base.h"
diff --git a/components/nacl/loader/nacl_main_platform_delegate_mac.mm b/components/nacl/loader/nacl_main_platform_delegate_mac.mm index f24dc4e..34832cb0 100644 --- a/components/nacl/loader/nacl_main_platform_delegate_mac.mm +++ b/components/nacl/loader/nacl_main_platform_delegate_mac.mm
@@ -16,12 +16,6 @@ void NaClMainPlatformDelegate::EnableSandbox( const content::MainFunctionParams& parameters) { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - sandbox::switches::kSeatbeltClientName)) { - // Make sure the sandbox is actually enabled if the V2 flag is present. - CHECK(sandbox::Seatbelt::IsSandboxed()); - } else { - CHECK(content::InitializeSandbox(service_manager::SANDBOX_TYPE_NACL_LOADER)) - << "Error initializing sandbox for " << switches::kNaClLoaderProcess; - } + // The sandbox on macOS is enabled as soon as main() executes, so there is + // nothing to do here. }
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc index 78432c9..15f8b68 100644 --- a/components/omnibox/browser/autocomplete_match.cc +++ b/components/omnibox/browser/autocomplete_match.cc
@@ -738,8 +738,15 @@ void AutocompleteMatch::ComputeStrippedDestinationURL( const AutocompleteInput& input, TemplateURLService* template_url_service) { - stripped_destination_url = - GURLToStrippedGURL(destination_url, input, template_url_service, keyword); + // Other than document suggestions, computing |stripped_destination_url| will + // have the same result during a match's lifecycle, so it's safe to skip + // re-computing it if it's already computed. Document suggestions' + // |stripped_url|s are pre-computed by the document provider, and overwriting + // them here would prevent potential deduping. + if (stripped_destination_url.is_empty()) { + stripped_destination_url = GURLToStrippedGURL( + destination_url, input, template_url_service, keyword); + } } void AutocompleteMatch::GetKeywordUIState(
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge.cc b/components/password_manager/core/browser/sync/password_sync_bridge.cc index ddeb0b09..5d26b87d 100644 --- a/components/password_manager/core/browser/sync/password_sync_bridge.cc +++ b/components/password_manager/core/browser/sync/password_sync_bridge.cc
@@ -545,6 +545,12 @@ metadata_change_list.get()); break; case syncer::EntityChange::ACTION_UPDATE: + // TODO(mamir): This had been added to mitigate some potential issues + // in the login database. Once the underlying cause is verified, we + // should remove this check. + if (entity_change->storage_key().empty()) { + continue; + } changes = password_store_sync_->UpdateLoginSync( PasswordFromEntityChange(*entity_change, /*sync_time=*/time_now)); if (changes.empty()) { @@ -558,6 +564,12 @@ ParsePrimaryKey(entity_change->storage_key())); break; case syncer::EntityChange::ACTION_DELETE: { + // TODO(mamir): This had been added to mitigate some potential issues + // in the login database. Once the underlying cause is verified, we + // should remove this check. + if (entity_change->storage_key().empty()) { + continue; + } int primary_key = ParsePrimaryKey(entity_change->storage_key()); changes = password_store_sync_->RemoveLoginByPrimaryKeySync(primary_key);
diff --git a/components/payments/content/BUILD.gn b/components/payments/content/BUILD.gn index 0c55166..67fc6a0e 100644 --- a/components/payments/content/BUILD.gn +++ b/components/payments/content/BUILD.gn
@@ -83,6 +83,7 @@ deps = [ ":content_common", "//components/autofill/core/browser", + "//components/payments/content/icon", "//components/payments/content/utility", "//components/payments/core", "//components/strings",
diff --git a/components/payments/content/icon/BUILD.gn b/components/payments/content/icon/BUILD.gn new file mode 100644 index 0000000..6054837f --- /dev/null +++ b/components/payments/content/icon/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. + +import("//build/config/jumbo.gni") + +jumbo_static_library("icon") { + sources = [ + "icon_size.cc", + "icon_size.h", + ] + + deps = [ + "//ui/display", + ] +}
diff --git a/components/payments/content/icon/DEPS b/components/payments/content/icon/DEPS new file mode 100644 index 0000000..6446557 --- /dev/null +++ b/components/payments/content/icon/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+ui/display", +]
diff --git a/components/payments/content/icon/icon_size.cc b/components/payments/content/icon/icon_size.cc new file mode 100644 index 0000000..afc9832 --- /dev/null +++ b/components/payments/content/icon/icon_size.cc
@@ -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. +#include "components/payments/content/icon/icon_size.h" + +#include "ui/display/display.h" +#include "ui/display/screen.h" + +namespace payments { + +namespace { + +float DeviceScaleFactor(gfx::NativeView view) { + display::Screen* screen = display::Screen::GetScreen(); + DCHECK(screen); + return screen->GetDisplayNearestView(view).device_scale_factor(); +} + +} // namespace + +// static +int IconSizeCalculator::IdealIconHeight(gfx::NativeView view) { + return DeviceScaleFactor(view) * kPaymentAppDeviceIndependentIdealIconHeight; +} + +// static +int IconSizeCalculator::MinimumIconHeight() { + return 0; +} + +} // namespace payments
diff --git a/components/payments/content/icon/icon_size.h b/components/payments/content/icon/icon_size.h new file mode 100644 index 0000000..141932b --- /dev/null +++ b/components/payments/content/icon/icon_size.h
@@ -0,0 +1,27 @@ +// 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_PAYMENTS_CONTENT_ICON_ICON_SIZE_H_ +#define COMPONENTS_PAYMENTS_CONTENT_ICON_ICON_SIZE_H_ + +#include "base/macros.h" +#include "ui/gfx/native_widget_types.h" + +namespace payments { + +// Calculates the ideal height in pixels for payment icons depending on the +// screen resolution (32 * device_scale_factor). +class IconSizeCalculator final { + public: + static int IdealIconHeight(gfx::NativeView view); + static int MinimumIconHeight(); + static constexpr int kPaymentAppDeviceIndependentIdealIconHeight = 32; + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(IconSizeCalculator); +}; + +} // namespace payments + +#endif // COMPONENTS_PAYMENTS_CONTENT_ICON_ICON_SIZE_H_
diff --git a/components/payments/content/installable_payment_app_crawler.cc b/components/payments/content/installable_payment_app_crawler.cc index bca52aad..da415de 100644 --- a/components/payments/content/installable_payment_app_crawler.cc +++ b/components/payments/content/installable_payment_app_crawler.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" +#include "components/payments/content/icon/icon_size.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -372,22 +373,6 @@ return; } - // TODO(crbug.com/782270): Choose appropriate icon size dynamically on - // different platforms. - const int kPaymentAppIdealIconSize = 32; - const int kPaymentAppMinimumIconSize = 0; - GURL best_icon_url = blink::ManifestIconSelector::FindBestMatchingIcon( - manifest_icons, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize, - content::ManifestIconDownloader::kMaxWidthToHeightRatio, - blink::Manifest::ImageResource::Purpose::ANY); - if (!best_icon_url.is_valid()) { - log_.Error("No suitable icon found in web app manifest \"" + - web_app_manifest_url.spec() + - "\" for payment handler manifest \"" + - method_manifest_url.spec() + "\"."); - return; - } - // Stop if the web_contents is gone. if (web_contents() == nullptr) { log_.Error( @@ -398,10 +383,25 @@ return; } + gfx::NativeView native_view = web_contents()->GetNativeView(); + GURL best_icon_url = blink::ManifestIconSelector::FindBestMatchingIcon( + manifest_icons, IconSizeCalculator::IdealIconHeight(native_view), + IconSizeCalculator::MinimumIconHeight(), + content::ManifestIconDownloader::kMaxWidthToHeightRatio, + blink::Manifest::ImageResource::Purpose::ANY); + if (!best_icon_url.is_valid()) { + log_.Error("No suitable icon found in web app manifest \"" + + web_app_manifest_url.spec() + + "\" for payment handler manifest \"" + + method_manifest_url.spec() + "\"."); + return; + } + number_of_web_app_icons_to_download_and_decode_++; bool can_download_icon = content::ManifestIconDownloader::Download( - web_contents(), best_icon_url, kPaymentAppIdealIconSize, - kPaymentAppMinimumIconSize, + web_contents(), best_icon_url, + IconSizeCalculator::IdealIconHeight(native_view), + IconSizeCalculator::MinimumIconHeight(), base::BindOnce( &InstallablePaymentAppCrawler::OnPaymentWebAppIconDownloadAndDecoded, weak_ptr_factory_.GetWeakPtr(), method_manifest_url,
diff --git a/components/sync/nigori/nigori_model_type_processor.cc b/components/sync/nigori/nigori_model_type_processor.cc index cc78a52..3516cb0 100644 --- a/components/sync/nigori/nigori_model_type_processor.cc +++ b/components/sync/nigori/nigori_model_type_processor.cc
@@ -5,11 +5,14 @@ #include "components/sync/nigori/nigori_model_type_processor.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "components/sync/base/data_type_histogram.h" #include "components/sync/base/time.h" #include "components/sync/engine/commit_queue.h" #include "components/sync/engine/model_type_processor_proxy.h" #include "components/sync/model_impl/processor_entity.h" #include "components/sync/nigori/nigori_sync_bridge.h" +#include "components/sync/protocol/proto_memory_estimations.h" +#include "components/sync/protocol/proto_value_conversions.h" namespace syncer { @@ -231,18 +234,58 @@ void NigoriModelTypeProcessor::GetAllNodesForDebugging( AllNodesCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTIMPLEMENTED(); + + std::unique_ptr<base::DictionaryValue> root_node; + std::unique_ptr<EntityData> entity_data = bridge_->GetData(); + if (entity_data) { + if (entity_) { + const sync_pb::EntityMetadata& metadata = entity_->metadata(); + // Set id value as directory, "s" means server. + entity_data->id = "s" + metadata.server_id(); + entity_data->creation_time = ProtoTimeToTime(metadata.creation_time()); + entity_data->modification_time = + ProtoTimeToTime(metadata.modification_time()); + } + root_node = entity_data->ToDictionaryValue(); + if (entity_) { + root_node->Set("metadata", EntityMetadataToValue(entity_->metadata())); + } + } else { + root_node = std::make_unique<base::DictionaryValue>(); + } + + // Function isTypeRootNode in sync_node_browser.js use PARENT_ID and + // UNIQUE_SERVER_TAG to check if the node is root node. isChildOf in + // sync_node_browser.js uses modelType to check if root node is parent of real + // data node. NON_UNIQUE_NAME will be the name of node to display. + root_node->SetString("ID", "NIGORI_ROOT"); + root_node->SetString("PARENT_ID", "r"); + root_node->SetString("UNIQUE_SERVER_TAG", "Nigori"); + root_node->SetBoolean("IS_DIR", false); + root_node->SetString("modelType", "Nigori"); + root_node->SetString("NON_UNIQUE_NAME", "Nigori"); + + auto all_nodes = std::make_unique<base::ListValue>(); + all_nodes->Append(std::move(root_node)); + std::move(callback).Run(syncer::NIGORI, std::move(all_nodes)); } void NigoriModelTypeProcessor::GetStatusCountersForDebugging( StatusCountersCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTIMPLEMENTED(); + StatusCounters counters; + counters.num_entries = entity_ ? 1 : 0; + counters.num_entries_and_tombstones = counters.num_entries; + std::move(callback).Run(syncer::NIGORI, counters); } void NigoriModelTypeProcessor::RecordMemoryUsageAndCountsHistograms() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTIMPLEMENTED(); + size_t memory_usage = 0; + memory_usage += EstimateMemoryUsage(model_type_state_); + memory_usage += entity_ ? entity_->EstimateMemoryUsage() : 0; + SyncRecordModelTypeMemoryHistogram(ModelType::NIGORI, memory_usage); + SyncRecordModelTypeCountHistogram(ModelType::NIGORI, entity_ ? 1 : 0); } void NigoriModelTypeProcessor::ModelReadyToSync(
diff --git a/components/tracing/common/trace_startup_config.cc b/components/tracing/common/trace_startup_config.cc index d21058d..7e984cb 100644 --- a/components/tracing/common/trace_startup_config.cc +++ b/components/tracing/common/trace_startup_config.cc
@@ -242,12 +242,10 @@ bool TraceStartupConfig::EnableFromBackgroundTracing() { #if defined(OS_ANDROID) - // Tests can enable this value. is_enabled_from_background_tracing_ = - is_enabled_from_background_tracing_ || base::android::GetBackgroundStartupTracingFlag(); #else - // TODO(ssid): Implement saving setting to preference for next startup. + is_enabled_from_background_tracing_ = false; #endif // Do not set the flag to false if it's not enabled unnecessarily. if (!is_enabled_from_background_tracing_)
diff --git a/components/tracing/common/trace_startup_config.h b/components/tracing/common/trace_startup_config.h index be13970..a1e4e34 100644 --- a/components/tracing/common/trace_startup_config.h +++ b/components/tracing/common/trace_startup_config.h
@@ -17,8 +17,7 @@ } // namespace base namespace content { -class CommandlineStartupTracingTest; -class BackgroundStartupTracingTest; +class StartupTracingControllerTest; } namespace tracing { @@ -140,8 +139,7 @@ // This allows constructor and destructor to be private and usable only // by the Singleton class. friend struct base::DefaultSingletonTraits<TraceStartupConfig>; - friend class content::CommandlineStartupTracingTest; - friend class content::BackgroundStartupTracingTest; + friend class content::StartupTracingControllerTest; TraceStartupConfig(); ~TraceStartupConfig();
diff --git a/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.cc b/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.cc index b55ef3e41..53ed9e7 100644 --- a/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.cc +++ b/components/viz/service/compositor_frame_fuzzer/fuzzer_software_display_provider.cc
@@ -105,7 +105,7 @@ : std::make_unique<SoftwareOutputDevice>(); auto output_surface = std::make_unique<SoftwareOutputSurface>( - std::move(software_output_device), std::move(update_vsync_callback)); + std::move(software_output_device)); auto scheduler = std::make_unique<DisplayScheduler>( begin_frame_source_.get(), task_runner.get(),
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 488edae2..faa61ce 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -1220,7 +1220,7 @@ filter->asColorFilter(&colorfilter_rawptr); sk_sp<SkColorFilter> cf(colorfilter_rawptr); - if (cf && cf->asColorMatrix(params->color_matrix)) { + if (cf && cf->asAColorMatrix(params->color_matrix)) { // We have a color matrix at the root of the filter DAG; apply it // locally in the compositor and process the rest of the DAG (if any) // in Skia. @@ -1453,11 +1453,10 @@ matrix); } - static const float kScale = 1.0f / 255.0f; if (current_program_->color_offset_location() != -1) { float offset[4]; for (int i = 0; i < 4; ++i) - offset[i] = SkScalarToFloat(params->color_matrix[i * 5 + 4]) * kScale; + offset[i] = params->color_matrix[i * 5 + 4]; gl_->Uniform4fv(current_program_->color_offset_location(), 1, offset); }
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc index 1a4771a..b243a54 100644 --- a/components/viz/service/display/gl_renderer_unittest.cc +++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -1787,7 +1787,7 @@ child_context_provider_.get()); ResourceId mapped_mask = resource_map[mask]; - SkScalar matrix[20]; + float matrix[20]; float amount = 0.5f; matrix[0] = 0.213f + 0.787f * amount; matrix[1] = 0.715f - 0.715f * amount; @@ -1805,8 +1805,8 @@ matrix[18] = 1; cc::FilterOperations filters; filters.Append(cc::FilterOperation::CreateReferenceFilter( - sk_make_sp<cc::ColorFilterPaintFilter>( - SkColorFilters::MatrixRowMajor255(matrix), nullptr))); + sk_make_sp<cc::ColorFilterPaintFilter>(SkColorFilters::Matrix(matrix), + nullptr))); gfx::Transform transform_causing_aa; transform_causing_aa.Rotate(20.0); @@ -2081,6 +2081,8 @@ MOCK_CONST_METHOD0(GetOverlayBufferFormat, gfx::BufferFormat()); MOCK_CONST_METHOD0(HasExternalStencilTest, bool()); MOCK_METHOD0(ApplyExternalStencil, void()); + MOCK_METHOD1(SetUpdateVSyncParametersCallback, + void(UpdateVSyncParametersCallback)); }; class MockOutputSurfaceTest : public GLRendererTest {
diff --git a/components/viz/service/display/output_surface.h b/components/viz/service/display/output_surface.h index 00f7168..fe6bd91 100644 --- a/components/viz/service/display/output_surface.h +++ b/components/viz/service/display/output_surface.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/threading/thread_checker.h" +#include "components/viz/common/display/update_vsync_parameters_callback.h" #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/resources/returned_resource.h" #include "components/viz/service/display/overlay_candidate_validator.h" @@ -49,7 +50,7 @@ // Note: HasExternalStencilTest() must return false when an output surface // has been configured for stencil usage. bool supports_stencil = false; - // Whether this OutputSurface suppotrs post sub buffer or not. + // Whether this OutputSurface supports post sub buffer or not. bool supports_post_sub_buffer = false; }; @@ -132,6 +133,11 @@ // can be passed directly to any related extension functions. virtual unsigned UpdateGpuFence() = 0; + // Sets callback to receive updated vsync parameters after SwapBuffers() if + // supported. + virtual void SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) = 0; + // If set to true, the OutputSurface must deliver // OutputSurfaceclient::DidSwapWithSize notifications to its client. // OutputSurfaces which support delivering swap size notifications should
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc index f0a7521..0923324 100644 --- a/components/viz/service/display/overlay_unittest.cc +++ b/components/viz/service/display/overlay_unittest.cc
@@ -229,6 +229,8 @@ return gfx::BufferFormat::RGBX_8888; } unsigned UpdateGpuFence() override { return 0; } + void SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) override {} void set_is_displayed_as_overlay_plane(bool value) { is_displayed_as_overlay_plane_ = value;
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 00ff891f7..a855b21 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -2061,7 +2061,7 @@ int child_pass_id = 2; gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - SkScalar matrix[20]; + float matrix[20]; float amount = 0.5f; matrix[0] = 0.213f + 0.787f * amount; matrix[1] = 0.715f - 0.715f * amount; @@ -2079,8 +2079,8 @@ matrix[18] = 1; cc::FilterOperations filters; filters.Append(cc::FilterOperation::CreateReferenceFilter( - sk_make_sp<cc::ColorFilterPaintFilter>( - SkColorFilters::MatrixRowMajor255(matrix), nullptr))); + sk_make_sp<cc::ColorFilterPaintFilter>(SkColorFilters::Matrix(matrix), + nullptr))); std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); @@ -2261,29 +2261,29 @@ int child_pass_id = 2; gfx::Rect pass_rect(this->device_viewport_size_); gfx::Transform transform_to_root; - SkScalar matrix[20]; + float matrix[20]; float amount = 0.5f; matrix[0] = 0.213f + 0.787f * amount; matrix[1] = 0.715f - 0.715f * amount; matrix[2] = 1.f - (matrix[0] + matrix[1]); matrix[3] = 0; - matrix[4] = 20.f; + matrix[4] = 20.f / 255; matrix[5] = 0.213f - 0.213f * amount; matrix[6] = 0.715f + 0.285f * amount; matrix[7] = 1.f - (matrix[5] + matrix[6]); matrix[8] = 0; - matrix[9] = 200.f; + matrix[9] = 200.f / 255; matrix[10] = 0.213f - 0.213f * amount; matrix[11] = 0.715f - 0.715f * amount; matrix[12] = 1.f - (matrix[10] + matrix[11]); matrix[13] = 0; - matrix[14] = 1.5f; + matrix[14] = 1.5f / 255; matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; matrix[18] = 1; cc::FilterOperations filters; filters.Append(cc::FilterOperation::CreateReferenceFilter( - sk_make_sp<cc::ColorFilterPaintFilter>( - SkColorFilters::MatrixRowMajor255(matrix), nullptr))); + sk_make_sp<cc::ColorFilterPaintFilter>(SkColorFilters::Matrix(matrix), + nullptr))); std::unique_ptr<RenderPass> child_pass = CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
diff --git a/components/viz/service/display_embedder/gl_output_surface.cc b/components/viz/service/display_embedder/gl_output_surface.cc index 80f1c450..117363e5 100644 --- a/components/viz/service/display_embedder/gl_output_surface.cc +++ b/components/viz/service/display_embedder/gl_output_surface.cc
@@ -22,10 +22,9 @@ namespace viz { GLOutputSurface::GLOutputSurface( - scoped_refptr<VizProcessContextProvider> context_provider, - UpdateVSyncParametersCallback update_vsync_callback) + scoped_refptr<VizProcessContextProvider> context_provider) : OutputSurface(context_provider), - wants_vsync_parameter_updates_(!update_vsync_callback.is_null()), + viz_context_provider_(context_provider), use_gpu_fence_( context_provider->ContextCapabilities().chromium_gpu_fence && context_provider->ContextCapabilities() @@ -40,8 +39,6 @@ // can use. capabilities_.max_frames_pending = context_provider->ContextCapabilities().num_surface_buffers - 1; - context_provider->SetUpdateVSyncParametersCallback( - std::move(update_vsync_callback)); } GLOutputSurface::~GLOutputSurface() { @@ -202,4 +199,10 @@ needs_swap_size_notifications_ = needs_swap_size_notifications; } +void GLOutputSurface::SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) { + wants_vsync_parameter_updates_ = !callback.is_null(); + viz_context_provider_->SetUpdateVSyncParametersCallback(std::move(callback)); +} + } // namespace viz
diff --git a/components/viz/service/display_embedder/gl_output_surface.h b/components/viz/service/display_embedder/gl_output_surface.h index 3789fdb0..1820e59 100644 --- a/components/viz/service/display_embedder/gl_output_surface.h +++ b/components/viz/service/display_embedder/gl_output_surface.h
@@ -19,8 +19,8 @@ // swaps to an actual GL surface. class GLOutputSurface : public OutputSurface { public: - GLOutputSurface(scoped_refptr<VizProcessContextProvider> context_provider, - UpdateVSyncParametersCallback update_vsync_callback); + explicit GLOutputSurface( + scoped_refptr<VizProcessContextProvider> context_provider); ~GLOutputSurface() override; // OutputSurface implementation @@ -45,6 +45,8 @@ unsigned UpdateGpuFence() override; void SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) override; + void SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) override; protected: OutputSurfaceClient* client() const { return client_; } @@ -69,8 +71,9 @@ const gpu::SwapBuffersCompleteParams& params); void OnPresentation(const gfx::PresentationFeedback& feedback); + scoped_refptr<VizProcessContextProvider> viz_context_provider_; OutputSurfaceClient* client_ = nullptr; - const bool wants_vsync_parameter_updates_; + bool wants_vsync_parameter_updates_ = false; ui::LatencyTracker latency_tracker_; bool set_draw_rectangle_for_frame_ = false;
diff --git a/components/viz/service/display_embedder/gl_output_surface_android.cc b/components/viz/service/display_embedder/gl_output_surface_android.cc index 4bee327..18397c09 100644 --- a/components/viz/service/display_embedder/gl_output_surface_android.cc +++ b/components/viz/service/display_embedder/gl_output_surface_android.cc
@@ -10,9 +10,8 @@ GLOutputSurfaceAndroid::GLOutputSurfaceAndroid( scoped_refptr<VizProcessContextProvider> context_provider, - UpdateVSyncParametersCallback update_vsync_callback, bool allow_overlays) - : GLOutputSurface(context_provider, std::move(update_vsync_callback)) { + : GLOutputSurface(context_provider) { if (allow_overlays) { overlay_candidate_validator_ = std::make_unique<CompositorOverlayCandidateValidatorAndroid>();
diff --git a/components/viz/service/display_embedder/gl_output_surface_android.h b/components/viz/service/display_embedder/gl_output_surface_android.h index 759d800..439838b 100644 --- a/components/viz/service/display_embedder/gl_output_surface_android.h +++ b/components/viz/service/display_embedder/gl_output_surface_android.h
@@ -16,7 +16,6 @@ public: GLOutputSurfaceAndroid( scoped_refptr<VizProcessContextProvider> context_provider, - UpdateVSyncParametersCallback update_vsync_callback, bool allow_overlays); ~GLOutputSurfaceAndroid() override;
diff --git a/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc b/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc index 5b61a39..e367d73 100644 --- a/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc +++ b/components/viz/service/display_embedder/gl_output_surface_buffer_queue.cc
@@ -20,10 +20,9 @@ GLOutputSurfaceBufferQueue::GLOutputSurfaceBufferQueue( scoped_refptr<VizProcessContextProvider> context_provider, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gfx::BufferFormat buffer_format) - : GLOutputSurface(context_provider, std::move(update_vsync_callback)) { + : GLOutputSurface(context_provider) { capabilities_.uses_default_gl_framebuffer = false; capabilities_.flipped_output_surface = true; // Set |max_frames_pending| to 2 for buffer_queue, which aligns scheduling
diff --git a/components/viz/service/display_embedder/gl_output_surface_buffer_queue.h b/components/viz/service/display_embedder/gl_output_surface_buffer_queue.h index 6843772a4..ce392a3 100644 --- a/components/viz/service/display_embedder/gl_output_surface_buffer_queue.h +++ b/components/viz/service/display_embedder/gl_output_surface_buffer_queue.h
@@ -34,7 +34,6 @@ GLOutputSurfaceBufferQueue( scoped_refptr<VizProcessContextProvider> context_provider, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gfx::BufferFormat buffer_format);
diff --git a/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc b/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc index 8269aad1..4ab76d8 100644 --- a/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc +++ b/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc
@@ -11,12 +11,10 @@ GLOutputSurfaceBufferQueueAndroid::GLOutputSurfaceBufferQueueAndroid( scoped_refptr<VizProcessContextProvider> context_provider, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gfx::BufferFormat buffer_format) : GLOutputSurfaceBufferQueue(context_provider, surface_handle, - std::move(update_vsync_callback), gpu_memory_buffer_manager, buffer_format) {}
diff --git a/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h b/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h index 879f5c0..ebda140 100644 --- a/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h +++ b/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h
@@ -17,7 +17,6 @@ GLOutputSurfaceBufferQueueAndroid( scoped_refptr<VizProcessContextProvider> context_provider, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gfx::BufferFormat buffer_format); ~GLOutputSurfaceBufferQueueAndroid() override;
diff --git a/components/viz/service/display_embedder/gl_output_surface_mac.cc b/components/viz/service/display_embedder/gl_output_surface_mac.cc index 1c4f94d..f306ae94 100644 --- a/components/viz/service/display_embedder/gl_output_surface_mac.cc +++ b/components/viz/service/display_embedder/gl_output_surface_mac.cc
@@ -11,12 +11,10 @@ GLOutputSurfaceMac::GLOutputSurfaceMac( scoped_refptr<VizProcessContextProvider> context_provider, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, bool allow_overlays) : GLOutputSurfaceBufferQueue(context_provider, surface_handle, - std::move(update_vsync_callback), gpu_memory_buffer_manager, gfx::BufferFormat::RGBA_8888), overlay_validator_(
diff --git a/components/viz/service/display_embedder/gl_output_surface_mac.h b/components/viz/service/display_embedder/gl_output_surface_mac.h index 093b1ad5..077be04 100644 --- a/components/viz/service/display_embedder/gl_output_surface_mac.h +++ b/components/viz/service/display_embedder/gl_output_surface_mac.h
@@ -14,7 +14,6 @@ public: GLOutputSurfaceMac(scoped_refptr<VizProcessContextProvider> context_provider, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, bool allow_overlays); ~GLOutputSurfaceMac() override;
diff --git a/components/viz/service/display_embedder/gl_output_surface_offscreen.cc b/components/viz/service/display_embedder/gl_output_surface_offscreen.cc index 5cd270a..2ef563d 100644 --- a/components/viz/service/display_embedder/gl_output_surface_offscreen.cc +++ b/components/viz/service/display_embedder/gl_output_surface_offscreen.cc
@@ -24,10 +24,8 @@ } // namespace GLOutputSurfaceOffscreen::GLOutputSurfaceOffscreen( - scoped_refptr<VizProcessContextProvider> context_provider, - UpdateVSyncParametersCallback update_vsync_callback) - : GLOutputSurface(context_provider, std::move(update_vsync_callback)), - weak_ptr_factory_(this) {} + scoped_refptr<VizProcessContextProvider> context_provider) + : GLOutputSurface(context_provider), weak_ptr_factory_(this) {} GLOutputSurfaceOffscreen::~GLOutputSurfaceOffscreen() {}
diff --git a/components/viz/service/display_embedder/gl_output_surface_offscreen.h b/components/viz/service/display_embedder/gl_output_surface_offscreen.h index c39018b..fa6ca15 100644 --- a/components/viz/service/display_embedder/gl_output_surface_offscreen.h +++ b/components/viz/service/display_embedder/gl_output_surface_offscreen.h
@@ -18,9 +18,8 @@ // framebuffer. class GLOutputSurfaceOffscreen : public GLOutputSurface { public: - GLOutputSurfaceOffscreen( - scoped_refptr<VizProcessContextProvider> context_provider, - UpdateVSyncParametersCallback update_vsync_callback); + explicit GLOutputSurfaceOffscreen( + scoped_refptr<VizProcessContextProvider> context_provider); ~GLOutputSurfaceOffscreen() override; // OutputSurface implementation.
diff --git a/components/viz/service/display_embedder/gl_output_surface_ozone.cc b/components/viz/service/display_embedder/gl_output_surface_ozone.cc index cd217c8..af942123 100644 --- a/components/viz/service/display_embedder/gl_output_surface_ozone.cc +++ b/components/viz/service/display_embedder/gl_output_surface_ozone.cc
@@ -17,12 +17,10 @@ GLOutputSurfaceOzone::GLOutputSurfaceOzone( scoped_refptr<VizProcessContextProvider> context_provider, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, std::vector<OverlayStrategy> strategies) : GLOutputSurfaceBufferQueue(context_provider, surface_handle, - std::move(update_vsync_callback), gpu_memory_buffer_manager, display::DisplaySnapshot::PrimaryFormat()) { if (!strategies.empty()) {
diff --git a/components/viz/service/display_embedder/gl_output_surface_ozone.h b/components/viz/service/display_embedder/gl_output_surface_ozone.h index 1676c49..ba4b2f3 100644 --- a/components/viz/service/display_embedder/gl_output_surface_ozone.h +++ b/components/viz/service/display_embedder/gl_output_surface_ozone.h
@@ -20,7 +20,6 @@ GLOutputSurfaceOzone( scoped_refptr<VizProcessContextProvider> context_provider, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, std::vector<OverlayStrategy> strategies); ~GLOutputSurfaceOzone() override;
diff --git a/components/viz/service/display_embedder/gl_output_surface_win.cc b/components/viz/service/display_embedder/gl_output_surface_win.cc index 117d9c8..e6cd5e3 100644 --- a/components/viz/service/display_embedder/gl_output_surface_win.cc +++ b/components/viz/service/display_embedder/gl_output_surface_win.cc
@@ -10,9 +10,8 @@ GLOutputSurfaceWin::GLOutputSurfaceWin( scoped_refptr<VizProcessContextProvider> context_provider, - UpdateVSyncParametersCallback update_vsync_callback, bool use_overlays) - : GLOutputSurface(context_provider, std::move(update_vsync_callback)) { + : GLOutputSurface(context_provider) { if (use_overlays) { overlay_validator_ = std::make_unique<CompositorOverlayCandidateValidatorWin>();
diff --git a/components/viz/service/display_embedder/gl_output_surface_win.h b/components/viz/service/display_embedder/gl_output_surface_win.h index 67ef72d3..da4cf52f 100644 --- a/components/viz/service/display_embedder/gl_output_surface_win.h +++ b/components/viz/service/display_embedder/gl_output_surface_win.h
@@ -17,7 +17,6 @@ class GLOutputSurfaceWin : public GLOutputSurface { public: GLOutputSurfaceWin(scoped_refptr<VizProcessContextProvider> context_provider, - UpdateVSyncParametersCallback update_vsync_callback, bool use_overlays); ~GLOutputSurfaceWin() override;
diff --git a/components/viz/service/display_embedder/gpu_display_provider.cc b/components/viz/service/display_embedder/gpu_display_provider.cc index 6ddc4d9..e57ba4be 100644 --- a/components/viz/service/display_embedder/gpu_display_provider.cc +++ b/components/viz/service/display_embedder/gpu_display_provider.cc
@@ -120,8 +120,7 @@ if (!gpu_compositing) { output_surface = std::make_unique<SoftwareOutputSurface>( - CreateSoftwareOutputDeviceForPlatform(surface_handle, display_client), - std::move(update_vsync_callback)); + CreateSoftwareOutputDeviceForPlatform(surface_handle, display_client)); } else if (renderer_settings.use_skia_renderer || renderer_settings.use_skia_renderer_non_ddl) { #if defined(OS_MACOSX) || defined(OS_WIN) @@ -157,8 +156,7 @@ } else { output_surface = std::make_unique<SkiaOutputSurfaceImpl>( - gpu_service_impl_, surface_handle, std::move(update_vsync_callback), - renderer_settings); + gpu_service_impl_, surface_handle, renderer_settings); } #endif } else { @@ -200,26 +198,24 @@ if (surface_handle == gpu::kNullSurfaceHandle) { output_surface = std::make_unique<GLOutputSurfaceOffscreen>( - std::move(context_provider), std::move(update_vsync_callback)); + std::move(context_provider)); } else if (context_provider->ContextCapabilities().surfaceless) { #if defined(USE_OZONE) output_surface = std::make_unique<GLOutputSurfaceOzone>( std::move(context_provider), surface_handle, - std::move(update_vsync_callback), gpu_memory_buffer_manager_.get(), + gpu_memory_buffer_manager_.get(), renderer_settings.overlay_strategies); #elif defined(OS_MACOSX) output_surface = std::make_unique<GLOutputSurfaceMac>( std::move(context_provider), surface_handle, - std::move(update_vsync_callback), gpu_memory_buffer_manager_.get(), - renderer_settings.allow_overlays); + gpu_memory_buffer_manager_.get(), renderer_settings.allow_overlays); #elif defined(OS_ANDROID) auto buffer_format = context_provider->UseRGB565PixelFormat() ? gfx::BufferFormat::BGR_565 : gfx::BufferFormat::RGBA_8888; output_surface = std::make_unique<GLOutputSurfaceBufferQueueAndroid>( std::move(context_provider), surface_handle, - std::move(update_vsync_callback), gpu_memory_buffer_manager_.get(), - buffer_format); + gpu_memory_buffer_manager_.get(), buffer_format); #else NOTREACHED(); #endif @@ -233,8 +229,7 @@ capabilities.dc_layers && (capabilities.use_dc_overlays_for_video || use_overlays_for_sw_protected_video); output_surface = std::make_unique<GLOutputSurfaceWin>( - std::move(context_provider), std::move(update_vsync_callback), - use_overlays); + std::move(context_provider), use_overlays); #elif defined(OS_ANDROID) const bool surface_control_enabled = task_executor_->gpu_feature_info() @@ -244,11 +239,11 @@ renderer_settings.backed_by_surface_texture); output_surface = std::make_unique<GLOutputSurfaceAndroid>( - std::move(context_provider), std::move(update_vsync_callback), + std::move(context_provider), !surface_control_enabled /* allow_overlays */); #else - output_surface = std::make_unique<GLOutputSurface>( - std::move(context_provider), std::move(update_vsync_callback)); + output_surface = + std::make_unique<GLOutputSurface>(std::move(context_provider)); #endif } } @@ -256,6 +251,9 @@ // If we need swap size notifications tell the output surface now. output_surface->SetNeedsSwapSizeNotifications(send_swap_size_notifications); + output_surface->SetUpdateVSyncParametersCallback( + std::move(update_vsync_callback)); + int max_frames_pending = output_surface->capabilities().max_frames_pending; DCHECK_GT(max_frames_pending, 0);
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index bcc5e4b9..45f09fc2 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -69,12 +69,10 @@ SkiaOutputSurfaceImpl::SkiaOutputSurfaceImpl( GpuServiceImpl* gpu_service, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, const RendererSettings& renderer_settings) : gpu_service_(gpu_service), is_using_vulkan_(gpu_service->is_using_vulkan()), surface_handle_(surface_handle), - update_vsync_callback_(std::move(update_vsync_callback)), renderer_settings_(renderer_settings), weak_ptr_factory_(this) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); @@ -248,6 +246,11 @@ needs_swap_size_notifications_ = needs_swap_size_notifications; } +void SkiaOutputSurfaceImpl::SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) { + update_vsync_parameters_callback_ = std::move(callback); +} + SkCanvas* SkiaOutputSurfaceImpl::BeginPaintCurrentFrame() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Make sure there is no unsubmitted PaintFrame or PaintRenderPass. @@ -690,13 +693,13 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(client_); client_->DidReceivePresentationFeedback(feedback); - if (update_vsync_callback_ && + if (update_vsync_parameters_callback_ && feedback.flags & gfx::PresentationFeedback::kVSync) { // TODO(brianderson): We should not be receiving 0 intervals. - update_vsync_callback_.Run(feedback.timestamp, - feedback.interval.is_zero() - ? BeginFrameArgs::DefaultInterval() - : feedback.interval); + update_vsync_parameters_callback_.Run( + feedback.timestamp, feedback.interval.is_zero() + ? BeginFrameArgs::DefaultInterval() + : feedback.interval); } }
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index e4971fb..08ff06ef 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -48,7 +48,6 @@ public: SkiaOutputSurfaceImpl(GpuServiceImpl* gpu_service, gpu::SurfaceHandle surface_handle, - UpdateVSyncParametersCallback update_vsync_callback, const RendererSettings& renderer_settings); ~SkiaOutputSurfaceImpl() override; @@ -74,6 +73,8 @@ unsigned UpdateGpuFence() override; void SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) override; + void SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) override; // SkiaOutputSurface implementation: SkCanvas* BeginPaintCurrentFrame() override; @@ -135,7 +136,7 @@ const bool is_using_vulkan_; const gpu::SurfaceHandle surface_handle_; - UpdateVSyncParametersCallback update_vsync_callback_; + UpdateVSyncParametersCallback update_vsync_parameters_callback_; OutputSurfaceClient* client_ = nullptr; std::unique_ptr<base::WaitableEvent> initialize_waitable_event_;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.cc b/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.cc index 70bce5f..e4e197c 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.cc
@@ -208,6 +208,11 @@ NOTIMPLEMENTED(); } +void SkiaOutputSurfaceImplNonDDL::SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) { + NOTIMPLEMENTED(); +} + SkCanvas* SkiaOutputSurfaceImplNonDDL::BeginPaintCurrentFrame() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_EQ(current_render_pass_id_, 0u);
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h b/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h index 9b4375e..e0511bc 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_non_ddl.h
@@ -83,6 +83,8 @@ unsigned UpdateGpuFence() override; void SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) override; + void SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) override; // SkiaOutputSurface implementation: SkCanvas* BeginPaintCurrentFrame() override;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc b/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc index 22d3b35..f75e8b80 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc
@@ -16,7 +16,6 @@ #include "cc/test/fake_output_surface_client.h" #include "cc/test/pixel_test_utils.h" #include "components/viz/common/display/renderer_settings.h" -#include "components/viz/common/display/update_vsync_parameters_callback.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/common/frame_sinks/copy_output_util.h" @@ -211,8 +210,7 @@ #endif } output_surface_ = std::make_unique<SkiaOutputSurfaceImpl>( - gpu_service_.get(), surface_handle_, UpdateVSyncParametersCallback(), - RendererSettings()); + gpu_service_.get(), surface_handle_, RendererSettings()); output_surface_->BindToClient(output_surface_client_.get()); }
diff --git a/components/viz/service/display_embedder/software_output_surface.cc b/components/viz/service/display_embedder/software_output_surface.cc index fe5cd0f..2763038 100644 --- a/components/viz/service/display_embedder/software_output_surface.cc +++ b/components/viz/service/display_embedder/software_output_surface.cc
@@ -22,10 +22,8 @@ namespace viz { SoftwareOutputSurface::SoftwareOutputSurface( - std::unique_ptr<SoftwareOutputDevice> software_device, - UpdateVSyncParametersCallback update_vsync_callback) - : OutputSurface(std::move(software_device)), - update_vsync_callback_(std::move(update_vsync_callback)) {} + std::unique_ptr<SoftwareOutputDevice> software_device) + : OutputSurface(std::move(software_device)) {} SoftwareOutputSurface::~SoftwareOutputSurface() = default; @@ -77,7 +75,7 @@ &SoftwareOutputSurface::SwapBuffersCallback, weak_factory_.GetWeakPtr())); gfx::VSyncProvider* vsync_provider = software_device()->GetVSyncProvider(); - if (vsync_provider && update_vsync_callback_) { + if (vsync_provider && update_vsync_parameters_callback_) { vsync_provider->GetVSyncParameters( base::BindOnce(&SoftwareOutputSurface::UpdateVSyncParameters, weak_factory_.GetWeakPtr())); @@ -130,14 +128,19 @@ void SoftwareOutputSurface::UpdateVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval) { - DCHECK(update_vsync_callback_); + DCHECK(update_vsync_parameters_callback_); refresh_timebase_ = timebase; refresh_interval_ = interval; - update_vsync_callback_.Run(timebase, interval); + update_vsync_parameters_callback_.Run(timebase, interval); } unsigned SoftwareOutputSurface::UpdateGpuFence() { return 0; } +void SoftwareOutputSurface::SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) { + update_vsync_parameters_callback_ = std::move(callback); +} + } // namespace viz
diff --git a/components/viz/service/display_embedder/software_output_surface.h b/components/viz/service/display_embedder/software_output_surface.h index 04593bf..29c0b85 100644 --- a/components/viz/service/display_embedder/software_output_surface.h +++ b/components/viz/service/display_embedder/software_output_surface.h
@@ -20,8 +20,8 @@ class VIZ_SERVICE_EXPORT SoftwareOutputSurface : public OutputSurface { public: - SoftwareOutputSurface(std::unique_ptr<SoftwareOutputDevice> software_device, - UpdateVSyncParametersCallback update_vsync_callback); + explicit SoftwareOutputSurface( + std::unique_ptr<SoftwareOutputDevice> software_device); ~SoftwareOutputSurface() override; // OutputSurface implementation. @@ -44,6 +44,8 @@ void ApplyExternalStencil() override; uint32_t GetFramebufferCopyTextureFormat() override; unsigned UpdateGpuFence() override; + void SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) override; private: void SwapBuffersCallback(); @@ -52,7 +54,7 @@ OutputSurfaceClient* client_ = nullptr; - UpdateVSyncParametersCallback update_vsync_callback_; + UpdateVSyncParametersCallback update_vsync_parameters_callback_; base::TimeTicks refresh_timebase_; base::TimeDelta refresh_interval_ = BeginFrameArgs::DefaultInterval();
diff --git a/components/viz/test/fake_output_surface.cc b/components/viz/test/fake_output_surface.cc index e472e85..e981783 100644 --- a/components/viz/test/fake_output_surface.cc +++ b/components/viz/test/fake_output_surface.cc
@@ -105,4 +105,7 @@ return gpu_fence_id_; } +void FakeOutputSurface::SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) {} + } // namespace viz
diff --git a/components/viz/test/fake_output_surface.h b/components/viz/test/fake_output_surface.h index aa4a2d7..d429c68 100644 --- a/components/viz/test/fake_output_surface.h +++ b/components/viz/test/fake_output_surface.h
@@ -75,6 +75,8 @@ unsigned GetOverlayTextureId() const override; gfx::BufferFormat GetOverlayBufferFormat() const override; unsigned UpdateGpuFence() override; + void SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) override; void set_framebuffer(GLint framebuffer, GLenum format) { framebuffer_ = framebuffer;
diff --git a/components/viz/test/fake_skia_output_surface.cc b/components/viz/test/fake_skia_output_surface.cc index ca376bf..19c5462f 100644 --- a/components/viz/test/fake_skia_output_surface.cc +++ b/components/viz/test/fake_skia_output_surface.cc
@@ -120,6 +120,11 @@ NOTIMPLEMENTED(); } +void FakeSkiaOutputSurface::SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) { + NOTIMPLEMENTED(); +} + SkCanvas* FakeSkiaOutputSurface::BeginPaintCurrentFrame() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); auto& sk_surface = sk_surfaces_[0];
diff --git a/components/viz/test/fake_skia_output_surface.h b/components/viz/test/fake_skia_output_surface.h index 19df347d..29e0fc83 100644 --- a/components/viz/test/fake_skia_output_surface.h +++ b/components/viz/test/fake_skia_output_surface.h
@@ -52,6 +52,8 @@ unsigned UpdateGpuFence() override; void SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) override; + void SetUpdateVSyncParametersCallback( + UpdateVSyncParametersCallback callback) override; // SkiaOutputSurface implementation: SkCanvas* BeginPaintCurrentFrame() override;
diff --git a/components/viz/test/test_context_provider.cc b/components/viz/test/test_context_provider.cc index 12ce11c..69ddcd1 100644 --- a/components/viz/test/test_context_provider.cc +++ b/components/viz/test/test_context_provider.cc
@@ -160,6 +160,7 @@ const gpu::SyncToken& sync_token, const gpu::Mailbox& mailbox) { shared_images_.erase(mailbox); + most_recent_destroy_token_ = sync_token; } #if defined(OS_WIN) @@ -180,15 +181,18 @@ #endif // OS_WIN gpu::SyncToken TestSharedImageInterface::GenVerifiedSyncToken() { - gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO, - gpu::CommandBufferId(), ++release_id_); - sync_token.SetVerifyFlush(); - return sync_token; + most_recent_generated_token_ = + gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, + gpu::CommandBufferId(), ++release_id_); + most_recent_generated_token_.SetVerifyFlush(); + return most_recent_generated_token_; } gpu::SyncToken TestSharedImageInterface::GenUnverifiedSyncToken() { - return gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, - gpu::CommandBufferId(), ++release_id_); + most_recent_generated_token_ = + gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, + gpu::CommandBufferId(), ++release_id_); + return most_recent_generated_token_; } bool TestSharedImageInterface::CheckSharedImageExists(
diff --git a/components/viz/test/test_context_provider.h b/components/viz/test/test_context_provider.h index b5eb723c..2258b12 100644 --- a/components/viz/test/test_context_provider.h +++ b/components/viz/test/test_context_provider.h
@@ -77,11 +77,19 @@ size_t shared_image_count() const { return shared_images_.size(); } const gfx::Size& MostRecentSize() const { return most_recent_size_; } + const gpu::SyncToken& MostRecentGeneratedToken() const { + return most_recent_generated_token_; + } + const gpu::SyncToken& MostRecentDestroyToken() const { + return most_recent_destroy_token_; + } bool CheckSharedImageExists(const gpu::Mailbox& mailbox) const; private: uint64_t release_id_ = 0; gfx::Size most_recent_size_; + gpu::SyncToken most_recent_generated_token_; + gpu::SyncToken most_recent_destroy_token_; base::flat_set<gpu::Mailbox> shared_images_; };
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index 4dc87d82..732dc46 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -86,6 +86,7 @@ #elif defined(OS_MACOSX) #include "base/mac/mach_port_broker.h" #include "base/power_monitor/power_monitor_device_source.h" +#include "sandbox/mac/seatbelt.h" #include "sandbox/mac/seatbelt_exec.h" #endif // OS_WIN @@ -812,19 +813,16 @@ params.sandbox_info)) return TerminateForFatalInitializationError(); #elif defined(OS_MACOSX) - // Do not initialize the sandbox at this point if the V2 - // sandbox is enabled for the process type. + // Only the GPU process still runs the V1 sandbox. bool v2_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch( sandbox::switches::kSeatbeltClientName); - if (process_type == switches::kRendererProcess || - process_type == switches::kPpapiPluginProcess || v2_enabled || - delegate_->DelaySandboxInitialization(process_type)) { - // On OS X the renderer sandbox needs to be initialized later in the - // startup sequence in RendererMainPlatformDelegate::EnableSandbox(). - } else { - if (!InitializeSandbox()) + if (!v2_enabled && process_type == switches::kGpuProcess) { + if (!InitializeSandbox()) { return TerminateForFatalInitializationError(); + } + } else if (v2_enabled) { + CHECK(sandbox::Seatbelt::IsSandboxed()); } #endif
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 7b01d3c..18761f1 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -59,6 +59,7 @@ "//components/network_session_configurator/browser", "//components/offline_pages/buildflags", "//components/offline_pages/core/request_header", + "//components/payments/content/icon", "//components/rappor", "//components/services/filesystem:lib", "//components/services/leveldb:lib",
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index 400e17c..6370dcf 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -1321,8 +1321,9 @@ RunHtmlTest(FILE_PATH_LITERAL("iframe-coordinates.html")); } +// https://crbug.com/956990 IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - AccessibilityIframeCoordinatesCrossProcess) { + DISABLED_AccessibilityIframeCoordinatesCrossProcess) { RunHtmlTest(FILE_PATH_LITERAL("iframe-coordinates-cross-process.html")); } IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityIframePadding) {
diff --git a/content/browser/after_startup_task_utils.cc b/content/browser/after_startup_task_utils.cc index 2024105..66d25548 100644 --- a/content/browser/after_startup_task_utils.cc +++ b/content/browser/after_startup_task_utils.cc
@@ -11,7 +11,7 @@ namespace content { void SetBrowserStartupIsCompleteForTesting() { - content::BrowserTaskExecutor::NotifyBrowserStartupCompleted(); + content::BrowserTaskExecutor::EnableBestEffortQueues(); // Forward the message to ContentBrowserClient if one is registered (there are // many tests where one isn't but that's fine as that also means they get the // default ContentBrowserClient::IsBrowserStartupComplete() which is always
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 6e3dfde10..7580d35 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -1212,7 +1212,7 @@ // TODO(https://crbug.com/863341): Replace with a better API GetContentClient()->browser()->PostAfterStartupTask( FROM_HERE, base::SequencedTaskRunnerHandle::Get(), base::BindOnce([]() { - content::BrowserTaskExecutor::NotifyBrowserStartupCompleted(); + content::BrowserTaskExecutor::EnableBestEffortQueues(); })); } @@ -1460,7 +1460,7 @@ if (base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)) { content::DWriteFontLookupTableBuilder::GetInstance() - ->SchedulePrepareFontUniqueNameTable(); + ->SchedulePrepareFontUniqueNameTableIfNeeded(); } #endif
diff --git a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc index a2adb6b..c43aaee 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
@@ -60,6 +60,7 @@ #include "url/origin.h" #if BUILDFLAG(ENABLE_REPORTING) +#include "net/network_error_logging/mock_persistent_nel_store.h" #include "net/network_error_logging/network_error_logging_service.h" #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_report.h" @@ -1360,9 +1361,44 @@ BrowsingDataRemover::DATA_TYPE_COOKIES, false); } -// TODO(chlily): Use a PersistentNELStore and test that entries are removed from -// it. TEST_F(BrowsingDataRemoverImplTest, RemoveNetworkErrorLogging) { + auto store = std::make_unique<net::MockPersistentNELStore>(); + std::unique_ptr<net::NetworkErrorLoggingService> logging_service = + net::NetworkErrorLoggingService::Create(store.get()); + BrowserContext::GetDefaultStoragePartition(GetBrowserContext()) + ->GetURLRequestContext() + ->GetURLRequestContext() + ->set_network_error_logging_service(logging_service.get()); + + GURL domain("https://google.com"); + logging_service->OnHeader(url::Origin::Create(domain), + net::IPAddress(192, 168, 0, 1), + "{\"report_to\":\"group\",\"max_age\":86400}"); + store->FinishLoading(true /* load_success */); + store->Flush(); + + ASSERT_EQ(1u, logging_service->GetPolicyOriginsForTesting().size()); + ASSERT_EQ(1, store->StoredPoliciesCount()); + + BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), + BrowsingDataRemover::DATA_TYPE_COOKIES, false); + + EXPECT_TRUE(logging_service->GetPolicyOriginsForTesting().empty()); + EXPECT_EQ(0, store->StoredPoliciesCount()); + + // Check that the persistent store was told to delete the policy. + net::NetworkErrorLoggingService::NELPolicy deleted_policy; + deleted_policy.origin = url::Origin::Create(domain); + EXPECT_THAT(store->GetAllCommands(), + testing::Contains(net::MockPersistentNELStore::Command( + net::MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, + deleted_policy))); +} + +// Test that removal of in-memory browsing data works without a persistent +// store. +TEST_F(BrowsingDataRemoverImplTest, + RemoveNetworkErrorLogging_NoPersistentStore) { std::unique_ptr<net::NetworkErrorLoggingService> logging_service = net::NetworkErrorLoggingService::Create(nullptr /* store */); BrowserContext::GetDefaultStoragePartition(GetBrowserContext()) @@ -1383,11 +1419,10 @@ EXPECT_TRUE(logging_service->GetPolicyOriginsForTesting().empty()); } -// TODO(chlily): Use a PersistentNELStore and test that entries are removed from -// it. TEST_F(BrowsingDataRemoverImplTest, RemoveNetworkErrorLogging_SpecificOrigins) { + auto store = std::make_unique<net::MockPersistentNELStore>(); std::unique_ptr<net::NetworkErrorLoggingService> logging_service = - net::NetworkErrorLoggingService::Create(nullptr /* store */); + net::NetworkErrorLoggingService::Create(store.get()); BrowserContext::GetDefaultStoragePartition(GetBrowserContext()) ->GetURLRequestContext() ->GetURLRequestContext() @@ -1409,8 +1444,11 @@ logging_service->OnHeader(url::Origin::Create(domain4), net::IPAddress(192, 168, 0, 1), "{\"report_to\":\"group\",\"max_age\":86400}"); + store->FinishLoading(true /* load_success */); + store->Flush(); ASSERT_EQ(4u, logging_service->GetPolicyOriginsForTesting().size()); + ASSERT_EQ(4, store->StoredPoliciesCount()); std::unique_ptr<BrowsingDataFilterBuilder> filter_builder( BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST)); @@ -1426,6 +1464,21 @@ EXPECT_THAT(policy_origins, UnorderedElementsAre(url::Origin::Create(domain2), url::Origin::Create(domain4))); + EXPECT_EQ(2, store->StoredPoliciesCount()); + + // Check that the persistent store was told to delete the policies. + net::NetworkErrorLoggingService::NELPolicy deleted_policy1; + deleted_policy1.origin = url::Origin::Create(domain1); + net::NetworkErrorLoggingService::NELPolicy deleted_policy2; + deleted_policy2.origin = url::Origin::Create(domain3); + EXPECT_THAT(store->GetAllCommands(), + testing::Contains(net::MockPersistentNELStore::Command( + net::MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, + deleted_policy1))); + EXPECT_THAT(store->GetAllCommands(), + testing::Contains(net::MockPersistentNELStore::Command( + net::MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, + deleted_policy2))); } TEST_F(BrowsingDataRemoverImplTest, RemoveNetworkErrorLogging_NoService) {
diff --git a/content/browser/compositor/browser_compositor_output_surface.cc b/content/browser/compositor/browser_compositor_output_surface.cc index 24cfe2fb..08883fb3 100644 --- a/content/browser/compositor/browser_compositor_output_surface.cc +++ b/content/browser/compositor/browser_compositor_output_surface.cc
@@ -20,21 +20,15 @@ BrowserCompositorOutputSurface::BrowserCompositorOutputSurface( scoped_refptr<viz::ContextProvider> context_provider, - const viz::UpdateVSyncParametersCallback& update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator) - : OutputSurface(std::move(context_provider)), - update_vsync_parameters_callback_(update_vsync_parameters_callback), - reflector_(nullptr) { + : OutputSurface(std::move(context_provider)) { overlay_candidate_validator_ = std::move(overlay_candidate_validator); } BrowserCompositorOutputSurface::BrowserCompositorOutputSurface( - std::unique_ptr<viz::SoftwareOutputDevice> software_device, - const viz::UpdateVSyncParametersCallback& update_vsync_parameters_callback) - : OutputSurface(std::move(software_device)), - update_vsync_parameters_callback_(update_vsync_parameters_callback), - reflector_(nullptr) {} + std::unique_ptr<viz::SoftwareOutputDevice> software_device) + : OutputSurface(std::move(software_device)) {} BrowserCompositorOutputSurface::~BrowserCompositorOutputSurface() { if (reflector_) @@ -67,4 +61,9 @@ void BrowserCompositorOutputSurface::ApplyExternalStencil() {} +void BrowserCompositorOutputSurface::SetUpdateVSyncParametersCallback( + viz::UpdateVSyncParametersCallback callback) { + update_vsync_parameters_callback_ = std::move(callback); +} + } // namespace content
diff --git a/content/browser/compositor/browser_compositor_output_surface.h b/content/browser/compositor/browser_compositor_output_surface.h index dda4ac0..e3fe1a9 100644 --- a/content/browser/compositor/browser_compositor_output_surface.h +++ b/content/browser/compositor/browser_compositor_output_surface.h
@@ -35,6 +35,8 @@ viz::OverlayCandidateValidator* GetOverlayCandidateValidator() const override; bool HasExternalStencilTest() const override; void ApplyExternalStencil() override; + void SetUpdateVSyncParametersCallback( + viz::UpdateVSyncParametersCallback callback) override; void SetReflector(ReflectorImpl* reflector); @@ -45,19 +47,15 @@ // Constructor used by the accelerated implementation. BrowserCompositorOutputSurface( scoped_refptr<viz::ContextProvider> context, - const viz::UpdateVSyncParametersCallback& - update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator); // Constructor used by the software implementation. - BrowserCompositorOutputSurface( - std::unique_ptr<viz::SoftwareOutputDevice> software_device, - const viz::UpdateVSyncParametersCallback& - update_vsync_parameters_callback); + explicit BrowserCompositorOutputSurface( + std::unique_ptr<viz::SoftwareOutputDevice> software_device); - const viz::UpdateVSyncParametersCallback update_vsync_parameters_callback_; - ReflectorImpl* reflector_; + viz::UpdateVSyncParametersCallback update_vsync_parameters_callback_; + ReflectorImpl* reflector_ = nullptr; private: std::unique_ptr<viz::CompositorOverlayCandidateValidator>
diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_browser_compositor_output_surface.cc index b9838196..762df71 100644 --- a/content/browser/compositor/gpu_browser_compositor_output_surface.cc +++ b/content/browser/compositor/gpu_browser_compositor_output_surface.cc
@@ -26,11 +26,9 @@ GpuBrowserCompositorOutputSurface::GpuBrowserCompositorOutputSurface( scoped_refptr<ws::ContextProviderCommandBuffer> context, - const viz::UpdateVSyncParametersCallback& update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator) : BrowserCompositorOutputSurface(std::move(context), - update_vsync_parameters_callback, std::move(overlay_candidate_validator)), weak_ptr_factory_(this) { if (capabilities_.uses_default_gl_framebuffer) {
diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.h b/content/browser/compositor/gpu_browser_compositor_output_surface.h index 8c728be..a050aee 100644 --- a/content/browser/compositor/gpu_browser_compositor_output_surface.h +++ b/content/browser/compositor/gpu_browser_compositor_output_surface.h
@@ -41,8 +41,6 @@ public: GpuBrowserCompositorOutputSurface( scoped_refptr<ws::ContextProviderCommandBuffer> context, - const viz::UpdateVSyncParametersCallback& - update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator);
diff --git a/content/browser/compositor/gpu_output_surface_mac.cc b/content/browser/compositor/gpu_output_surface_mac.cc index 91ebbee..eeace7b4 100644 --- a/content/browser/compositor/gpu_output_surface_mac.cc +++ b/content/browser/compositor/gpu_output_surface_mac.cc
@@ -15,14 +15,12 @@ GpuOutputSurfaceMac::GpuOutputSurfaceMac( scoped_refptr<ws::ContextProviderCommandBuffer> context, gpu::SurfaceHandle surface_handle, - const viz::UpdateVSyncParametersCallback& update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) : GpuSurfacelessBrowserCompositorOutputSurface( std::move(context), surface_handle, - update_vsync_parameters_callback, std::move(overlay_candidate_validator), gfx::BufferFormat::RGBA_8888, gpu_memory_buffer_manager) {}
diff --git a/content/browser/compositor/gpu_output_surface_mac.h b/content/browser/compositor/gpu_output_surface_mac.h index 573358a..b9e184f 100644 --- a/content/browser/compositor/gpu_output_surface_mac.h +++ b/content/browser/compositor/gpu_output_surface_mac.h
@@ -16,8 +16,6 @@ public: GpuOutputSurfaceMac(scoped_refptr<ws::ContextProviderCommandBuffer> context, gpu::SurfaceHandle surface_handle, - const viz::UpdateVSyncParametersCallback& - update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager);
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index 99c703a1..e5a43b9 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -437,8 +437,6 @@ } } - auto vsync_callback = base::BindRepeating( - &ui::Compositor::SetDisplayVSyncParameters, compositor); std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface; if (!use_gpu_compositing) { if (!is_gpu_compositing_disabled_ && @@ -453,15 +451,14 @@ display_output_surface = std::make_unique<SoftwareBrowserCompositorOutputSurface>( CreateSoftwareOutputDevice(compositor->widget(), - compositor->task_runner()), - std::move(vsync_callback)); + compositor->task_runner())); } else { DCHECK(context_provider); const auto& capabilities = context_provider->ContextCapabilities(); if (data->surface_handle == gpu::kNullSurfaceHandle) { display_output_surface = std::make_unique<OffscreenBrowserCompositorOutputSurface>( - context_provider, std::move(vsync_callback), + context_provider, std::unique_ptr<viz::CompositorOverlayCandidateValidator>()); } else if (capabilities.surfaceless) { #if defined(OS_MACOSX) @@ -469,7 +466,7 @@ bool disable_overlay_ca_layers = gpu_feature_info.IsWorkaroundEnabled(gpu::DISABLE_OVERLAY_CA_LAYERS); display_output_surface = std::make_unique<GpuOutputSurfaceMac>( - context_provider, data->surface_handle, vsync_callback, + context_provider, data->surface_handle, CreateOverlayCandidateValidator(compositor->widget(), disable_overlay_ca_layers), GetGpuMemoryBufferManager()); @@ -477,7 +474,7 @@ DCHECK(capabilities.texture_format_bgra8888); auto gpu_output_surface = std::make_unique<GpuSurfacelessBrowserCompositorOutputSurface>( - context_provider, data->surface_handle, std::move(vsync_callback), + context_provider, data->surface_handle, CreateOverlayCandidateValidator(compositor->widget()), display::DisplaySnapshot::PrimaryFormat(), GetGpuMemoryBufferManager()); @@ -498,12 +495,15 @@ #endif auto gpu_output_surface = std::make_unique<GpuBrowserCompositorOutputSurface>( - context_provider, std::move(vsync_callback), - std::move(validator)); + context_provider, std::move(validator)); display_output_surface = std::move(gpu_output_surface); } } + auto vsync_callback = base::BindRepeating( + &ui::Compositor::SetDisplayVSyncParameters, compositor); + display_output_surface->SetUpdateVSyncParametersCallback(vsync_callback); + data->display_output_surface = display_output_surface.get(); if (data->reflector) data->reflector->OnSourceSurfaceReady(data->display_output_surface);
diff --git a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc index 4d4f7136..bdcef70 100644 --- a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc +++ b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.cc
@@ -22,14 +22,11 @@ GpuSurfacelessBrowserCompositorOutputSurface( scoped_refptr<ws::ContextProviderCommandBuffer> context, gpu::SurfaceHandle surface_handle, - const viz::UpdateVSyncParametersCallback& - update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator, gfx::BufferFormat format, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) : GpuBrowserCompositorOutputSurface(std::move(context), - update_vsync_parameters_callback, std::move(overlay_candidate_validator)), use_gpu_fence_( context_provider_->ContextCapabilities().chromium_gpu_fence &&
diff --git a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h index af364ef..bfc610a 100644 --- a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h +++ b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h
@@ -27,8 +27,6 @@ GpuSurfacelessBrowserCompositorOutputSurface( scoped_refptr<ws::ContextProviderCommandBuffer> context, gpu::SurfaceHandle surface_handle, - const viz::UpdateVSyncParametersCallback& - update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator, gfx::BufferFormat format,
diff --git a/content/browser/compositor/offscreen_browser_compositor_output_surface.cc b/content/browser/compositor/offscreen_browser_compositor_output_surface.cc index dfedf6a..bcbe12c2 100644 --- a/content/browser/compositor/offscreen_browser_compositor_output_surface.cc +++ b/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
@@ -32,12 +32,9 @@ OffscreenBrowserCompositorOutputSurface:: OffscreenBrowserCompositorOutputSurface( scoped_refptr<ws::ContextProviderCommandBuffer> context, - const viz::UpdateVSyncParametersCallback& - update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator) : BrowserCompositorOutputSurface(std::move(context), - update_vsync_parameters_callback, std::move(overlay_candidate_validator)), weak_ptr_factory_(this) { capabilities_.uses_default_gl_framebuffer = false;
diff --git a/content/browser/compositor/offscreen_browser_compositor_output_surface.h b/content/browser/compositor/offscreen_browser_compositor_output_surface.h index 9751f1e..ac2786d 100644 --- a/content/browser/compositor/offscreen_browser_compositor_output_surface.h +++ b/content/browser/compositor/offscreen_browser_compositor_output_surface.h
@@ -29,8 +29,6 @@ public: OffscreenBrowserCompositorOutputSurface( scoped_refptr<ws::ContextProviderCommandBuffer> context, - const viz::UpdateVSyncParametersCallback& - update_vsync_parameters_callback, std::unique_ptr<viz::CompositorOverlayCandidateValidator> overlay_candidate_validator);
diff --git a/content/browser/compositor/reflector_impl_unittest.cc b/content/browser/compositor/reflector_impl_unittest.cc index d3fc3f8..0352bf8 100644 --- a/content/browser/compositor/reflector_impl_unittest.cc +++ b/content/browser/compositor/reflector_impl_unittest.cc
@@ -80,7 +80,6 @@ public: TestOutputSurface(scoped_refptr<viz::ContextProvider> context_provider) : BrowserCompositorOutputSurface(std::move(context_provider), - viz::UpdateVSyncParametersCallback(), CreateTestValidatorOzone()) {} void SetFlip(bool flip) { capabilities_.flipped_output_surface = flip; }
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.cc b/content/browser/compositor/software_browser_compositor_output_surface.cc index 0f13e98..22412d9 100644 --- a/content/browser/compositor/software_browser_compositor_output_surface.cc +++ b/content/browser/compositor/software_browser_compositor_output_surface.cc
@@ -21,10 +21,8 @@ namespace content { SoftwareBrowserCompositorOutputSurface::SoftwareBrowserCompositorOutputSurface( - std::unique_ptr<viz::SoftwareOutputDevice> software_device, - const viz::UpdateVSyncParametersCallback& update_vsync_parameters_callback) - : BrowserCompositorOutputSurface(std::move(software_device), - update_vsync_parameters_callback), + std::unique_ptr<viz::SoftwareOutputDevice> software_device) + : BrowserCompositorOutputSurface(std::move(software_device)), weak_factory_(this) {} SoftwareBrowserCompositorOutputSurface:: @@ -98,7 +96,8 @@ const base::TimeTicks timebase, const base::TimeDelta interval) { refresh_interval_ = interval; - update_vsync_parameters_callback_.Run(timebase, interval); + if (update_vsync_parameters_callback_) + update_vsync_parameters_callback_.Run(timebase, interval); } bool SoftwareBrowserCompositorOutputSurface::IsDisplayedAsOverlayPlane() const {
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.h b/content/browser/compositor/software_browser_compositor_output_surface.h index fa54dcb..012ba86 100644 --- a/content/browser/compositor/software_browser_compositor_output_surface.h +++ b/content/browser/compositor/software_browser_compositor_output_surface.h
@@ -17,10 +17,8 @@ class CONTENT_EXPORT SoftwareBrowserCompositorOutputSurface : public BrowserCompositorOutputSurface { public: - SoftwareBrowserCompositorOutputSurface( - std::unique_ptr<viz::SoftwareOutputDevice> software_device, - const viz::UpdateVSyncParametersCallback& - update_vsync_parameters_callback); + explicit SoftwareBrowserCompositorOutputSurface( + std::unique_ptr<viz::SoftwareOutputDevice> software_device); ~SoftwareBrowserCompositorOutputSurface() override;
diff --git a/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc b/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc index 5ac8128f..c04aefd7 100644 --- a/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc +++ b/content/browser/compositor/software_browser_compositor_output_surface_unittest.cc
@@ -126,11 +126,13 @@ std::unique_ptr<content::BrowserCompositorOutputSurface> SoftwareBrowserCompositorOutputSurfaceTest::CreateSurface( std::unique_ptr<viz::SoftwareOutputDevice> device) { - return std::make_unique<content::SoftwareBrowserCompositorOutputSurface>( - std::move(device), - base::Bind( - &SoftwareBrowserCompositorOutputSurfaceTest::UpdateVSyncParameters, - base::Unretained(this))); + auto surface = + std::make_unique<content::SoftwareBrowserCompositorOutputSurface>( + std::move(device)); + surface->SetUpdateVSyncParametersCallback(base::BindRepeating( + &SoftwareBrowserCompositorOutputSurfaceTest::UpdateVSyncParameters, + base::Unretained(this))); + return surface; } void SoftwareBrowserCompositorOutputSurfaceTest::UpdateVSyncParameters(
diff --git a/content/browser/notifications/OWNERS b/content/browser/notifications/OWNERS index 0d5ed95..fec618f3 100644 --- a/content/browser/notifications/OWNERS +++ b/content/browser/notifications/OWNERS
@@ -4,6 +4,7 @@ # //content/renderer/notifications/ # //content/test/mock_platform_notification_service.* +knollr@chromium.org mkwst@chromium.org peter@chromium.org
diff --git a/content/browser/notifications/platform_notification_context_impl.cc b/content/browser/notifications/platform_notification_context_impl.cc index 37c746bc..258d423 100644 --- a/content/browser/notifications/platform_notification_context_impl.cc +++ b/content/browser/notifications/platform_notification_context_impl.cc
@@ -67,7 +67,8 @@ const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context) : path_(path), browser_context_(browser_context), - service_worker_context_(service_worker_context) { + service_worker_context_(service_worker_context), + has_shutdown_(false) { DCHECK_CURRENTLY_ON(BrowserThread::UI); } @@ -109,6 +110,10 @@ std::set<std::string> displayed_notifications, bool supports_synchronization) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Abort if the profile has been shut down already. This mainly happens in + // tests and very short lived sessions. + if (has_shutdown_) + return; // Check if there are pending notifications to display. base::Time next_trigger = base::Time::Max(); @@ -189,8 +194,11 @@ void PlatformNotificationContextImpl::Shutdown() { DCHECK_CURRENTLY_ON(BrowserThread::UI); + has_shutdown_ = true; - service_proxy_.reset(); + if (service_proxy_) + service_proxy_->Shutdown(); + services_.clear(); // |service_worker_context_| may be NULL in tests. @@ -267,7 +275,7 @@ std::set<GURL> origins) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // Make sure |browser_context_| is still valid before getting the controller. - if (!success || !service_proxy_) { + if (!success || !service_proxy_ || has_shutdown_) { std::move(callback).Run(/* success= */ false, /* deleted_count= */ 0); return; }
diff --git a/content/browser/notifications/platform_notification_context_impl.h b/content/browser/notifications/platform_notification_context_impl.h index 11eed74..de7f9d4 100644 --- a/content/browser/notifications/platform_notification_context_impl.h +++ b/content/browser/notifications/platform_notification_context_impl.h
@@ -272,6 +272,9 @@ NotificationDatabase::UkmCallback ukm_callback_; + // Flag if the |browser_context_| has been shutdown already. + bool has_shutdown_; + DISALLOW_COPY_AND_ASSIGN(PlatformNotificationContextImpl); };
diff --git a/content/browser/notifications/platform_notification_service_proxy.cc b/content/browser/notifications/platform_notification_service_proxy.cc index 1e65ea4..5ad2b972 100644 --- a/content/browser/notifications/platform_notification_service_proxy.cc +++ b/content/browser/notifications/platform_notification_service_proxy.cc
@@ -24,10 +24,21 @@ notification_service_( GetContentClient()->browser()->GetPlatformNotificationService( browser_context)), + weak_ptr_factory_ui_(this), weak_ptr_factory_io_(this) {} PlatformNotificationServiceProxy::~PlatformNotificationServiceProxy() = default; +void PlatformNotificationServiceProxy::Shutdown() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + weak_ptr_factory_ui_.InvalidateWeakPtrs(); +} + +base::WeakPtr<PlatformNotificationServiceProxy> +PlatformNotificationServiceProxy::AsWeakPtr() { + return weak_ptr_factory_ui_.GetWeakPtr(); +} + void PlatformNotificationServiceProxy::DoDisplayNotification( const NotificationDatabaseData& data, const GURL& service_worker_scope,
diff --git a/content/browser/notifications/platform_notification_service_proxy.h b/content/browser/notifications/platform_notification_service_proxy.h index 2989f332..c24cf42 100644 --- a/content/browser/notifications/platform_notification_service_proxy.h +++ b/content/browser/notifications/platform_notification_service_proxy.h
@@ -28,8 +28,7 @@ class ServiceWorkerContextWrapper; class ServiceWorkerRegistration; -class CONTENT_EXPORT PlatformNotificationServiceProxy - : public base::SupportsWeakPtr<PlatformNotificationServiceProxy> { +class CONTENT_EXPORT PlatformNotificationServiceProxy { public: using DisplayResultCallback = base::OnceCallback<void(bool /* success */, @@ -41,6 +40,13 @@ ~PlatformNotificationServiceProxy(); + // To be called when the |browser_context_| has been shutdown. This + // invalidates all weak pointers. Must be called on the UI thread. + void Shutdown(); + + // Gets a weak pointer to be used on the UI thread. + base::WeakPtr<PlatformNotificationServiceProxy> AsWeakPtr(); + // Displays a notification with |data| and calls |callback| with the result. // This will verify against the given |service_worker_context_| if available. void DisplayNotification(const NotificationDatabaseData& data, @@ -84,6 +90,7 @@ scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_; PlatformNotificationService* notification_service_; + base::WeakPtrFactory<PlatformNotificationServiceProxy> weak_ptr_factory_ui_; base::WeakPtrFactory<PlatformNotificationServiceProxy> weak_ptr_factory_io_; DISALLOW_COPY_AND_ASSIGN(PlatformNotificationServiceProxy);
diff --git a/content/browser/payments/payment_app_info_fetcher.cc b/content/browser/payments/payment_app_info_fetcher.cc index 0a10a01..2ccd84c6 100644 --- a/content/browser/payments/payment_app_info_fetcher.cc +++ b/content/browser/payments/payment_app_info_fetcher.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/task/post_task.h" +#include "components/payments/content/icon/icon_size.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -238,13 +239,6 @@ &(fetched_payment_app_info_->name)); } - // TODO(gogerald): Choose appropriate icon size dynamically on different - // platforms. - // Here we choose a large ideal icon size to be big enough for all platforms. - // Note that we only scale down for this icon size but not scale up. - const int kPaymentAppIdealIconSize = 0xFFFF; - const int kPaymentAppMinimumIconSize = 0; - if (manifest.icons.empty()) { WarnIfPossible( "Unable to download the payment handler's icon, because the web app " @@ -256,8 +250,22 @@ return; } + WebContents* web_contents = web_contents_helper_->web_contents(); + if (!web_contents) { + LOG(WARNING) << "Unable to download the payment handler's icon because no " + "renderer was found, possibly because the page was closed " + "or navigated away during installation. User may not " + "recognize this payment handler in UI, because it will be " + "labeled only by its name and origin."; + RunCallbackAndDestroy(); + return; + } + gfx::NativeView native_view = web_contents->GetNativeView(); + icon_url_ = blink::ManifestIconSelector::FindBestMatchingIcon( - manifest.icons, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize, + manifest.icons, + payments::IconSizeCalculator::IdealIconHeight(native_view), + payments::IconSizeCalculator::MinimumIconHeight(), ManifestIconDownloader::kMaxWidthToHeightRatio, blink::Manifest::ImageResource::Purpose::ANY); if (!icon_url_.is_valid()) { @@ -271,19 +279,10 @@ return; } - if (!web_contents_helper_->web_contents()) { - LOG(WARNING) << "Unable to download the payment handler's icon because no " - "renderer was found, possibly because the page was closed " - "or navigated away during installation. User may not " - "recognize this payment handler in UI, because it will be " - "labeled only by its name and origin."; - RunCallbackAndDestroy(); - return; - } - bool can_download = ManifestIconDownloader::Download( - web_contents_helper_->web_contents(), icon_url_, kPaymentAppIdealIconSize, - kPaymentAppMinimumIconSize, + web_contents, icon_url_, + payments::IconSizeCalculator::IdealIconHeight(native_view), + payments::IconSizeCalculator::MinimumIconHeight(), base::BindOnce(&PaymentAppInfoFetcher::SelfDeleteFetcher::OnIconFetched, base::Unretained(this)), false /* square_only */);
diff --git a/content/browser/payments/payment_instrument_icon_fetcher.cc b/content/browser/payments/payment_instrument_icon_fetcher.cc index c1e109b7..d0d47d2d 100644 --- a/content/browser/payments/payment_instrument_icon_fetcher.cc +++ b/content/browser/payments/payment_instrument_icon_fetcher.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/task/post_task.h" +#include "components/payments/content/icon/icon_size.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -23,13 +24,6 @@ namespace content { namespace { -// TODO(zino): Choose appropriate icon size dynamically on different platforms. -// Here we choose a large ideal icon size to be big enough for all platforms. -// Note that we only scale down for this icon size but not scale up. -// Please see: https://crbug.com/763886 -const int kPaymentAppIdealIconSize = 0xFFFF; -const int kPaymentAppMinimumIconSize = 0; - void DownloadBestMatchingIcon( WebContents* web_contents, const std::vector<blink::Manifest::ImageResource>& icons, @@ -75,11 +69,20 @@ callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (web_contents == nullptr) { + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::IO}, + base::BindOnce(std::move(callback), std::string())); + return; + } + + gfx::NativeView native_view = web_contents->GetNativeView(); GURL icon_url = blink::ManifestIconSelector::FindBestMatchingIcon( - icons, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize, + icons, payments::IconSizeCalculator::IdealIconHeight(native_view), + payments::IconSizeCalculator::MinimumIconHeight(), ManifestIconDownloader::kMaxWidthToHeightRatio, blink::Manifest::ImageResource::Purpose::ANY); - if (web_contents == nullptr || !icon_url.is_valid()) { + if (!icon_url.is_valid()) { // If the icon url is invalid, it's better to give the information to // developers in advance unlike when fetching or decoding fails. We already // checked whether they are valid in renderer side. So, if the icon url is @@ -98,8 +101,9 @@ } bool can_download_icon = ManifestIconDownloader::Download( - web_contents, icon_url, kPaymentAppIdealIconSize, - kPaymentAppMinimumIconSize, + web_contents, icon_url, + payments::IconSizeCalculator::IdealIconHeight(native_view), + payments::IconSizeCalculator::MinimumIconHeight(), base::BindOnce(&OnIconFetched, web_contents, copy_icons, std::move(callback)), false /* square_only */);
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 992eedf..4420a91a 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -478,6 +478,9 @@ unsigned UpdateGpuFence() override { return 0; } + void SetUpdateVSyncParametersCallback( + viz::UpdateVSyncParametersCallback callback) override {} + private: gpu::CommandBufferProxyImpl* GetCommandBufferProxy() { ws::ContextProviderCommandBuffer* provider_command_buffer =
diff --git a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc index dd757b8..38d33e7 100644 --- a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc +++ b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc
@@ -170,6 +170,11 @@ // running an older version of DirectWrite (earlier than Win8.1). factory.As<IDWriteFactory2>(&factory2_); + // QueryInterface for IDwriteFactory3, needed for MatchUniqueFont on Windows + // 10. May fail on older versions, in which case, unique font matching must be + // done through indexing system fonts using DWriteFontLookupTableBuilder. + factory.As<IDWriteFactory3>(&factory3_); + HRESULT hr = factory->GetSystemFontCollection(&collection_); DCHECK(SUCCEEDED(hr)); @@ -228,6 +233,16 @@ caching_enabled_ = caching_enabled; } +bool DWriteFontLookupTableBuilder::HasDWriteUniqueFontLookups() { + InitializeDirectWrite(); + return factory3_; +} + +void DWriteFontLookupTableBuilder::OverrideDWriteVersionChecksForTesting() { + InitializeDirectWrite(); + factory3_.Reset(); +} + base::FilePath DWriteFontLookupTableBuilder::TableCacheFilePath() { if (!EnsureCacheDirectory(cache_directory_)) return base::FilePath(); @@ -303,6 +318,7 @@ TRACE_EVENT0("dwrite,fonts", "DWriteFontLookupTableBuilder::EnsureFontUniqueNameTable"); DCHECK(base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)); + DCHECK(!HasDWriteUniqueFontLookups()); base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives; font_table_built_.Wait(); return IsFontUniqueNameTableValid(); @@ -312,9 +328,20 @@ return font_table_built_.IsSignaled() && IsFontUniqueNameTableValid(); } -void DWriteFontLookupTableBuilder::SchedulePrepareFontUniqueNameTable() { +void DWriteFontLookupTableBuilder:: + SchedulePrepareFontUniqueNameTableIfNeeded() { DCHECK(base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)); + { + base::ScopedBlockingCall scoped_blocking_call( + FROM_HERE, base::BlockingType::MAY_BLOCK); + InitializeDirectWrite(); + } + + // Nothing to do if we have API to directly lookup local fonts by unique name. + if (HasDWriteUniqueFontLookups()) + return; + start_time_table_ready_ = base::TimeTicks::Now(); // TODO(https://crbug.com/931366): Downgrade the priority of this startup @@ -335,6 +362,7 @@ void DWriteFontLookupTableBuilder::PrepareFontUniqueNameTable() { TRACE_EVENT0("dwrite,fonts", "DWriteFontLookupTableBuilder::BuildFontUniqueNameTable"); + DCHECK(!HasDWriteUniqueFontLookups()); // The table must only be built once. DCHECK(!font_table_built_.IsSignaled()); @@ -359,12 +387,6 @@ } } - { - base::ScopedBlockingCall scoped_blocking_call( - FROM_HERE, base::BlockingType::MAY_BLOCK); - InitializeDirectWrite(); - } - start_time_table_build_ = base::TimeTicks::Now(); font_unique_name_table_ = std::make_unique<blink::FontUniqueNameTable>();
diff --git a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h index bbd066fb..8262f59 100644 --- a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h +++ b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h
@@ -7,6 +7,7 @@ #include <dwrite.h> #include <dwrite_2.h> +#include <dwrite_3.h> #include <wrl.h> #include <memory> #include <string> @@ -56,11 +57,12 @@ // immediately ready without any sync operations. bool FontUniqueNameTableReady(); - // Posts a task to load from cache or build (if cache not available) the - // unique name table index, should only be called once at browser startup, - // after that, use EnsureFontUniqueNameTable() and - // DuplicatedMemoryRegion() to retrieve the lookup structure buffer. - void SchedulePrepareFontUniqueNameTable(); + // If needed, i.e. if we're on pre-Windows 10, posts a task to load from cache + // or build (if cache not available) the unique name table index, should only + // be called once at browser startup, after that, use + // EnsureFontUniqueNameTable() and DuplicatedMemoryRegion() to retrieve the + // lookup structure buffer. + void SchedulePrepareFontUniqueNameTableIfNeeded(); enum class SlowDownMode { kDelayEachTask, kHangOneTask, kNoSlowdown }; @@ -91,6 +93,10 @@ // repeated rebuilding of the font table lookup structure. void SetCachingEnabledForTesting(bool caching_enabled); + // Disables DCHECKs that ensure DWriteFontLookupTableBuilder is only run pre + // Windows 10, used for testing only to allow running the tests on Windows 10. + void OverrideDWriteVersionChecksForTesting(); + private: friend class base::NoDestructor<DWriteFontLookupTableBuilder>; @@ -149,6 +155,11 @@ base::FilePath TableCacheFilePath(); + // Returns true if IDWriteFactory3 is available, which means that we can + // access IDWriteFontSet API which provides direct lookup by PostScript name + // and full font name, in which case we do not need to build this table. + bool HasDWriteUniqueFontLookups(); + DWriteFontLookupTableBuilder(); ~DWriteFontLookupTableBuilder(); @@ -161,6 +172,7 @@ bool direct_write_initialized_ = false; Microsoft::WRL::ComPtr<IDWriteFontCollection> collection_; Microsoft::WRL::ComPtr<IDWriteFactory2> factory2_; + Microsoft::WRL::ComPtr<IDWriteFactory3> factory3_; SlowDownMode slow_down_mode_for_testing_ = SlowDownMode::kNoSlowdown; uint32_t outstanding_family_results_ = 0; base::TimeTicks start_time_table_ready_;
diff --git a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win_unittest.cc b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win_unittest.cc index 2e9ebfdd..2e8e8fc 100644 --- a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win_unittest.cc +++ b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win_unittest.cc
@@ -42,6 +42,7 @@ void SetUp() override { font_lookup_table_builder_ = DWriteFontLookupTableBuilder::GetInstance(); + font_lookup_table_builder_->OverrideDWriteVersionChecksForTesting(); font_lookup_table_builder_->ResetLookupTableForTesting(); bool temp_dir_created = scoped_temp_dir_.CreateUniqueTempDir(); ASSERT_TRUE(temp_dir_created); @@ -88,14 +89,14 @@ // without going through Mojo and running it on the DWRiteFontLookupTableBuilder // class directly. TEST_F(DWriteFontLookupTableBuilderTest, TestFindUniqueFontDirect) { - font_lookup_table_builder_->SchedulePrepareFontUniqueNameTable(); + font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); font_lookup_table_builder_->EnsureFontUniqueNameTable(); TestMatchFonts(); } TEST_P(DWriteFontLookupTableBuilderTimeoutTest, TestTimeout) { font_lookup_table_builder_->SetSlowDownIndexingForTesting(GetParam()); - font_lookup_table_builder_->SchedulePrepareFontUniqueNameTable(); + font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); font_lookup_table_builder_->EnsureFontUniqueNameTable(); base::ReadOnlySharedMemoryRegion font_table_memory = font_lookup_table_builder_->DuplicateMemoryRegion(); @@ -120,7 +121,7 @@ TEST_F(DWriteFontLookupTableBuilderTest, TestReadyEarly) { font_lookup_table_builder_->SetSlowDownIndexingForTesting( DWriteFontLookupTableBuilder::SlowDownMode::kHangOneTask); - font_lookup_table_builder_->SchedulePrepareFontUniqueNameTable(); + font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); ASSERT_FALSE(font_lookup_table_builder_->FontUniqueNameTableReady()); font_lookup_table_builder_->ResumeFromHangForTesting(); font_lookup_table_builder_->EnsureFontUniqueNameTable(); @@ -131,7 +132,7 @@ for (unsigned i = 0; i < 3; ++i) { font_lookup_table_builder_->ResetLookupTableForTesting(); font_lookup_table_builder_->SetCachingEnabledForTesting(false); - font_lookup_table_builder_->SchedulePrepareFontUniqueNameTable(); + font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); font_lookup_table_builder_->EnsureFontUniqueNameTable(); } } @@ -143,7 +144,7 @@ TEST_F(DWriteFontLookupTableBuilderTest, HandleCorruptCacheFile) { // Cycle once to build cache file. font_lookup_table_builder_->ResetLookupTableForTesting(); - font_lookup_table_builder_->SchedulePrepareFontUniqueNameTable(); + font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); font_lookup_table_builder_->EnsureFontUniqueNameTable(); // Truncate table for testing base::FilePath cache_file_path = scoped_temp_dir_.GetPath().Append( @@ -164,7 +165,7 @@ // Reload the cache file. font_lookup_table_builder_->ResetLookupTableForTesting(); - font_lookup_table_builder_->SchedulePrepareFontUniqueNameTable(); + font_lookup_table_builder_->SchedulePrepareFontUniqueNameTableIfNeeded(); ASSERT_TRUE(font_lookup_table_builder_->EnsureFontUniqueNameTable()); TestMatchFonts();
diff --git a/content/browser/renderer_host/dwrite_font_proxy_impl_win_unittest.cc b/content/browser/renderer_host/dwrite_font_proxy_impl_win_unittest.cc index aa6f45f..c64885b 100644 --- a/content/browser/renderer_host/dwrite_font_proxy_impl_win_unittest.cc +++ b/content/browser/renderer_host/dwrite_font_proxy_impl_win_unittest.cc
@@ -42,6 +42,16 @@ {u8"NSimSun", 1}, {u8"calibri-bolditalic", 0}}; +// DirectWrite on Windows supports IDWriteFontSet API which allows for querying +// by PostScript name and full font name directly. In the implementation of +// DWriteFontProxy we check whether this API is available by checking for +// whether IDWriteFactory3 is available. In order to validate in a unit test +// whether this check works, compare it against the dwrite.dll major version - +// versions starting from 10 have the required functionality. +constexpr int kDWriteMajorVersionSupportingSingleLookups = 10; + +// Base test class that sets up the Mojo connection to DWriteFontProxy so that +// tests can call its Mojo methods. class DWriteFontProxyImplUnitTest : public testing::Test { public: DWriteFontProxyImplUnitTest() @@ -51,34 +61,50 @@ return *dwrite_font_proxy_; } - base::test::ScopedTaskEnvironment scoped_task_environment_; - blink::mojom::DWriteFontProxyPtr dwrite_font_proxy_; - DWriteFontProxyImpl impl_; - mojo::Binding<blink::mojom::DWriteFontProxy> binding_; -}; - -class DWriteFontProxyUniqueNameMatchingTest - : public DWriteFontProxyImplUnitTest { - public: - DWriteFontProxyUniqueNameMatchingTest() { - feature_list_.InitAndEnableFeature(features::kFontSrcLocalMatching); - DWriteFontLookupTableBuilder* table_builder_instance = - DWriteFontLookupTableBuilder::GetInstance(); - DCHECK(scoped_temp_dir_.CreateUniqueTempDir()); - table_builder_instance->SetCacheDirectoryForTesting( - scoped_temp_dir_.GetPath()); - table_builder_instance->ResetLookupTableForTesting(); - table_builder_instance->SchedulePrepareFontUniqueNameTable(); - } - bool SupportsSingleLookups() { blink::mojom::UniqueFontLookupMode lookup_mode; dwrite_font_proxy().GetUniqueFontLookupMode(&lookup_mode); return lookup_mode == blink::mojom::UniqueFontLookupMode::kSingleLookups; } + base::test::ScopedTaskEnvironment scoped_task_environment_; + blink::mojom::DWriteFontProxyPtr dwrite_font_proxy_; + DWriteFontProxyImpl impl_; + mojo::Binding<blink::mojom::DWriteFontProxy> binding_; +}; + +// Derived class for tests that exercise font unique local matching mojo methods +// of DWriteFontProxy. Needs a ScopedFeatureList to activate the feature as it +// is currently behind a flag. +class DWriteFontProxyLocalMatchingTest : public DWriteFontProxyImplUnitTest { + public: + DWriteFontProxyLocalMatchingTest() { + feature_list_.InitAndEnableFeature(features::kFontSrcLocalMatching); + } + private: base::test::ScopedFeatureList feature_list_; +}; + +// Derived class for tests that exercise the parts of the DWriteFontProxy Mojo +// interface that deal with accessing the font lookup table created by +// DWriteFontLookupTableBuilder. Initializes the DWriteFontLookupTableBuilder +// and has a ScopedTempDir for testing persisting the lookup table to disk. +class DWriteFontProxyTableMatchingTest + : public DWriteFontProxyLocalMatchingTest { + public: + DWriteFontProxyTableMatchingTest() { + DWriteFontLookupTableBuilder* table_builder_instance = + DWriteFontLookupTableBuilder::GetInstance(); + DCHECK(scoped_temp_dir_.CreateUniqueTempDir()); + table_builder_instance->OverrideDWriteVersionChecksForTesting(); + table_builder_instance->SetCacheDirectoryForTesting( + scoped_temp_dir_.GetPath()); + table_builder_instance->ResetLookupTableForTesting(); + table_builder_instance->SchedulePrepareFontUniqueNameTableIfNeeded(); + } + + private: base::ScopedTempDir scoped_temp_dir_; }; @@ -247,7 +273,7 @@ } } // namespace -TEST_F(DWriteFontProxyUniqueNameMatchingTest, TestFindUniqueFont) { +TEST_F(DWriteFontProxyTableMatchingTest, TestFindUniqueFont) { bool lookup_table_results_were_tested = false; dwrite_font_proxy().GetUniqueNameLookupTable(base::BindOnce( &TestWhenLookupTableReady, &lookup_table_results_were_tested)); @@ -255,7 +281,7 @@ ASSERT_TRUE(lookup_table_results_were_tested); } -TEST_F(DWriteFontProxyUniqueNameMatchingTest, TestSingleLookup) { +TEST_F(DWriteFontProxyLocalMatchingTest, TestSingleLookup) { // Do not run this test on unsupported Windows versions. if (!SupportsSingleLookups()) return; @@ -274,7 +300,7 @@ } } -TEST_F(DWriteFontProxyUniqueNameMatchingTest, TestSingleLookupUnavailable) { +TEST_F(DWriteFontProxyLocalMatchingTest, TestSingleLookupUnavailable) { // Do not run this test on unsupported Windows versions. if (!SupportsSingleLookups()) return; @@ -288,7 +314,7 @@ ASSERT_EQ(ttc_index, 0u); } -TEST_F(DWriteFontProxyUniqueNameMatchingTest, TestLookupMode) { +TEST_F(DWriteFontProxyLocalMatchingTest, TestLookupMode) { std::unique_ptr<FileVersionInfo> dwrite_version_info = FileVersionInfo::CreateFileVersionInfo( base::FilePath(FILE_PATH_LITERAL("DWrite.dll"))); @@ -300,7 +326,8 @@ std::stoi(dwrite_version.substr(0, dwrite_version.find("."))); blink::mojom::UniqueFontLookupMode expected_lookup_mode; - if (dwrite_major_version_number >= 10) { + if (dwrite_major_version_number >= + kDWriteMajorVersionSupportingSingleLookups) { expected_lookup_mode = blink::mojom::UniqueFontLookupMode::kSingleLookups; } else { expected_lookup_mode = blink::mojom::UniqueFontLookupMode::kRetrieveTable;
diff --git a/content/browser/scheduler/browser_task_executor.cc b/content/browser/scheduler/browser_task_executor.cc index 81131371..18d61e1 100644 --- a/content/browser/scheduler/browser_task_executor.cc +++ b/content/browser/scheduler/browser_task_executor.cc
@@ -372,7 +372,7 @@ } // static -void BrowserTaskExecutor::NotifyBrowserStartupCompleted() { +void BrowserTaskExecutor::EnableBestEffortQueues() { DCHECK(g_browser_task_executor); g_browser_task_executor->browser_ui_thread_scheduler_ ->EnableBestEffortQueues();
diff --git a/content/browser/scheduler/browser_task_executor.h b/content/browser/scheduler/browser_task_executor.h index 65a084e..9c00991 100644 --- a/content/browser/scheduler/browser_task_executor.h +++ b/content/browser/scheduler/browser_task_executor.h
@@ -42,7 +42,7 @@ // called. static void Shutdown(); - static void NotifyBrowserStartupCompleted(); + static void EnableBestEffortQueues(); // Unregister and delete the TaskExecutor after a test. static void ResetForTesting();
diff --git a/content/browser/scheduler/browser_task_executor_unittest.cc b/content/browser/scheduler/browser_task_executor_unittest.cc index 995755c..0d47c88 100644 --- a/content/browser/scheduler/browser_task_executor_unittest.cc +++ b/content/browser/scheduler/browser_task_executor_unittest.cc
@@ -230,7 +230,7 @@ best_effort.Get()); scoped_task_environment_.RunUntilIdle(); - BrowserTaskExecutor::NotifyBrowserStartupCompleted(); + BrowserTaskExecutor::EnableBestEffortQueues(); EXPECT_CALL(best_effort, Run).Times(4); scoped_task_environment_.FastForwardBy( base::TimeDelta::FromMilliseconds(100));
diff --git a/content/browser/scheduler/browser_ui_thread_scheduler.cc b/content/browser/scheduler/browser_ui_thread_scheduler.cc index 54cae85..16399f7 100644 --- a/content/browser/scheduler/browser_ui_thread_scheduler.cc +++ b/content/browser/scheduler/browser_ui_thread_scheduler.cc
@@ -123,7 +123,6 @@ } void BrowserUIThreadScheduler::EnableBestEffortQueues() { - DCHECK(!best_effort_voter_->IsVotingToEnable()); best_effort_voter_->SetVoteToEnable(true); }
diff --git a/content/browser/scheduler/browser_ui_thread_scheduler.h b/content/browser/scheduler/browser_ui_thread_scheduler.h index 17f7c4f..5db6d42 100644 --- a/content/browser/scheduler/browser_ui_thread_scheduler.h +++ b/content/browser/scheduler/browser_ui_thread_scheduler.h
@@ -42,7 +42,6 @@ // however no tasks will be executed after this point. void Shutdown(); - // Attention: Can only be called once void EnableBestEffortQueues(); using QueueType = BrowserUIThreadTaskQueue::QueueType;
diff --git a/content/browser/tracing/background_tracing_active_scenario.cc b/content/browser/tracing/background_tracing_active_scenario.cc index 7fad9c7..558bc51 100644 --- a/content/browser/tracing/background_tracing_active_scenario.cc +++ b/content/browser/tracing/background_tracing_active_scenario.cc
@@ -147,12 +147,7 @@ // Perfetto-related deadlocks are resolved. if (!TracingControllerImpl::GetInstance()->IsTracing() && tracing::TracingUsesPerfettoBackend()) { - // TODO(oysteine): This should pass in |requires_anonymized_data_| instead - // of false only when using consumer API with proto output. But, for JSON - // output we still need this to be false since filtering happens in the JSON - // exporter. - tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/false); + tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing(); } #endif
diff --git a/content/browser/tracing/perfetto_file_tracer.cc b/content/browser/tracing/perfetto_file_tracer.cc index d1f93a13..b977c4d 100644 --- a/content/browser/tracing/perfetto_file_tracer.cc +++ b/content/browser/tracing/perfetto_file_tracer.cc
@@ -9,7 +9,6 @@ #include "base/command_line.h" #include "base/files/file.h" #include "base/files/file_util.h" -#include "base/strings/string_number_conversions.h" #include "base/task/post_task.h" #include "base/threading/scoped_blocking_call.h" #include "components/tracing/common/trace_startup_config.h" @@ -17,7 +16,6 @@ #include "content/public/common/service_manager_connection.h" #include "mojo/public/cpp/system/data_pipe_drainer.h" #include "services/service_manager/public/cpp/connector.h" -#include "services/tracing/public/cpp/perfetto/perfetto_config.h" #include "services/tracing/public/mojom/constants.mojom.h" #include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h" #include "third_party/perfetto/protos/perfetto/config/trace_config.pb.h" @@ -91,27 +89,36 @@ ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface( tracing::mojom::kServiceName, &consumer_host_); - const auto& chrome_config = - tracing::TraceStartupConfig::GetInstance()->GetTraceConfig(); - perfetto::TraceConfig trace_config = - tracing::GetDefaultPerfettoConfig(chrome_config); - - // TODO(ssid): This should be moved to GetDefaultPerfettoConfig(). But, - // currently we only require this for proto output since JSON exporter still - // needs sensitive fields in trace, which will later be stripped. - for (auto& source : *trace_config.mutable_data_sources()) { - source.mutable_config() - ->mutable_chrome_config() - ->set_privacy_filtering_enabled( - chrome_config.IsArgumentFilterEnabled()); - } - + perfetto::TraceConfig trace_config; int duration_in_seconds = tracing::TraceStartupConfig::GetInstance()->GetStartupDuration(); trace_config.set_duration_ms(duration_in_seconds * 1000); // We just need a single global trace buffer, for our data. - trace_config.mutable_buffers()->front().set_size_kb(32 * 1024); + trace_config.add_buffers()->set_size_kb(32 * 1024); + + // We need data from two different sources to get the complete trace + // we're interested in both, written into the single buffer we + // configure above. + + // This source is the actual trace events themselves coming + // from the base::TraceLog + auto* trace_event_config = trace_config.add_data_sources()->mutable_config(); + trace_event_config->set_name(tracing::mojom::kTraceEventDataSourceName); + trace_event_config->set_target_buffer(0); + auto* chrome_config = trace_event_config->mutable_chrome_config(); + + // The Chrome config string is passed straight through to base::TraceLog + // and defines which tracing categories should be enabled. + auto chrome_raw_config = + tracing::TraceStartupConfig::GetInstance()->GetTraceConfig().ToString(); + chrome_config->set_trace_config(chrome_raw_config); + + // The second data source we're interested in is the global metadata. + auto* trace_metadata_config = + trace_config.add_data_sources()->mutable_config(); + trace_metadata_config->set_name(tracing::mojom::kMetaDataSourceName); + trace_metadata_config->set_target_buffer(0); tracing::mojom::TracingSessionPtr tracing_session; binding_.Bind(mojo::MakeRequest(&tracing_session));
diff --git a/content/browser/tracing/perfetto_file_tracer.h b/content/browser/tracing/perfetto_file_tracer.h index df24c5f..e6ca8ac77 100644 --- a/content/browser/tracing/perfetto_file_tracer.h +++ b/content/browser/tracing/perfetto_file_tracer.h
@@ -33,8 +33,6 @@ // tracing::mojom::TracingSession implementation: void OnTracingEnabled() override; - bool is_finished_for_testing() const { return !background_drainer_; } - private: void OnNoMorePackets(bool queued_after_disable); void ReadBuffers();
diff --git a/content/browser/tracing/startup_tracing_browsertest.cc b/content/browser/tracing/startup_tracing_browsertest.cc index cce8cad9..02cc57c9 100644 --- a/content/browser/tracing/startup_tracing_browsertest.cc +++ b/content/browser/tracing/startup_tracing_browsertest.cc
@@ -11,11 +11,9 @@ #include "build/build_config.h" #include "components/tracing/common/trace_startup_config.h" #include "components/tracing/common/tracing_switches.h" -#include "content/browser/tracing/perfetto_file_tracer.h" #include "content/browser/tracing/tracing_controller_impl.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" -#include "services/tracing/perfetto/privacy_filtering_check.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h" #include "services/tracing/public/cpp/trace_startup.h" #include "services/tracing/public/cpp/tracing_features.h" @@ -27,7 +25,7 @@ // Wait until |condition| returns true. void WaitForCondition(base::RepeatingCallback<bool()> condition, const std::string& description) { - const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(15); + const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(30); const base::TimeTicks start_time = base::TimeTicks::Now(); while (!condition.Run() && (base::TimeTicks::Now() - start_time < kTimeout)) { base::RunLoop run_loop; @@ -41,10 +39,7 @@ } // namespace -class CommandlineStartupTracingTest : public ContentBrowserTest { - public: - CommandlineStartupTracingTest() = default; - +class StartupTracingControllerTest : public ContentBrowserTest { void SetUpCommandLine(base::CommandLine* command_line) override { base::CreateTemporaryFile(&temp_file_path_); command_line->AppendSwitch(switches::kTraceStartup); @@ -63,13 +58,10 @@ protected: base::FilePath temp_file_path_; - - private: - DISALLOW_COPY_AND_ASSIGN(CommandlineStartupTracingTest); }; -IN_PROC_BROWSER_TEST_F(CommandlineStartupTracingTest, TestStartupTracing) { - NavigateToURL(shell(), GetTestUrl("", "title1.html")); +IN_PROC_BROWSER_TEST_F(StartupTracingControllerTest, TestStartupTracing) { + NavigateToURL(shell(), GetTestUrl("", "title.html")); WaitForCondition(base::BindRepeating([]() { return !TracingController::GetInstance()->IsTracing(); }), @@ -124,8 +116,7 @@ // deadlocks. IN_PROC_BROWSER_TEST_F(StartupTracingInProcessTest, DISABLED_TestFilledStartupBuffer) { - tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/false); + tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing(); auto config = tracing::TraceStartupConfig::GetInstance() ->GetDefaultBrowserStartupConfig(); @@ -147,56 +138,4 @@ NavigateToURL(shell(), GetTestUrl("", "title1.html")); } -class BackgroundStartupTracingTest : public ContentBrowserTest { - public: - BackgroundStartupTracingTest() = default; - - void SetUpCommandLine(base::CommandLine* command_line) override { - base::CreateTemporaryFile(&temp_file_path_); - auto* startup_config = tracing::TraceStartupConfig::GetInstance(); - startup_config->is_enabled_from_background_tracing_ = true; - startup_config->EnableFromBackgroundTracing(); - startup_config->startup_duration_ = 3; - tracing::EnableStartupTracingIfNeeded(); - command_line->AppendSwitchASCII(switches::kPerfettoOutputFile, - temp_file_path_.AsUTF8Unsafe()); - } - - protected: - base::FilePath temp_file_path_; - - private: - DISALLOW_COPY_AND_ASSIGN(BackgroundStartupTracingTest); -}; - -#if defined(IS_CHROMECAST) && defined(OS_LINUX) -#define MAYBE_TestStartupTracing DISABLED_TestStartupTracing -#else -#define MAYBE_TestStartupTracing TestStartupTracing -#endif -IN_PROC_BROWSER_TEST_F(BackgroundStartupTracingTest, MAYBE_TestStartupTracing) { - NavigateToURL(shell(), GetTestUrl("", "title1.html")); - - EXPECT_FALSE(tracing::TraceStartupConfig::GetInstance()->IsEnabled()); - EXPECT_FALSE(TracingController::GetInstance()->IsTracing()); - WaitForCondition(base::BindRepeating([]() { - return TracingControllerImpl::GetInstance() - ->perfetto_file_tracer_for_testing() - ->is_finished_for_testing(); - }), - "finish file write"); - - std::string trace; - base::ScopedAllowBlockingForTesting allow_blocking; - ASSERT_TRUE(base::ReadFileToString(temp_file_path_, &trace)); - tracing::PrivacyFilteringCheck checker; - checker.CheckProtoForUnexpectedFields(trace); - EXPECT_GT(checker.counts().track_event, 0u); - EXPECT_EQ(checker.counts().process_desc, 0u); - EXPECT_GT(checker.counts().thread_desc, 0u); - EXPECT_GT(checker.counts().interned_name, 0u); - EXPECT_GT(checker.counts().interned_category, 0u); - EXPECT_GT(checker.counts().interned_source_location, 0u); -} - } // namespace content
diff --git a/content/browser/tracing/tracing_controller_impl.h b/content/browser/tracing/tracing_controller_impl.h index c91a3b7..58242048f 100644 --- a/content/browser/tracing/tracing_controller_impl.h +++ b/content/browser/tracing/tracing_controller_impl.h
@@ -84,10 +84,6 @@ // exists. void FinalizeStartupTracingIfNeeded(); - const PerfettoFileTracer* perfetto_file_tracer_for_testing() const { - return perfetto_file_tracer_.get(); - } - private: friend std::default_delete<TracingControllerImpl>;
diff --git a/content/browser/webrtc/webrtc_image_capture_browsertest.cc b/content/browser/webrtc/webrtc_image_capture_browsertest.cc index 7137b79..f627aac 100644 --- a/content/browser/webrtc/webrtc_image_capture_browsertest.cc +++ b/content/browser/webrtc/webrtc_image_capture_browsertest.cc
@@ -24,24 +24,12 @@ namespace content { #if defined(OS_ANDROID) -// TODO(chfremer): Re-enable test on Android as soon as the cause for -// https://crbug.com/793859 is understood and fixed. -#define MAYBE_GetPhotoCapabilities GetPhotoCapabilities -#define MAYBE_GetPhotoSettings GetPhotoSettings -#define MAYBE_TakePhoto TakePhoto -#define MAYBE_GrabFrame GrabFrame -#define MAYBE_GetTrackCapabilities GetTrackCapabilities -#define MAYBE_GetTrackSettings GetTrackSettings +// TODO(crbug.com/793859): Re-enable test on Android as soon as the cause for +// the bug is understood and fixed. #define MAYBE_ManipulateZoom DISABLED_ManipulateZoom #define MAYBE_ManipulateExposureTime DISABLED_ManipulateExposureTime #define MAYBE_ManipulateFocusDistance DISABLED_ManipulateFocusDistance #else -#define MAYBE_GetPhotoCapabilities GetPhotoCapabilities -#define MAYBE_GetPhotoSettings GetPhotoSettings -#define MAYBE_TakePhoto TakePhoto -#define MAYBE_GrabFrame GrabFrame -#define MAYBE_GetTrackCapabilities GetTrackCapabilities -#define MAYBE_GetTrackSettings GetTrackSettings #define MAYBE_ManipulateZoom ManipulateZoom #define MAYBE_ManipulateExposureTime ManipulateExposureTime #define MAYBE_ManipulateFocusDistance ManipulateFocusDistance @@ -190,37 +178,37 @@ }; IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest, - MAYBE_GetPhotoCapabilities) { + GetPhotoCapabilities) { embedded_test_server()->StartAcceptingConnections(); ASSERT_TRUE( RunImageCaptureTestCase("testCreateAndGetPhotoCapabilitiesSucceeds()")); } IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest, - MAYBE_GetPhotoSettings) { + GetPhotoSettings) { embedded_test_server()->StartAcceptingConnections(); ASSERT_TRUE( RunImageCaptureTestCase("testCreateAndGetPhotoSettingsSucceeds()")); } -IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest, MAYBE_TakePhoto) { +IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest, TakePhoto) { embedded_test_server()->StartAcceptingConnections(); ASSERT_TRUE(RunImageCaptureTestCase("testCreateAndTakePhotoSucceeds()")); } -IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest, MAYBE_GrabFrame) { +IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest, GrabFrame) { embedded_test_server()->StartAcceptingConnections(); ASSERT_TRUE(RunImageCaptureTestCase("testCreateAndGrabFrameSucceeds()")); } IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest, - MAYBE_GetTrackCapabilities) { + GetTrackCapabilities) { embedded_test_server()->StartAcceptingConnections(); ASSERT_TRUE(RunImageCaptureTestCase("testCreateAndGetTrackCapabilities()")); } IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureSucceedsBrowserTest, - MAYBE_GetTrackSettings) { + GetTrackSettings) { embedded_test_server()->StartAcceptingConnections(); ASSERT_TRUE(RunImageCaptureTestCase("testCreateAndGetTrackSettings()")); }
diff --git a/content/common/throttling_url_loader.cc b/content/common/throttling_url_loader.cc index aca8fa0..9943363a 100644 --- a/content/common/throttling_url_loader.cc +++ b/content/common/throttling_url_loader.cc
@@ -10,6 +10,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "net/http/http_status_code.h" #include "net/http/http_util.h" +#include "net/url_request/redirect_util.h" #include "services/network/public/cpp/features.h" namespace content { @@ -325,17 +326,13 @@ DCHECK(throttle_will_start_redirect_url_.is_empty()) << "ThrottlingURLLoader doesn't support multiple throttles " "changing the URL."; - // Only do this sanity check if the schemes are both http[s], as this - // generated-redirect functionality is also used by - // registerProtocolHandler to map non-web to web schemes and that is - // safe. if (original_url.SchemeIsHTTPOrHTTPS() && - url_request->url.SchemeIsHTTPOrHTTPS()) { - CHECK_EQ(original_url.GetOrigin(), url_request->url.GetOrigin()) - << "ThrottlingURLLoader doesn't support a throttle making a " - << "cross-origin redirect."; + !url_request->url.SchemeIsHTTPOrHTTPS()) { + NOTREACHED() << "A URLLoaderThrottle can't redirect from http(s) to " + << "a non http(s) scheme."; + } else { + throttle_will_start_redirect_url_ = url_request->url; } - throttle_will_start_redirect_url_ = url_request->url; // Restore the original URL so that all throttles see the same original // URL. url_request->url = original_url; @@ -343,11 +340,6 @@ if (!HandleThrottleResult(throttle, throttle_deferred, &deferred)) return; } - - // If a throttle had changed the URL, set it in the ResourceRequest struct - // so that it is the URL that's requested. - if (!throttle_will_start_redirect_url_.is_empty()) - url_request->url = throttle_will_start_redirect_url_; } start_info_ = @@ -362,13 +354,35 @@ void ThrottlingURLLoader::StartNow() { DCHECK(start_info_); if (!throttle_will_start_redirect_url_.is_empty()) { - net::RedirectInfo redirect_info; - redirect_info.status_code = net::HTTP_TEMPORARY_REDIRECT; - redirect_info.new_method = start_info_->url_request.method; - redirect_info.new_url = throttle_will_start_redirect_url_; - redirect_info.new_site_for_cookies = throttle_will_start_redirect_url_; - redirect_info.new_top_frame_origin = - url::Origin::Create(throttle_will_start_redirect_url_); + auto first_party_url_policy = + start_info_->url_request.update_first_party_url_on_redirect + ? net::URLRequest::FirstPartyURLPolicy:: + UPDATE_FIRST_PARTY_URL_ON_REDIRECT + : net::URLRequest::FirstPartyURLPolicy:: + NEVER_CHANGE_FIRST_PARTY_URL; + + net::RedirectInfo redirect_info = net::RedirectInfo::ComputeRedirectInfo( + start_info_->url_request.method, start_info_->url_request.url, + start_info_->url_request.site_for_cookies, + start_info_->url_request.top_frame_origin, first_party_url_policy, + start_info_->url_request.referrer_policy, + start_info_->url_request.referrer.spec(), + // Use status code 307 to preserve the method, so POST requests work. + net::HTTP_TEMPORARY_REDIRECT, throttle_will_start_redirect_url_, + base::nullopt, false, false, false); + + bool should_clear_upload = false; + net::RedirectUtil::UpdateHttpRequest( + start_info_->url_request.url, start_info_->url_request.method, + redirect_info, base::nullopt, base::nullopt, + &start_info_->url_request.headers, &should_clear_upload); + + if (should_clear_upload) + start_info_->url_request.request_body = nullptr; + + // Set the new URL in the ResourceRequest struct so that it is the URL + // that's requested. + start_info_->url_request.url = throttle_will_start_redirect_url_; network::ResourceResponseHead response_head; std::string header_string = base::StringPrintf( @@ -530,17 +544,6 @@ DCHECK(throttle_will_redirect_redirect_url_.is_empty()) << "ThrottlingURLLoader doesn't support multiple throttles " "changing the URL."; - // Only do this sanity check if the schemes are both http[s], as this - // generated-redirect functionality is also used by - // registerProtocolHandler to map non-web to web schemes and that is - // safe. - if (redirect_info_copy.new_url.SchemeIsHTTPOrHTTPS() && - redirect_info.new_url.SchemeIsHTTPOrHTTPS()) { - CHECK_EQ(redirect_info_copy.new_url.GetOrigin(), - redirect_info.new_url.GetOrigin()) - << "ThrottlingURLLoader doesn't support a throttle making a " - << "cross-origin redirect."; - } throttle_will_redirect_redirect_url_ = redirect_info_copy.new_url; } else { CHECK_EQ(redirect_info_copy.new_url, redirect_info.new_url)
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc index 404c240..adf8faa9 100644 --- a/content/ppapi_plugin/ppapi_thread.cc +++ b/content/ppapi_plugin/ppapi_thread.cc
@@ -430,17 +430,6 @@ return; } } else { -#if defined(OS_MACOSX) - // TODO(kerrnel): Delete this once the V2 sandbox is default. - const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); - if (!cmdline->HasSwitch(sandbox::switches::kSeatbeltClientName)) { - // We need to do this after getting |PPP_GetInterface()| (or presumably - // doing something nontrivial with the library), else the sandbox - // intercedes. - CHECK(InitializeSandbox()); - } -#endif - int32_t init_error = plugin_entry_points_.initialize_module( local_pp_module_, &ppapi::proxy::PluginDispatcher::GetBrowserInterface); if (init_error != PP_OK) {
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.cc b/content/renderer/android/synchronous_layer_tree_frame_sink.cc index e40f9a3..2c514e0 100644 --- a/content/renderer/android/synchronous_layer_tree_frame_sink.cc +++ b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
@@ -105,6 +105,8 @@ bool HasExternalStencilTest() const override { return false; } void ApplyExternalStencil() override {} unsigned UpdateGpuFence() override { return 0; } + void SetUpdateVSyncParametersCallback( + viz::UpdateVSyncParametersCallback callback) override {} }; base::TimeDelta SynchronousLayerTreeFrameSink::StubDisplayClient::
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 8553e46c..e3b818a 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1038,7 +1038,6 @@ "//services/network:test_support", "//services/service_manager/public/cpp", "//services/test/echo/public/mojom", - "//services/tracing:privacy_check", "//services/video_capture/public/cpp", "//services/video_capture/public/cpp:mocks", "//services/video_capture/public/mojom:constants",
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index 66f44be..3235591 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -171,11 +171,3 @@ # Mark all webview tests as RetryOnFailure due to Nexus 5x driver bug. crbug.com/950932 [ android-webview-instrumentation qualcomm-adreno-(tm)-418 ] * [ RetryOnFailure ] - -# Need to rebaseline for accelerated canvases due to small anti-aliasing differences -Pixel_CanvasLowLatency2D [ Failure ] -Pixel_CSSFilterEffects [ Failure ] -Pixel_CSSFilterEffects_NoOverlays [ Failure ] -# Previously these tests were not using accelerated canvases at all due to size -# heuristic. Rebaseline them here -Pixel_CanvasDisplayLinearRGBAccelerated2D [ Failure ]
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 3796bef..307e1cb 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -153,6 +153,12 @@ "command_buffer/client/client_test_helper.h", "command_buffer/client/gles2_interface_stub.cc", "command_buffer/client/gles2_interface_stub.h", + "command_buffer/client/gles2_interface_stub_autogen.h", + "command_buffer/client/gles2_interface_stub_impl_autogen.h", + "command_buffer/client/webgpu_interface_stub.cc", + "command_buffer/client/webgpu_interface_stub.h", + "command_buffer/client/webgpu_interface_stub_autogen.h", + "command_buffer/client/webgpu_interface_stub_impl_autogen.h", "command_buffer/service/copy_texture_chromium_mock.cc", "command_buffer/service/copy_texture_chromium_mock.h", "command_buffer/service/error_state_mock.cc", @@ -171,6 +177,7 @@ ":gpu", ":webgpu", "//gpu/command_buffer/client:gles2_interface", + "//gpu/command_buffer/client:webgpu_interface", "//gpu/ipc:gpu_thread_holder", ] deps = [
diff --git a/gpu/command_buffer/build_cmd_buffer_lib.py b/gpu/command_buffer/build_cmd_buffer_lib.py index 65915b7b..9d66d12 100644 --- a/gpu/command_buffer/build_cmd_buffer_lib.py +++ b/gpu/command_buffer/build_cmd_buffer_lib.py
@@ -1485,8 +1485,8 @@ args = func.GetOriginalArgs() arg_string = ", ".join( ["%s /* %s */" % (arg.type, arg.name) for arg in args]) - f.write("%s GLES2InterfaceStub::%s(%s) {\n" % - (func.return_type, func.original_name, arg_string)) + f.write("%s %sInterfaceStub::%s(%s) {\n" % + (func.return_type, _prefix, func.original_name, arg_string)) if func.return_type != "void": f.write(" return 0;\n") f.write("}\n")
diff --git a/gpu/command_buffer/build_webgpu_cmd_buffer.py b/gpu/command_buffer/build_webgpu_cmd_buffer.py index 66df1e9..e8f179a 100755 --- a/gpu/command_buffer/build_webgpu_cmd_buffer.py +++ b/gpu/command_buffer/build_webgpu_cmd_buffer.py
@@ -96,6 +96,10 @@ "gpu/command_buffer/client/webgpu_interface_autogen.h") gen.WriteGLES2ImplementationHeader( "gpu/command_buffer/client/webgpu_implementation_autogen.h") + gen.WriteGLES2InterfaceStub( + "gpu/command_buffer/client/webgpu_interface_stub_autogen.h") + gen.WriteGLES2InterfaceStubImpl( + "gpu/command_buffer/client/webgpu_interface_stub_impl_autogen.h") gen.WriteGLES2Implementation( "gpu/command_buffer/client/webgpu_implementation_impl_autogen.h") gen.WriteGLES2ImplementationUnitTests(
diff --git a/gpu/command_buffer/client/webgpu_interface.h b/gpu/command_buffer/client/webgpu_interface.h index 917042a..5cdf6b52 100644 --- a/gpu/command_buffer/client/webgpu_interface.h +++ b/gpu/command_buffer/client/webgpu_interface.h
@@ -9,9 +9,6 @@ #include "gpu/command_buffer/client/interface_base.h" -extern "C" typedef struct _ClientBuffer* ClientBuffer; -extern "C" typedef struct _GLColorSpace* GLColorSpace; - namespace gpu { namespace webgpu {
diff --git a/gpu/command_buffer/client/webgpu_interface_stub.cc b/gpu/command_buffer/client/webgpu_interface_stub.cc new file mode 100644 index 0000000..c0163e3 --- /dev/null +++ b/gpu/command_buffer/client/webgpu_interface_stub.cc
@@ -0,0 +1,39 @@ +// 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. + +#include "gpu/command_buffer/client/webgpu_interface_stub.h" + +namespace gpu { +namespace webgpu { + +WebGPUInterfaceStub::WebGPUInterfaceStub() = default; + +WebGPUInterfaceStub::~WebGPUInterfaceStub() = default; + +// InterfaceBase implementation. +void WebGPUInterfaceStub::GenSyncTokenCHROMIUM(GLbyte* sync_token) {} +void WebGPUInterfaceStub::GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) {} +void WebGPUInterfaceStub::VerifySyncTokensCHROMIUM(GLbyte** sync_tokens, + GLsizei count) {} +void WebGPUInterfaceStub::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) {} + +// WebGPUInterface implementation +const DawnProcTable& WebGPUInterfaceStub::GetProcs() const { + return null_procs_; +} +void WebGPUInterfaceStub::FlushCommands() {} +DawnDevice WebGPUInterfaceStub::GetDefaultDevice() { + return nullptr; +} +ReservedTexture WebGPUInterfaceStub::ReserveTexture(DawnDevice device) { + return {nullptr, 0, 0}; +} + +// Include the auto-generated part of this class. We split this because +// it means we can easily edit the non-auto generated parts right here in +// this file instead of having to edit some template or the code generator. +#include "gpu/command_buffer/client/webgpu_interface_stub_impl_autogen.h" + +} // namespace webgpu +} // namespace gpu
diff --git a/gpu/command_buffer/client/webgpu_interface_stub.h b/gpu/command_buffer/client/webgpu_interface_stub.h new file mode 100644 index 0000000..e16a57e --- /dev/null +++ b/gpu/command_buffer/client/webgpu_interface_stub.h
@@ -0,0 +1,43 @@ +// 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. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_H_ +#define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_H_ + +#include "gpu/command_buffer/client/webgpu_interface.h" + +namespace gpu { +namespace webgpu { + +// This class a stub to help with mocks for the WebGPUInterface class. +class WebGPUInterfaceStub : public WebGPUInterface { + public: + WebGPUInterfaceStub(); + ~WebGPUInterfaceStub() override; + + // InterfaceBase implementation. + void GenSyncTokenCHROMIUM(GLbyte* sync_token) override; + void GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) override; + void VerifySyncTokensCHROMIUM(GLbyte** sync_tokens, GLsizei count) override; + void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; + + // WebGPUInterface implementation + const DawnProcTable& GetProcs() const override; + void FlushCommands() override; + DawnDevice GetDefaultDevice() override; + ReservedTexture ReserveTexture(DawnDevice device) override; + +// Include the auto-generated part of this class. We split this because +// it means we can easily edit the non-auto generated parts right here in +// this file instead of having to edit some template or the code generator. +#include "gpu/command_buffer/client/webgpu_interface_stub_autogen.h" + + private: + DawnProcTable null_procs_; +}; + +} // namespace webgpu +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_H_
diff --git a/gpu/command_buffer/client/webgpu_interface_stub_autogen.h b/gpu/command_buffer/client/webgpu_interface_stub_autogen.h new file mode 100644 index 0000000..6d23a68 --- /dev/null +++ b/gpu/command_buffer/client/webgpu_interface_stub_autogen.h
@@ -0,0 +1,22 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is auto-generated from +// gpu/command_buffer/build_webgpu_cmd_buffer.py +// It's formatted by clang-format using chromium coding style: +// clang-format -i -style=chromium filename +// DO NOT EDIT! + +// This file is included by gles2_interface_stub.h. +#ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_AUTOGEN_H_ +#define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_AUTOGEN_H_ + +void AssociateMailbox(GLuint device_id, + GLuint device_generation, + GLuint id, + GLuint generation, + GLuint usage, + const GLbyte* mailbox) override; +void DissociateMailbox(GLuint texture_id, GLuint texture_generation) override; +#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/webgpu_interface_stub_impl_autogen.h b/gpu/command_buffer/client/webgpu_interface_stub_impl_autogen.h new file mode 100644 index 0000000..0d89b68 --- /dev/null +++ b/gpu/command_buffer/client/webgpu_interface_stub_impl_autogen.h
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is auto-generated from +// gpu/command_buffer/build_webgpu_cmd_buffer.py +// It's formatted by clang-format using chromium coding style: +// clang-format -i -style=chromium filename +// DO NOT EDIT! + +// This file is included by gles2_interface_stub.cc. +#ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_IMPL_AUTOGEN_H_ +#define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_IMPL_AUTOGEN_H_ + +void WebGPUInterfaceStub::AssociateMailbox(GLuint /* device_id */, + GLuint /* device_generation */, + GLuint /* id */, + GLuint /* generation */, + GLuint /* usage */, + const GLbyte* /* mailbox */) {} +void WebGPUInterfaceStub::DissociateMailbox(GLuint /* texture_id */, + GLuint /* texture_generation */) {} +#endif // GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_STUB_IMPL_AUTOGEN_H_
diff --git a/ios/build/bots/chromium.fyi/ios-simulator-cronet.json b/ios/build/bots/chromium.fyi/ios-simulator-cronet.json index 23c987a..c59f12f2 100644 --- a/ios/build/bots/chromium.fyi/ios-simulator-cronet.json +++ b/ios/build/bots/chromium.fyi/ios-simulator-cronet.json
@@ -27,50 +27,106 @@ "app": "cronet_unittests_ios", "device type": "iPhone 5s", "os": "9.3", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "cronet_test", "device type": "iPhone 5s", "os": "9.3", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "cronet_test", "device type": "iPad Retina", "os": "9.3", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "cronet_test", "device type": "iPhone 5s", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "cronet_test", "device type": "iPad Air 2", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "cronet_test", "device type": "iPhone X", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "cronet_test", "device type": "iPhone X", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } } ] }
diff --git a/ios/build/bots/chromium.fyi/ios-simulator.json b/ios/build/bots/chromium.fyi/ios-simulator.json index e4dea649..0691392 100644 --- a/ios/build/bots/chromium.fyi/ios-simulator.json +++ b/ios/build/bots/chromium.fyi/ios-simulator.json
@@ -21,8 +21,16 @@ ], "device type": "iPhone 6s", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "ios_chrome_integration_egtests", @@ -32,8 +40,16 @@ "device type": "iPhone 6s", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "ios_chrome_integration_egtests", @@ -43,8 +59,16 @@ "device type": "iPad Air 2", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "ios_chrome_integration_egtests", @@ -54,8 +78,16 @@ "device type": "iPhone 6s", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "ios_chrome_smoke_egtests", @@ -65,8 +97,16 @@ "device type": "iPhone 6s", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "ios_chrome_web_egtests", @@ -76,8 +116,16 @@ "device type": "iPhone 6s", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "60": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "ios_web_shell_egtests", @@ -87,8 +135,16 @@ "device type": "iPhone 6s", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "app": "ios_chrome_ui_egtests", @@ -98,8 +154,16 @@ "device type": "iPhone 6s", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } } ] }
diff --git a/ios/build/bots/chromium.fyi/ios12-beta-simulator.json b/ios/build/bots/chromium.fyi/ios12-beta-simulator.json index 096ac82..efcaf67fc 100644 --- a/ios/build/bots/chromium.fyi/ios12-beta-simulator.json +++ b/ios/build/bots/chromium.fyi/ios12-beta-simulator.json
@@ -19,104 +19,208 @@ "device type": "iPhone X", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_cq_tests.json", "device type": "iPhone X", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_cq_tests.json", "device type": "iPhone 6 Plus", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_cq_tests.json", "device type": "iPhone 5s", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_cq_tests.json", "device type": "iPad Pro", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPhone X", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPhone 6 Plus", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPad Air", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPhone 5s", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "screen_size_dependent_tests.json", "device type": "iPhone 6s Plus", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "screen_size_dependent_tests.json", "device type": "iPhone X", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "screen_size_dependent_tests.json", "device type": "iPhone 5s", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "screen_size_dependent_tests.json", "device type": "iPad Air 2", "os": "12.1", "xcode build version": "10o45e", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } } ] }
diff --git a/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json b/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json index 78c9dba6..f93493f 100644 --- a/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json +++ b/ios/build/bots/chromium.fyi/ios12-sdk-simulator.json
@@ -28,8 +28,16 @@ "include": "eg_cq_tests_ios12_simulator_fyi_experiment.json", "device type": "iPhone X", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "shards": 4, "priority": 35 }, @@ -38,8 +46,16 @@ "include": "eg_cq_tests.json", "device type": "iPhone X", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 35 }, { @@ -47,8 +63,16 @@ "include": "eg_cq_tests_ios12_simulator_fyi_experiment.json", "device type": "iPad Air 2", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "shards": 4, "priority": 35 }, @@ -57,8 +81,16 @@ "include": "eg_cq_tests.json", "device type": "iPad Air 2", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 35 }, { @@ -66,8 +98,16 @@ "include": "eg_cq_tests_ios12_simulator_fyi_experiment.json", "device type": "iPhone 7", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "shards": 4, "priority": 35 }, @@ -76,8 +116,16 @@ "include": "eg_cq_tests.json", "device type": "iPhone 7", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 35 }, { @@ -85,8 +133,16 @@ "include": "eg_cq_tests_ios12_simulator_fyi_experiment.json", "device type": "iPhone 7", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "shards": 4, "priority": 35 }, @@ -95,8 +151,16 @@ "include": "eg_cq_tests.json", "device type": "iPhone 7", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 35 }, { @@ -104,8 +168,16 @@ "include": "eg_cq_tests_ios12_simulator_fyi_experiment.json", "device type": "iPad Air 2", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "shards": 4, "priority": 35 }, @@ -114,8 +186,16 @@ "include": "eg_cq_tests.json", "device type": "iPad Air 2", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 35 }, { @@ -123,8 +203,16 @@ "include": "eg_cq_tests_ios12_simulator_fyi_experiment.json", "device type": "iPhone X", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "shards": 4, "priority": 35 }, @@ -133,8 +221,16 @@ "include": "eg_cq_tests.json", "device type": "iPhone X", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 35 } ]
diff --git a/ios/build/bots/chromium.mac/ios-simulator-full-configs.json b/ios/build/bots/chromium.mac/ios-simulator-full-configs.json index 4e1768d..f441b09 100644 --- a/ios/build/bots/chromium.mac/ios-simulator-full-configs.json +++ b/ios/build/bots/chromium.mac/ios-simulator-full-configs.json
@@ -22,80 +22,160 @@ "include": "eg_tests.json", "device type": "iPhone 7", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_tests.json", "device type": "iPhone 7", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_tests.json", "device type": "iPad Air 2", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_tests.json", "device type": "iPad Air 2", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_tests.json", "device type": "iPhone X", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_tests.json", "device type": "iPhone X", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_cq_tests.json", "device type": "iPhone X", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_cq_tests.json", "device type": "iPhone X", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_cq_tests.json", "device type": "iPad Air 2", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_cq_tests.json", "device type": "iPad Air 2", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 } ]
diff --git a/ios/build/bots/chromium.mac/ios-simulator.json b/ios/build/bots/chromium.mac/ios-simulator.json index 19687a4..ef943ce 100644 --- a/ios/build/bots/chromium.mac/ios-simulator.json +++ b/ios/build/bots/chromium.mac/ios-simulator.json
@@ -1,7 +1,7 @@ { "comments": [ - "Runs tests on 64-bit iOS 10.3 and 11.4 and 12.1 tests", - "on iPad, iPhone, @3x, and @2x on main and CQ ios-simulator.", + "Runs tests on 64-bit iOS 11.4 and 12.1 on iPad, iPhone, @3x, and @2x on", + "main and CQ ios-simulator.", "Note: Xcode 10 requires Mac OS 10.13.4 or higher, hence 'host os'." ], "xcode build version": "10b61", @@ -23,72 +23,144 @@ "include": "screen_size_dependent_tests.json", "device type": "iPhone 6s Plus", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "screen_size_dependent_tests.json", "device type": "iPhone 6s", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "common_tests.json", "device type": "iPhone 6s", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "screen_size_dependent_tests.json", "device type": "iPad Air 2", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "screen_size_dependent_tests.json", "device type": "iPhone 6s Plus", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "screen_size_dependent_tests.json", "device type": "iPhone 6s", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "common_tests.json", "device type": "iPhone 6s", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "screen_size_dependent_tests.json", "device type": "iPad Air 2", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { "include": "eg_cq_tests.json", "device type": "iPhone 6s", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 } ]
diff --git a/ios/build/bots/chromium.mac/ios-slimnav.json b/ios/build/bots/chromium.mac/ios-slimnav.json index 99ab81b..dd0f4ee2 100644 --- a/ios/build/bots/chromium.mac/ios-slimnav.json +++ b/ios/build/bots/chromium.mac/ios-slimnav.json
@@ -21,8 +21,16 @@ ], "device type": "iPhone 6s Plus", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -32,8 +40,16 @@ ], "device type": "iPhone 6s", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -43,8 +59,16 @@ ], "device type": "iPhone 6s", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -54,8 +78,16 @@ ], "device type": "iPad Air 2", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -65,8 +97,16 @@ ], "device type": "iPhone 6s Plus", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -76,8 +116,16 @@ ], "device type": "iPhone 6s", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -87,8 +135,16 @@ ], "device type": "iPhone 6s", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -98,8 +154,16 @@ ], "device type": "iPad Air 2", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -109,8 +173,16 @@ ], "device type": "iPhone 6s", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -123,8 +195,16 @@ "shards": 3, "xcode parallelization": true, "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -135,8 +215,16 @@ "device type": "iPad Air 2", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -147,8 +235,16 @@ "device type": "iPad Air 2", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -159,8 +255,16 @@ "device type": "iPad Air 2", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -171,8 +275,16 @@ "device type": "iPad Air 2", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -183,8 +295,16 @@ "device type": "iPad Air 2", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -195,8 +315,16 @@ "device type": "iPad Air 2", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -209,8 +337,16 @@ "device type": "iPad Air 2", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -221,8 +357,16 @@ "xctest": true, "device type": "iPad Air 2", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -233,8 +377,16 @@ "device type": "iPad Air 2", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -245,8 +397,16 @@ "device type": "iPad Air 2", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -257,8 +417,16 @@ "device type": "iPad Air 2", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -269,8 +437,16 @@ "device type": "iPad Air 2", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -281,8 +457,16 @@ "device type": "iPad Air 2", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -295,8 +479,16 @@ "shards": 3, "xcode parallelization": true, "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -307,8 +499,16 @@ "xctest": true, "device type": "iPhone X", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -319,8 +519,16 @@ "device type": "iPhone X", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -331,8 +539,16 @@ "device type": "iPhone X", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -343,8 +559,16 @@ "device type": "iPhone X", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -355,8 +579,16 @@ "device type": "iPhone X", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -367,8 +599,16 @@ "device type": "iPhone X", "os": "11.4", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -381,8 +621,16 @@ "device type": "iPhone X", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -393,8 +641,16 @@ "device type": "iPhone X", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -405,8 +661,16 @@ "device type": "iPhone X", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -417,8 +681,16 @@ "device type": "iPhone X", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -429,8 +701,16 @@ "device type": "iPhone X", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -441,8 +721,16 @@ "device type": "iPhone X", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -453,8 +741,16 @@ "device type": "iPhone X", "os": "12.1", "xctest": true, - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -464,8 +760,16 @@ ], "device type": "iPhone X", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 }, { @@ -475,8 +779,16 @@ ], "device type": "iPhone X", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome", + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + }, "priority": 30 } ]
diff --git a/ios/build/bots/chromium.mac/ios12-sdk-simulator.json b/ios/build/bots/chromium.mac/ios12-sdk-simulator.json index c149c52..eb23bc0 100644 --- a/ios/build/bots/chromium.mac/ios12-sdk-simulator.json +++ b/ios/build/bots/chromium.mac/ios12-sdk-simulator.json
@@ -23,106 +23,226 @@ "include": "eg_cq_tests.json", "device type": "iPhone X", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPhone X", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPad Air 2", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPhone 7", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPhone 7", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPad Air 2", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_tests.json", "device type": "iPhone X", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_cq_tests.json", "device type": "iPhone X", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "screen_size_dependent_tests.json", "device type": "iPhone 6s Plus", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "screen_size_dependent_tests.json", "device type": "iPhone 6s", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "screen_size_dependent_tests.json", "device type": "iPad Air 2", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "screen_size_dependent_tests.json", "device type": "iPad Air 2", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "common_tests.json", "device type": "iPhone 6s", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_cq_tests.json", "device type": "iPhone 6s", "os": "12.1", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } }, { "include": "eg_cq_tests.json", "device type": "iPhone 6s", "os": "11.4", - "host os": "Mac-10.13.6", - "pool": "Chrome" + "host os": "Mac-10.14.4", + "pool":"Chrome", + "optional_dimensions": { + "60": [{ + "host os": "Mac-10.13.6" + }], + "120": [{ + "host os": "Mac-10.14.3" + }] + } } ] }
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 355e07b1..ea96037 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1677,11 +1677,14 @@ Open Settings </message> <message name="IDS_IOS_SYNC_SETTINGS_NOT_CONFIRMED_DESCRIPTION" desc="The error message to display when sign-in was interrupted and the user didn't review the sync settings."> - Initial sync setup was not finished. To start Sync, enabled the Sync toggle. + To start sync, turn on "Sync your Chrome data". </message> <message name="IDS_IOS_SYNC_SETUP_IN_PROGRESS" desc="The message to display when the sync setup is in progress and sync isn't available yet. [Length: 60em] [iOS only]"> Setup in progress… </message> + <message name="IDS_IOS_SYNC_SETUP_NOT_CONFIRMED_TITLE" desc="Title of the error message shown for sync errors. [Length: 60em] [iOS only]"> + Initial Sync Setup Not Finished + </message> <message name="IDS_IOS_SYNC_SIGN_IN_AGAIN" desc="Title displayed when the signed in user needs sign in again. [Length: 20em] [iOS only]"> Sign in again </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SYNC_SETTINGS_NOT_CONFIRMED_DESCRIPTION.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SYNC_SETTINGS_NOT_CONFIRMED_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..358c157 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SYNC_SETTINGS_NOT_CONFIRMED_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +76654a8b7dc6b17ab2e9e405e1f278caea8d2202 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SYNC_SETUP_NOT_CONFIRMED_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SYNC_SETUP_NOT_CONFIRMED_TITLE.png.sha1 new file mode 100644 index 0000000..e52cb8e --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SYNC_SETUP_NOT_CONFIRMED_TITLE.png.sha1
@@ -0,0 +1 @@ +0267b5bf502598d47acef8619e9eb601eda3e5c1 \ No newline at end of file
diff --git a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h index ced29fa3..3cf3813e 100644 --- a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h +++ b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h
@@ -23,6 +23,8 @@ style:(UIAlertActionStyle)style handler:(void (^)(AlertAction* action))handler; +- (instancetype)init NS_UNAVAILABLE; + @end // This class is a replacement for UIAlertController that supports custom
diff --git a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm index 3231933..10f6360 100644 --- a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm +++ b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm
@@ -25,7 +25,7 @@ // Properties of the alert view. constexpr CGFloat kCornerRadius = 14; -constexpr CGFloat kMinimumWidth = 30; +constexpr CGFloat kAlertWidth = 270; constexpr CGFloat kMinimumHeight = 30; constexpr CGFloat kMinimumMargin = 4; @@ -64,16 +64,24 @@ @implementation AlertAction +- (instancetype)initWithTitle:(NSString*)title + style:(UIAlertActionStyle)style + handler:(void (^)(AlertAction* action))handler { + self = [super init]; + if (self) { + static NSInteger actionIdentifier = 0; + _uniqueIdentifier = ++actionIdentifier; + _title = title; + _handler = handler; + _style = style; + } + return self; +} + + (instancetype)actionWithTitle:(NSString*)title style:(UIAlertActionStyle)style handler:(void (^)(AlertAction* action))handler { - AlertAction* action = [[AlertAction alloc] init]; - static NSInteger actionIdentifier = 0; - action.uniqueIdentifier = ++actionIdentifier; - action.title = title; - action.handler = handler; - action.style = style; - return action; + return [[AlertAction alloc] initWithTitle:title style:style handler:handler]; } @end @@ -131,9 +139,10 @@ [self.contentView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor], + // Width + [self.contentView.widthAnchor constraintEqualToConstant:kAlertWidth], + // Minimum Size - [self.contentView.widthAnchor - constraintGreaterThanOrEqualToConstant:kMinimumWidth], [self.contentView.heightAnchor constraintGreaterThanOrEqualToConstant:kMinimumHeight],
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 5a8dbba..3a9df5e 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
@@ -192,6 +192,19 @@ } } +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + // Write the browsing data selection states back to the browser state. + NSArray* dataTypeItems = [self.tableViewModel + itemsInSectionWithIdentifier:SectionIdentifierDataTypes]; + for (TableViewClearBrowsingDataItem* dataTypeItem in dataTypeItems) { + DCHECK([dataTypeItem isKindOfClass:[TableViewClearBrowsingDataItem class]]); + self.browserState->GetPrefs()->SetBoolean(dataTypeItem.prefName, + dataTypeItem.checked); + } +} + - (void)loadModel { [super loadModel]; [self.dataManager loadModel:self.tableViewModel]; @@ -511,8 +524,6 @@ TableViewClearBrowsingDataItem* clearBrowsingDataItem = base::mac::ObjCCastStrict<TableViewClearBrowsingDataItem>(item); clearBrowsingDataItem.checked = flag; - self.browserState->GetPrefs()->SetBoolean(clearBrowsingDataItem.prefName, - clearBrowsingDataItem.checked); [self reconfigureCellsForItems:@[ clearBrowsingDataItem ]]; }
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm index db8d5c98..8ddc74d 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
@@ -583,14 +583,16 @@ SettingsImageDetailTextItem* syncErrorItem = [[SettingsImageDetailTextItem alloc] initWithType:itemType]; syncErrorItem.text = GetNSString(IDS_IOS_SYNC_ERROR_TITLE); - if (itemType == ShowPassphraseDialogErrorItemType) { + syncErrorItem.detailText = + GetSyncErrorDescriptionForSyncSetupService(self.syncSetupService); + if (itemType == SyncSettingsNotCofirmedErrorItemType) { + // Special case for the sync error title. + syncErrorItem.text = GetNSString(IDS_IOS_SYNC_SETUP_NOT_CONFIRMED_TITLE); + } else if (itemType == ShowPassphraseDialogErrorItemType) { // Special case only for the sync passphrase error message. The regular // error message should be still be displayed in the first settings screen. syncErrorItem.detailText = GetNSString( IDS_IOS_GOOGLE_SERVICES_SETTINGS_ENTER_PASSPHRASE_TO_START_SYNC); - } else { - syncErrorItem.detailText = - GetSyncErrorDescriptionForSyncSetupService(self.syncSetupService); } syncErrorItem.image = [UIImage imageNamed:kGoogleServicesSyncErrorImage]; return syncErrorItem;
diff --git a/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm b/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm index df6b806e..18e48eb 100644 --- a/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/privacy_table_view_controller.mm
@@ -327,7 +327,9 @@ UIView* footerView = [super tableView:tableView viewForFooterInSection:section]; if (SectionIdentifierWebServices == - [self.tableViewModel sectionIdentifierForSection:section]) { + [self.tableViewModel sectionIdentifierForSection:section] && + !unified_consent::IsUnifiedConsentFeatureEnabled()) { + // The footer view is only shown when Unified consent flag is off. TableViewLinkHeaderFooterView* footer = base::mac::ObjCCastStrict<TableViewLinkHeaderFooterView>(footerView); footer.delegate = self;
diff --git a/ios/web/navigation/BUILD.gn b/ios/web/navigation/BUILD.gn index 76d1e39a..5f573dc 100644 --- a/ios/web/navigation/BUILD.gn +++ b/ios/web/navigation/BUILD.gn
@@ -22,6 +22,8 @@ sources = [ "crw_navigation_item_holder.h", "crw_navigation_item_holder.mm", + "crw_pending_navigation_info.h", + "crw_pending_navigation_info.mm", "crw_session_controller+private_constructors.h", "crw_session_controller.h", "crw_session_controller.mm",
diff --git a/ios/web/navigation/crw_pending_navigation_info.h b/ios/web/navigation/crw_pending_navigation_info.h new file mode 100644 index 0000000..86da1d4 --- /dev/null +++ b/ios/web/navigation/crw_pending_navigation_info.h
@@ -0,0 +1,34 @@ +// 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_WEB_NAVIGATION_CRW_PENDING_NAVIGATION_INFO_H_ +#define IOS_WEB_NAVIGATION_CRW_PENDING_NAVIGATION_INFO_H_ + +#import <UIKit/UIKit.h> +#import <WebKit/WebKit.h> + +// A container object for any navigation information that is only available +// during pre-commit delegate callbacks, and thus must be held until the +// navigation commits and the information can be used. +@interface CRWPendingNavigationInfo : NSObject { +} +// The referrer for the page. +@property(nonatomic, copy) NSString* referrer; +// The MIME type for the page. +@property(nonatomic, copy) NSString* MIMEType; +// The navigation type for the load. +@property(nonatomic, assign) WKNavigationType navigationType; +// HTTP request method for the load. +@property(nonatomic, copy) NSString* HTTPMethod; +// Whether the pending navigation has been directly cancelled before the +// navigation is committed. +// Cancelled navigations should be simply discarded without handling any +// specific error. +@property(nonatomic, assign) BOOL cancelled; +// Whether the navigation was initiated by a user gesture. +@property(nonatomic, assign) BOOL hasUserGesture; + +@end + +#endif // IOS_WEB_NAVIGATION_CRW_PENDING_NAVIGATION_INFO_H_
diff --git a/ios/web/navigation/crw_pending_navigation_info.mm b/ios/web/navigation/crw_pending_navigation_info.mm new file mode 100644 index 0000000..0981d027 --- /dev/null +++ b/ios/web/navigation/crw_pending_navigation_info.mm
@@ -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. + +#import "ios/web/navigation/crw_pending_navigation_info.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation CRWPendingNavigationInfo + +- (instancetype)init { + if ((self = [super init])) { + _navigationType = WKNavigationTypeOther; + } + return self; +} + +@end
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 9502ba97..3bdad4390 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -52,6 +52,7 @@ #include "ios/web/history_state_util.h" #import "ios/web/interstitials/web_interstitial_impl.h" #import "ios/web/navigation/crw_navigation_item_holder.h" +#import "ios/web/navigation/crw_pending_navigation_info.h" #include "ios/web/navigation/error_retry_state_machine.h" #import "ios/web/navigation/navigation_context_impl.h" #import "ios/web/navigation/navigation_item_impl.h" @@ -226,42 +227,6 @@ } // namespace -#pragma mark - - -// A container object for any navigation information that is only available -// during pre-commit delegate callbacks, and thus must be held until the -// navigation commits and the informatino can be used. -@interface CRWWebControllerPendingNavigationInfo : NSObject { -} -// The referrer for the page. -@property(nonatomic, copy) NSString* referrer; -// The MIME type for the page. -@property(nonatomic, copy) NSString* MIMEType; -// The navigation type for the load. -@property(nonatomic, assign) WKNavigationType navigationType; -// HTTP request method for the load. -@property(nonatomic, copy) NSString* HTTPMethod; -// Whether the pending navigation has been directly cancelled before the -// navigation is committed. -// Cancelled navigations should be simply discarded without handling any -// specific error. -@property(nonatomic, assign) BOOL cancelled; -// Whether the navigation was initiated by a user gesture. -@property(nonatomic, assign) BOOL hasUserGesture; - -@end - -@implementation CRWWebControllerPendingNavigationInfo - -- (instancetype)init { - if ((self = [super init])) { - _navigationType = WKNavigationTypeOther; - } - return self; -} - -@end - @interface CRWWebController () <BrowsingDataRemoverObserver, CRWContextMenuDelegate, CRWNativeContentDelegate, @@ -347,7 +312,7 @@ // this object starts at |decidePolicyForNavigationAction| where the info is // extracted from the request, and ends at either |didCommitNavigation| or // |didFailProvisionalNavigation|. - CRWWebControllerPendingNavigationInfo* _pendingNavigationInfo; + CRWPendingNavigationInfo* _pendingNavigationInfo; // Holds all WKNavigation objects and their states which are currently in // flight. @@ -5440,8 +5405,7 @@ - (void)updatePendingNavigationInfoFromNavigationAction: (WKNavigationAction*)action { if (action.targetFrame.mainFrame) { - _pendingNavigationInfo = - [[CRWWebControllerPendingNavigationInfo alloc] init]; + _pendingNavigationInfo = [[CRWPendingNavigationInfo alloc] init]; [_pendingNavigationInfo setReferrer:[self referrerFromNavigationAction:action]]; [_pendingNavigationInfo setNavigationType:action.navigationType]; @@ -5460,8 +5424,7 @@ (WKNavigationResponse*)response { if (response.isForMainFrame) { if (!_pendingNavigationInfo) { - _pendingNavigationInfo = - [[CRWWebControllerPendingNavigationInfo alloc] init]; + _pendingNavigationInfo = [[CRWPendingNavigationInfo alloc] init]; } [_pendingNavigationInfo setMIMEType:response.response.MIMEType]; }
diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc index f7efeff6..f65aa6c0 100644 --- a/media/audio/win/audio_manager_win.cc +++ b/media/audio/win/audio_manager_win.cc
@@ -149,9 +149,9 @@ AudioLogFactory* audio_log_factory) : AudioManagerBase(std::move(audio_thread), audio_log_factory) { // |CoreAudioUtil::IsSupported()| uses static variables to avoid doing - // multiple initializations. This is however not thread safe. - // So, here we call it explicitly before we kick off the audio thread - // or do any other work. + // multiple initializations. This is thread safe but call it here explicitly + // to ensure initialization is done on the main thread and before we do any + // other work. CoreAudioUtil::IsSupported(); SetMaxOutputStreamsAllowed(kMaxOutputStreams);
diff --git a/media/audio/win/core_audio_util_win.cc b/media/audio/win/core_audio_util_win.cc index 9e4144c..6b5278db 100644 --- a/media/audio/win/core_audio_util_win.cc +++ b/media/audio/win/core_audio_util_win.cc
@@ -413,13 +413,13 @@ return channel_layout; } -bool IsSupportedInternal() { +IMMDeviceEnumerator* IsSupportedInternal() { // It is possible to force usage of WaveXxx APIs by using a command line // flag. const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); if (cmd_line->HasSwitch(switches::kForceWaveAudio)) { DVLOG(1) << "Forcing usage of Windows WaveXxx APIs"; - return false; + return nullptr; } // Verify that it is possible to a create the IMMDeviceEnumerator interface. @@ -430,10 +430,10 @@ LOG(ERROR) << "Failed to create Core Audio device enumerator on thread with ID " << GetCurrentThreadId(); - return false; + return nullptr; } - return true; + return device_enumerator.Detach(); } // Retrieve an audio device specified by |device_id| or a default device @@ -647,8 +647,10 @@ } bool CoreAudioUtil::IsSupported() { - static bool g_is_supported = IsSupportedInternal(); - return g_is_supported; + // Hold on to the device enumerator throughout, to avoid multiple + // de-/initializations of CoreAudio. See: crbug.com/955434 + static IMMDeviceEnumerator* g_enumerator = IsSupportedInternal(); + return g_enumerator != nullptr; } // CoreAudioUtil implementation.
diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc index 5d14a38..2d54f08 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc +++ b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc
@@ -86,7 +86,7 @@ if (!camera_device_delegate_) { return; } - CloseDevice(base::OnceClosure()); + CloseDevice(base::UnguessableToken()); camera_device_ipc_thread_.Stop(); camera_device_delegate_.reset(); device_context_.reset(); @@ -123,13 +123,12 @@ void VideoCaptureDeviceChromeOSHalv3::SuspendImminent( power_manager::SuspendImminent::Reason reason) { + auto token = base::UnguessableToken::Create(); + chromeos::PowerManagerClient::Get()->BlockSuspend( + token, "VideoCaptureDeviceChromeOSHalv3"); capture_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &VideoCaptureDeviceChromeOSHalv3::CloseDevice, - weak_ptr_factory_.GetWeakPtr(), - BindToCurrentLoop(chromeos::PowerManagerClient::Get() - ->GetSuspendReadinessCallback(FROM_HERE)))); + FROM_HERE, base::BindOnce(&VideoCaptureDeviceChromeOSHalv3::CloseDevice, + weak_ptr_factory_.GetWeakPtr(), token)); } void VideoCaptureDeviceChromeOSHalv3::SuspendDone( @@ -159,7 +158,8 @@ camera_device_delegate_->GetWeakPtr(), rotation_)); } -void VideoCaptureDeviceChromeOSHalv3::CloseDevice(base::OnceClosure callback) { +void VideoCaptureDeviceChromeOSHalv3::CloseDevice( + base::UnguessableToken unblock_suspend_token) { DCHECK(capture_task_runner_->BelongsToCurrentThread()); if (!camera_device_delegate_) { @@ -182,8 +182,8 @@ base::Unretained(&device_closed)))); base::TimeDelta kWaitTimeoutSecs = base::TimeDelta::FromSeconds(3); device_closed.TimedWait(kWaitTimeoutSecs); - if (callback) { - std::move(callback).Run(); + if (!unblock_suspend_token.is_empty()) { + chromeos::PowerManagerClient::Get()->UnblockSuspend(unblock_suspend_token); } }
diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h index 559907a..ddd776a 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h +++ b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h
@@ -61,7 +61,7 @@ private: void OpenDevice(); - void CloseDevice(base::OnceClosure callback); + void CloseDevice(base::UnguessableToken unblock_suspend_token); // DisplayRotationDelegate implementation. void SetDisplayRotation(const display::Display& display) final;
diff --git a/net/BUILD.gn b/net/BUILD.gn index 8fb236f8..2c595be 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -3076,8 +3076,20 @@ if (is_linux) { static_library("epoll_server") { sources = [ - "tools/epoll_server/epoll_server.cc", - "tools/epoll_server/epoll_server.h", + "third_party/quiche/src/epoll_server/platform/api/epoll_bug.h", + "third_party/quiche/src/epoll_server/platform/api/epoll_export.h", + "third_party/quiche/src/epoll_server/platform/api/epoll_logging.h", + "third_party/quiche/src/epoll_server/platform/api/epoll_ptr_util.h", + "third_party/quiche/src/epoll_server/platform/api/epoll_thread.h", + "third_party/quiche/src/epoll_server/platform/api/epoll_time.h", + "third_party/quiche/src/epoll_server/simple_epoll_server.cc", + "third_party/quiche/src/epoll_server/simple_epoll_server.h", + "tools/epoll_server/platform/impl/epoll_bug_impl.h", + "tools/epoll_server/platform/impl/epoll_export_impl.h", + "tools/epoll_server/platform/impl/epoll_logging_impl.h", + "tools/epoll_server/platform/impl/epoll_ptr_util_impl.h", + "tools/epoll_server/platform/impl/epoll_thread_impl.h", + "tools/epoll_server/platform/impl/epoll_time_impl.h", ] deps = [ ":net", @@ -3199,6 +3211,25 @@ } } +source_set("epoll_server_test_tools") { + testonly = true + sources = [ + "third_party/quiche/src/epoll_server/platform/api/epoll_address_test_utils.h", + "third_party/quiche/src/epoll_server/platform/api/epoll_expect_bug.h", + "third_party/quiche/src/epoll_server/platform/api/epoll_test.h", + "tools/epoll_server/platform/impl/epoll_address_test_utils_impl.h", + "tools/epoll_server/platform/impl/epoll_expect_bug_impl.h", + "tools/epoll_server/platform/impl/epoll_test_impl.h", + ] + deps = [ + ":net", + ":test_support", + "//base", + "//testing/gmock", + "//testing/gtest", + ] +} + source_set("spdy_test_tools") { testonly = true sources = [ @@ -3369,6 +3400,8 @@ if (is_linux) { sources += [ + "third_party/quiche/src/epoll_server/fake_simple_epoll_server.cc", + "third_party/quiche/src/epoll_server/fake_simple_epoll_server.h", "third_party/quiche/src/quic/test_tools/bad_packet_writer.cc", "third_party/quiche/src/quic/test_tools/bad_packet_writer.h", "third_party/quiche/src/quic/test_tools/limited_mtu_test_writer.cc", @@ -3387,8 +3420,6 @@ "third_party/quiche/src/quic/test_tools/quic_test_server.h", "third_party/quiche/src/quic/test_tools/server_thread.cc", "third_party/quiche/src/quic/test_tools/server_thread.h", - "tools/epoll_server/fake_epoll_server.cc", - "tools/epoll_server/fake_epoll_server.h", ] deps += [ ":epoll_quic_tools", @@ -5557,6 +5588,7 @@ "quic/platform/impl/quic_flags_test.cc", "quic/platform/impl/quic_linux_socket_utils_test.cc", "quic/platform/impl/quic_socket_utils_test.cc", + "third_party/quiche/src/epoll_server/simple_epoll_server_test.cc", "third_party/quiche/src/quic/core/chlo_extractor_test.cc", "third_party/quiche/src/quic/core/http/end_to_end_test.cc", "third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc", @@ -5579,6 +5611,7 @@ deps += [ ":epoll_quic_tools", ":epoll_server", + ":epoll_server_test_tools", ] }
diff --git a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc index c61007d9..bab431d 100644 --- a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc +++ b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store_unittest.cc
@@ -15,8 +15,11 @@ #include "base/synchronization/waitable_event.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" +#include "base/test/simple_test_clock.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" +#include "net/network_error_logging/network_error_logging_service.h" +#include "net/reporting/reporting_test_util.h" #include "net/test/test_with_scoped_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" @@ -27,8 +30,13 @@ const base::FilePath::CharType kReportingAndNELStoreFilename[] = FILE_PATH_LITERAL("ReportingAndNEL"); -const url::Origin kOrigin1 = url::Origin::Create(GURL("https://www.foo.test")); -const url::Origin kOrigin2 = url::Origin::Create(GURL("https://www.bar.test")); +const GURL kUrl1 = GURL("https://www.foo.test"); +const GURL kUrl2 = GURL("https://www.bar.test"); +const url::Origin kOrigin1 = url::Origin::Create(kUrl1); +const url::Origin kOrigin2 = url::Origin::Create(kUrl2); +const IPAddress kServerIP = IPAddress(192, 168, 0, 1); +const std::string kHeader = "{\"report_to\":\"group\",\"max_age\":86400}"; +const std::string kHeaderMaxAge0 = "{\"report_to\":\"group\",\"max_age\":0}"; enum class Op { kAdd, kDelete, kUpdate }; @@ -350,4 +358,216 @@ RunUntilIdle(); } +// These tests test that a SQLitePersistentReportingAndNELStore +// can be used by a NetworkErrorLoggingService to persist NEL policies. +class SQLitePersistNELTest : public SQLitePersistentReportingAndNELStoreTest { + public: + SQLitePersistNELTest() {} + + void SetUp() override { + SQLitePersistentReportingAndNELStoreTest::SetUp(); + SetUpNetworkErrorLoggingService(); + } + + void TearDown() override { + service_->OnShutdown(); + service_.reset(); + reporting_service_.reset(); + SQLitePersistentReportingAndNELStoreTest::TearDown(); + } + + void SetUpNetworkErrorLoggingService() { + CreateStore(); + service_ = NetworkErrorLoggingService::Create(store_.get()); + reporting_service_ = std::make_unique<TestReportingService>(); + service_->SetReportingService(reporting_service_.get()); + service_->SetClockForTesting(&clock_); + } + + void SimulateRestart() { + TearDown(); + SetUpNetworkErrorLoggingService(); + } + + NetworkErrorLoggingService::RequestDetails MakeRequestDetails( + GURL url, + Error error_type) { + NetworkErrorLoggingService::RequestDetails details; + + details.uri = url; + details.referrer = GURL("https://referrer.com/"); + details.user_agent = "Mozilla/1.0"; + details.server_ip = kServerIP; + details.method = "GET"; + details.status_code = 0; + details.elapsed_time = base::TimeDelta::FromSeconds(1); + details.type = error_type; + details.reporting_upload_depth = 0; + + return details; + } + + protected: + base::SimpleTestClock clock_; + std::unique_ptr<NetworkErrorLoggingService> service_; + std::unique_ptr<TestReportingService> reporting_service_; +}; + +TEST_F(SQLitePersistNELTest, AddAndRetrieveNELPolicy) { + service_->OnHeader(kOrigin1, kServerIP, kHeader); + RunUntilIdle(); + + EXPECT_EQ(1u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + SimulateRestart(); + + service_->OnRequest(MakeRequestDetails(kUrl1, ERR_INVALID_RESPONSE)); + RunUntilIdle(); + + EXPECT_EQ(1u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + + EXPECT_THAT(reporting_service_->reports(), + testing::ElementsAre(ReportUrlIs(kUrl1))); +} + +TEST_F(SQLitePersistNELTest, AddAndDeleteNELPolicy) { + service_->OnHeader(kOrigin1, kServerIP, kHeader); + RunUntilIdle(); + + EXPECT_EQ(1u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + SimulateRestart(); + + // Deletes the stored policy. + service_->OnHeader(kOrigin1, kServerIP, kHeaderMaxAge0); + RunUntilIdle(); + + EXPECT_EQ(0u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + SimulateRestart(); + + service_->OnRequest(MakeRequestDetails(kUrl1, ERR_INVALID_RESPONSE)); + RunUntilIdle(); + + EXPECT_EQ(0u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + EXPECT_EQ(0u, reporting_service_->reports().size()); +} + +TEST_F(SQLitePersistNELTest, ExpirationTimeIsPersisted) { + service_->OnHeader(kOrigin1, kServerIP, kHeader); + RunUntilIdle(); + + // Makes the policy we just added expired. + clock_.Advance(base::TimeDelta::FromSeconds(86401)); + + SimulateRestart(); + + service_->OnRequest(MakeRequestDetails(kUrl1, ERR_INVALID_RESPONSE)); + RunUntilIdle(); + + EXPECT_EQ(0u, reporting_service_->reports().size()); + + // Add the policy again so that it is not expired. + service_->OnHeader(kOrigin1, kServerIP, kHeader); + + SimulateRestart(); + + service_->OnRequest(MakeRequestDetails(kUrl1, ERR_INVALID_RESPONSE)); + RunUntilIdle(); + + EXPECT_THAT(reporting_service_->reports(), + testing::ElementsAre(ReportUrlIs(kUrl1))); +} + +TEST_F(SQLitePersistNELTest, OnRequestUpdatesAccessTime) { + service_->OnHeader(kOrigin1, kServerIP, kHeader); + RunUntilIdle(); + + SimulateRestart(); + + // Update the access time by sending a request. + clock_.Advance(base::TimeDelta::FromSeconds(100)); + service_->OnRequest(MakeRequestDetails(kUrl1, ERR_INVALID_RESPONSE)); + RunUntilIdle(); + + EXPECT_THAT(reporting_service_->reports(), + testing::ElementsAre(ReportUrlIs(kUrl1))); + + SimulateRestart(); + // Check that the policy's access time has been updated. + base::Time now = clock_.Now(); + NetworkErrorLoggingService::NELPolicy policy = MakeNELPolicy(kOrigin1, now); + std::vector<NetworkErrorLoggingService::NELPolicy> policies; + LoadNELPolicies(&policies); + ASSERT_EQ(1u, policies.size()); + EXPECT_EQ(policy.origin, policies[0].origin); + EXPECT_TRUE(WithinOneMicrosecond(policy.last_used, policies[0].last_used)); +} + +TEST_F(SQLitePersistNELTest, RemoveSomeBrowsingData) { + service_->OnHeader(kOrigin1, kServerIP, kHeader); + service_->OnHeader(kOrigin2, kServerIP, kHeader); + RunUntilIdle(); + + SimulateRestart(); + + service_->OnRequest(MakeRequestDetails(kUrl1, ERR_INVALID_RESPONSE)); + RunUntilIdle(); + + ASSERT_EQ(1u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + ASSERT_EQ(1u, service_->GetPolicyOriginsForTesting().count(kOrigin2)); + EXPECT_THAT(reporting_service_->reports(), + testing::ElementsAre(ReportUrlIs(kUrl1))); + + SimulateRestart(); + + service_->RemoveBrowsingData( + base::BindRepeating([](const GURL& origin) -> bool { + return origin.host() == kOrigin1.host(); + })); + RunUntilIdle(); + + EXPECT_EQ(0u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + EXPECT_EQ(1u, service_->GetPolicyOriginsForTesting().count(kOrigin2)); + + SimulateRestart(); + + service_->OnRequest(MakeRequestDetails(kUrl1, ERR_INVALID_RESPONSE)); + RunUntilIdle(); + EXPECT_EQ(0u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + EXPECT_EQ(1u, service_->GetPolicyOriginsForTesting().count(kOrigin2)); + EXPECT_EQ(0u, reporting_service_->reports().size()); +} + +TEST_F(SQLitePersistNELTest, RemoveAllBrowsingData) { + service_->OnHeader(kOrigin1, kServerIP, kHeader); + service_->OnHeader(kOrigin2, kServerIP, kHeader); + RunUntilIdle(); + + SimulateRestart(); + + service_->OnRequest(MakeRequestDetails(kUrl1, ERR_INVALID_RESPONSE)); + service_->OnRequest(MakeRequestDetails(kUrl2, ERR_INVALID_RESPONSE)); + RunUntilIdle(); + + ASSERT_EQ(1u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + ASSERT_EQ(1u, service_->GetPolicyOriginsForTesting().count(kOrigin2)); + EXPECT_THAT(reporting_service_->reports(), + testing::ElementsAre(ReportUrlIs(kUrl1), ReportUrlIs(kUrl2))); + + SimulateRestart(); + + service_->RemoveAllBrowsingData(); + RunUntilIdle(); + + EXPECT_EQ(0u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + EXPECT_EQ(0u, service_->GetPolicyOriginsForTesting().count(kOrigin2)); + + SimulateRestart(); + + service_->OnRequest(MakeRequestDetails(kUrl1, ERR_INVALID_RESPONSE)); + service_->OnRequest(MakeRequestDetails(kUrl2, ERR_INVALID_RESPONSE)); + RunUntilIdle(); + EXPECT_EQ(0u, service_->GetPolicyOriginsForTesting().count(kOrigin1)); + EXPECT_EQ(0u, service_->GetPolicyOriginsForTesting().count(kOrigin2)); + EXPECT_EQ(0u, reporting_service_->reports().size()); +} + } // namespace net
diff --git a/net/network_error_logging/network_error_logging_service.cc b/net/network_error_logging/network_error_logging_service.cc index aa875fb..f3c8af42 100644 --- a/net/network_error_logging/network_error_logging_service.cc +++ b/net/network_error_logging/network_error_logging_service.cc
@@ -9,6 +9,7 @@ #include <utility> #include <vector> +#include "base/bind.h" #include "base/json/json_reader.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" @@ -181,10 +182,16 @@ class NetworkErrorLoggingServiceImpl : public NetworkErrorLoggingService { public: explicit NetworkErrorLoggingServiceImpl(PersistentNELStore* store) - : store_(store) {} + : store_(store), + started_loading_policies_(false), + initialized_(false), + weak_factory_(this) { + if (!PoliciesArePersisted()) + initialized_ = true; + } ~NetworkErrorLoggingServiceImpl() override { - if (store_) + if (PoliciesArePersisted() && initialized_) store_->Flush(); } @@ -193,9 +200,6 @@ void OnHeader(const url::Origin& origin, const IPAddress& received_ip_address, const std::string& value) override { - if (shut_down_) - return; - // NEL is only available to secure origins, so don't permit insecure origins // to set policies. if (!origin.GetURL().SchemeIsCryptographic()) { @@ -203,10 +207,184 @@ return; } + base::Time header_received_time = clock_->Now(); + // base::Unretained is safe because the callback gets stored in + // task_backlog_, so the callback will not outlive |*this|. + DoOrBacklogTask(base::BindOnce( + &NetworkErrorLoggingServiceImpl::DoOnHeader, base::Unretained(this), + origin, received_ip_address, value, header_received_time)); + } + + void OnRequest(RequestDetails details) override { + // This method is only called on secure requests. + DCHECK(details.uri.SchemeIsCryptographic()); + + if (!reporting_service_) { + RecordRequestOutcome(RequestOutcome::kDiscardedNoReportingService); + return; + } + + base::Time request_received_time = clock_->Now(); + // base::Unretained is safe because the callback gets stored in + // task_backlog_, so the callback will not outlive |*this|. + DoOrBacklogTask(base::BindOnce(&NetworkErrorLoggingServiceImpl::DoOnRequest, + base::Unretained(this), std::move(details), + request_received_time)); + } + + void QueueSignedExchangeReport(SignedExchangeReportDetails details) override { + if (!reporting_service_) { + RecordSignedExchangeRequestOutcome( + RequestOutcome::kDiscardedNoReportingService); + return; + } + if (!details.outer_url.SchemeIsCryptographic()) { + RecordSignedExchangeRequestOutcome( + RequestOutcome::kDiscardedInsecureOrigin); + return; + } + + base::Time request_received_time = clock_->Now(); + // base::Unretained is safe because the callback gets stored in + // task_backlog_, so the callback will not outlive |*this|. + DoOrBacklogTask(base::BindOnce( + &NetworkErrorLoggingServiceImpl::DoQueueSignedExchangeReport, + base::Unretained(this), std::move(details), request_received_time)); + } + + void RemoveBrowsingData(const base::RepeatingCallback<bool(const GURL&)>& + origin_filter) override { + // base::Unretained is safe because the callback gets stored in + // task_backlog_, so the callback will not outlive |*this|. + DoOrBacklogTask( + base::BindOnce(&NetworkErrorLoggingServiceImpl::DoRemoveBrowsingData, + base::Unretained(this), origin_filter)); + } + + void RemoveAllBrowsingData() override { + // base::Unretained is safe because the callback gets stored in + // task_backlog_, so the callback will not outlive |*this|. + DoOrBacklogTask( + base::BindOnce(&NetworkErrorLoggingServiceImpl::DoRemoveAllBrowsingData, + base::Unretained(this))); + } + + base::Value StatusAsValue() const override { + base::Value dict(base::Value::Type::DICTIONARY); + std::vector<base::Value> policy_list; + // We wanted sorted (or at least reproducible) output; luckily, policies_ is + // a std::map, and therefore already sorted. + for (const auto& origin_and_policy : policies_) { + const auto& origin = origin_and_policy.first; + const auto& policy = origin_and_policy.second; + base::Value policy_dict(base::Value::Type::DICTIONARY); + policy_dict.SetKey("origin", base::Value(origin.Serialize())); + policy_dict.SetKey("includeSubdomains", + base::Value(policy.include_subdomains)); + policy_dict.SetKey("reportTo", base::Value(policy.report_to)); + policy_dict.SetKey("expires", + base::Value(NetLog::TimeToString(policy.expires))); + policy_dict.SetKey("successFraction", + base::Value(policy.success_fraction)); + policy_dict.SetKey("failureFraction", + base::Value(policy.failure_fraction)); + policy_list.push_back(std::move(policy_dict)); + } + dict.SetKey("originPolicies", base::Value(std::move(policy_list))); + return dict; + } + + std::set<url::Origin> GetPolicyOriginsForTesting() override { + std::set<url::Origin> origins; + for (const auto& entry : policies_) { + origins.insert(entry.first); + } + return origins; + } + + private: + // Map from origin to origin's (owned) policy. + // Would be unordered_map, but url::Origin has no hash. + using PolicyMap = std::map<url::Origin, NELPolicy>; + + // Wildcard policies are policies for which the include_subdomains flag is + // set. + // + // Wildcard policies are accessed by domain name, not full origin, so there + // can be multiple wildcard policies per domain name. + // + // This is a map from domain name to the set of pointers to wildcard policies + // in that domain. + // + // Policies in the map are unowned; they are pointers to the original in the + // PolicyMap. + using WildcardPolicyMap = std::map<std::string, std::set<const NELPolicy*>>; + + PolicyMap policies_; + WildcardPolicyMap wildcard_policies_; + + // The persistent store in which NEL policies will be stored to disk, if not + // null. If |store_| is null, then NEL policies will be in-memory only. + // The store is owned by the URLRequestContext because Reporting also needs + // access to it. + PersistentNELStore* store_; + + // Set to true when we have told the store to load NEL policies. This is to + // make sure we don't try to load policies multiple times. + bool started_loading_policies_; + + // Set to true when the NEL service has been initialized. Before + // initialization is complete, commands to the NEL service (i.e. public + // method calls) are stashed away in |task_backlog_|, to be executed once + // initialization is complete. Initialization is complete automatically if + // there is no PersistentNELStore. If there is a store, then initialization is + // complete when the NEL policies have finished being loaded from the store + // (either successfully or unsuccessfully). + bool initialized_; + + // Backlog of tasks waiting on initialization. + std::vector<base::OnceClosure> task_backlog_; + + base::WeakPtrFactory<NetworkErrorLoggingServiceImpl> weak_factory_; + + bool PoliciesArePersisted() const { return store_ != nullptr; } + + void DoOrBacklogTask(base::OnceClosure task) { + if (shut_down_) + return; + + FetchAllPoliciesFromStoreIfNecessary(); + + if (!initialized_) { + task_backlog_.push_back(std::move(task)); + return; + } + + std::move(task).Run(); + } + + void ExecuteBacklog() { + DCHECK(initialized_); + + if (shut_down_) + return; + + for (base::OnceClosure& task : task_backlog_) { + std::move(task).Run(); + } + task_backlog_.clear(); + } + + void DoOnHeader(const url::Origin& origin, + const IPAddress& received_ip_address, + const std::string& value, + base::Time header_received_time) { + DCHECK(initialized_); + NELPolicy policy; policy.origin = origin; policy.received_ip_address = received_ip_address; - policy.last_used = clock_->Now(); + policy.last_used = header_received_time; HeaderOutcome outcome = ParseHeader(value, clock_->Now(), &policy); RecordHeaderOutcome(outcome); if (outcome != HeaderOutcome::SET && outcome != HeaderOutcome::REMOVED) @@ -224,9 +402,7 @@ return; DVLOG(1) << "Received NEL policy for " << origin; - auto inserted = policies_.insert(std::make_pair(origin, policy)); - DCHECK(inserted.second); - MaybeAddWildcardPolicy(origin, &inserted.first->second); + AddPolicy(std::move(policy)); // Evict policies if the policy limit is exceeded. if (policies_.size() > kMaxPolicies) { @@ -237,17 +413,9 @@ } } - void OnRequest(RequestDetails details) override { - if (shut_down_) - return; - - if (!reporting_service_) { - RecordRequestOutcome(RequestOutcome::kDiscardedNoReportingService); - return; - } - - // This method is only called on secure requests. - DCHECK(details.uri.SchemeIsCryptographic()); + void DoOnRequest(RequestDetails details, base::Time request_received_time) { + DCHECK(reporting_service_); + DCHECK(initialized_); auto report_origin = url::Origin::Create(details.uri); const NELPolicy* policy = FindPolicyForOrigin(report_origin); @@ -256,8 +424,7 @@ return; } - // Mark the policy used. - policy->last_used = clock_->Now(); + MarkPolicyUsed(policy, request_received_time); Error type = details.type; // It is expected for Reporting uploads to terminate with ERR_ABORTED, since @@ -329,21 +496,10 @@ RecordRequestOutcome(RequestOutcome::kQueued); } - void QueueSignedExchangeReport( - const SignedExchangeReportDetails& details) override { - if (shut_down_) - return; + void DoQueueSignedExchangeReport(SignedExchangeReportDetails details, + base::Time request_received_time) { + DCHECK(reporting_service_); - if (!reporting_service_) { - RecordSignedExchangeRequestOutcome( - RequestOutcome::kDiscardedNoReportingService); - return; - } - if (!details.outer_url.SchemeIsCryptographic()) { - RecordSignedExchangeRequestOutcome( - RequestOutcome::kDiscardedInsecureOrigin); - return; - } const auto report_origin = url::Origin::Create(details.outer_url); const NELPolicy* policy = FindPolicyForOrigin(report_origin); if (!policy) { @@ -352,8 +508,7 @@ return; } - // Mark the policy used. - policy->last_used = clock_->Now(); + MarkPolicyUsed(policy, request_received_time); if (IsMismatchingSubdomainReport(*policy, report_origin)) { RecordSignedExchangeRequestOutcome( @@ -386,8 +541,9 @@ RecordSignedExchangeRequestOutcome(RequestOutcome::kQueued); } - void RemoveBrowsingData(const base::RepeatingCallback<bool(const GURL&)>& - origin_filter) override { + void DoRemoveBrowsingData( + const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { + DCHECK(initialized_); for (auto it = policies_.begin(); it != policies_.end();) { const url::Origin& origin = it->first; // Remove policies matching the filter. @@ -397,74 +553,24 @@ ++it; } } + if (PoliciesArePersisted()) + store_->Flush(); } - void RemoveAllBrowsingData() override { + void DoRemoveAllBrowsingData() { + DCHECK(initialized_); + if (PoliciesArePersisted()) { + // TODO(chlily): Add a DeleteAllNELPolicies command to PersistentNELStore. + for (auto origin_and_policy : policies_) { + store_->DeleteNELPolicy(origin_and_policy.second); + } + store_->Flush(); + } + wildcard_policies_.clear(); policies_.clear(); } - base::Value StatusAsValue() const override { - base::Value dict(base::Value::Type::DICTIONARY); - std::vector<base::Value> policy_list; - // We wanted sorted (or at least reproducible) output; luckily, policies_ is - // a std::map, and therefore already sorted. - for (const auto& origin_and_policy : policies_) { - const auto& origin = origin_and_policy.first; - const auto& policy = origin_and_policy.second; - base::Value policy_dict(base::Value::Type::DICTIONARY); - policy_dict.SetKey("origin", base::Value(origin.Serialize())); - policy_dict.SetKey("includeSubdomains", - base::Value(policy.include_subdomains)); - policy_dict.SetKey("reportTo", base::Value(policy.report_to)); - policy_dict.SetKey("expires", - base::Value(NetLog::TimeToString(policy.expires))); - policy_dict.SetKey("successFraction", - base::Value(policy.success_fraction)); - policy_dict.SetKey("failureFraction", - base::Value(policy.failure_fraction)); - policy_list.push_back(std::move(policy_dict)); - } - dict.SetKey("originPolicies", base::Value(std::move(policy_list))); - return dict; - } - - std::set<url::Origin> GetPolicyOriginsForTesting() override { - std::set<url::Origin> origins; - for (const auto& entry : policies_) { - origins.insert(entry.first); - } - return origins; - } - - private: - // Map from origin to origin's (owned) policy. - // Would be unordered_map, but url::Origin has no hash. - using PolicyMap = std::map<url::Origin, NELPolicy>; - - // Wildcard policies are policies for which the include_subdomains flag is - // set. - // - // Wildcard policies are accessed by domain name, not full origin, so there - // can be multiple wildcard policies per domain name. - // - // This is a map from domain name to the set of pointers to wildcard policies - // in that domain. - // - // Policies in the map are unowned; they are pointers to the original in the - // PolicyMap. - using WildcardPolicyMap = std::map<std::string, std::set<const NELPolicy*>>; - - PolicyMap policies_; - WildcardPolicyMap wildcard_policies_; - - // The persistent store in which NEL policies will be stored to disk, if not - // null. If |store_| is null, then NEL policies will be in-memory only. - // The store is owned by the URLRequestContext because Reporting also needs - // access to it. - // TODO(chlily): Implement. - PersistentNELStore* store_; - HeaderOutcome ParseHeader(const std::string& json_value, base::Time now, NELPolicy* policy_out) const { @@ -529,6 +635,8 @@ } const NELPolicy* FindPolicyForOrigin(const url::Origin& origin) const { + DCHECK(initialized_); + auto it = policies_.find(origin); if (it != policies_.end() && clock_->Now() < it->second.expires) return &it->second; @@ -568,6 +676,25 @@ return nullptr; } + // There must be no pre-existing policy for |policy.origin|. Returns iterator + // to the inserted policy. + PolicyMap::iterator AddPolicy(NELPolicy policy) { + // If |initialized_| is false, then we are calling this from + // OnPoliciesLoaded(), which means we don't want to add the given policy to + // the store because we have just loaded it from there. + if (PoliciesArePersisted() && initialized_) + store_->AddNELPolicy(policy); + + auto iter_and_result = + policies_.insert(std::make_pair(policy.origin, std::move(policy))); + DCHECK(iter_and_result.second); + + const NELPolicy& inserted_policy = iter_and_result.first->second; + MaybeAddWildcardPolicy(inserted_policy.origin, &inserted_policy); + + return iter_and_result.first; + } + void MaybeAddWildcardPolicy(const url::Origin& origin, const NELPolicy* policy) { DCHECK(policy); @@ -586,6 +713,10 @@ DCHECK(policy_it != policies_.end()); NELPolicy* policy = &policy_it->second; MaybeRemoveWildcardPolicy(policy); + + if (PoliciesArePersisted() && initialized_) + store_->DeleteNELPolicy(*policy); + return policies_.erase(policy_it); } @@ -607,6 +738,12 @@ wildcard_policies_.erase(wildcard_it); } + void MarkPolicyUsed(const NELPolicy* policy, base::Time time_used) const { + policy->last_used = time_used; + if (PoliciesArePersisted() && initialized_) + store_->UpdateNELPolicyAccessTime(*policy); + } + void RemoveAllExpiredPolicies() { for (auto it = policies_.begin(); it != policies_.end();) { if (it->second.expires < clock_->Now()) { @@ -701,6 +838,41 @@ return base::nullopt; return sampling_fraction; } + + void FetchAllPoliciesFromStoreIfNecessary() { + if (!PoliciesArePersisted() || started_loading_policies_) + return; + + started_loading_policies_ = true; + FetchAllPoliciesFromStore(); + } + + void FetchAllPoliciesFromStore() { + DCHECK(PoliciesArePersisted()); + DCHECK(!initialized_); + + store_->LoadNELPolicies( + base::BindOnce(&NetworkErrorLoggingServiceImpl::OnPoliciesLoaded, + weak_factory_.GetWeakPtr())); + } + + // This is called when loading from the store is complete, regardless of + // success or failure. + // DB initialization may have failed, in which case we will receive an empty + // vector from the PersistentNELStore. This is indistinguishable from a + // successful load that happens to not yield any policies, but in + // either case we still want to go through the task backlog. + void OnPoliciesLoaded(std::vector<NELPolicy> loaded_policies) { + DCHECK(PoliciesArePersisted()); + DCHECK(!initialized_); + + // TODO(chlily): Toss any expired policies we encounter. + for (NELPolicy& policy : loaded_policies) { + AddPolicy(std::move(policy)); + } + initialized_ = true; + ExecuteBacklog(); + } }; } // namespace @@ -815,12 +987,13 @@ void NetworkErrorLoggingService::SetReportingService( ReportingService* reporting_service) { + DCHECK(!reporting_service_); reporting_service_ = reporting_service; } void NetworkErrorLoggingService::OnShutdown() { shut_down_ = true; - SetReportingService(nullptr); + reporting_service_ = nullptr; } void NetworkErrorLoggingService::SetClockForTesting(const base::Clock* clock) {
diff --git a/net/network_error_logging/network_error_logging_service.h b/net/network_error_logging/network_error_logging_service.h index 642e2fc..98e08ce1 100644 --- a/net/network_error_logging/network_error_logging_service.h +++ b/net/network_error_logging/network_error_logging_service.h
@@ -227,7 +227,7 @@ // Queues a Signed Exchange report. virtual void QueueSignedExchangeReport( - const SignedExchangeReportDetails& details) = 0; + SignedExchangeReportDetails details) = 0; // Removes browsing data (origin policies) associated with any origin for // which |origin_filter| returns true. @@ -241,10 +241,12 @@ // Sets the ReportingService that will be used to queue network error reports. // If |nullptr| is passed, reports will be queued locally or discarded. // |reporting_service| must outlive the NetworkErrorLoggingService. + // Should not be called again if previously called with a non-null pointer. void SetReportingService(ReportingService* reporting_service); - // Shuts down the NEL service so that no more requests or headers are - // processed and no more reports are queued. + // Shuts down the NEL service, so that no more requests or headers can be + // processed, no more reports are queued, and browsing data can no longer be + // cleared. void OnShutdown(); // Sets a base::Clock (used to track policy expiration) for tests.
diff --git a/net/network_error_logging/network_error_logging_service_unittest.cc b/net/network_error_logging/network_error_logging_service_unittest.cc index 8e274fd53..c2fefd5 100644 --- a/net/network_error_logging/network_error_logging_service_unittest.cc +++ b/net/network_error_logging/network_error_logging_service_unittest.cc
@@ -18,8 +18,7 @@ #include "net/base/net_errors.h" #include "net/network_error_logging/mock_persistent_nel_store.h" #include "net/network_error_logging/network_error_logging_service.h" -#include "net/reporting/reporting_policy.h" -#include "net/reporting/reporting_service.h" +#include "net/reporting/reporting_test_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" #include "url/origin.h" @@ -27,97 +26,15 @@ namespace net { namespace { -class TestReportingService : public ReportingService { - public: - struct Report { - Report() = default; - - Report(Report&& other) - : url(other.url), - user_agent(other.user_agent), - group(other.group), - type(other.type), - body(std::move(other.body)), - depth(other.depth) {} - - Report(const GURL& url, - const std::string& user_agent, - const std::string& group, - const std::string& type, - std::unique_ptr<const base::Value> body, - int depth) - : url(url), - user_agent(user_agent), - group(group), - type(type), - body(std::move(body)), - depth(depth) {} - - ~Report() = default; - - GURL url; - std::string user_agent; - std::string group; - std::string type; - std::unique_ptr<const base::Value> body; - int depth; - - private: - DISALLOW_COPY(Report); - }; - - TestReportingService() = default; - - const std::vector<Report>& reports() const { return reports_; } - - // ReportingService implementation: - - ~TestReportingService() override = default; - - void QueueReport(const GURL& url, - const std::string& user_agent, - const std::string& group, - const std::string& type, - std::unique_ptr<const base::Value> body, - int depth) override { - reports_.push_back( - Report(url, user_agent, group, type, std::move(body), depth)); - } - - void ProcessHeader(const GURL& url, - const std::string& header_value) override { - NOTREACHED(); - } - - void RemoveBrowsingData(int data_type_mask, - const base::RepeatingCallback<bool(const GURL&)>& - origin_filter) override { - NOTREACHED(); - } - - void RemoveAllBrowsingData(int data_type_mask) override { NOTREACHED(); } - - void OnShutdown() override {} - - const ReportingPolicy& GetPolicy() const override { - NOTREACHED(); - return dummy_policy_; - } - - ReportingContext* GetContextForTesting() const override { - NOTREACHED(); - return nullptr; - } - - private: - std::vector<Report> reports_; - ReportingPolicy dummy_policy_; - - DISALLOW_COPY_AND_ASSIGN(TestReportingService); -}; - // The tests are parametrized on a boolean value which represents whether or not // to use a MockPersistentNELStore. +// If a MockPersistentNELStore is used, then calls to +// NetworkErrorLoggingService::OnHeader(), OnRequest(), +// QueueSignedExchangeReport(), RemoveBrowsingData(), and +// RemoveAllBrowsingData() will block until the store finishes loading. +// Therefore, for tests that should run synchronously (i.e. tests that don't +// specifically test the asynchronous/deferred task behavior), FinishLoading() +// must be called after the first call to one of the above methods. class NetworkErrorLoggingServiceTest : public ::testing::TestWithParam<bool> { protected: NetworkErrorLoggingServiceTest() { @@ -137,13 +54,6 @@ service_->SetReportingService(reporting_service_.get()); } - void DestroyReportingService() { - DCHECK(reporting_service_); - - service_->SetReportingService(nullptr); - reporting_service_.reset(); - } - NetworkErrorLoggingService::RequestDetails MakeRequestDetails( GURL url, Error error_type, @@ -198,6 +108,18 @@ return url::Origin::Create(url); } + NetworkErrorLoggingService::NELPolicy MakePolicyForOrigin( + url::Origin origin, + base::Time expires = base::Time(), + base::Time last_used = base::Time()) { + NetworkErrorLoggingService::NELPolicy policy; + policy.origin = std::move(origin); + policy.expires = expires; + policy.last_used = last_used; + + return policy; + } + // Returns whether the NetworkErrorLoggingService has a policy corresponding // to |origin|. Returns true if so, even if the policy is expired. bool HasPolicyForOrigin(const url::Origin& origin) { @@ -208,6 +130,12 @@ size_t PolicyCount() { return service_->GetPolicyOriginsForTesting().size(); } + // Makes the rest of the test run synchronously. + void FinishLoading(bool load_success) { + if (store()) + store()->FinishLoading(load_success); + } + const GURL kUrl_ = GURL("https://example.com/path"); const GURL kUrlDifferentPort_ = GURL("https://example.com:4433/path"); const GURL kUrlSubdomain_ = GURL("https://subdomain.example.com/path"); @@ -247,7 +175,6 @@ const GURL kReferrer_ = GURL("https://referrer.com/"); - private: // |store_| needs to outlive |service_|. std::unique_ptr<MockPersistentNELStore> store_; std::unique_ptr<NetworkErrorLoggingService> service_; @@ -268,22 +195,32 @@ } TEST_P(NetworkErrorLoggingServiceTest, NoReportingService) { - DestroyReportingService(); + service_ = NetworkErrorLoggingService::Create(store_.get()); service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + + // Should not crash. service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED)); } TEST_P(NetworkErrorLoggingServiceTest, NoPolicyForOrigin) { service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED)); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + EXPECT_TRUE(reports().empty()); } TEST_P(NetworkErrorLoggingServiceTest, JsonTooLong) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderTooLong_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED)); EXPECT_TRUE(reports().empty()); @@ -292,6 +229,9 @@ TEST_P(NetworkErrorLoggingServiceTest, JsonTooDeep) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderTooDeep_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED)); EXPECT_TRUE(reports().empty()); @@ -300,6 +240,9 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessReportQueued) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, OK)); ASSERT_EQ(1u, reports().size()); @@ -337,6 +280,9 @@ "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}"; service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction1); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED)); ASSERT_EQ(1u, reports().size()); @@ -374,6 +320,9 @@ "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}"; service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction1); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + // This error code happens to not be mapped to a NEL report `type` field // value. service()->OnRequest(MakeRequestDetails(kUrl_, ERR_FILE_NO_SPACE)); @@ -392,6 +341,9 @@ "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}"; service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction1); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + // This error code happens to not be mapped to a NEL report `type` field // value. Because it's a certificate error, we'll set the `phase` to be // `connection`. @@ -411,6 +363,9 @@ "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":1.0}"; service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction1); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, OK, "GET", 504)); ASSERT_EQ(1u, reports().size()); @@ -446,6 +401,9 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessReportDowngraded) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest( MakeRequestDetails(kUrl_, OK, "GET", 200, kOtherServerIP_)); @@ -480,6 +438,9 @@ TEST_P(NetworkErrorLoggingServiceTest, FailureReportDowngraded) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED, "GET", 200, kOtherServerIP_)); @@ -514,6 +475,9 @@ TEST_P(NetworkErrorLoggingServiceTest, HttpErrorReportDowngraded) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest( MakeRequestDetails(kUrl_, OK, "GET", 504, kOtherServerIP_)); @@ -548,6 +512,9 @@ TEST_P(NetworkErrorLoggingServiceTest, DNSFailureReportNotDowngraded) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, ERR_NAME_NOT_RESOLVED, "GET", 0, kOtherServerIP_)); @@ -582,6 +549,9 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessPOSTReportQueued) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, OK, "POST")); ASSERT_EQ(1u, reports().size()); @@ -610,6 +580,10 @@ TEST_P(NetworkErrorLoggingServiceTest, MaxAge0) { service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + EXPECT_EQ(1u, PolicyCount()); // Max_age of 0 removes the policy. @@ -624,6 +598,9 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessFraction0) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction0_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + // Each network error has a 0% chance of being reported. Fire off several and // verify that no reports are produced. constexpr size_t kReportCount = 100; @@ -641,6 +618,9 @@ "\"failure_fraction\":0.25}"; service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFractionHalf); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + // Each network error has a 50% chance of being reported. Fire off several // and verify that some requests were reported and some weren't. (We can't // verify exact counts because each decision is made randomly.) @@ -672,6 +652,9 @@ "{\"report_to\":\"group\",\"max_age\":86400,\"failure_fraction\":0.0}"; service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFraction0); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + // Each network error has a 0% chance of being reported. Fire off several and // verify that no reports are produced. constexpr size_t kReportCount = 100; @@ -689,6 +672,9 @@ "\"success_fraction\":0.25}"; service()->OnHeader(kOrigin_, kServerIP_, kHeaderFailureFractionHalf); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + // Each network error has a 50% chance of being reported. Fire off several // and verify that some requests were reported and some weren't. (We can't // verify exact counts because each decision is made randomly.) @@ -717,6 +703,9 @@ ExcludeSubdomainsDoesntMatchDifferentPort) { service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest( MakeRequestDetails(kUrlDifferentPort_, ERR_CONNECTION_REFUSED)); @@ -726,6 +715,9 @@ TEST_P(NetworkErrorLoggingServiceTest, ExcludeSubdomainsDoesntMatchSubdomain) { service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest( MakeRequestDetails(kUrlSubdomain_, ERR_CONNECTION_REFUSED)); @@ -735,6 +727,9 @@ TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsMatchesDifferentPort) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest( MakeRequestDetails(kUrlDifferentPort_, ERR_NAME_NOT_RESOLVED)); @@ -745,6 +740,9 @@ TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsMatchesSubdomain) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest( MakeRequestDetails(kUrlSubdomain_, ERR_NAME_NOT_RESOLVED)); @@ -755,6 +753,9 @@ IncludeSubdomainsDoesntMatchSuperdomain) { service()->OnHeader(kOriginSubdomain_, kServerIP_, kHeaderIncludeSubdomains_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, ERR_NAME_NOT_RESOLVED)); EXPECT_TRUE(reports().empty()); @@ -764,6 +765,9 @@ IncludeSubdomainsDoesntReportConnectionError) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest( MakeRequestDetails(kUrlSubdomain_, ERR_CONNECTION_REFUSED)); @@ -774,6 +778,9 @@ IncludeSubdomainsDoesntReportApplicationError) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest( MakeRequestDetails(kUrlSubdomain_, ERR_INVALID_HTTP_RESPONSE)); @@ -783,6 +790,9 @@ TEST_P(NetworkErrorLoggingServiceTest, IncludeSubdomainsDoesntReportSuccess) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrlSubdomain_, OK)); EXPECT_TRUE(reports().empty()); @@ -795,6 +805,9 @@ "\"include_subdomains\":true,\"success_fraction\":1.0}"; service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomainsSuccess1); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnRequest(MakeRequestDetails(kUrl_, OK)); ASSERT_EQ(1u, reports().size()); @@ -803,6 +816,10 @@ TEST_P(NetworkErrorLoggingServiceTest, RemoveAllBrowsingData) { service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + EXPECT_EQ(1u, PolicyCount()); EXPECT_TRUE(HasPolicyForOrigin(kOrigin_)); @@ -817,6 +834,10 @@ TEST_P(NetworkErrorLoggingServiceTest, RemoveSomeBrowsingData) { service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnHeader(kOriginDifferentHost_, kServerIP_, kHeader_); EXPECT_EQ(2u, PolicyCount()); @@ -842,6 +863,9 @@ TEST_P(NetworkErrorLoggingServiceTest, Nested) { service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + NetworkErrorLoggingService::RequestDetails details = MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED); details.reporting_upload_depth = @@ -856,6 +880,9 @@ TEST_P(NetworkErrorLoggingServiceTest, NestedTooDeep) { service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + NetworkErrorLoggingService::RequestDetails details = MakeRequestDetails(kUrl_, ERR_CONNECTION_REFUSED); details.reporting_upload_depth = @@ -880,6 +907,10 @@ clock.Advance(delta_from_origin); service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->OnHeader(kOriginDifferentHost_, kServerIP_, kHeader_); service()->OnHeader(kOriginSubdomain_, kServerIP_, kHeaderIncludeSubdomains_); const std::string kHeaderWrongTypes = @@ -938,9 +969,14 @@ } TEST_P(NetworkErrorLoggingServiceTest, NoReportingService_SignedExchange) { - DestroyReportingService(); + service_ = NetworkErrorLoggingService::Create(store_.get()); service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + + // Should not crash service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_)); } @@ -948,12 +984,19 @@ TEST_P(NetworkErrorLoggingServiceTest, NoPolicyForOrigin_SignedExchange) { service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_)); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + EXPECT_TRUE(reports().empty()); } TEST_P(NetworkErrorLoggingServiceTest, SuccessFraction0_SignedExchange) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction0_); + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + // Each network error has a 0% chance of being reported. Fire off several and // verify that no reports are produced. constexpr size_t kReportCount = 100; @@ -967,6 +1010,10 @@ TEST_P(NetworkErrorLoggingServiceTest, SuccessReportQueued_SignedExchange) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderSuccessFraction1_); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( true, "ok", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_)); ASSERT_EQ(1u, reports().size()); @@ -1013,6 +1060,10 @@ TEST_P(NetworkErrorLoggingServiceTest, FailureReportQueued_SignedExchange) { service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_)); ASSERT_EQ(1u, reports().size()); @@ -1059,6 +1110,10 @@ TEST_P(NetworkErrorLoggingServiceTest, MismatchingSubdomain_SignedExchange) { service()->OnHeader(kOrigin_, kServerIP_, kHeaderIncludeSubdomains_); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( false, "sxg.failed", kUrlSubdomain_, kInnerUrl_, kCertUrl_, kServerIP_)); EXPECT_TRUE(reports().empty()); @@ -1066,6 +1121,10 @@ TEST_P(NetworkErrorLoggingServiceTest, MismatchingIPAddress_SignedExchange) { service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kOtherServerIP_)); EXPECT_TRUE(reports().empty()); @@ -1081,6 +1140,9 @@ for (size_t i = 0; i < 100; ++i) { service()->OnHeader(MakeOrigin(i), kServerIP_, kHeader_); } + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + EXPECT_EQ(100u, PolicyCount()); clock.Advance(base::TimeDelta::FromSeconds(86401)); // max_age is 86400 sec // Expired policies are allowed to linger before hitting the policy limit. @@ -1106,6 +1168,8 @@ service()->OnHeader(MakeOrigin(i), kServerIP_, kHeader_); clock.Advance(base::TimeDelta::FromSeconds(1)); } + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); EXPECT_EQ(PolicyCount(), NetworkErrorLoggingService::kMaxPolicies); @@ -1152,6 +1216,315 @@ // this test. } +TEST_P(NetworkErrorLoggingServiceTest, SendsCommandsToStoreSynchronous) { + if (!store()) + return; + + MockPersistentNELStore::CommandList expected_commands; + NetworkErrorLoggingService::NELPolicy policy1 = MakePolicyForOrigin(kOrigin_); + NetworkErrorLoggingService::NELPolicy policy2 = + MakePolicyForOrigin(kOriginDifferentHost_); + std::vector<NetworkErrorLoggingService::NELPolicy> prestored_policies = { + policy1, policy2}; + store()->SetPrestoredPolicies(std::move(prestored_policies)); + + // The first call to any of the public methods triggers a load. + service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + // Make the rest of the test run synchronously. + FinishLoading(true /* load_success */); + // DoOnHeader() should now execute. + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy1); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::ADD_NEL_POLICY, policy1); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->OnRequest( + MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED)); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY, policy1); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( + false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_)); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY, policy1); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + // Removes policy1 but not policy2. + EXPECT_EQ(2, store()->StoredPoliciesCount()); + service()->RemoveBrowsingData( + base::BindRepeating([](const GURL& origin) -> bool { + return origin.host() == "example.com"; + })); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy1); + expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH); + EXPECT_EQ(1, store()->StoredPoliciesCount()); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->RemoveAllBrowsingData(); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy2); + expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH); + EXPECT_EQ(0, store()->StoredPoliciesCount()); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); +} + +// Same as the above test, except that all the tasks are queued until loading +// is complete. +TEST_P(NetworkErrorLoggingServiceTest, SendsCommandsToStoreDeferred) { + if (!store()) + return; + + MockPersistentNELStore::CommandList expected_commands; + NetworkErrorLoggingService::NELPolicy policy1 = MakePolicyForOrigin(kOrigin_); + NetworkErrorLoggingService::NELPolicy policy2 = + MakePolicyForOrigin(kOriginDifferentHost_); + std::vector<NetworkErrorLoggingService::NELPolicy> prestored_policies = { + policy1, policy2}; + store()->SetPrestoredPolicies(std::move(prestored_policies)); + + // The first call to any of the public methods triggers a load. + service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->OnRequest( + MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED)); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( + false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_)); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + // Removes policy1 but not policy2. + service()->RemoveBrowsingData( + base::BindRepeating([](const GURL& origin) -> bool { + return origin.host() == "example.com"; + })); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->RemoveAllBrowsingData(); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + // The store has not yet been told to remove the policies because the tasks + // to remove browsing data were queued pending initialization. + EXPECT_EQ(2, store()->StoredPoliciesCount()); + + FinishLoading(true /* load_success */); + // DoOnHeader() + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy1); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::ADD_NEL_POLICY, policy1); + // DoOnRequest() + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY, policy1); + // DoQueueSignedExchangeReport() + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY, policy1); + // DoRemoveBrowsingData() + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy1); + expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH); + // DoRemoveAllBrowsingData() + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy2); + expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); +} + +// These two tests check that if loading fails, the commands should still +// be sent to the store; the actual store impl will just ignore them. +TEST_P(NetworkErrorLoggingServiceTest, + SendsCommandsToStoreSynchronousLoadFailed) { + if (!store()) + return; + + MockPersistentNELStore::CommandList expected_commands; + NetworkErrorLoggingService::NELPolicy policy1 = MakePolicyForOrigin(kOrigin_); + NetworkErrorLoggingService::NELPolicy policy2 = + MakePolicyForOrigin(kOriginDifferentHost_); + std::vector<NetworkErrorLoggingService::NELPolicy> prestored_policies = { + policy1, policy2}; + store()->SetPrestoredPolicies(std::move(prestored_policies)); + + // The first call to any of the public methods triggers a load. + service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + // Make the rest of the test run synchronously. + FinishLoading(false /* load_success */); + // DoOnHeader() should now execute. + // Because the load failed, there will be no policies in memory, so the store + // is not told to delete anything. + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::ADD_NEL_POLICY, policy1); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + LOG(INFO) << store()->GetDebugString(); + + service()->OnRequest( + MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED)); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY, policy1); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( + false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_)); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY, policy1); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + // Removes policy1 but not policy2. + service()->RemoveBrowsingData( + base::BindRepeating([](const GURL& origin) -> bool { + return origin.host() == "example.com"; + })); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy1); + expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->RemoveAllBrowsingData(); + // We failed to load policy2 from the store, so there is nothing to remove + // here. + expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); +} + +TEST_P(NetworkErrorLoggingServiceTest, SendsCommandsToStoreDeferredLoadFailed) { + if (!store()) + return; + + MockPersistentNELStore::CommandList expected_commands; + NetworkErrorLoggingService::NELPolicy policy1 = MakePolicyForOrigin(kOrigin_); + NetworkErrorLoggingService::NELPolicy policy2 = + MakePolicyForOrigin(kOriginDifferentHost_); + std::vector<NetworkErrorLoggingService::NELPolicy> prestored_policies = { + policy1, policy2}; + store()->SetPrestoredPolicies(std::move(prestored_policies)); + + // The first call to any of the public methods triggers a load. + service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->OnRequest( + MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED)); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( + false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_)); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + // Removes policy1 but not policy2. + service()->RemoveBrowsingData( + base::BindRepeating([](const GURL& origin) -> bool { + return origin.host() == "example.com"; + })); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->RemoveAllBrowsingData(); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + FinishLoading(false /* load_success */); + // DoOnHeader() + // Because the load failed, there will be no policies in memory, so the store + // is not told to delete anything. + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::ADD_NEL_POLICY, policy1); + // DoOnRequest() + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY, policy1); + // DoQueueSignedExchangeReport() + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::UPDATE_NEL_POLICY, policy1); + // DoRemoveBrowsingData() + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::DELETE_NEL_POLICY, policy1); + expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH); + // DoRemoveAllBrowsingData() + // We failed to load policy2 from the store, so there is nothing to remove + // here. + expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); +} + +TEST_P(NetworkErrorLoggingServiceTest, FlushesStoreOnDestruction) { + auto store = std::make_unique<MockPersistentNELStore>(); + std::unique_ptr<NetworkErrorLoggingService> service = + NetworkErrorLoggingService::Create(store.get()); + + MockPersistentNELStore::CommandList expected_commands; + + service->OnHeader(kOrigin_, kServerIP_, kHeader_); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES); + EXPECT_TRUE(store->VerifyCommands(expected_commands)); + + store->FinishLoading(false /* load_success */); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::ADD_NEL_POLICY, + MakePolicyForOrigin(kOrigin_)); + EXPECT_TRUE(store->VerifyCommands(expected_commands)); + + // Store should be flushed on destruction of service. + service.reset(); + expected_commands.emplace_back(MockPersistentNELStore::Command::Type::FLUSH); + EXPECT_TRUE(store->VerifyCommands(expected_commands)); +} + +TEST_P(NetworkErrorLoggingServiceTest, + DoesntFlushStoreOnDestructionBeforeLoad) { + auto store = std::make_unique<MockPersistentNELStore>(); + std::unique_ptr<NetworkErrorLoggingService> service = + NetworkErrorLoggingService::Create(store.get()); + + service.reset(); + EXPECT_EQ(0u, store->GetAllCommands().size()); +} + +TEST_P(NetworkErrorLoggingServiceTest, DoNothingIfShutDown) { + if (!store()) + return; + + MockPersistentNELStore::CommandList expected_commands; + + // The first call to any of the public methods triggers a load. + service()->OnHeader(kOrigin_, kServerIP_, kHeader_); + expected_commands.emplace_back( + MockPersistentNELStore::Command::Type::LOAD_NEL_POLICIES); + EXPECT_TRUE(store()->VerifyCommands(expected_commands)); + + service()->OnRequest( + MakeRequestDetails(kOrigin_.GetURL(), ERR_CONNECTION_REFUSED)); + service()->QueueSignedExchangeReport(MakeSignedExchangeReportDetails( + false, "sxg.failed", kUrl_, kInnerUrl_, kCertUrl_, kServerIP_)); + service()->RemoveBrowsingData( + base::BindRepeating([](const GURL& origin) -> bool { + return origin.host() == "example.com"; + })); + service()->RemoveAllBrowsingData(); + + // Finish loading after the service has been shut down. + service()->OnShutdown(); + FinishLoading(true /* load_success */); + + // Only the LOAD command should have been sent to the store. + EXPECT_EQ(1u, store()->GetAllCommands().size()); + EXPECT_EQ(0u, PolicyCount()); + EXPECT_EQ(0u, reports().size()); +} + INSTANTIATE_TEST_SUITE_P(NetworkErrorLoggingServiceStoreTest, NetworkErrorLoggingServiceTest, testing::Bool());
diff --git a/net/network_error_logging/network_error_logging_test_util.cc b/net/network_error_logging/network_error_logging_test_util.cc index 54d6376..a75a06d8 100644 --- a/net/network_error_logging/network_error_logging_test_util.cc +++ b/net/network_error_logging/network_error_logging_test_util.cc
@@ -33,7 +33,7 @@ } void TestNetworkErrorLoggingService::QueueSignedExchangeReport( - const SignedExchangeReportDetails& details) {} + SignedExchangeReportDetails details) {} void TestNetworkErrorLoggingService::RemoveBrowsingData( const base::RepeatingCallback<bool(const GURL&)>& origin_filter) {}
diff --git a/net/network_error_logging/network_error_logging_test_util.h b/net/network_error_logging/network_error_logging_test_util.h index 3eb29c3..c6af941 100644 --- a/net/network_error_logging/network_error_logging_test_util.h +++ b/net/network_error_logging/network_error_logging_test_util.h
@@ -48,8 +48,7 @@ const IPAddress& received_ip_address, const std::string& value) override; void OnRequest(RequestDetails details) override; - void QueueSignedExchangeReport( - const SignedExchangeReportDetails& details) override; + void QueueSignedExchangeReport(SignedExchangeReportDetails details) override; void RemoveBrowsingData( const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override; void RemoveAllBrowsingData() override;
diff --git a/net/quic/platform/impl/quic_epoll_clock.cc b/net/quic/platform/impl/quic_epoll_clock.cc index dfba155..7a84a68 100644 --- a/net/quic/platform/impl/quic_epoll_clock.cc +++ b/net/quic/platform/impl/quic_epoll_clock.cc
@@ -4,13 +4,13 @@ #include "net/quic/platform/impl/quic_epoll_clock.h" +#include "net/third_party/quiche/src/epoll_server/simple_epoll_server.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" -#include "net/tools/epoll_server/epoll_server.h" namespace quic { -QuicEpollClock::QuicEpollClock(net::EpollServer* epoll_server) +QuicEpollClock::QuicEpollClock(epoll_server::SimpleEpollServer* epoll_server) : epoll_server_(epoll_server), largest_time_(QuicTime::Zero()) {} QuicEpollClock::~QuicEpollClock() {}
diff --git a/net/quic/platform/impl/quic_epoll_clock.h b/net/quic/platform/impl/quic_epoll_clock.h index f20df24..cece73f 100644 --- a/net/quic/platform/impl/quic_epoll_clock.h +++ b/net/quic/platform/impl/quic_epoll_clock.h
@@ -10,17 +10,19 @@ #include "net/third_party/quiche/src/quic/core/quic_time.h" #include "net/third_party/quiche/src/quic/platform/api/quic_clock.h" -namespace quic {} // namespace quic -namespace net { -class EpollServer; -} // namespace net +namespace epoll_server { + +class SimpleEpollServer; + +} // namespace epoll_server + namespace quic { // Clock to efficiently retrieve an approximately accurate time from an // net::EpollServer. class QuicEpollClock : public QuicClock { public: - explicit QuicEpollClock(net::EpollServer* epoll_server); + explicit QuicEpollClock(epoll_server::SimpleEpollServer* epoll_server); ~QuicEpollClock() override; // Returns the approximate current time as a QuicTime object. @@ -40,7 +42,7 @@ const QuicWallTime& walltime) const override; protected: - net::EpollServer* epoll_server_; + epoll_server::SimpleEpollServer* epoll_server_; // Largest time returned from Now() so far. mutable QuicTime largest_time_;
diff --git a/net/quic/platform/impl/quic_epoll_clock_test.cc b/net/quic/platform/impl/quic_epoll_clock_test.cc index 75caf111..d641f54 100644 --- a/net/quic/platform/impl/quic_epoll_clock_test.cc +++ b/net/quic/platform/impl/quic_epoll_clock_test.cc
@@ -4,9 +4,9 @@ #include "net/quic/platform/impl/quic_epoll_clock.h" +#include "net/third_party/quiche/src/epoll_server/fake_simple_epoll_server.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" -#include "net/tools/epoll_server/fake_epoll_server.h" namespace quic { namespace test { @@ -14,7 +14,7 @@ class QuicEpollClockTest : public QuicTest {}; TEST_F(QuicEpollClockTest, ApproximateNowInUsec) { - FakeEpollServer epoll_server; + epoll_server::test::FakeSimpleEpollServer epoll_server; QuicEpollClock clock(&epoll_server); epoll_server.set_now_in_usec(1000000); @@ -35,7 +35,7 @@ } TEST_F(QuicEpollClockTest, NowInUsec) { - FakeEpollServer epoll_server; + epoll_server::test::FakeSimpleEpollServer epoll_server; QuicEpollClock clock(&epoll_server); epoll_server.set_now_in_usec(1000000); @@ -47,7 +47,7 @@ TEST_F(QuicEpollClockTest, MonotonicityWithRealEpollClock) { SetQuicReloadableFlag(quic_monotonic_epoll_clock, true); - net::EpollServer epoll_server; + epoll_server::SimpleEpollServer epoll_server; QuicEpollClock clock(&epoll_server); quic::QuicTime last_now = clock.Now(); @@ -61,7 +61,7 @@ } TEST_F(QuicEpollClockTest, MonotonicityWithFakeEpollClock) { - FakeEpollServer epoll_server; + epoll_server::test::FakeSimpleEpollServer epoll_server; QuicEpollClock clock(&epoll_server); epoll_server.set_now_in_usec(100);
diff --git a/net/quic/platform/impl/quic_epoll_impl.h b/net/quic/platform/impl/quic_epoll_impl.h index 94a5b0b0..f53ef8b 100644 --- a/net/quic/platform/impl/quic_epoll_impl.h +++ b/net/quic/platform/impl/quic_epoll_impl.h
@@ -10,14 +10,14 @@ #ifndef NET_QUIC_PLATFORM_IMPL_QUIC_EPOLL_IMPL_H_ #define NET_QUIC_PLATFORM_IMPL_QUIC_EPOLL_IMPL_H_ -#include "net/tools/epoll_server/epoll_server.h" +#include "net/third_party/quiche/src/epoll_server/simple_epoll_server.h" namespace quic { -using QuicEpollServerImpl = ::net::EpollServer; -using QuicEpollEventImpl = ::net::EpollEvent; -using QuicEpollAlarmBaseImpl = ::net::EpollAlarm; -using QuicEpollCallbackInterfaceImpl = ::net::EpollCallbackInterface; +using QuicEpollServerImpl = epoll_server::SimpleEpollServer; +using QuicEpollEventImpl = epoll_server::EpollEvent; +using QuicEpollAlarmBaseImpl = epoll_server::EpollAlarm; +using QuicEpollCallbackInterfaceImpl = epoll_server::EpollCallbackInterface; } // namespace quic
diff --git a/net/quic/platform/impl/quic_epoll_test_tools_impl.h b/net/quic/platform/impl/quic_epoll_test_tools_impl.h index ed7443c0..1cde56a 100644 --- a/net/quic/platform/impl/quic_epoll_test_tools_impl.h +++ b/net/quic/platform/impl/quic_epoll_test_tools_impl.h
@@ -5,8 +5,8 @@ #ifndef NET_QUIC_PLATFORM_IMPL_QUIC_EPOLL_TEST_TOOLS_IMPL_H_ #define NET_QUIC_PLATFORM_IMPL_QUIC_EPOLL_TEST_TOOLS_IMPL_H_ -#include "net/tools/epoll_server/fake_epoll_server.h" +#include "net/third_party/quiche/src/epoll_server/fake_simple_epoll_server.h" -using QuicFakeEpollServerImpl = quic::test::FakeEpollServer; +using QuicFakeEpollServerImpl = epoll_server::test::FakeSimpleEpollServer; #endif // NET_QUIC_PLATFORM_IMPL_QUIC_EPOLL_TEST_TOOLS_IMPL_H_
diff --git a/net/reporting/reporting_test_util.cc b/net/reporting/reporting_test_util.cc index c78789f..c9383f9a 100644 --- a/net/reporting/reporting_test_util.cc +++ b/net/reporting/reporting_test_util.cc
@@ -283,4 +283,70 @@ return tick_clock()->NowTicks() + base::TimeDelta::FromDays(1); } +TestReportingService::Report::Report() = default; + +TestReportingService::Report::Report(Report&& other) + : url(other.url), + user_agent(other.user_agent), + group(other.group), + type(other.type), + body(std::move(other.body)), + depth(other.depth) {} + +TestReportingService::Report::Report(const GURL& url, + const std::string& user_agent, + const std::string& group, + const std::string& type, + std::unique_ptr<const base::Value> body, + int depth) + : url(url), + user_agent(user_agent), + group(group), + type(type), + body(std::move(body)), + depth(depth) {} + +TestReportingService::Report::~Report() = default; + +TestReportingService::TestReportingService() = default; + +TestReportingService::~TestReportingService() = default; + +void TestReportingService::QueueReport(const GURL& url, + const std::string& user_agent, + const std::string& group, + const std::string& type, + std::unique_ptr<const base::Value> body, + int depth) { + reports_.push_back( + Report(url, user_agent, group, type, std::move(body), depth)); +} + +void TestReportingService::ProcessHeader(const GURL& url, + const std::string& header_value) { + NOTREACHED(); +} + +void TestReportingService::RemoveBrowsingData( + int data_type_mask, + const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { + NOTREACHED(); +} + +void TestReportingService::RemoveAllBrowsingData(int data_type_mask) { + NOTREACHED(); +} + +void TestReportingService::OnShutdown() {} + +const ReportingPolicy& TestReportingService::GetPolicy() const { + NOTREACHED(); + return dummy_policy_; +} + +ReportingContext* TestReportingService::GetContextForTesting() const { + NOTREACHED(); + return nullptr; +} + } // namespace net
diff --git a/net/reporting/reporting_test_util.h b/net/reporting/reporting_test_util.h index b6a558c..f290c3de 100644 --- a/net/reporting/reporting_test_util.h +++ b/net/reporting/reporting_test_util.h
@@ -16,8 +16,10 @@ #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_context.h" #include "net/reporting/reporting_delegate.h" +#include "net/reporting/reporting_service.h" #include "net/reporting/reporting_uploader.h" #include "net/test/test_with_scoped_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -38,6 +40,15 @@ class ReportingGarbageCollector; class TestURLRequestContext; +// A matcher for ReportingReports, which checks that the url of the report is +// the given url. +// Usage: EXPECT_THAT(report, ReportUrlIs(url)); +// EXPECT_THAT(reports(), +// testing::ElementsAre(ReportUrlIs(url1), ReportUrlIs(url2))); +MATCHER_P(ReportUrlIs, url, "") { + return arg.url == url; +} + // A test implementation of ReportingUploader that holds uploads for tests to // examine and complete with a specified outcome. class TestReportingUploader : public ReportingUploader { @@ -267,6 +278,69 @@ DISALLOW_COPY_AND_ASSIGN(ReportingTestBase); }; +class TestReportingService : public ReportingService { + public: + struct Report { + Report(); + + Report(Report&& other); + + Report(const GURL& url, + const std::string& user_agent, + const std::string& group, + const std::string& type, + std::unique_ptr<const base::Value> body, + int depth); + + ~Report(); + + GURL url; + std::string user_agent; + std::string group; + std::string type; + std::unique_ptr<const base::Value> body; + int depth; + + private: + DISALLOW_COPY(Report); + }; + + TestReportingService(); + + const std::vector<Report>& reports() const { return reports_; } + + // ReportingService implementation: + + ~TestReportingService() override; + + void QueueReport(const GURL& url, + const std::string& user_agent, + const std::string& group, + const std::string& type, + std::unique_ptr<const base::Value> body, + int depth) override; + + void ProcessHeader(const GURL& url, const std::string& header_value) override; + + void RemoveBrowsingData( + int data_type_mask, + const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override; + + void RemoveAllBrowsingData(int data_type_mask) override; + + void OnShutdown() override; + + const ReportingPolicy& GetPolicy() const override; + + ReportingContext* GetContextForTesting() const override; + + private: + std::vector<Report> reports_; + ReportingPolicy dummy_policy_; + + DISALLOW_COPY_AND_ASSIGN(TestReportingService); +}; + } // namespace net #endif // NET_REPORTING_REPORTING_TEST_UTIL_H_
diff --git a/net/tools/epoll_server/epoll_server.cc b/net/tools/epoll_server/epoll_server.cc deleted file mode 100644 index a686dd7d..0000000 --- a/net/tools/epoll_server/epoll_server.cc +++ /dev/null
@@ -1,809 +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 "net/tools/epoll_server/epoll_server.h" - -#include <unistd.h> // For read, pipe, close and write. -#include <stdlib.h> // for abort -#include <errno.h> // for errno and strerror_r -#include <algorithm> -#include <utility> - -#include "base/auto_reset.h" -#include "base/logging.h" -#include "base/stl_util.h" -#include "base/time/time.h" - -// Design notes: An efficient implementation of ready list has the following -// desirable properties: -// -// A. O(1) insertion into/removal from the list in any location. -// B. Once the callback is found by hash lookup using the fd, the lookup of -// corresponding entry in the list is O(1). -// C. Safe insertion into/removal from the list during list iteration. (The -// ready list's purpose is to enable completely event driven I/O model. -// Thus, all the interesting bits happen in the callback. It is critical -// to not place any restriction on the API during list iteration. -// -// The current implementation achieves these goals with the following design: -// -// - The ready list is constructed as a doubly linked list to enable O(1) -// insertion/removal (see man 3 queue). -// - The forward and backward links are directly embedded inside the -// CBAndEventMask struct. This enables O(1) lookup in the list for a given -// callback. (Techincally, we could've used std::list of hash_set::iterator, -// and keep a list::iterator in CBAndEventMask to achieve the same effect. -// However, iterators have two problems: no way to portably invalidate them, -// and no way to tell whether an iterator is singular or not. The only way to -// overcome these issues is to keep bools in both places, but that throws off -// memory alignment (up to 7 wasted bytes for each bool). The extra level of -// indirection will also likely be less cache friendly. Direct manipulation -// of link pointers makes it easier to retrieve the CBAndEventMask from the -// list, easier to check whether an CBAndEventMask is in the list, uses less -// memory (save 32 bytes/fd), and does not affect cache usage (we need to -// read in the struct to use the callback anyway).) -// - Embed the fd directly into CBAndEventMask and switch to using hash_set. -// This removes the need to store hash_map::iterator in the list just so that -// we can get both the fd and the callback. -// - The ready list is "one shot": each entry is removed before OnEvent is -// called. This removes the mutation-while-iterating problem. -// - Use two lists to keep track of callbacks. The ready_list_ is the one used -// for registration. Before iteration, the ready_list_ is swapped into the -// tmp_list_. Once iteration is done, tmp_list_ will be empty, and -// ready_list_ will have all the new ready fds. - -// The size we use for buffers passed to strerror_r -static const int kErrorBufferSize = 256; - -namespace net { - -// Clears the pipe and returns. Used for waking the epoll server up. -class ReadPipeCallback : public EpollCallbackInterface { - public: - void OnEvent(int fd, EpollEvent* event) override { - DCHECK(event->in_events == EPOLLIN); - int data; - int data_read = 1; - // Read until the pipe is empty. - while (data_read > 0) { - data_read = read(fd, &data, sizeof(data)); - } - } - void OnShutdown(EpollServer* eps, int fd) override {} - void OnRegistration(EpollServer*, int, int) override {} - void OnModification(int, int) override {} // COV_NF_LINE - void OnUnregistration(int, bool) override {} // COV_NF_LINE - std::string Name() const override { return "ReadPipeCallback"; } -}; - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -EpollServer::EpollServer() - : epoll_fd_(epoll_create(1024)), - timeout_in_us_(0), - recorded_now_in_us_(0), - ready_list_size_(0), - wake_cb_(new ReadPipeCallback), - read_fd_(-1), - write_fd_(-1), - in_wait_for_events_and_execute_callbacks_(false), - in_shutdown_(false) { - // ensure that the epoll_fd_ is valid. - CHECK_NE(epoll_fd_, -1); - LIST_INIT(&ready_list_); - LIST_INIT(&tmp_list_); - - int pipe_fds[2]; - if (pipe(pipe_fds) < 0) { - // Unfortunately, it is impossible to test any such initialization in - // a constructor (as virtual methods do not yet work). - // This -could- be solved by moving initialization to an outside - // call... - int saved_errno = errno; - char buf[kErrorBufferSize]; - LOG(FATAL) << "Error " << saved_errno - << " in pipe(): " << strerror_r(saved_errno, buf, sizeof(buf)); - } - read_fd_ = pipe_fds[0]; - write_fd_ = pipe_fds[1]; - RegisterFD(read_fd_, wake_cb_.get(), EPOLLIN); -} - -void EpollServer::CleanupFDToCBMap() { - auto cb_iter = cb_map_.begin(); - while (cb_iter != cb_map_.end()) { - int fd = cb_iter->fd; - CB* cb = cb_iter->cb; - - cb_iter->in_use = true; - if (cb) { - cb->OnShutdown(this, fd); - } - - cb_map_.erase(cb_iter); - cb_iter = cb_map_.begin(); - } -} - -void EpollServer::CleanupTimeToAlarmCBMap() { - TimeToAlarmCBMap::iterator erase_it; - - // Call OnShutdown() on alarms. Note that the structure of the loop - // is similar to the structure of loop in the function HandleAlarms() - for (auto i = alarm_map_.begin(); i != alarm_map_.end();) { - // Note that OnShutdown() can call UnregisterAlarm() on - // other iterators. OnShutdown() should not call UnregisterAlarm() - // on self because by definition the iterator is not valid any more. - i->second->OnShutdown(this); - erase_it = i; - ++i; - alarm_map_.erase(erase_it); - } -} - -EpollServer::~EpollServer() { - DCHECK_EQ(in_shutdown_, false); - in_shutdown_ = true; -#ifdef EPOLL_SERVER_EVENT_TRACING - LOG(INFO) << "\n" << event_recorder_; -#endif - VLOG(2) << "Shutting down epoll server "; - CleanupFDToCBMap(); - - LIST_INIT(&ready_list_); - LIST_INIT(&tmp_list_); - - CleanupTimeToAlarmCBMap(); - - close(read_fd_); - close(write_fd_); - close(epoll_fd_); -} - -// Whether a CBAandEventMask is on the ready list is determined by a non-NULL -// le_prev pointer (le_next being NULL indicates end of list). -inline void EpollServer::AddToReadyList(CBAndEventMask* cb_and_mask) { - if (cb_and_mask->entry.le_prev == NULL) { - LIST_INSERT_HEAD(&ready_list_, cb_and_mask, entry); - ++ready_list_size_; - } -} - -inline void EpollServer::RemoveFromReadyList( - const CBAndEventMask& cb_and_mask) { - if (cb_and_mask.entry.le_prev != NULL) { - LIST_REMOVE(&cb_and_mask, entry); - // Clean up all the ready list states. Don't bother with the other fields - // as they are initialized when the CBAandEventMask is added to the ready - // list. This saves a few cycles in the inner loop. - cb_and_mask.entry.le_prev = NULL; - --ready_list_size_; - if (ready_list_size_ == 0) { - DCHECK(ready_list_.lh_first == NULL); - DCHECK(tmp_list_.lh_first == NULL); - } - } -} - -void EpollServer::RegisterFD(int fd, CB* cb, int event_mask) { - CHECK(cb); - VLOG(3) << "RegisterFD fd=" << fd << " event_mask=" << event_mask; - auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); - if (cb_map_.end() != fd_i) { - // do we just abort, or do we just unregister the other callback? - // for now, lets just unregister the other callback. - - // unregister any callback that may already be registered for this FD. - CB* other_cb = fd_i->cb; - if (other_cb) { - // Must remove from the ready list before erasing. - RemoveFromReadyList(*fd_i); - other_cb->OnUnregistration(fd, true); - ModFD(fd, event_mask); - } else { - // already unregistered, so just recycle the node. - AddFD(fd, event_mask); - } - fd_i->cb = cb; - fd_i->event_mask = event_mask; - fd_i->events_to_fake = 0; - } else { - AddFD(fd, event_mask); - cb_map_.insert(CBAndEventMask(cb, event_mask, fd)); - } - - - // set the FD to be non-blocking. - SetNonblocking(fd); - - cb->OnRegistration(this, fd, event_mask); -} - -void EpollServer::SetNonblocking(int fd) { - int flags = fcntl(fd, F_GETFL, 0); - if (flags == -1) { - int saved_errno = errno; - char buf[kErrorBufferSize]; - LOG(FATAL) << "Error " << saved_errno - << " doing fcntl(" << fd << ", F_GETFL, 0): " - << strerror_r(saved_errno, buf, sizeof(buf)); - } - if (!(flags & O_NONBLOCK)) { - int saved_flags = flags; - flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK); - if (flags == -1) { - // bad. - int saved_errno = errno; - char buf[kErrorBufferSize]; - LOG(FATAL) << "Error " << saved_errno - << " doing fcntl(" << fd << ", F_SETFL, " << saved_flags << "): " - << strerror_r(saved_errno, buf, sizeof(buf)); - } - } -} - -int EpollServer::epoll_wait_impl(int epfd, - struct epoll_event* events, - int max_events, - int timeout_in_ms) { - return epoll_wait(epfd, events, max_events, timeout_in_ms); -} - -void EpollServer::RegisterFDForWrite(int fd, CB* cb) { - RegisterFD(fd, cb, EPOLLOUT); -} - -void EpollServer::RegisterFDForReadWrite(int fd, CB* cb) { - RegisterFD(fd, cb, EPOLLIN | EPOLLOUT); -} - -void EpollServer::RegisterFDForRead(int fd, CB* cb) { - RegisterFD(fd, cb, EPOLLIN); -} - -void EpollServer::UnregisterFD(int fd) { - auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); - if (cb_map_.end() == fd_i || fd_i->cb == NULL) { - // Doesn't exist in server, or has gone through UnregisterFD once and still - // inside the callchain of OnEvent. - return; - } -#ifdef EPOLL_SERVER_EVENT_TRACING - event_recorder_.RecordUnregistration(fd); -#endif - CB* cb = fd_i->cb; - // Since the links are embedded within the struct, we must remove it from the - // list before erasing it from the hash_set. - RemoveFromReadyList(*fd_i); - DelFD(fd); - cb->OnUnregistration(fd, false); - // fd_i->cb is NULL if that fd is unregistered inside the callchain of - // OnEvent. Since the EpollServer needs a valid CBAndEventMask after OnEvent - // returns in order to add it to the ready list, we cannot have UnregisterFD - // erase the entry if it is in use. Thus, a NULL fd_i->cb is used as a - // condition that tells the EpollServer that this entry is unused at a later - // point. - if (!fd_i->in_use) { - cb_map_.erase(fd_i); - } else { - // Remove all trace of the registration, and just keep the node alive long - // enough so the code that calls OnEvent doesn't have to worry about - // figuring out whether the CBAndEventMask is valid or not. - fd_i->cb = NULL; - fd_i->event_mask = 0; - fd_i->events_to_fake = 0; - } -} - -void EpollServer::ModifyCallback(int fd, int event_mask) { - ModifyFD(fd, ~0, event_mask); -} - -void EpollServer::StopRead(int fd) { - ModifyFD(fd, EPOLLIN, 0); -} - -void EpollServer::StartRead(int fd) { - ModifyFD(fd, 0, EPOLLIN); -} - -void EpollServer::StopWrite(int fd) { - ModifyFD(fd, EPOLLOUT, 0); -} - -void EpollServer::StartWrite(int fd) { - ModifyFD(fd, 0, EPOLLOUT); -} - -void EpollServer::HandleEvent(int fd, int event_mask) { -#ifdef EPOLL_SERVER_EVENT_TRACING - event_recorder_.RecordEpollEvent(fd, event_mask); -#endif - auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); - if (fd_i == cb_map_.end() || fd_i->cb == NULL) { - // Ignore the event. - // This could occur if epoll() returns a set of events, and - // while processing event A (earlier) we removed the callback - // for event B (and are now processing event B). - return; - } - fd_i->events_asserted = event_mask; - CBAndEventMask* cb_and_mask = const_cast<CBAndEventMask*>(&*fd_i); - AddToReadyList(cb_and_mask); -} - -void EpollServer::WaitForEventsAndExecuteCallbacks() { - if (in_wait_for_events_and_execute_callbacks_) { - LOG(DFATAL) << - "Attempting to call WaitForEventsAndExecuteCallbacks" - " when an ancestor to the current function is already" - " WaitForEventsAndExecuteCallbacks!"; - // The line below is actually tested, but in coverage mode, - // we never see it. - return; // COV_NF_LINE - } - base::AutoReset<bool> recursion_guard( - &in_wait_for_events_and_execute_callbacks_, true); - if (alarm_map_.empty()) { - // no alarms, this is business as usual. - WaitForEventsAndCallHandleEvents(timeout_in_us_, - events_, - events_size_); - recorded_now_in_us_ = 0; - return; - } - - // store the 'now'. If we recomputed 'now' every iteration - // down below, then we might never exit that loop-- any - // long-running alarms might install other long-running - // alarms, etc. By storing it here now, we ensure that - // a more reasonable amount of work is done here. - int64_t now_in_us = NowInUsec(); - - // Get the first timeout from the alarm_map where it is - // stored in absolute time. - int64_t next_alarm_time_in_us = alarm_map_.begin()->first; - VLOG(4) << "next_alarm_time = " << next_alarm_time_in_us - << " now = " << now_in_us - << " timeout_in_us = " << timeout_in_us_; - - int64_t wait_time_in_us; - int64_t alarm_timeout_in_us = next_alarm_time_in_us - now_in_us; - - // If the next alarm is sooner than the default timeout, or if there is no - // timeout (timeout_in_us_ == -1), wake up when the alarm should fire. - // Otherwise use the default timeout. - if (alarm_timeout_in_us < timeout_in_us_ || timeout_in_us_ < 0) { - wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64_t>(0)); - } else { - wait_time_in_us = timeout_in_us_; - } - - VLOG(4) << "wait_time_in_us = " << wait_time_in_us; - - // wait for events. - - WaitForEventsAndCallHandleEvents(wait_time_in_us, - events_, - events_size_); - CallAndReregisterAlarmEvents(); - recorded_now_in_us_ = 0; -} - -void EpollServer::SetFDReady(int fd, int events_to_fake) { - auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); - if (cb_map_.end() != fd_i && fd_i->cb != NULL) { - // This const_cast is necessary for LIST_HEAD_INSERT to work. Declaring - // entry mutable is insufficient because LIST_HEAD_INSERT assigns the - // forward pointer of the list head to the current cb_and_mask, and the - // compiler complains that it can't assign a const T* to a T*. - CBAndEventMask* cb_and_mask = const_cast<CBAndEventMask*>(&*fd_i); - // Note that there is no clearly correct behavior here when - // cb_and_mask->events_to_fake != 0 and this function is called. - // Of the two operations: - // cb_and_mask->events_to_fake = events_to_fake - // cb_and_mask->events_to_fake |= events_to_fake - // the first was picked because it discourages users from calling - // SetFDReady repeatedly to build up the correct event set as it is more - // efficient to call SetFDReady once with the correct, final mask. - cb_and_mask->events_to_fake = events_to_fake; - AddToReadyList(cb_and_mask); - } -} - -void EpollServer::SetFDNotReady(int fd) { - auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); - if (cb_map_.end() != fd_i) { - RemoveFromReadyList(*fd_i); - } -} - -bool EpollServer::IsFDReady(int fd) const { - auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); - return (cb_map_.end() != fd_i && - fd_i->cb != NULL && - fd_i->entry.le_prev != NULL); -} - -void EpollServer::VerifyReadyList() const { - int count = 0; - CBAndEventMask* cur = ready_list_.lh_first; - for (; cur; cur = cur->entry.le_next) { - ++count; - } - for (cur = tmp_list_.lh_first; cur; cur = cur->entry.le_next) { - ++count; - } - CHECK_EQ(ready_list_size_, count) << "Ready list size does not match count"; -} - -void EpollServer::RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac) { - CHECK(ac); - if (base::ContainsKey(all_alarms_, ac)) { - LOG(FATAL) << "Alarm already exists " << ac; - } - VLOG(4) << "RegisteringAlarm at : " << timeout_time_in_us; - - auto alarm_iter = alarm_map_.insert(std::make_pair(timeout_time_in_us, ac)); - - all_alarms_.insert(ac); - // Pass the iterator to the EpollAlarmCallbackInterface. - ac->OnRegistration(alarm_iter, this); -} - -// Unregister a specific alarm callback: iterator_token must be a -// valid iterator. The caller must ensure the validity of the iterator. -void EpollServer::UnregisterAlarm(const AlarmRegToken& iterator_token) { - AlarmCB* cb = iterator_token->second; - alarm_map_.erase(iterator_token); - all_alarms_.erase(cb); - cb->OnUnregistration(); -} - -EpollServer::AlarmRegToken EpollServer::ReregisterAlarm( - EpollServer::AlarmRegToken iterator_token, - int64_t timeout_time_in_us) { - AlarmCB* cb = iterator_token->second; - alarm_map_.erase(iterator_token); - return alarm_map_.emplace(timeout_time_in_us, cb); -} - -int EpollServer::NumFDsRegistered() const { - DCHECK_GE(cb_map_.size(), 1u); - // Omit the internal FD (read_fd_) - return cb_map_.size() - 1; -} - -void EpollServer::Wake() { - char data = 'd'; // 'd' is for data. It's good enough for me. - int rv = write(write_fd_, &data, 1); - DCHECK_EQ(rv, 1); -} - -int64_t EpollServer::NowInUsec() const { - return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); -} - -int64_t EpollServer::ApproximateNowInUsec() const { - if (recorded_now_in_us_ != 0) { - return recorded_now_in_us_; - } - return this->NowInUsec(); -} - -std::string EpollServer::EventMaskToString(int event_mask) { - std::string s; - if (event_mask & EPOLLIN) s += "EPOLLIN "; - if (event_mask & EPOLLPRI) s += "EPOLLPRI "; - if (event_mask & EPOLLOUT) s += "EPOLLOUT "; - if (event_mask & EPOLLRDNORM) s += "EPOLLRDNORM "; - if (event_mask & EPOLLRDBAND) s += "EPOLLRDBAND "; - if (event_mask & EPOLLWRNORM) s += "EPOLLWRNORM "; - if (event_mask & EPOLLWRBAND) s += "EPOLLWRBAND "; - if (event_mask & EPOLLMSG) s += "EPOLLMSG "; - if (event_mask & EPOLLERR) s += "EPOLLERR "; - if (event_mask & EPOLLHUP) s += "EPOLLHUP "; - if (event_mask & EPOLLONESHOT) s += "EPOLLONESHOT "; - if (event_mask & EPOLLET) s += "EPOLLET "; - return s; -} - -void EpollServer::LogStateOnCrash() { - LOG(ERROR) << "----------------------Epoll Server---------------------------"; - LOG(ERROR) << "Epoll server " << this << " polling on fd " << epoll_fd_; - LOG(ERROR) << "timeout_in_us_: " << timeout_in_us_; - - // Log sessions with alarms. - LOG(ERROR) << alarm_map_.size() << " alarms registered."; - for (auto it = alarm_map_.begin(); it != alarm_map_.end(); ++it) { - const bool skipped = - alarms_reregistered_and_should_be_skipped_.find(it->second) - != alarms_reregistered_and_should_be_skipped_.end(); - LOG(ERROR) << "Alarm " << it->second << " registered at time " << it->first - << " and should be skipped = " << skipped; - } - - LOG(ERROR) << cb_map_.size() << " fd callbacks registered."; - for (auto it = cb_map_.begin(); it != cb_map_.end(); ++it) { - LOG(ERROR) << "fd: " << it->fd << " with mask " << it->event_mask - << " registered with cb: " << it->cb; - } - LOG(ERROR) << "----------------------/Epoll Server--------------------------"; -} - - - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -void EpollServer::DelFD(int fd) const { - struct epoll_event ee; - memset(&ee, 0, sizeof(ee)); -#ifdef EPOLL_SERVER_EVENT_TRACING - event_recorder_.RecordFDMaskEvent(fd, 0, "DelFD"); -#endif - if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee)) { - int saved_errno = errno; - char buf[kErrorBufferSize]; - LOG(FATAL) << "Epoll set removal error for fd " << fd << ": " - << strerror_r(saved_errno, buf, sizeof(buf)); - } -} - -//////////////////////////////////////// - -void EpollServer::AddFD(int fd, int event_mask) const { - struct epoll_event ee; - memset(&ee, 0, sizeof(ee)); - ee.events = event_mask | EPOLLERR | EPOLLHUP; - ee.data.fd = fd; -#ifdef EPOLL_SERVER_EVENT_TRACING - event_recorder_.RecordFDMaskEvent(fd, ee.events, "AddFD"); -#endif - if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ee)) { - int saved_errno = errno; - char buf[kErrorBufferSize]; - LOG(FATAL) << "Epoll set insertion error for fd " << fd << ": " - << strerror_r(saved_errno, buf, sizeof(buf)); - } -} - -//////////////////////////////////////// - -void EpollServer::ModFD(int fd, int event_mask) const { - struct epoll_event ee; - memset(&ee, 0, sizeof(ee)); - ee.events = event_mask | EPOLLERR | EPOLLHUP; - ee.data.fd = fd; -#ifdef EPOLL_SERVER_EVENT_TRACING - event_recorder_.RecordFDMaskEvent(fd, ee.events, "ModFD"); -#endif - VLOG(3) << "modifying fd= " << fd << " " - << EventMaskToString(ee.events); - if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &ee)) { - int saved_errno = errno; - char buf[kErrorBufferSize]; - LOG(FATAL) << "Epoll set modification error for fd " << fd << ": " - << strerror_r(saved_errno, buf, sizeof(buf)); - } -} - -//////////////////////////////////////// - -void EpollServer::ModifyFD(int fd, int remove_event, int add_event) { - auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd)); - if (cb_map_.end() == fd_i) { - VLOG(2) << "Didn't find the fd " << fd << "in internal structures"; - return; - } - - if (fd_i->cb != NULL) { - int & event_mask = fd_i->event_mask; - VLOG(3) << "fd= " << fd - << " event_mask before: " << EventMaskToString(event_mask); - event_mask &= ~remove_event; - event_mask |= add_event; - - VLOG(3) << " event_mask after: " << EventMaskToString(event_mask); - - ModFD(fd, event_mask); - - fd_i->cb->OnModification(fd, event_mask); - } -} - -void EpollServer::WaitForEventsAndCallHandleEvents(int64_t timeout_in_us, - struct epoll_event events[], - int events_size) { - if (timeout_in_us == 0 || ready_list_.lh_first != NULL) { - // If ready list is not empty, then don't sleep at all. - timeout_in_us = 0; - } else if (timeout_in_us < 0) { - LOG(INFO) << "Negative epoll timeout: " << timeout_in_us - << "us; epoll will wait forever for events."; - // If timeout_in_us is < 0 we are supposed to Wait forever. This means we - // should set timeout_in_us to -1000 so we will - // Wait(-1000/1000) == Wait(-1) == Wait forever. - timeout_in_us = -1000; - } else { - // If timeout is specified, and the ready list is empty. - if (timeout_in_us < 1000) { - timeout_in_us = 1000; - } - } - const int timeout_in_ms = timeout_in_us / 1000; - int nfds = epoll_wait_impl(epoll_fd_, - events, - events_size, - timeout_in_ms); - VLOG(3) << "nfds=" << nfds; - -#ifdef EPOLL_SERVER_EVENT_TRACING - event_recorder_.RecordEpollWaitEvent(timeout_in_ms, nfds); -#endif - - // If you're wondering why the NowInUsec() is recorded here, the answer is - // simple: If we did it before the epoll_wait_impl, then the max error for - // the ApproximateNowInUs() call would be as large as the maximum length of - // epoll_wait, which can be arbitrarily long. Since this would make - // ApproximateNowInUs() worthless, we instead record the time -after- we've - // done epoll_wait, which guarantees that the maximum error is the amount of - // time it takes to process all the events generated by epoll_wait. - recorded_now_in_us_ = NowInUsec(); - if (nfds > 0) { - for (int i = 0; i < nfds; ++i) { - int event_mask = events[i].events; - int fd = events[i].data.fd; - HandleEvent(fd, event_mask); - } - } else if (nfds < 0) { - // Catch interrupted syscall and just ignore it and move on. - if (errno != EINTR && errno != 0) { - int saved_errno = errno; - char buf[kErrorBufferSize]; - LOG(FATAL) << "Error " << saved_errno << " in epoll_wait: " - << strerror_r(saved_errno, buf, sizeof(buf)); - } - } - - // Now run through the ready list. - if (ready_list_.lh_first) { - CallReadyListCallbacks(); - } -} - -void EpollServer::CallReadyListCallbacks() { - // Check pre-conditions. - DCHECK(tmp_list_.lh_first == NULL); - // Swap out the ready_list_ into the tmp_list_ before traversing the list to - // enable SetFDReady() to just push new items into the ready_list_. - std::swap(ready_list_.lh_first, tmp_list_.lh_first); - if (tmp_list_.lh_first) { - tmp_list_.lh_first->entry.le_prev = &tmp_list_.lh_first; - EpollEvent event(0); - while (tmp_list_.lh_first != NULL) { - DCHECK_GT(ready_list_size_, 0); - CBAndEventMask* cb_and_mask = tmp_list_.lh_first; - RemoveFromReadyList(*cb_and_mask); - - event.out_ready_mask = 0; - event.in_events = - cb_and_mask->events_asserted | cb_and_mask->events_to_fake; - // TODO(fenix): get rid of the two separate fields in cb_and_mask. - cb_and_mask->events_asserted = 0; - cb_and_mask->events_to_fake = 0; - { - // OnEvent() may call UnRegister, so we set in_use, here. Any - // UnRegister call will now simply set the cb to NULL instead of - // invalidating the cb_and_mask object (by deleting the object in the - // map to which cb_and_mask refers) - base::AutoReset<bool> in_use_guard(&(cb_and_mask->in_use), true); - cb_and_mask->cb->OnEvent(cb_and_mask->fd, &event); - } - - // Since OnEvent may have called UnregisterFD, we must check here that - // the callback is still valid. If it isn't, then UnregisterFD *was* - // called, and we should now get rid of the object. - if (cb_and_mask->cb == NULL) { - cb_map_.erase(*cb_and_mask); - } else if (event.out_ready_mask != 0) { - cb_and_mask->events_to_fake = event.out_ready_mask; - AddToReadyList(cb_and_mask); - } - } - } - DCHECK(tmp_list_.lh_first == NULL); -} - -void EpollServer::CallAndReregisterAlarmEvents() { - int64_t now_in_us = recorded_now_in_us_; - DCHECK_NE(0, recorded_now_in_us_); - - TimeToAlarmCBMap::iterator erase_it; - - // execute alarms. - for (auto i = alarm_map_.begin(); i != alarm_map_.end();) { - if (i->first > now_in_us) { - break; - } - AlarmCB* cb = i->second; - // Execute the OnAlarm() only if we did not register - // it in this loop itself. - const bool added_in_this_round = - alarms_reregistered_and_should_be_skipped_.find(cb) - != alarms_reregistered_and_should_be_skipped_.end(); - if (added_in_this_round) { - ++i; - continue; - } - all_alarms_.erase(cb); - const int64_t new_timeout_time_in_us = cb->OnAlarm(); - - erase_it = i; - ++i; - alarm_map_.erase(erase_it); - - if (new_timeout_time_in_us > 0) { - // We add to hash_set only if the new timeout is <= now_in_us. - // if timeout is > now_in_us then we have no fear that this alarm - // can be reexecuted in this loop, and hence we do not need to - // worry about a recursive loop. - DVLOG(3) << "Reregistering alarm " - << " " << cb - << " " << new_timeout_time_in_us - << " " << now_in_us; - if (new_timeout_time_in_us <= now_in_us) { - alarms_reregistered_and_should_be_skipped_.insert(cb); - } - RegisterAlarm(new_timeout_time_in_us, cb); - } - } - alarms_reregistered_and_should_be_skipped_.clear(); -} - -EpollAlarm::EpollAlarm() : eps_(NULL), registered_(false) { -} - -EpollAlarm::~EpollAlarm() { - UnregisterIfRegistered(); -} - -int64_t EpollAlarm::OnAlarm() { - registered_ = false; - return 0; -} - -void EpollAlarm::OnRegistration(const EpollServer::AlarmRegToken& token, - EpollServer* eps) { - DCHECK_EQ(false, registered_); - - token_ = token; - eps_ = eps; - registered_ = true; -} - -void EpollAlarm::OnUnregistration() { - registered_ = false; -} - -void EpollAlarm::OnShutdown(EpollServer* eps) { - registered_ = false; - eps_ = NULL; -} - -// If the alarm was registered, unregister it. -void EpollAlarm::UnregisterIfRegistered() { - if (!registered_) { - return; - } - eps_->UnregisterAlarm(token_); -} - -void EpollAlarm::ReregisterAlarm(int64_t timeout_time_in_us) { - DCHECK(registered_); - token_ = eps_->ReregisterAlarm(token_, timeout_time_in_us); -} - -} // namespace net
diff --git a/net/tools/epoll_server/epoll_server.h b/net/tools/epoll_server/epoll_server.h deleted file mode 100644 index 507c82158..0000000 --- a/net/tools/epoll_server/epoll_server.h +++ /dev/null
@@ -1,1058 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_TOOLS_EPOLL_SERVER_EPOLL_SERVER_H_ -#define NET_TOOLS_EPOLL_SERVER_EPOLL_SERVER_H_ - -#include <fcntl.h> -#include <stddef.h> -#include <stdint.h> -#include <sys/queue.h> - -#include <map> -#include <memory> -#include <string> -#include <unordered_map> -#include <unordered_set> -#include <vector> - -// #define EPOLL_SERVER_EVENT_TRACING 1 -// -// Defining EPOLL_SERVER_EVENT_TRACING -// causes code to exist which didn't before. -// This code tracks each event generated by the epollserver, -// as well as providing a per-fd-registered summary of -// events. Note that enabling this code vastly slows -// down operations, and uses substantially more -// memory. For these reasons, it should only be enabled by developers doing -// development at their workstations. -// -// A structure called 'EventRecorder' will exist when -// the macro is defined. See the EventRecorder class interface -// within the EpollServer class for more details. -#ifdef EPOLL_SERVER_EVENT_TRACING -#include <ostream> -#include "base/logging.h" -#endif - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include <sys/epoll.h> - -namespace net { - -class EpollServer; -class EpollAlarmCallbackInterface; -class ReadPipeCallback; - -struct EpollEvent { - EpollEvent(int events) - : in_events(events), - out_ready_mask(0) { - } - - int in_events; // incoming events - int out_ready_mask; // the new event mask for ready list (0 means don't - // get on the ready list). This field is always - // initialized to 0 when the event is passed to - // OnEvent. -}; - -// Callbacks which go into EpollServers are expected to derive from this class. -class EpollCallbackInterface { - public: - // Summary: - // Called when the callback is registered into a EpollServer. - // Args: - // eps - the poll server into which this callback was registered - // fd - the file descriptor which was registered - // event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc) - // which was registered (and will initially be used - // in the epoll() calls) - virtual void OnRegistration(EpollServer* eps, int fd, int event_mask) = 0; - - // Summary: - // Called when the event_mask is modified (for a file-descriptor) - // Args: - // fd - the file descriptor which was registered - // event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc) - // which was is now curren (and will be used - // in subsequent epoll() calls) - virtual void OnModification(int fd, int event_mask) = 0; - - // Summary: - // Called whenever an event occurs on the file-descriptor. - // This is where the bulk of processing is expected to occur. - // Args: - // fd - the file descriptor which was registered - // event - a struct that contains the event mask (composed of EPOLLIN, - // EPOLLOUT, etc), a flag that indicates whether this is a true - // epoll_wait event vs one from the ready list, and an output - // parameter for OnEvent to inform the EpollServer whether to put - // this fd on the ready list. - virtual void OnEvent(int fd, EpollEvent* event) = 0; - - // Summary: - // Called when the file-descriptor is unregistered from the poll-server. - // Args: - // fd - the file descriptor which was registered, and of this call, is now - // unregistered. - // replaced - If true, this callback is being replaced by another, otherwise - // it is simply being removed. - virtual void OnUnregistration(int fd, bool replaced) = 0; - - // Summary: - // Called when the epoll server is shutting down. This is different from - // OnUnregistration because the subclass may want to clean up memory. - // This is called in leiu of OnUnregistration. - // Args: - // fd - the file descriptor which was registered. - virtual void OnShutdown(EpollServer* eps, int fd) = 0; - - // Summary: - // Returns a name describing the class for use in debug/error reporting. - virtual std::string Name() const = 0; - - virtual ~EpollCallbackInterface() {} - - protected: - EpollCallbackInterface() {} -}; - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -class EpollServer { - public: - typedef EpollAlarmCallbackInterface AlarmCB; - typedef EpollCallbackInterface CB; - - typedef std::multimap<int64_t, AlarmCB*> TimeToAlarmCBMap; - typedef TimeToAlarmCBMap::iterator AlarmRegToken; - - // Summary: - // Constructor: - // By default, we don't wait any amount of time for events, and - // we suggest to the epoll-system that we're going to use on-the-order - // of 1024 FDs. - EpollServer(); - - //////////////////////////////////////// - - // Destructor - virtual ~EpollServer(); - - //////////////////////////////////////// - - // Summary - // Register a callback to be called whenever an event contained - // in the set of events included in event_mask occurs on the - // file-descriptor 'fd' - // - // Note that only one callback is allowed to be registered for - // any specific file-decriptor. - // - // If a callback is registered for a file-descriptor which has already - // been registered, then the previous callback is unregistered with - // the 'replaced' flag set to true. I.e. the previous callback's - // OnUnregistration() function is called like so: - // OnUnregistration(fd, true); - // - // The epoll server does NOT take on ownership of the callback: the callback - // creator is responsible for managing that memory. - // - // Args: - // fd - a valid file-descriptor - // cb - an instance of a subclass of EpollCallbackInterface - // event_mask - a combination of (EPOLLOUT, EPOLLIN.. etc) indicating - // the events for which the callback would like to be - // called. - virtual void RegisterFD(int fd, CB* cb, int event_mask); - - //////////////////////////////////////// - - // Summary: - // A shortcut for RegisterFD which sets things up such that the - // callback is called when 'fd' is available for writing. - // Args: - // fd - a valid file-descriptor - // cb - an instance of a subclass of EpollCallbackInterface - virtual void RegisterFDForWrite(int fd, CB* cb); - - //////////////////////////////////////// - - // Summary: - // A shortcut for RegisterFD which sets things up such that the - // callback is called when 'fd' is available for reading or writing. - // Args: - // fd - a valid file-descriptor - // cb - an instance of a subclass of EpollCallbackInterface - virtual void RegisterFDForReadWrite(int fd, CB* cb); - - //////////////////////////////////////// - - // Summary: - // A shortcut for RegisterFD which sets things up such that the - // callback is called when 'fd' is available for reading. - // Args: - // fd - a valid file-descriptor - // cb - an instance of a subclass of EpollCallbackInterface - virtual void RegisterFDForRead(int fd, CB* cb); - - //////////////////////////////////////// - - // Summary: - // Removes the FD and the associated callback from the pollserver. - // If the callback is registered with other FDs, they will continue - // to be processed using the callback without modification. - // If the file-descriptor specified is not registered in the - // epoll_server, then nothing happens as a result of this call. - // Args: - // fd - the file-descriptor which should no-longer be monitored. - virtual void UnregisterFD(int fd); - - //////////////////////////////////////// - - // Summary: - // Modifies the event mask for the file-descriptor, replacing - // the old event_mask with the new one specified here. - // If the file-descriptor specified is not registered in the - // epoll_server, then nothing happens as a result of this call. - // Args: - // fd - the fd whose event mask should be modified. - // event_mask - the new event mask. - virtual void ModifyCallback(int fd, int event_mask); - - //////////////////////////////////////// - - // Summary: - // Modifies the event mask for the file-descriptor such that we - // no longer request events when 'fd' is readable. - // If the file-descriptor specified is not registered in the - // epoll_server, then nothing happens as a result of this call. - // Args: - // fd - the fd whose event mask should be modified. - virtual void StopRead(int fd); - - //////////////////////////////////////// - - // Summary: - // Modifies the event mask for the file-descriptor such that we - // request events when 'fd' is readable. - // If the file-descriptor specified is not registered in the - // epoll_server, then nothing happens as a result of this call. - // Args: - // fd - the fd whose event mask should be modified. - virtual void StartRead(int fd); - - //////////////////////////////////////// - - // Summary: - // Modifies the event mask for the file-descriptor such that we - // no longer request events when 'fd' is writable. - // If the file-descriptor specified is not registered in the - // epoll_server, then nothing happens as a result of this call. - // Args: - // fd - the fd whose event mask should be modified. - virtual void StopWrite(int fd); - - //////////////////////////////////////// - - // Summary: - // Modifies the event mask for the file-descriptor such that we - // request events when 'fd' is writable. - // If the file-descriptor specified is not registered in the - // epoll_server, then nothing happens as a result of this call. - // Args: - // fd - the fd whose event mask should be modified. - virtual void StartWrite(int fd); - - //////////////////////////////////////// - - // Summary: - // Looks up the callback associated with the file-desriptor 'fd'. - // If a callback is associated with this file-descriptor, then - // it's OnEvent() method is called with the file-descriptor 'fd', - // and event_mask 'event_mask' - // - // If no callback is registered for this file-descriptor, nothing - // will happen as a result of this call. - // - // This function is used internally by the EpollServer, but is - // available publically so that events might be 'faked'. Calling - // this function with an fd and event_mask is equivalent (as far - // as the callback is concerned) to having a real event generated - // by epoll (except, of course, that read(), etc won't necessarily - // be able to read anything) - // Args: - // fd - the file-descriptor on which an event has occured. - // event_mask - a bitmask representing the events which have occured - // on/for this fd. This bitmask is composed of - // POLLIN, POLLOUT, etc. - // - void HandleEvent(int fd, int event_mask); - - // Summary: - // Call this when you want the pollserver to - // wait for events and execute the callbacks associated with - // the file-descriptors on which those events have occured. - // Depending on the value of timeout_in_us_, this may or may - // not return immediately. Please reference the set_timeout() - // function for the specific behaviour. - virtual void WaitForEventsAndExecuteCallbacks(); - - // Summary: - // When an fd is registered to use edge trigger notification, the ready - // list can be used to simulate level trigger semantics. Edge trigger - // registration doesn't send an initial event, and only rising edge (going - // from blocked to unblocked) events are sent. A callback can put itself on - // the ready list by calling SetFDReady() after calling RegisterFD(). The - // OnEvent method of all callbacks associated with the fds on the ready - // list will be called immediately after processing the events returned by - // epoll_wait(). The fd is removed from the ready list before the - // callback's OnEvent() method is invoked. To stay on the ready list, the - // OnEvent() (or some function in that call chain) must call SetFDReady - // again. When a fd is unregistered using UnregisterFD(), the fd is - // automatically removed from the ready list. - // - // When the callback for a edge triggered fd hits the falling edge (about - // to block, either because of it got an EAGAIN, or had a short read/write - // operation), it should remove itself from the ready list using - // SetFDNotReady() (since OnEvent cannot distinguish between invocation - // from the ready list vs from a normal epoll event). All four ready list - // methods are safe to be called within the context of the callbacks. - // - // Since the ready list invokes EpollCallbackInterface::OnEvent, only fds - // that are registered with the EpollServer will be put on the ready list. - // SetFDReady() and SetFDNotReady() will do nothing if the EpollServer - // doesn't know about the fd passed in. - // - // Since the ready list cannot reliably determine proper set of events - // which should be sent to the callback, SetFDReady() requests the caller - // to provide the ready list with the event mask, which will be used later - // when OnEvent() is invoked by the ready list. Hence, the event_mask - // passedto SetFDReady() does not affect the actual epoll registration of - // the fd with the kernel. If a fd is already put on the ready list, and - // SetFDReady() is called again for that fd with a different event_mask, - // the event_mask will be updated. - virtual void SetFDReady(int fd, int events_to_fake); - - virtual void SetFDNotReady(int fd); - - // Summary: - // IsFDReady(), ReadyListSize(), and VerifyReadyList are intended as - // debugging tools and for writing unit tests. - // ISFDReady() returns whether a fd is in the ready list. - // ReadyListSize() returns the number of fds on the ready list. - // VerifyReadyList() checks the consistency of internal data structure. It - // will CHECK if it finds an error. - virtual bool IsFDReady(int fd) const; - - size_t ReadyListSize() const { return ready_list_size_; } - - void VerifyReadyList() const; - - //////////////////////////////////////// - - // Summary: - // Registers an alarm 'ac' to go off at time 'timeout_time_in_us'. - // If the callback returns a positive number from its OnAlarm() function, - // then the callback will be re-registered at that time, else the alarm - // owner is responsible for freeing up memory. - // - // Important: A give AlarmCB* can not be registered again if it is already - // registered. If a user wants to register a callback again it should first - // unregister the previous callback before calling RegisterAlarm again. - // Args: - // timeout_time_in_us - the absolute time at which the alarm should go off - // ac - the alarm which will be called. - virtual void RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac); - - // Summary: - // Registers an alarm 'ac' to go off at time: (ApproximateNowInUs() + - // delta_in_us). While this is somewhat less accurate (see the description - // for ApproximateNowInUs() to see how 'approximate'), the error is never - // worse than the amount of time it takes to process all events in one - // WaitForEvents. As with 'RegisterAlarm()', if the callback returns a - // positive number from its OnAlarm() function, then the callback will be - // re-registered at that time, else the alarm owner is responsible for - // freeing up memory. - // Note that this function is purely a convienence. The - // same thing may be accomplished by using RegisterAlarm with - // ApproximateNowInUs() directly. - // - // Important: A give AlarmCB* can not be registered again if it is already - // registered. If a user wants to register a callback again it should first - // unregister the previous callback before calling RegisterAlarm again. - // Args: - // delta_in_us - the delta in microseconds from the ApproximateTimeInUs() at - // which point the alarm should go off. - // ac - the alarm which will be called. - void RegisterAlarmApproximateDelta(int64_t delta_in_us, AlarmCB* ac) { - RegisterAlarm(ApproximateNowInUsec() + delta_in_us, ac); - } - - //////////////////////////////////////// - - // Summary: - // Unregister the alarm referred to by iterator_token; Callers should - // be warned that a token may have become already invalid when OnAlarm() - // is called, was unregistered, or OnShutdown was called on that alarm. - // Args: - // iterator_token - iterator to the alarm callback to unregister. - virtual void UnregisterAlarm( - const EpollServer::AlarmRegToken& iterator_token); - - virtual EpollServer::AlarmRegToken ReregisterAlarm( - EpollServer::AlarmRegToken iterator_token, - int64_t timeout_time_in_us); - - //////////////////////////////////////// - - // Summary: - // returns the number of file-descriptors registered in this EpollServer. - // Returns: - // number of FDs registered (discounting the internal pipe used for Wake) - virtual int NumFDsRegistered() const; - - // Summary: - // Force the epoll server to wake up (by writing to an internal pipe). - virtual void Wake(); - - // Summary: - // Wrapper around WallTimer's NowInUsec. We do this so that we can test - // EpollServer without using the system clock (and can avoid the flakiness - // that would ensue) - // Returns: - // the current time as number of microseconds since the Unix epoch. - virtual int64_t NowInUsec() const; - - // Summary: - // Since calling NowInUsec() many thousands of times per - // WaitForEventsAndExecuteCallbacks function call is, to say the least, - // inefficient, we allow users to use an approximate time instead. The - // time returned from this function is as accurate as NowInUsec() when - // WaitForEventsAndExecuteCallbacks is not an ancestor of the caller's - // callstack. - // However, when WaitForEventsAndExecuteCallbacks -is- an ancestor, then - // this function returns the time at which the - // WaitForEventsAndExecuteCallbacks function started to process events or - // alarms. - // - // Essentially, this function makes available a fast and mostly accurate - // mechanism for getting the time for any function handling an event or - // alarm. When functions which are not handling callbacks or alarms call - // this function, they get the slow and "absolutely" accurate time. - // - // Users should be encouraged to use this function. - // Returns: - // the "approximate" current time as number of microseconds since the Unix - // epoch. - virtual int64_t ApproximateNowInUsec() const; - - static std::string EventMaskToString(int event_mask); - - // Summary: - // Logs the state of the epoll server with LOG(ERROR). - void LogStateOnCrash(); - - // Summary: - // Set the timeout to the value specified. - // If the timeout is set to a negative number, - // WaitForEventsAndExecuteCallbacks() will only return when an event has - // occured - // If the timeout is set to zero, - // WaitForEventsAndExecuteCallbacks() will return immediately - // If the timeout is set to a positive number, - // WaitForEventsAndExecuteCallbacks() will return when an event has - // occured, or when timeout_in_us microseconds has elapsed, whichever - // is first. - // Args: - // timeout_in_us - value specified depending on behaviour desired. - // See above. - void set_timeout_in_us(int64_t timeout_in_us) { - timeout_in_us_ = timeout_in_us; - } - - //////////////////////////////////////// - - // Summary: - // Accessor for the current value of timeout_in_us. - int timeout_in_us_for_test() const { return timeout_in_us_; } - - // Summary: - // Returns true when the EpollServer() is being destroyed. - bool in_shutdown() const { return in_shutdown_; } - - // Compatibility stub. - void Shutdown() {} - - protected: - virtual void SetNonblocking(int fd); - - // This exists here so that we can override this function in unittests - // in order to make effective mock EpollServer objects. - virtual int epoll_wait_impl(int epfd, - struct epoll_event* events, - int max_events, - int timeout_in_ms); - - // this struct is used internally, and is never used by anything external - // to this class. Some of its members are declared mutable to get around the - // restriction imposed by hash_set. Since hash_set knows nothing about the - // objects it stores, it has to assume that every bit of the object is used - // in the hash function and equal_to comparison. Thus hash_set::iterator is a - // const iterator. In this case, the only thing that must stay constant is - // fd. Everything else are just along for the ride and changing them doesn't - // compromise the hash_set integrity. - struct CBAndEventMask { - CBAndEventMask() - : cb(NULL), - fd(-1), - event_mask(0), - events_asserted(0), - events_to_fake(0), - in_use(false) { - entry.le_next = NULL; - entry.le_prev = NULL; - } - - CBAndEventMask(EpollCallbackInterface* cb, - int event_mask, - int fd) - : cb(cb), fd(fd), event_mask(event_mask), events_asserted(0), - events_to_fake(0), in_use(false) { - entry.le_next = NULL; - entry.le_prev = NULL; - } - - // Required operator for hash_set. Normally operator== should be a free - // standing function. However, since CBAndEventMask is a protected type and - // it will never be a base class, it makes no difference. - bool operator==(const CBAndEventMask& cb_and_mask) const { - return fd == cb_and_mask.fd; - } - // A callback. If the fd is unregistered inside the callchain of OnEvent, - // the cb will be set to NULL. - mutable EpollCallbackInterface* cb; - - mutable LIST_ENTRY(CBAndEventMask) entry; - // file descriptor registered with the epoll server. - int fd; - // the current event_mask registered for this callback. - mutable int event_mask; - // the event_mask that was returned by epoll - mutable int events_asserted; - // the event_mask for the ready list to use to call OnEvent. - mutable int events_to_fake; - // toggle around calls to OnEvent to tell UnregisterFD to not erase the - // iterator because HandleEvent is using it. - mutable bool in_use; - }; - - // Custom hash function to be used by hash_set. - struct CBAndEventMaskHash { - size_t operator()(const CBAndEventMask& cb_and_eventmask) const { - return static_cast<size_t>(cb_and_eventmask.fd); - } - }; - - using FDToCBMap = std::unordered_set<CBAndEventMask, CBAndEventMaskHash>; - - // the following four functions are OS-specific, and are likely - // to be changed in a subclass if the poll/select method is changed - // from epoll. - - // Summary: - // Deletes a file-descriptor from the set of FDs that should be - // monitored with epoll. - // Note that this only deals with modifying data relating -directly- - // with the epoll call-- it does not modify any data within the - // epoll_server. - // Args: - // fd - the file descriptor to-be-removed from the monitoring set - virtual void DelFD(int fd) const; - - //////////////////////////////////////// - - // Summary: - // Adds a file-descriptor to the set of FDs that should be - // monitored with epoll. - // Note that this only deals with modifying data relating -directly- - // with the epoll call. - // Args: - // fd - the file descriptor to-be-added to the monitoring set - // event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc - // OR'd together) which will be associated with this - // FD initially. - virtual void AddFD(int fd, int event_mask) const; - - //////////////////////////////////////// - - // Summary: - // Modifies a file-descriptor in the set of FDs that should be - // monitored with epoll. - // Note that this only deals with modifying data relating -directly- - // with the epoll call. - // Args: - // fd - the file descriptor to-be-added to the monitoring set - // event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc - // OR'd together) which will be associated with this - // FD after this call. - virtual void ModFD(int fd, int event_mask) const; - - //////////////////////////////////////// - - // Summary: - // Modified the event mask associated with an FD in the set of - // data needed by epoll. - // Events are removed before they are added, thus, if ~0 is put - // in 'remove_event', whatever is put in 'add_event' will be - // the new event mask. - // If the file-descriptor specified is not registered in the - // epoll_server, then nothing happens as a result of this call. - // Args: - // fd - the file descriptor whose event mask is to be modified - // remove_event - the events which are to be removed from the current - // event_mask - // add_event - the events which are to be added to the current event_mask - // - // - virtual void ModifyFD(int fd, int remove_event, int add_event); - - //////////////////////////////////////// - - // Summary: - // Waits for events, and calls HandleEvents() for each - // fd, event pair discovered to possibly have an event. - // Note that a callback (B) may get a spurious event if - // another callback (A) has closed a file-descriptor N, and - // the callback (B) has a newly opened file-descriptor, which - // also happens to be N. - virtual void WaitForEventsAndCallHandleEvents(int64_t timeout_in_us, - struct epoll_event events[], - int events_size); - - // Summary: - // A function for implementing the ready list. It invokes OnEvent for each - // of the fd in the ready list, and takes care of adding them back to the - // ready list if the callback requests it (by checking that out_ready_mask - // is non-zero). - void CallReadyListCallbacks(); - - // Summary: - // An internal function for implementing the ready list. It adds a fd's - // CBAndEventMask to the ready list. If the fd is already on the ready - // list, it is a no-op. - void AddToReadyList(CBAndEventMask* cb_and_mask); - - // Summary: - // An internal function for implementing the ready list. It remove a fd's - // CBAndEventMask from the ready list. If the fd is not on the ready list, - // it is a no-op. - void RemoveFromReadyList(const CBAndEventMask& cb_and_mask); - - // Summary: - // Calls any pending alarms that should go off and reregisters them if they - // were recurring. - virtual void CallAndReregisterAlarmEvents(); - - // The file-descriptor created for epolling - int epoll_fd_; - - // The mapping of file-descriptor to CBAndEventMasks - FDToCBMap cb_map_; - - // Custom hash function to be used by hash_set. - struct AlarmCBHash { - size_t operator()(AlarmCB*const& p) const { - return reinterpret_cast<size_t>(p); - } - }; - - - // TODO(sushantj): Having this hash_set is avoidable. We currently have it - // only so that we can enforce stringent checks that a caller can not register - // the same alarm twice. One option is to have an implementation in which - // this hash_set is used only in the debug mode. - using AlarmCBMap = std::unordered_set<AlarmCB*, AlarmCBHash>; - AlarmCBMap all_alarms_; - - TimeToAlarmCBMap alarm_map_; - - // The amount of time in microseconds that we'll wait before returning - // from the WaitForEventsAndExecuteCallbacks() function. - // If this is positive, wait that many microseconds. - // If this is negative, wait forever, or for the first event that occurs - // If this is zero, never wait for an event. - int64_t timeout_in_us_; - - // This is nonzero only after the invocation of epoll_wait_impl within - // WaitForEventsAndCallHandleEvents and before the function - // WaitForEventsAndExecuteCallbacks returns. At all other times, this is - // zero. This enables us to have relatively accurate time returned from the - // ApproximateNowInUs() function. See that function for more details. - int64_t recorded_now_in_us_; - - // This is used to implement CallAndReregisterAlarmEvents. This stores - // all alarms that were reregistered because OnAlarm() returned a - // value > 0 and the time at which they should be executed is less that - // the current time. By storing such alarms in this map we ensure - // that while calling CallAndReregisterAlarmEvents we do not call - // OnAlarm on any alarm in this set. This ensures that we do not - // go in an infinite loop. - AlarmCBMap alarms_reregistered_and_should_be_skipped_; - - LIST_HEAD(ReadyList, CBAndEventMask) ready_list_; - LIST_HEAD(TmpList, CBAndEventMask) tmp_list_; - int ready_list_size_; - // TODO(alyssar): make this into something that scales up. - static const int events_size_ = 256; - struct epoll_event events_[256]; - -#ifdef EPOLL_SERVER_EVENT_TRACING - struct EventRecorder { - public: - EventRecorder() : num_records_(0), record_threshold_(10000) {} - - ~EventRecorder() { - Clear(); - } - - // When a number of events equals the record threshold, - // the collected data summary for all FDs will be written - // to LOG(INFO). Note that this does not include the - // individual events (if you'reinterested in those, you'll - // have to get at them programmatically). - // After any such flushing to LOG(INFO) all events will - // be cleared. - // Note that the definition of an 'event' is a bit 'hazy', - // as it includes the 'Unregistration' event, and perhaps - // others. - void set_record_threshold(int64_t new_threshold) { - record_threshold_ = new_threshold; - } - - void Clear() { - for (int i = 0; i < debug_events_.size(); ++i) { - delete debug_events_[i]; - } - debug_events_.clear(); - unregistered_fds_.clear(); - event_counts_.clear(); - } - - void MaybeRecordAndClear() { - ++num_records_; - if ((num_records_ > record_threshold_) && - (record_threshold_ > 0)) { - LOG(INFO) << "\n" << *this; - num_records_ = 0; - Clear(); - } - } - - void RecordFDMaskEvent(int fd, int mask, const char* function) { - FDMaskOutput* fdmo = new FDMaskOutput(fd, mask, function); - debug_events_.push_back(fdmo); - MaybeRecordAndClear(); - } - - void RecordEpollWaitEvent(int timeout_in_ms, - int num_events_generated) { - EpollWaitOutput* ewo = new EpollWaitOutput(timeout_in_ms, - num_events_generated); - debug_events_.push_back(ewo); - MaybeRecordAndClear(); - } - - void RecordEpollEvent(int fd, int event_mask) { - Events& events_for_fd = event_counts_[fd]; - events_for_fd.AssignFromMask(event_mask); - MaybeRecordAndClear(); - } - - friend ostream& operator<<(ostream& os, const EventRecorder& er) { - for (int i = 0; i < er.unregistered_fds_.size(); ++i) { - os << "fd: " << er.unregistered_fds_[i] << "\n"; - os << er.unregistered_fds_[i]; - } - for (EventCountsMap::const_iterator i = er.event_counts_.begin(); - i != er.event_counts_.end(); - ++i) { - os << "fd: " << i->first << "\n"; - os << i->second; - } - for (int i = 0; i < er.debug_events_.size(); ++i) { - os << *(er.debug_events_[i]) << "\n"; - } - return os; - } - - void RecordUnregistration(int fd) { - EventCountsMap::iterator i = event_counts_.find(fd); - if (i != event_counts_.end()) { - unregistered_fds_.push_back(i->second); - event_counts_.erase(i); - } - MaybeRecordAndClear(); - } - - protected: - class DebugOutput { - public: - friend ostream& operator<<(ostream& os, const DebugOutput& debug_output) { - debug_output.OutputToStream(os); - return os; - } - virtual void OutputToStream(ostream* os) const = 0; - virtual ~DebugOutput() {} - }; - - class FDMaskOutput : public DebugOutput { - public: - FDMaskOutput(int fd, int mask, const char* function) : - fd_(fd), mask_(mask), function_(function) {} - virtual void OutputToStream(ostream* os) const { - (*os) << "func: " << function_ - << "\tfd: " << fd_; - if (mask_ != 0) { - (*os) << "\tmask: " << EventMaskToString(mask_); - } - } - int fd_; - int mask_; - const char* function_; - }; - - class EpollWaitOutput : public DebugOutput { - public: - EpollWaitOutput(int timeout_in_ms, - int num_events_generated) : - timeout_in_ms_(timeout_in_ms), - num_events_generated_(num_events_generated) {} - virtual void OutputToStream(ostream* os) const { - (*os) << "timeout_in_ms: " << timeout_in_ms_ - << "\tnum_events_generated: " << num_events_generated_; - } - protected: - int timeout_in_ms_; - int num_events_generated_; - }; - - struct Events { - Events() : - epoll_in(0), - epoll_pri(0), - epoll_out(0), - epoll_rdnorm(0), - epoll_rdband(0), - epoll_wrnorm(0), - epoll_wrband(0), - epoll_msg(0), - epoll_err(0), - epoll_hup(0), - epoll_oneshot(0), - epoll_et(0) {} - - void AssignFromMask(int event_mask) { - if (event_mask & EPOLLIN) ++epoll_in; - if (event_mask & EPOLLPRI) ++epoll_pri; - if (event_mask & EPOLLOUT) ++epoll_out; - if (event_mask & EPOLLRDNORM) ++epoll_rdnorm; - if (event_mask & EPOLLRDBAND) ++epoll_rdband; - if (event_mask & EPOLLWRNORM) ++epoll_wrnorm; - if (event_mask & EPOLLWRBAND) ++epoll_wrband; - if (event_mask & EPOLLMSG) ++epoll_msg; - if (event_mask & EPOLLERR) ++epoll_err; - if (event_mask & EPOLLHUP) ++epoll_hup; - if (event_mask & EPOLLONESHOT) ++epoll_oneshot; - if (event_mask & EPOLLET) ++epoll_et; - }; - - friend ostream& operator<<(ostream& os, const Events& ev) { - if (ev.epoll_in) { - os << "\t EPOLLIN: " << ev.epoll_in << "\n"; - } - if (ev.epoll_pri) { - os << "\t EPOLLPRI: " << ev.epoll_pri << "\n"; - } - if (ev.epoll_out) { - os << "\t EPOLLOUT: " << ev.epoll_out << "\n"; - } - if (ev.epoll_rdnorm) { - os << "\t EPOLLRDNORM: " << ev.epoll_rdnorm << "\n"; - } - if (ev.epoll_rdband) { - os << "\t EPOLLRDBAND: " << ev.epoll_rdband << "\n"; - } - if (ev.epoll_wrnorm) { - os << "\t EPOLLWRNORM: " << ev.epoll_wrnorm << "\n"; - } - if (ev.epoll_wrband) { - os << "\t EPOLLWRBAND: " << ev.epoll_wrband << "\n"; - } - if (ev.epoll_msg) { - os << "\t EPOLLMSG: " << ev.epoll_msg << "\n"; - } - if (ev.epoll_err) { - os << "\t EPOLLERR: " << ev.epoll_err << "\n"; - } - if (ev.epoll_hup) { - os << "\t EPOLLHUP: " << ev.epoll_hup << "\n"; - } - if (ev.epoll_oneshot) { - os << "\t EPOLLONESHOT: " << ev.epoll_oneshot << "\n"; - } - if (ev.epoll_et) { - os << "\t EPOLLET: " << ev.epoll_et << "\n"; - } - return os; - } - - unsigned int epoll_in; - unsigned int epoll_pri; - unsigned int epoll_out; - unsigned int epoll_rdnorm; - unsigned int epoll_rdband; - unsigned int epoll_wrnorm; - unsigned int epoll_wrband; - unsigned int epoll_msg; - unsigned int epoll_err; - unsigned int epoll_hup; - unsigned int epoll_oneshot; - unsigned int epoll_et; - }; - - std::vector<DebugOutput*> debug_events_; - std::vector<Events> unregistered_fds_; - using EventCountsMap = std::unordered_map<int, Events>; - EventCountsMap event_counts_; - int64_t num_records_; - int64_t record_threshold_; - }; - - void ClearEventRecords() { - event_recorder_.Clear(); - } - void WriteEventRecords(ostream* os) const { - (*os) << event_recorder_; - } - - mutable EventRecorder event_recorder_; - -#endif - - private: - // Helper functions used in the destructor. - void CleanupFDToCBMap(); - void CleanupTimeToAlarmCBMap(); - - // The callback registered to the fds below. As the purpose of their - // registration is to wake the epoll server it just clears the pipe and - // returns. - std::unique_ptr<ReadPipeCallback> wake_cb_; - - // A pipe owned by the epoll server. The server will be registered to listen - // on read_fd_ and can be woken by Wake() which writes to write_fd_. - int read_fd_; - int write_fd_; - - // This boolean is checked to see if it is false at the top of the - // WaitForEventsAndExecuteCallbacks function. If not, then it either returns - // without doing work, and logs to ERROR, or aborts the program (in - // DEBUG mode). If so, then it sets the bool to true, does work, and - // sets it back to false when done. This catches unwanted recursion. - bool in_wait_for_events_and_execute_callbacks_; - - // Returns true when the EpollServer() is being destroyed. - bool in_shutdown_; - - DISALLOW_COPY_AND_ASSIGN(EpollServer); -}; - -class EpollAlarmCallbackInterface { - public: - // Summary: - // Called when an alarm times out. Invalidates an AlarmRegToken. - // WARNING: If a token was saved to refer to an alarm callback, OnAlarm must - // delete it, as the reference is no longer valid. - // Returns: - // the unix time (in microseconds) at which this alarm should be signaled - // again, or 0 if the alarm should be removed. - virtual int64_t OnAlarm() = 0; - - // Summary: - // Called when the an alarm is registered. Invalidates an AlarmRegToken. - // Args: - // token: the iterator to the the alarm registered in the alarm map. - // WARNING: this token becomes invalid when the alarm fires, is - // unregistered, or OnShutdown is called on that alarm. - // eps: the epoll server the alarm is registered with. - virtual void OnRegistration(const EpollServer::AlarmRegToken& token, - EpollServer* eps) = 0; - - // Summary: - // Called when the an alarm is unregistered. - // WARNING: It is not valid to unregister a callback and then use the token - // that was saved to refer to the callback. - virtual void OnUnregistration() = 0; - - // Summary: - // Called when the epoll server is shutting down. - // Invalidates the AlarmRegToken that was given when this alarm was - // registered. - virtual void OnShutdown(EpollServer* eps) = 0; - - virtual ~EpollAlarmCallbackInterface() {} - - protected: - EpollAlarmCallbackInterface() {} -}; - -// A simple alarm which unregisters itself on destruction. -// -// PLEASE NOTE: -// Any classes overriding these functions must either call the implementation -// of the parent class, or is must otherwise make sure that the 'registered_' -// boolean and the token, 'token_', are updated appropriately. -class EpollAlarm : public EpollAlarmCallbackInterface { - public: - EpollAlarm(); - - ~EpollAlarm() override; - - // Marks the alarm as unregistered and returns 0. The return value may be - // safely ignored by subclasses. - int64_t OnAlarm() override; - - // Marks the alarm as registered, and stores the token. - void OnRegistration(const EpollServer::AlarmRegToken& token, - EpollServer* eps) override; - - // Marks the alarm as unregistered. - void OnUnregistration() override; - - // Marks the alarm as unregistered. - void OnShutdown(EpollServer* eps) override; - - // If the alarm was registered, unregister it. - void UnregisterIfRegistered(); - - // Reregisters the alarm at specified time. - void ReregisterAlarm(int64_t timeout_time_in_us); - - bool registered() const { return registered_; } - - const EpollServer* eps() const { return eps_; } - - private: - EpollServer::AlarmRegToken token_; - EpollServer* eps_; - bool registered_; -}; - -} // namespace net - -#endif // NET_TOOLS_EPOLL_SERVER_EPOLL_SERVER_H_
diff --git a/net/tools/epoll_server/fake_epoll_server.cc b/net/tools/epoll_server/fake_epoll_server.cc deleted file mode 100644 index e5ab48c..0000000 --- a/net/tools/epoll_server/fake_epoll_server.cc +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/tools/epoll_server/fake_epoll_server.h" - -namespace quic { -namespace test { - -FakeTimeEpollServer::FakeTimeEpollServer() : now_in_usec_(0) {} - -FakeTimeEpollServer::~FakeTimeEpollServer() = default; - -int64_t FakeTimeEpollServer::NowInUsec() const { - return now_in_usec_; -} - -FakeEpollServer::FakeEpollServer() : until_in_usec_(-1) {} - -FakeEpollServer::~FakeEpollServer() = default; - -int FakeEpollServer::epoll_wait_impl(int epfd, - struct epoll_event* events, - int max_events, - int timeout_in_ms) { - int num_events = 0; - while (!event_queue_.empty() && num_events < max_events && - event_queue_.begin()->first <= NowInUsec() && - ((until_in_usec_ == -1) || - (event_queue_.begin()->first < until_in_usec_))) { - int64_t event_time_in_usec = event_queue_.begin()->first; - events[num_events] = event_queue_.begin()->second; - if (event_time_in_usec > NowInUsec()) { - set_now_in_usec(event_time_in_usec); - } - event_queue_.erase(event_queue_.begin()); - ++num_events; - } - if (num_events == 0) { // then we'd have waited 'till the timeout. - if (until_in_usec_ < 0) { // then we don't care what the final time is. - if (timeout_in_ms > 0) { - AdvanceBy(timeout_in_ms * 1000); - } - } else { // except we assume that we don't wait for the timeout - // period if until_in_usec_ is a positive number. - set_now_in_usec(until_in_usec_); - // And reset until_in_usec_ to signal no waiting (as - // the AdvanceByExactly* stuff is meant to be one-shot, - // as are all similar net::EpollServer functions) - until_in_usec_ = -1; - } - } - if (until_in_usec_ >= 0) { - CHECK(until_in_usec_ >= NowInUsec()); - } - return num_events; -} - -} // namespace test -} // namespace quic
diff --git a/net/tools/epoll_server/fake_epoll_server.h b/net/tools/epoll_server/fake_epoll_server.h deleted file mode 100644 index 8605c43..0000000 --- a/net/tools/epoll_server/fake_epoll_server.h +++ /dev/null
@@ -1,115 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_TOOLS_EPOLL_SERVER_FAKE_EPOLL_SERVER_H_ -#define NET_TOOLS_EPOLL_SERVER_FAKE_EPOLL_SERVER_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <unordered_map> -#include <unordered_set> - -#include "base/logging.h" -#include "base/macros.h" -#include "net/tools/epoll_server/epoll_server.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace quic { -namespace test { - -// Unlike the full FakeEpollServer, this only lies about the time but lets -// fd events operate normally. Usefully when interacting with real backends -// but wanting to skip forward in time to trigger timeouts. -class FakeTimeEpollServer : public net::EpollServer { - public: - FakeTimeEpollServer(); - ~FakeTimeEpollServer() override; - - // Replaces the net::EpollServer NowInUsec. - int64_t NowInUsec() const override; - - void set_now_in_usec(int64_t nius) { now_in_usec_ = nius; } - - // Advances the virtual 'now' by advancement_usec. - void AdvanceBy(int64_t advancement_usec) { - set_now_in_usec(NowInUsec() + advancement_usec); - } - - // Advances the virtual 'now' by advancement_usec, and - // calls WaitForEventAndExecteCallbacks. - // Note that the WaitForEventsAndExecuteCallbacks invocation - // may cause NowInUs to advance beyond what was specified here. - // If that is not desired, use the AdvanceByExactly calls. - void AdvanceByAndWaitForEventsAndExecuteCallbacks(int64_t advancement_usec) { - AdvanceBy(advancement_usec); - WaitForEventsAndExecuteCallbacks(); - } - - private: - int64_t now_in_usec_; - - DISALLOW_COPY_AND_ASSIGN(FakeTimeEpollServer); -}; - -class FakeEpollServer : public FakeTimeEpollServer { - public: // type definitions - using EventQueue = std::unordered_multimap<int64_t, struct epoll_event>; - - FakeEpollServer(); - ~FakeEpollServer() override; - - // time_in_usec is the time at which the event specified - // by 'ee' will be delivered. Note that it -is- possible - // to add an event for a time which has already been passed.. - // .. upon the next time that the callbacks are invoked, - // all events which are in the 'past' will be delivered. - void AddEvent(int64_t time_in_usec, const struct epoll_event& ee) { - event_queue_.insert(std::make_pair(time_in_usec, ee)); - } - - // Advances the virtual 'now' by advancement_usec, - // and ensure that the next invocation of - // WaitForEventsAndExecuteCallbacks goes no farther than - // advancement_usec from the current time. - void AdvanceByExactly(int64_t advancement_usec) { - until_in_usec_ = NowInUsec() + advancement_usec; - set_now_in_usec(NowInUsec() + advancement_usec); - } - - // As above, except calls WaitForEventsAndExecuteCallbacks. - void AdvanceByExactlyAndCallCallbacks(int64_t advancement_usec) { - AdvanceByExactly(advancement_usec); - WaitForEventsAndExecuteCallbacks(); - } - - std::unordered_set<AlarmCB*>::size_type NumberOfAlarms() const { - return all_alarms_.size(); - } - - protected: // functions - // These functions do nothing here, as we're not actually - // using the epoll_* syscalls. - void DelFD(int fd) const override {} - void AddFD(int fd, int event_mask) const override {} - void ModFD(int fd, int event_mask) const override {} - - // Replaces the epoll_server's epoll_wait_impl. - int epoll_wait_impl(int epfd, - struct epoll_event* events, - int max_events, - int timeout_in_ms) override; - void SetNonblocking(int fd) override {} - - private: // members - EventQueue event_queue_; - int64_t until_in_usec_; - - DISALLOW_COPY_AND_ASSIGN(FakeEpollServer); -}; - -} // namespace test -} // namespace quic - -#endif // NET_TOOLS_EPOLL_SERVER_FAKE_EPOLL_SERVER_H_
diff --git a/net/tools/epoll_server/platform/impl/epoll_address_test_utils_impl.h b/net/tools/epoll_server/platform/impl/epoll_address_test_utils_impl.h new file mode 100644 index 0000000..378acd4 --- /dev/null +++ b/net/tools/epoll_server/platform/impl/epoll_address_test_utils_impl.h
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_ADDRESS_TEST_UTILS_IMPL_H_ +#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_ADDRESS_TEST_UTILS_IMPL_H_ + +#include <netinet/in.h> + +namespace epoll_server { + +int AddressFamilyUnderTestImpl() { + return AF_INET; +} + +} // namespace epoll_server + +#endif // NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_ADDRESS_TEST_UTILS_IMPL_H_
diff --git a/net/tools/epoll_server/platform/impl/epoll_bug_impl.h b/net/tools/epoll_server/platform/impl/epoll_bug_impl.h new file mode 100644 index 0000000..696a960 --- /dev/null +++ b/net/tools/epoll_server/platform/impl/epoll_bug_impl.h
@@ -0,0 +1,12 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_BUG_IMPL_H_ +#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_BUG_IMPL_H_ + +#include "net/tools/epoll_server/platform/impl/epoll_logging_impl.h" + +#define EPOLL_BUG_IMPL EPOLL_LOG_IMPL(DFATAL) + +#endif // NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_BUG_IMPL_H_
diff --git a/net/tools/epoll_server/platform/impl/epoll_expect_bug_impl.h b/net/tools/epoll_server/platform/impl/epoll_expect_bug_impl.h new file mode 100644 index 0000000..44ba4c6 --- /dev/null +++ b/net/tools/epoll_server/platform/impl/epoll_expect_bug_impl.h
@@ -0,0 +1,12 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_EXPECT_BUG_IMPL_H_ +#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_EXPECT_BUG_IMPL_H_ + +#include "net/test/gtest_util.h" + +#define EXPECT_EPOLL_BUG_IMPL EXPECT_DFATAL + +#endif // NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_EXPECT_BUG_IMPL_H_
diff --git a/net/tools/epoll_server/platform/impl/epoll_export_impl.h b/net/tools/epoll_server/platform/impl/epoll_export_impl.h new file mode 100644 index 0000000..5a46662 --- /dev/null +++ b/net/tools/epoll_server/platform/impl/epoll_export_impl.h
@@ -0,0 +1,13 @@ +// 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 "net/base/net_export.h" + +#ifndef NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_EXPORT_IMPL_H_ +#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_EXPORT_IMPL_H_ + +#define EPOLL_EXPORT NET_EXPORT +#define EPOLL_EXPORT_PRIVATE NET_EXPORT_PRIVATE + +#endif // NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_EXPORT_IMPL_H_
diff --git a/net/tools/epoll_server/platform/impl/epoll_logging_impl.h b/net/tools/epoll_server/platform/impl/epoll_logging_impl.h new file mode 100644 index 0000000..9f9b8ab --- /dev/null +++ b/net/tools/epoll_server/platform/impl/epoll_logging_impl.h
@@ -0,0 +1,21 @@ +// 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 NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_LOGGING_IMPL_H_ +#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_LOGGING_IMPL_H_ + +#include "base/logging.h" + +#define EPOLL_CHROMIUM_LOG_INFO VLOG(1) +#define EPOLL_CHROMIUM_LOG_WARNING DLOG(WARNING) +#define EPOLL_CHROMIUM_LOG_ERROR DLOG(ERROR) +#define EPOLL_CHROMIUM_LOG_FATAL LOG(FATAL) +#define EPOLL_CHROMIUM_LOG_DFATAL LOG(DFATAL) + +#define EPOLL_LOG_IMPL(severity) EPOLL_CHROMIUM_LOG_##severity +#define EPOLL_VLOG_IMPL(verbose_level) VLOG(verbose_level) +#define EPOLL_DVLOG_IMPL(verbose_level) DVLOG(verbose_level) +#define EPOLL_PLOG_IMPL(severity) DVLOG(1) + +#endif // NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_LOGGING_IMPL_H_
diff --git a/net/tools/epoll_server/platform/impl/epoll_ptr_util_impl.h b/net/tools/epoll_server/platform/impl/epoll_ptr_util_impl.h new file mode 100644 index 0000000..35bbea0 --- /dev/null +++ b/net/tools/epoll_server/platform/impl/epoll_ptr_util_impl.h
@@ -0,0 +1,19 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> + +#ifndef NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_PTR_UTIL_IMPL_H_ +#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_PTR_UTIL_IMPL_H_ + +namespace epoll_server { + +template <typename T, typename... Args> +std::unique_ptr<T> EpollMakeUniqueImpl(Args&&... args) { + return std::make_unique<T>(std::forward<Args>(args)...); +} + +} // namespace epoll_server + +#endif // NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_PTR_UTIL_IMPL_H_
diff --git a/net/tools/epoll_server/platform/impl/epoll_test_impl.h b/net/tools/epoll_server/platform/impl/epoll_test_impl.h new file mode 100644 index 0000000..a4f24b98 --- /dev/null +++ b/net/tools/epoll_server/platform/impl/epoll_test_impl.h
@@ -0,0 +1,12 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_TEST_IMPL_H_ +#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_TEST_IMPL_H_ + +#include "testing/gtest/include/gtest/gtest.h" // IWYU pragma: export + +using EpollTestImpl = ::testing::Test; + +#endif // NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_TEST_IMPL_H_
diff --git a/net/tools/epoll_server/platform/impl/epoll_thread_impl.h b/net/tools/epoll_server/platform/impl/epoll_thread_impl.h new file mode 100644 index 0000000..d726d13 --- /dev/null +++ b/net/tools/epoll_server/platform/impl/epoll_thread_impl.h
@@ -0,0 +1,22 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_THREAD_IMPL_H_ +#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_THREAD_IMPL_H_ + +#include "base/threading/simple_thread.h" + +namespace epoll_server { + +// A class representing a thread of execution in epoll_server. +class EpollThreadImpl : public base::SimpleThread { + public: + EpollThreadImpl(const std::string& string) : base::SimpleThread(string) {} + EpollThreadImpl(const EpollThreadImpl&) = delete; + EpollThreadImpl& operator=(const EpollThreadImpl&) = delete; +}; + +} // namespace epoll_server + +#endif // NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_THREAD_IMPL_H_
diff --git a/net/tools/epoll_server/platform/impl/epoll_time_impl.h b/net/tools/epoll_server/platform/impl/epoll_time_impl.h new file mode 100644 index 0000000..b1c3d219 --- /dev/null +++ b/net/tools/epoll_server/platform/impl/epoll_time_impl.h
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_TIME_IMPL_H_ +#define NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_TIME_IMPL_H_ + +#include "base/time/time.h" + +namespace epoll_server { + +inline int64_t WallTimeNowInUsecImpl() { + return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); +} + +} // namespace epoll_server + +#endif // NET_TOOLS_EPOLL_SERVER_PLATFORM_IMPL_EPOLL_TIME_IMPL_H_
diff --git a/remoting/base/chromium_url_request.cc b/remoting/base/chromium_url_request.cc index 010f16f2..2ae424c 100644 --- a/remoting/base/chromium_url_request.cc +++ b/remoting/base/chromium_url_request.cc
@@ -5,9 +5,9 @@ #include "remoting/base/chromium_url_request.h" #include <memory> +#include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "net/base/load_flags.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" @@ -83,7 +83,7 @@ } DCHECK(!on_result_callback_.is_null()); - base::ResetAndReturn(&on_result_callback_).Run(result); + std::move(on_result_callback_).Run(result); } ChromiumUrlRequestFactory::ChromiumUrlRequestFactory(
diff --git a/remoting/base/gaia_oauth_client.cc b/remoting/base/gaia_oauth_client.cc index 1274347..c85ff737 100644 --- a/remoting/base/gaia_oauth_client.cc +++ b/remoting/base/gaia_oauth_client.cc
@@ -4,7 +4,8 @@ #include "remoting/base/gaia_oauth_client.h" -#include "base/callback_helpers.h" +#include <utility> + #include "base/logging.h" namespace { @@ -57,7 +58,7 @@ void GaiaOAuthClient::SendResponse(const std::string& user_email, const std::string& refresh_token) { - base::ResetAndReturn(&on_done_).Run(user_email, refresh_token); + std::move(on_done_).Run(user_email, refresh_token); // Process the next request in the queue. if (pending_requests_.size()) {
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc index 256e235..a8182b7 100644 --- a/remoting/client/plugin/chromoting_instance.cc +++ b/remoting/client/plugin/chromoting_instance.cc
@@ -14,7 +14,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/lazy_instance.h" @@ -906,7 +905,7 @@ return; } if (!secret_fetched_callback_.is_null()) { - base::ResetAndReturn(&secret_fetched_callback_).Run(pin); + std::move(secret_fetched_callback_).Run(pin); } else { LOG(WARNING) << "Ignored OnPinFetched received without a pending fetch."; } @@ -922,8 +921,7 @@ return; } if (!third_party_token_fetched_callback_.is_null()) { - base::ResetAndReturn(&third_party_token_fetched_callback_) - .Run(token, shared_secret); + std::move(third_party_token_fetched_callback_).Run(token, shared_secret); } else { LOG(WARNING) << "Ignored OnThirdPartyTokenFetched without a pending fetch."; }
diff --git a/remoting/client/plugin/pepper_url_request.cc b/remoting/client/plugin/pepper_url_request.cc index 1555f5a..97fdb89 100644 --- a/remoting/client/plugin/pepper_url_request.cc +++ b/remoting/client/plugin/pepper_url_request.cc
@@ -5,8 +5,8 @@ #include "remoting/client/plugin/pepper_url_request.h" #include <memory> +#include <utility> -#include "base/callback_helpers.h" #include "base/logging.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "ppapi/cpp/url_response_info.h" @@ -66,7 +66,7 @@ if (result < 0) { LOG(WARNING) << "pp::URLLoader for " << url_ << " failed: " << result; - base::ResetAndReturn(&on_result_callback_).Run(Result::Failed()); + std::move(on_result_callback_).Run(Result::Failed()); return; } @@ -89,7 +89,7 @@ if (result < 0) { LOG(WARNING) << "Failed to read HTTP response body when fetching " << url_ << ", error: " << result; - base::ResetAndReturn(&on_result_callback_).Run(Result::Failed()); + std::move(on_result_callback_).Run(Result::Failed()); return; } @@ -104,7 +104,7 @@ return; } - base::ResetAndReturn(&on_result_callback_) + std::move(on_result_callback_) .Run(Result(url_loader_.GetResponseInfo().GetStatusCode(), response_)); }
diff --git a/remoting/host/chromeos/message_box.cc b/remoting/host/chromeos/message_box.cc index c3dc703..1378dff 100644 --- a/remoting/host/chromeos/message_box.cc +++ b/remoting/host/chromeos/message_box.cc
@@ -4,6 +4,8 @@ #include "remoting/host/chromeos/message_box.h" +#include <utility> + #include "base/macros.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/controls/message_box_view.h" @@ -99,14 +101,14 @@ bool MessageBox::Core::Accept() { if (!result_callback_.is_null()) { - base::ResetAndReturn(&result_callback_).Run(OK); + std::move(result_callback_).Run(OK); } return true /* close the window*/; } bool MessageBox::Core::Cancel() { if (!result_callback_.is_null()) { - base::ResetAndReturn(&result_callback_).Run(CANCEL); + std::move(result_callback_).Run(CANCEL); } return true /* close the window*/; }
diff --git a/remoting/host/daemon_process.cc b/remoting/host/daemon_process.cc index 5cba93f..21b6743 100644 --- a/remoting/host/daemon_process.cc +++ b/remoting/host/daemon_process.cc
@@ -6,10 +6,10 @@ #include <algorithm> #include <string> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -287,7 +287,7 @@ OnWorkerProcessStopped(); if (!stopped_callback_.is_null()) { - base::ResetAndReturn(&stopped_callback_).Run(); + std::move(stopped_callback_).Run(); } }
diff --git a/remoting/host/dns_blackhole_checker.cc b/remoting/host/dns_blackhole_checker.cc index 8758ebf8..264ec5b 100644 --- a/remoting/host/dns_blackhole_checker.cc +++ b/remoting/host/dns_blackhole_checker.cc
@@ -4,8 +4,9 @@ #include "remoting/host/dns_blackhole_checker.h" +#include <utility> + #include "base/bind.h" -#include "base/callback_helpers.h" #include "remoting/base/logging.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/simple_url_loader.h" @@ -45,7 +46,7 @@ << ")"; } url_loader_.reset(); - base::ResetAndReturn(&callback_).Run(allow); + std::move(callback_).Run(allow); } void DnsBlackholeChecker::CheckForDnsBlackhole(
diff --git a/remoting/host/gcd_rest_client.cc b/remoting/host/gcd_rest_client.cc index cbd3a42..0c31bc3 100644 --- a/remoting/host/gcd_rest_client.cc +++ b/remoting/host/gcd_rest_client.cc
@@ -9,7 +9,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/json/json_writer.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/default_clock.h" @@ -146,7 +145,7 @@ DCHECK(HasPendingRequest()); resource_request_.reset(); url_loader_.reset(); - base::ResetAndReturn(&callback_).Run(result); + std::move(callback_).Run(result); } void GcdRestClient::OnURLLoadComplete(
diff --git a/remoting/host/gcd_state_updater.cc b/remoting/host/gcd_state_updater.cc index 5714c14..3fea9009 100644 --- a/remoting/host/gcd_state_updater.cc +++ b/remoting/host/gcd_state_updater.cc
@@ -9,7 +9,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/strings/stringize_macros.h" #include "base/time/time.h" #include "base/values.h" @@ -91,12 +90,12 @@ if (result == GcdRestClient::SUCCESS) { if (!on_update_successful_callback_.is_null()) { on_unknown_host_id_error_.Reset(); - base::ResetAndReturn(&on_update_successful_callback_).Run(); + std::move(on_update_successful_callback_).Run(); } } else if (result == GcdRestClient::NO_SUCH_HOST) { if (!on_unknown_host_id_error_.is_null()) { on_update_successful_callback_.Reset(); - base::ResetAndReturn(&on_unknown_host_id_error_).Run(); + std::move(on_unknown_host_id_error_).Run(); } } else { // For any other error, do nothing since there's no way to handle
diff --git a/remoting/host/it2me/it2me_confirmation_dialog_chromeos.cc b/remoting/host/it2me/it2me_confirmation_dialog_chromeos.cc index 0c040b0..4e1b290 100644 --- a/remoting/host/it2me/it2me_confirmation_dialog_chromeos.cc +++ b/remoting/host/it2me/it2me_confirmation_dialog_chromeos.cc
@@ -4,10 +4,10 @@ #include <memory> #include <string> +#include <utility> #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "base/i18n/message_formatter.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" @@ -60,8 +60,8 @@ void It2MeConfirmationDialogChromeOS::OnMessageBoxResult( MessageBox::Result result) { - base::ResetAndReturn(&callback_).Run(result == MessageBox::OK ? - Result::OK : Result::CANCEL); + std::move(callback_).Run(result == MessageBox::OK ? Result::OK + : Result::CANCEL); } std::unique_ptr<It2MeConfirmationDialog>
diff --git a/remoting/host/it2me/it2me_confirmation_dialog_linux.cc b/remoting/host/it2me/it2me_confirmation_dialog_linux.cc index 4d586c4..69c2b9c0 100644 --- a/remoting/host/it2me/it2me_confirmation_dialog_linux.cc +++ b/remoting/host/it2me/it2me_confirmation_dialog_linux.cc
@@ -6,10 +6,10 @@ #include <memory> #include <string> +#include <utility> #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "base/i18n/message_formatter.h" #include "base/location.h" #include "base/logging.h" @@ -148,8 +148,8 @@ DCHECK(result_callback_); Hide(); - base::ResetAndReturn(&result_callback_).Run( - (response_id == GTK_RESPONSE_OK) ? Result::OK : Result::CANCEL); + std::move(result_callback_) + .Run((response_id == GTK_RESPONSE_OK) ? Result::OK : Result::CANCEL); } } // namespace
diff --git a/remoting/host/it2me/it2me_confirmation_dialog_mac.mm b/remoting/host/it2me/it2me_confirmation_dialog_mac.mm index 5c697b3..6234c39 100644 --- a/remoting/host/it2me/it2me_confirmation_dialog_mac.mm +++ b/remoting/host/it2me/it2me_confirmation_dialog_mac.mm
@@ -8,9 +8,10 @@ #import <Cocoa/Cocoa.h> +#include <utility> + #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "base/i18n/message_formatter.h" #include "base/location.h" #include "base/mac/scoped_nsautorelease_pool.h" @@ -108,7 +109,7 @@ } if (result_callback_) { - base::ResetAndReturn(&result_callback_).Run(result); + std::move(result_callback_).Run(result); } } @@ -176,7 +177,7 @@ - (void)onCancel:(id)sender { [self hide]; if (dialog_action_callback_) { - base::ResetAndReturn(&dialog_action_callback_) + std::move(dialog_action_callback_) .Run(remoting::It2MeConfirmationDialog::Result::CANCEL); } } @@ -184,7 +185,7 @@ - (void)onAccept:(id)sender { [self hide]; if (dialog_action_callback_) { - base::ResetAndReturn(&dialog_action_callback_) + std::move(dialog_action_callback_) .Run(remoting::It2MeConfirmationDialog::Result::OK); } }
diff --git a/remoting/host/it2me/it2me_confirmation_dialog_proxy.cc b/remoting/host/it2me/it2me_confirmation_dialog_proxy.cc index fa858891..0e4cfc1 100644 --- a/remoting/host/it2me/it2me_confirmation_dialog_proxy.cc +++ b/remoting/host/it2me/it2me_confirmation_dialog_proxy.cc
@@ -7,7 +7,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/location.h" #include "base/macros.h" #include "base/threading/thread_task_runner_handle.h" @@ -105,7 +104,7 @@ void It2MeConfirmationDialogProxy::ReportResult( It2MeConfirmationDialog::Result result) { DCHECK(core_->caller_task_runner()->BelongsToCurrentThread()); - base::ResetAndReturn(&callback_).Run(result); + std::move(callback_).Run(result); } } // namespace remoting
diff --git a/remoting/host/it2me/it2me_host_unittest.cc b/remoting/host/it2me/it2me_host_unittest.cc index 3ffb131..d375e90f 100644 --- a/remoting/host/it2me/it2me_host_unittest.cc +++ b/remoting/host/it2me/it2me_host_unittest.cc
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "base/location.h" #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -340,7 +339,7 @@ if (state_change_callback_) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::ResetAndReturn(&state_change_callback_)); + FROM_HERE, std::move(state_change_callback_)); } }
diff --git a/remoting/host/it2me/it2me_native_messaging_host.cc b/remoting/host/it2me/it2me_native_messaging_host.cc index 286a63bd..0eed0e92 100644 --- a/remoting/host/it2me/it2me_native_messaging_host.cc +++ b/remoting/host/it2me/it2me_native_messaging_host.cc
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/single_thread_task_runner.h" @@ -488,7 +487,7 @@ // may not be ideal, but is still functional. needs_elevation_ = needs_elevation_ && allow_elevated_host; if (pending_connect_) { - base::ResetAndReturn(&pending_connect_).Run(); + std::move(pending_connect_).Run(); } } @@ -515,7 +514,7 @@ // is one, but otherwise do nothing. The policy error will be sent when a // connection is made; doing so beforehand would break assumptions made by // the Chrome app. - base::ResetAndReturn(&pending_connect_).Run(); + std::move(pending_connect_).Run(); } }
diff --git a/remoting/host/register_support_host_request.cc b/remoting/host/register_support_host_request.cc index 4aed339c..543567c 100644 --- a/remoting/host/register_support_host_request.cc +++ b/remoting/host/register_support_host_request.cc
@@ -6,8 +6,9 @@ #include <stdint.h> +#include <utility> + #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringize_macros.h" @@ -242,7 +243,7 @@ signal_strategy_->RemoveListener(this); signal_strategy_ = nullptr; - base::ResetAndReturn(&callback_).Run(support_id, lifetime, error_code); + std::move(callback_).Run(support_id, lifetime, error_code); } } // namespace remoting
diff --git a/remoting/host/security_key/security_key_ipc_client.cc b/remoting/host/security_key/security_key_ipc_client.cc index 5a91879..eb4f5230 100644 --- a/remoting/host/security_key/security_key_ipc_client.cc +++ b/remoting/host/security_key/security_key_ipc_client.cc
@@ -5,10 +5,10 @@ #include "remoting/host/security_key/security_key_ipc_client.h" #include <string> +#include <utility> #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "base/threading/thread_task_runner_handle.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_listener.h" @@ -115,7 +115,7 @@ DWORD peer_session_id; if (!ProcessIdToSessionId(peer_pid, &peer_session_id)) { PLOG(ERROR) << "ProcessIdToSessionId failed"; - base::ResetAndReturn(&connection_error_callback_).Run(); + std::move(connection_error_callback_).Run(); return; } @@ -123,7 +123,7 @@ LOG(ERROR) << "Cannot establish connection with IPC server running in session: " << peer_session_id; - base::ResetAndReturn(&connection_error_callback_).Run(); + std::move(connection_error_callback_).Run(); return; } #endif // defined(OS_WIN) @@ -133,7 +133,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (connection_error_callback_) { - base::ResetAndReturn(&connection_error_callback_).Run(); + std::move(connection_error_callback_).Run(); } } @@ -142,11 +142,11 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!response_data.empty()) { - base::ResetAndReturn(&response_callback_).Run(response_data); + std::move(response_callback_).Run(response_data); } else { LOG(ERROR) << "Invalid response received"; if (connection_error_callback_) { - base::ResetAndReturn(&connection_error_callback_).Run(); + std::move(connection_error_callback_).Run(); } } } @@ -157,12 +157,12 @@ if (!connected_callback_) { LOG(ERROR) << "Unexpected ConnectionReady message received."; if (connection_error_callback_) { - base::ResetAndReturn(&connection_error_callback_).Run(); + std::move(connection_error_callback_).Run(); } return; } - base::ResetAndReturn(&connected_callback_).Run(/*connection_usable=*/true); + std::move(connected_callback_).Run(/*connection_usable=*/true); } void SecurityKeyIpcClient::OnInvalidSession() { @@ -171,12 +171,12 @@ if (!connected_callback_) { LOG(ERROR) << "Unexpected InvalidSession message received."; if (connection_error_callback_) { - base::ResetAndReturn(&connection_error_callback_).Run(); + std::move(connection_error_callback_).Run(); } return; } - base::ResetAndReturn(&connected_callback_).Run(/*connection_usable=*/false); + std::move(connected_callback_).Run(/*connection_usable=*/false); } void SecurityKeyIpcClient::ConnectToIpcChannel() { @@ -187,7 +187,7 @@ if (!channel_handle_.is_valid() && !CheckForSecurityKeyIpcServerChannel()) { if (connection_error_callback_) { - base::ResetAndReturn(&connection_error_callback_).Run(); + std::move(connection_error_callback_).Run(); } return; } @@ -201,7 +201,7 @@ ipc_channel_.reset(); if (connection_error_callback_) { - base::ResetAndReturn(&connection_error_callback_).Run(); + std::move(connection_error_callback_).Run(); } }
diff --git a/remoting/host/security_key/security_key_ipc_server_impl.cc b/remoting/host/security_key/security_key_ipc_server_impl.cc index 90cdcc37..5a02d9ac 100644 --- a/remoting/host/security_key/security_key_ipc_server_impl.cc +++ b/remoting/host/security_key/security_key_ipc_server_impl.cc
@@ -7,10 +7,10 @@ #include <cstdint> #include <memory> #include <string> +#include <utility> #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "base/location.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_checker.h" @@ -147,7 +147,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!connect_callback_.is_null()) { - base::ResetAndReturn(&connect_callback_).Run(); + std::move(connect_callback_).Run(); } #if defined(OS_WIN) @@ -186,11 +186,11 @@ CloseChannel(); if (!connect_callback_.is_null()) { - base::ResetAndReturn(&connect_callback_).Run(); + std::move(connect_callback_).Run(); } if (!done_callback_.is_null()) { // Note: This callback may result in this object being torn down. - base::ResetAndReturn(&done_callback_).Run(); + std::move(done_callback_).Run(); } }
diff --git a/remoting/host/security_key/security_key_message_handler.cc b/remoting/host/security_key/security_key_message_handler.cc index 85f725a..3b9b907d 100644 --- a/remoting/host/security_key/security_key_message_handler.cc +++ b/remoting/host/security_key/security_key_message_handler.cc
@@ -10,7 +10,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "remoting/host/security_key/security_key_ipc_client.h" #include "remoting/host/security_key/security_key_ipc_constants.h" #include "remoting/host/security_key/security_key_message_reader_impl.h" @@ -185,7 +184,7 @@ reader_.reset(); if (!error_callback_.is_null()) { - base::ResetAndReturn(&error_callback_).Run(); + std::move(error_callback_).Run(); } }
diff --git a/remoting/host/security_key/security_key_socket.cc b/remoting/host/security_key/security_key_socket.cc index 2d51dfd..f30e72b 100644 --- a/remoting/host/security_key/security_key_socket.cc +++ b/remoting/host/security_key/security_key_socket.cc
@@ -7,7 +7,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/stl_util.h" #include "base/timer/timer.h" #include "net/base/io_buffer.h" @@ -152,7 +151,7 @@ socket_read_error_ = true; } waiting_for_request_ = false; - base::ResetAndReturn(&request_received_callback_).Run(); + std::move(request_received_callback_).Run(); return; } @@ -165,7 +164,7 @@ read_buffer_->data() + result); if (IsRequestComplete()) { waiting_for_request_ = false; - base::ResetAndReturn(&request_received_callback_).Run(); + std::move(request_received_callback_).Run(); return; }
diff --git a/remoting/host/setup/host_starter.cc b/remoting/host/setup/host_starter.cc index da166d52..7f566c5 100644 --- a/remoting/host/setup/host_starter.cc +++ b/remoting/host/setup/host_starter.cc
@@ -8,7 +8,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/guid.h" #include "base/location.h" #include "base/memory/ptr_util.h" @@ -188,7 +187,7 @@ service_client_->UnregisterHost(host_id_, access_token_, this); return; } - base::ResetAndReturn(&on_done_).Run(START_COMPLETE); + std::move(on_done_).Run(START_COMPLETE); } void HostStarter::OnOAuthError() { @@ -201,8 +200,7 @@ LOG(ERROR) << "OAuth error occurred when unregistering host."; } - base::ResetAndReturn(&on_done_) - .Run(unregistering_host_ ? START_ERROR : OAUTH_ERROR); + std::move(on_done_).Run(unregistering_host_ ? START_ERROR : OAUTH_ERROR); } void HostStarter::OnNetworkError(int response_code) { @@ -216,8 +214,7 @@ LOG(ERROR) << "Network error occurred when unregistering host."; } - base::ResetAndReturn(&on_done_) - .Run(unregistering_host_ ? START_ERROR : NETWORK_ERROR); + std::move(on_done_).Run(unregistering_host_ ? START_ERROR : NETWORK_ERROR); } void HostStarter::OnHostUnregistered() { @@ -226,7 +223,7 @@ FROM_HERE, base::BindOnce(&HostStarter::OnHostUnregistered, weak_ptr_)); return; } - base::ResetAndReturn(&on_done_).Run(START_ERROR); + std::move(on_done_).Run(START_ERROR); } } // namespace remoting
diff --git a/remoting/protocol/fake_authenticator.cc b/remoting/protocol/fake_authenticator.cc index abac8a7..5c844c9 100644 --- a/remoting/protocol/fake_authenticator.cc +++ b/remoting/protocol/fake_authenticator.cc
@@ -9,7 +9,6 @@ #include "base/base64.h" #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" #include "net/base/io_buffer.h" @@ -90,7 +89,7 @@ void FakeChannelAuthenticator::CallDoneCallback() { if (result_ != net::OK) socket_.reset(); - base::ResetAndReturn(&done_callback_).Run(result_, std::move(socket_)); + std::move(done_callback_).Run(result_, std::move(socket_)); } FakeAuthenticator::Config::Config() = default; @@ -120,7 +119,7 @@ } void FakeAuthenticator::Resume() { - base::ResetAndReturn(&resume_closure_).Run(); + std::move(resume_closure_).Run(); } Authenticator::State FakeAuthenticator::state() const {
diff --git a/remoting/protocol/fake_datagram_socket.cc b/remoting/protocol/fake_datagram_socket.cc index b81619c..a7bd322 100644 --- a/remoting/protocol/fake_datagram_socket.cc +++ b/remoting/protocol/fake_datagram_socket.cc
@@ -7,7 +7,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -39,7 +38,7 @@ int result = CopyReadData(read_buffer_.get(), read_buffer_size_); read_buffer_ = nullptr; - base::ResetAndReturn(&read_callback_).Run(result); + std::move(read_callback_).Run(result); } }
diff --git a/remoting/protocol/http_ice_config_request.cc b/remoting/protocol/http_ice_config_request.cc index 241b9055..4e5c076a 100644 --- a/remoting/protocol/http_ice_config_request.cc +++ b/remoting/protocol/http_ice_config_request.cc
@@ -4,8 +4,9 @@ #include "remoting/protocol/http_ice_config_request.h" +#include <utility> + #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/values.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "remoting/protocol/ice_config.h" @@ -87,7 +88,7 @@ const std::string& access_token) { if (status != OAuthTokenGetter::SUCCESS) { LOG(ERROR) << "Failed to get OAuth token for IceConfig request."; - base::ResetAndReturn(&on_ice_config_callback_).Run(IceConfig()); + std::move(on_ice_config_callback_).Run(IceConfig()); return; } @@ -106,13 +107,13 @@ if (result.status != -1 && result.status != 200) { LOG(ERROR) << "Received status code " << result.status << " from " << url_ << ": " << result.response_body; - base::ResetAndReturn(&on_ice_config_callback_).Run(IceConfig()); + std::move(on_ice_config_callback_).Run(IceConfig()); return; } if (!result.success) { LOG(ERROR) << "Failed to fetch " << url_; - base::ResetAndReturn(&on_ice_config_callback_).Run(IceConfig()); + std::move(on_ice_config_callback_).Run(IceConfig()); return; } @@ -122,7 +123,7 @@ << result.response_body; } - base::ResetAndReturn(&on_ice_config_callback_).Run(ice_config); + std::move(on_ice_config_callback_).Run(ice_config); } } // namespace protocol
diff --git a/remoting/protocol/ice_transport_channel.cc b/remoting/protocol/ice_transport_channel.cc index 2870699..48efe98f7 100644 --- a/remoting/protocol/ice_transport_channel.cc +++ b/remoting/protocol/ice_transport_channel.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/callback_helpers.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "jingle/glue/utils.h" @@ -142,7 +141,7 @@ new TransportChannelSocketAdapter(channel_.get())); socket->SetOnDestroyedCallback(base::Bind( &IceTransportChannel::OnChannelDestroyed, base::Unretained(this))); - base::ResetAndReturn(&callback_).Run(std::move(socket)); + std::move(callback_).Run(std::move(socket)); } void IceTransportChannel::SetRemoteCredentials(const std::string& ufrag,
diff --git a/remoting/protocol/stream_message_pipe_adapter.cc b/remoting/protocol/stream_message_pipe_adapter.cc index 54dc5f1..7bbc79f 100644 --- a/remoting/protocol/stream_message_pipe_adapter.cc +++ b/remoting/protocol/stream_message_pipe_adapter.cc
@@ -8,7 +8,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "net/base/net_errors.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "remoting/base/buffered_socket_writer.h" @@ -90,7 +89,7 @@ if (error == 0) { event_handler_->OnMessagePipeClosed(); } else if (error_callback_) { - base::ResetAndReturn(&error_callback_).Run(error); + std::move(error_callback_).Run(error); } }
diff --git a/remoting/protocol/third_party_authenticator_unittest.cc b/remoting/protocol/third_party_authenticator_unittest.cc index 38f81273..c4775f4 100644 --- a/remoting/protocol/third_party_authenticator_unittest.cc +++ b/remoting/protocol/third_party_authenticator_unittest.cc
@@ -5,7 +5,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" @@ -60,7 +59,7 @@ void OnTokenFetched(const std::string& token, const std::string& shared_secret) { ASSERT_FALSE(on_token_fetched_.is_null()); - base::ResetAndReturn(&on_token_fetched_).Run(token, shared_secret); + std::move(on_token_fetched_).Run(token, shared_secret); } private: @@ -84,7 +83,7 @@ void OnTokenValidated(const std::string& shared_secret) { ASSERT_FALSE(on_token_validated_.is_null()); - base::ResetAndReturn(&on_token_validated_).Run(shared_secret); + std::move(on_token_validated_).Run(shared_secret); } const GURL& token_url() const override { return token_url_; }
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc index 48f2e5b..16ad0bce 100644 --- a/remoting/protocol/webrtc_transport.cc +++ b/remoting/protocol/webrtc_transport.cc
@@ -10,7 +10,6 @@ #include "base/base64.h" #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -155,11 +154,10 @@ result_callback); } void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { - base::ResetAndReturn(&result_callback_) - .Run(base::WrapUnique(desc), std::string()); + std::move(result_callback_).Run(base::WrapUnique(desc), std::string()); } void OnFailure(const std::string& error) override { - base::ResetAndReturn(&result_callback_).Run(nullptr, error); + std::move(result_callback_).Run(nullptr, error); } protected: @@ -189,11 +187,11 @@ } void OnSuccess() override { - base::ResetAndReturn(&result_callback_).Run(true, std::string()); + std::move(result_callback_).Run(true, std::string()); } void OnFailure(const std::string& error) override { - base::ResetAndReturn(&result_callback_).Run(false, error); + std::move(result_callback_).Run(false, error); } protected: @@ -221,7 +219,7 @@ void OnStatsDelivered( const rtc::scoped_refptr<const webrtc::RTCStatsReport>& report) override { - base::ResetAndReturn(&result_callback_).Run(report); + std::move(result_callback_).Run(report); } protected:
diff --git a/remoting/signaling/iq_sender.cc b/remoting/signaling/iq_sender.cc index 37c2ee6..94ffa39 100644 --- a/remoting/signaling/iq_sender.cc +++ b/remoting/signaling/iq_sender.cc
@@ -8,7 +8,6 @@ #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/location.h" #include "base/logging.h" #include "base/single_thread_task_runner.h" @@ -151,7 +150,7 @@ void IqRequest::CallCallback(const jingle_xmpp::XmlElement* stanza) { if (!callback_.is_null()) - base::ResetAndReturn(&callback_).Run(this, stanza); + std::move(callback_).Run(this, stanza); } void IqRequest::OnTimeout() {
diff --git a/remoting/test/access_token_fetcher.cc b/remoting/test/access_token_fetcher.cc index c8c214bc..02d028da 100644 --- a/remoting/test/access_token_fetcher.cc +++ b/remoting/test/access_token_fetcher.cc
@@ -5,10 +5,10 @@ #include "remoting/test/access_token_fetcher.h" #include <string> +#include <utility> #include <vector> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/logging.h" #include "base/threading/thread_task_runner_handle.h" #include "google_apis/gaia/gaia_constants.h" @@ -164,8 +164,7 @@ VLOG(1) << "Access Token has been validated"; } - base::ResetAndReturn(&access_token_callback_) - .Run(access_token_, refresh_token_); + std::move(access_token_callback_).Run(access_token_, refresh_token_); } void AccessTokenFetcher::OnOAuthError() { @@ -174,8 +173,7 @@ access_token_.clear(); refresh_token_.clear(); - base::ResetAndReturn(&access_token_callback_) - .Run(access_token_, refresh_token_); + std::move(access_token_callback_).Run(access_token_, refresh_token_); } void AccessTokenFetcher::OnNetworkError(int response_code) { @@ -185,8 +183,7 @@ access_token_.clear(); refresh_token_.clear(); - base::ResetAndReturn(&access_token_callback_) - .Run(access_token_, refresh_token_); + std::move(access_token_callback_).Run(access_token_, refresh_token_); } void AccessTokenFetcher::ValidateAccessToken() {
diff --git a/remoting/test/host_list_fetcher.cc b/remoting/test/host_list_fetcher.cc index 1fa28706..08f893a 100644 --- a/remoting/test/host_list_fetcher.cc +++ b/remoting/test/host_list_fetcher.cc
@@ -4,8 +4,9 @@ #include "remoting/test/host_list_fetcher.h" +#include <utility> + #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/json/json_reader.h" #include "base/logging.h" #include "base/threading/thread_task_runner_handle.h" @@ -104,7 +105,7 @@ if (!ProcessResponse(&hostlist)) { hostlist.clear(); } - base::ResetAndReturn(&hostlist_callback_).Run(hostlist); + std::move(hostlist_callback_).Run(hostlist); } } // namespace test
diff --git a/remoting/test/test_video_renderer.cc b/remoting/test/test_video_renderer.cc index 1734ba8..0ed0de4 100644 --- a/remoting/test/test_video_renderer.cc +++ b/remoting/test/test_video_renderer.cc
@@ -5,10 +5,10 @@ #include "remoting/test/test_video_renderer.h" #include <stdint.h> + #include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -214,8 +214,8 @@ // on the current frame. RGBValue accumulating_avg_value = CalculateAverageColorValue(expected_rect_); if (ExpectedAverageColorIsMatched(accumulating_avg_value)) { - main_task_runner_->PostTask( - FROM_HERE, base::ResetAndReturn(&image_pattern_matched_callback_)); + main_task_runner_->PostTask(FROM_HERE, + std::move(image_pattern_matched_callback_)); } }
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc index 40fcebf..cdeb210 100644 --- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc +++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc
@@ -10,9 +10,7 @@ #include <sched.h> #include <signal.h> #include <stddef.h> -#include <stdlib.h> #include <string.h> -#include <sys/mman.h> #include <sys/prctl.h> #include <sys/resource.h> #include <sys/socket.h> @@ -132,33 +130,6 @@ BPF_ASSERT_EQ(EPERM, fork_errno); } -BPF_TEST_C(BaselinePolicy, SystemEperm, BaselinePolicy) { - errno = 0; - int ret_val = system("echo SHOULD NEVER RUN"); - BPF_ASSERT_EQ(-1, ret_val); - BPF_ASSERT_EQ(EPERM, errno); -} - -BPF_TEST_C(BaselinePolicy, CloneVforkEperm, BaselinePolicy) { - errno = 0; - // Allocate a couple pages for the child's stack even though the child should - // never start. - constexpr size_t kStackSize = 4096 * 4; - void* child_stack = mmap(nullptr, kStackSize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); - BPF_ASSERT_NE(child_stack, nullptr); - pid_t pid = syscall(__NR_clone, CLONE_VM | CLONE_VFORK | SIGCHLD, - static_cast<char*>(child_stack) + kStackSize, nullptr, - nullptr, nullptr); - const int clone_errno = errno; - TestUtils::HandlePostForkReturn(pid); - - munmap(child_stack, kStackSize); - - BPF_ASSERT_EQ(-1, pid); - BPF_ASSERT_EQ(EPERM, clone_errno); -} - BPF_TEST_C(BaselinePolicy, CreateThread, BaselinePolicy) { base::Thread thread("sandbox_tests"); BPF_ASSERT(thread.Start());
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc index 348ab6e..100afe5 100644 --- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc +++ b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
@@ -135,8 +135,7 @@ #if !defined(OS_NACL_NONSFI) // Allow Glibc's and Android pthread creation flags, crash on any other // thread creation attempts and EPERM attempts to use neither -// CLONE_VM nor CLONE_THREAD (all fork implementations), unless CLONE_VFORK is -// present (as in newer versions of posix_spawn). +// CLONE_VM, nor CLONE_THREAD, which includes all fork() implementations. ResultExpr RestrictCloneToThreadsAndEPERMFork() { const Arg<unsigned long> flags(0); @@ -155,16 +154,8 @@ AnyOf(flags == kAndroidCloneMask, flags == kObsoleteAndroidCloneMask, flags == kGlibcPthreadFlags); - // The following two flags are the two important flags in any vfork-emulating - // clone call. EPERM any clone call that contains both of them. - const uint64_t kImportantCloneVforkFlags = CLONE_VFORK | CLONE_VM; - - const BoolExpr is_fork_or_clone_vfork = - AnyOf((flags & (CLONE_VM | CLONE_THREAD)) == 0, - (flags & kImportantCloneVforkFlags) == kImportantCloneVforkFlags); - return If(IsAndroid() ? android_test : glibc_test, Allow()) - .ElseIf(is_fork_or_clone_vfork, Error(EPERM)) + .ElseIf((flags & (CLONE_VM | CLONE_THREAD)) == 0, Error(EPERM)) .Else(CrashSIGSYSClone()); }
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 545324be..ba7bc6c7 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -932,7 +932,7 @@ details.status_code = report->status_code; details.elapsed_time = report->elapsed_time; details.user_agent = std::move(user_agent); - logging_service->QueueSignedExchangeReport(details); + logging_service->QueueSignedExchangeReport(std::move(details)); } #else // BUILDFLAG(ENABLE_REPORTING)
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 19b9c31c..841dac9 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -638,14 +638,6 @@ return; } - if (new_url && - (new_url->GetOrigin() != deferred_redirect_url_->GetOrigin())) { - NOTREACHED() << "Can only change the URL within the same origin."; - NotifyCompleted(net::ERR_UNEXPECTED); - // |this| may have been deleted. - return; - } - deferred_redirect_url_.reset(); new_redirect_url_ = new_url;
diff --git a/services/tracing/BUILD.gn b/services/tracing/BUILD.gn index f6bf49a..f03baab 100644 --- a/services/tracing/BUILD.gn +++ b/services/tracing/BUILD.gn
@@ -58,22 +58,6 @@ ] } -source_set("privacy_check") { - testonly = true - - sources = [ - "perfetto/privacy_filtering_check.cc", - "perfetto/privacy_filtering_check.h", - ] - - deps = [ - "//base", - "//third_party/perfetto/include/perfetto/protozero:protozero", - "//third_party/perfetto/protos/perfetto/common:lite", - "//third_party/perfetto/protos/perfetto/trace:lite", - ] -} - source_set("tests") { testonly = true
diff --git a/services/tracing/perfetto/consumer_host.cc b/services/tracing/perfetto/consumer_host.cc index 7e23fb3..eb1e28e 100644 --- a/services/tracing/perfetto/consumer_host.cc +++ b/services/tracing/perfetto/consumer_host.cc
@@ -139,14 +139,6 @@ privacy_filtering_enabled_ = true; } } -#if DCHECK_IS_ON() - if (privacy_filtering_enabled_) { - // If enabled, filtering must be enabled for all data sources. - for (const auto& data_source : trace_config.data_sources()) { - DCHECK(data_source.config().chrome_config().privacy_filtering_enabled()); - } - } -#endif perfetto::TraceConfig trace_config_copy = AdjustTraceConfig(trace_config); filtered_pids_.clear();
diff --git a/services/tracing/perfetto/privacy_filtering_check.cc b/services/tracing/perfetto/privacy_filtering_check.cc deleted file mode 100644 index eccc4d6..0000000 --- a/services/tracing/perfetto/privacy_filtering_check.cc +++ /dev/null
@@ -1,64 +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 "services/tracing/perfetto/privacy_filtering_check.h" - -#include "base/logging.h" -#include "third_party/perfetto/protos/perfetto/trace/trace.pb.h" -#include "third_party/perfetto/protos/perfetto/trace/trace_packet.pb.h" - -namespace tracing { -namespace { -using perfetto::protos::TracePacket; -} - -PrivacyFilteringCheck::PrivacyFilteringCheck() = default; -PrivacyFilteringCheck::~PrivacyFilteringCheck() = default; - -// static -void PrivacyFilteringCheck::CheckProtoForUnexpectedFields( - const std::string& serialized_trace_proto) { - auto proto = std::make_unique<perfetto::protos::Trace>(); - if (!proto->ParseFromArray(serialized_trace_proto.data(), - serialized_trace_proto.size())) { - NOTREACHED(); - return; - } - - for (auto& packet : *proto->mutable_packet()) { - DCHECK(packet.unknown_fields().empty()); - // TODO(ssid): For each of these messages verify that only expected fields - // are present. - if (packet.has_track_event()) { - ++counts_.track_event; - } else if (packet.has_process_descriptor()) { - ++counts_.process_desc; - } else if (packet.has_thread_descriptor()) { - ++counts_.thread_desc; - } else if (packet.has_synchronization_marker() || - packet.has_trace_stats() || packet.has_trace_config() || - packet.has_system_info()) { - // TODO(ssid): These should not be present in the traces or must be - // whitelisted. - } else { - DCHECK_EQ(TracePacket::DataCase::DATA_NOT_SET, packet.data_case()); - } - if (packet.has_interned_data()) { - counts_.interned_name += packet.interned_data().legacy_event_names_size(); - packet.mutable_interned_data()->clear_legacy_event_names(); - counts_.interned_category += - packet.interned_data().event_categories_size(); - packet.mutable_interned_data()->clear_event_categories(); - counts_.interned_source_location += - packet.interned_data().source_locations_size(); - packet.mutable_interned_data()->clear_source_locations(); - - std::string serialized; - packet.interned_data().SerializeToString(&serialized); - DCHECK_EQ(serialized.size(), 0u); - } - } -} - -} // namespace tracing
diff --git a/services/tracing/perfetto/privacy_filtering_check.h b/services/tracing/perfetto/privacy_filtering_check.h deleted file mode 100644 index 7928266..0000000 --- a/services/tracing/perfetto/privacy_filtering_check.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 SERVICES_TRACING_PERFETTO_PRIVACY_FILTERING_CHECK_H_ -#define SERVICES_TRACING_PERFETTO_PRIVACY_FILTERING_CHECK_H_ - -#include <string> - -#include "base/macros.h" - -namespace tracing { - -class PrivacyFilteringCheck { - public: - struct TypeCounts { - size_t track_event = 0; - size_t process_desc = 0; - size_t thread_desc = 0; - - size_t interned_name = 0; - size_t interned_category = 0; - size_t interned_source_location = 0; - }; - - PrivacyFilteringCheck(); - ~PrivacyFilteringCheck(); - - void CheckProtoForUnexpectedFields(const std::string& serialized_trace_proto); - - const TypeCounts& counts() const { return counts_; } - - private: - TypeCounts counts_; - - DISALLOW_COPY_AND_ASSIGN(PrivacyFilteringCheck); -}; - -} // namespace tracing - -#endif // SERVICES_TRACING_PERFETTO_PRIVACY_FILTERING_CHECK_H_
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc index aadb0b4..f0217ae 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -83,9 +83,6 @@ void TraceEventMetadataSource::GenerateMetadata( std::unique_ptr<perfetto::TraceWriter> trace_writer) { - if (privacy_filtering_enabled_) { - return; - } DCHECK(origin_task_runner_->RunsTasksInCurrentSequence()); auto trace_packet = trace_writer->NewTracePacket(); @@ -210,17 +207,15 @@ TraceLog::GetInstance()->SetAddTraceEventOverrides(nullptr, nullptr, nullptr); } -void TraceEventDataSource::SetupStartupTracing(bool privacy_filtering_enabled) { +void TraceEventDataSource::SetupStartupTracing() { { base::AutoLock lock(lock_); // No need to do anything if startup tracing has already been set, // or we know Perfetto has already been setup. if (startup_writer_registry_ || producer_client_) { - DCHECK(!privacy_filtering_enabled || privacy_filtering_enabled_); return; } - privacy_filtering_enabled_ = privacy_filtering_enabled; startup_writer_registry_ = std::make_unique<perfetto::StartupTraceWriterRegistry>(); } @@ -230,19 +225,13 @@ void TraceEventDataSource::StartTracing( PerfettoProducer* producer, const perfetto::DataSourceConfig& data_source_config) { + privacy_filtering_enabled_ = + data_source_config.chrome_config().privacy_filtering_enabled(); + std::unique_ptr<perfetto::StartupTraceWriterRegistry> unbound_writer_registry; { base::AutoLock lock(lock_); - bool should_enable_filtering = - data_source_config.chrome_config().privacy_filtering_enabled(); - if (should_enable_filtering) { - CHECK(!startup_writer_registry_ || privacy_filtering_enabled_) - << "Unexpected StartTracing received when startup tracing is " - "running."; - } - privacy_filtering_enabled_ = should_enable_filtering; - DCHECK(!producer_client_); producer_client_ = producer; target_buffer_ = data_source_config.target_buffer(); @@ -253,6 +242,9 @@ session_id_.fetch_add(1u, std::memory_order_relaxed); if (unbound_writer_registry) { + // TODO(ssid): Startup tracing should know about filtering output. + CHECK(!privacy_filtering_enabled_); + // TODO(oysteine): Investigate why trace events emitted by something in // BindStartupTraceWriterRegistry() causes deadlocks. AutoThreadLocalBoolean thread_is_in_trace_event(
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.h b/services/tracing/public/cpp/perfetto/trace_event_data_source.h index b350726f9..6b949321 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.h +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.h
@@ -99,7 +99,7 @@ // is locally buffered until connection to the perfetto service is // established. Expects a later call to StartTracing() to bind to the perfetto // service. Should only be called once. - void SetupStartupTracing(bool privacy_filtering_enabled); + void SetupStartupTracing(); // The PerfettoProducer is responsible for calling StopTracing // which will clear the stored pointer to it, before it @@ -150,6 +150,7 @@ void LogHistogram(base::HistogramBase* histogram); bool disable_interning_ = false; + bool privacy_filtering_enabled_ = false; base::OnceClosure stop_complete_callback_; // Incremented and accessed atomically but without memory order guarantees. @@ -167,7 +168,6 @@ std::unique_ptr<perfetto::StartupTraceWriterRegistry> startup_writer_registry_; std::vector<std::string> histograms_; - bool privacy_filtering_enabled_ = false; DISALLOW_COPY_AND_ASSIGN(TraceEventDataSource); };
diff --git a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h index 80d1227..54d4f04 100644 --- a/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h +++ b/services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h
@@ -64,7 +64,7 @@ base::trace_event::TraceEvent complete_event_stack_[kMaxCompleteEventDepth]; uint32_t current_stack_depth_ = 0; - const bool privacy_filtering_enabled_; + bool privacy_filtering_enabled_; }; } // namespace tracing
diff --git a/services/tracing/public/cpp/trace_startup.cc b/services/tracing/public/cpp/trace_startup.cc index f11df22..13a382f 100644 --- a/services/tracing/public/cpp/trace_startup.cc +++ b/services/tracing/public/cpp/trace_startup.cc
@@ -15,11 +15,6 @@ namespace tracing { -namespace { -using base::trace_event::TraceConfig; -using base::trace_event::TraceLog; -} // namespace - void EnableStartupTracingIfNeeded() { const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); @@ -32,31 +27,29 @@ // Ensure TraceLog is initialized first. // https://crbug.com/764357 - auto* trace_log = TraceLog::GetInstance(); - auto* startup_config = TraceStartupConfig::GetInstance(); + base::trace_event::TraceLog::GetInstance(); - if (startup_config->IsEnabled()) { - if (TracingUsesPerfettoBackend()) { - TraceEventDataSource::GetInstance()->SetupStartupTracing( - startup_config->GetBackgroundStartupTracingEnabled()); - } - - const TraceConfig& trace_config = startup_config->GetTraceConfig(); - uint8_t modes = TraceLog::RECORDING_MODE; + if (TraceStartupConfig::GetInstance()->IsEnabled()) { + const base::trace_event::TraceConfig& trace_config = + TraceStartupConfig::GetInstance()->GetTraceConfig(); + uint8_t modes = base::trace_event::TraceLog::RECORDING_MODE; if (!trace_config.event_filters().empty()) - modes |= TraceLog::FILTERING_MODE; - trace_log->SetEnabled(startup_config->GetTraceConfig(), modes); + modes |= base::trace_event::TraceLog::FILTERING_MODE; + if (TracingUsesPerfettoBackend()) + TraceEventDataSource::GetInstance()->SetupStartupTracing(); + base::trace_event::TraceLog::GetInstance()->SetEnabled( + TraceStartupConfig::GetInstance()->GetTraceConfig(), modes); } else if (command_line.HasSwitch(switches::kTraceToConsole)) { // TODO(eseckler): Remove ability to trace to the console, perfetto doesn't // support this and noone seems to use it. - TraceConfig trace_config = GetConfigForTraceToConsole(); + base::trace_event::TraceConfig trace_config = GetConfigForTraceToConsole(); LOG(ERROR) << "Start " << switches::kTraceToConsole << " with CategoryFilter '" << trace_config.ToCategoryFilterString() << "'."; if (TracingUsesPerfettoBackend()) - TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/false); - trace_log->SetEnabled(trace_config, TraceLog::RECORDING_MODE); + TraceEventDataSource::GetInstance()->SetupStartupTracing(); + base::trace_event::TraceLog::GetInstance()->SetEnabled( + trace_config, base::trace_event::TraceLog::RECORDING_MODE); } }
diff --git a/skia/ext/benchmarking_canvas.cc b/skia/ext/benchmarking_canvas.cc index 595bc3e..c6b7974 100644 --- a/skia/ext/benchmarking_canvas.cc +++ b/skia/ext/benchmarking_canvas.cc
@@ -145,7 +145,7 @@ } SkScalar color_matrix[20]; - if (filter.asColorMatrix(color_matrix)) { + if (filter.asAColorMatrix(color_matrix)) { std::unique_ptr<base::ListValue> color_matrix_val(new base::ListValue()); for (unsigned i = 0; i < 20; ++i) color_matrix_val->Append(AsValue(color_matrix[i]));
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 77104b0f..263e6b2 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -17292,7 +17292,8 @@ "device_type": "marlin", "os": "Android" } - ] + ], + "shards": 2 }, "test": "chrome_public_test_vr_apk" }, @@ -17474,7 +17475,8 @@ ], "name": "shard #${SHARD_INDEX} logcats" } - ] + ], + "shards": 2 }, "test": "chrome_public_test_vr_apk" }, @@ -24707,7 +24709,8 @@ ], "name": "shard #${SHARD_INDEX} logcats" } - ] + ], + "shards": 2 }, "test": "chrome_public_test_vr_apk" },
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 1d8ef80..d947cd7 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -38,6 +38,9 @@ '--replace-system-package=com.google.vr.vrcore,//third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk', '--additional-apk=//third_party/gvr-android-sdk/test-apks/vr_keyboard/vr_keyboard_current.apk', ], + 'swarming': { + 'shards': 2, + }, 'test': 'chrome_public_test_vr_apk', }, 'chrome_public_test_vr_apk-ddready-dynamicsettings': {
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 4e6f583..01a4ec7 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -48,11 +48,6 @@ const base::Feature kFreezePurgeMemoryAllPagesFrozen{ "FreezePurgeMemoryAllPagesFrozen", base::FEATURE_DISABLED_BY_DEFAULT}; -// Controls whether or not the font cache is invalidated when a critical memory -// pressure signal is sent. -const base::Feature kInvalidateFontCacheOnPurge{ - "InvalidateFontCacheOnPurge", base::FEATURE_ENABLED_BY_DEFAULT}; - // Enables the experimental sweep-line algorithm for tracking "jank" from // layout objects changing their visual location between animation frames. const base::Feature kJankTrackingSweepLine{"JankTrackingSweepLine",
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index ef1dc1b4..4a13ca9 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -23,7 +23,6 @@ BLINK_COMMON_EXPORT extern const base::Feature kFirstContentfulPaintPlusPlus; BLINK_COMMON_EXPORT extern const base::Feature kFreezePurgeMemoryAllPagesFrozen; BLINK_COMMON_EXPORT extern const base::Feature kImplicitRootScroller; -BLINK_COMMON_EXPORT extern const base::Feature kInvalidateFontCacheOnPurge; BLINK_COMMON_EXPORT extern const base::Feature kJankTrackingSweepLine; BLINK_COMMON_EXPORT extern const base::Feature kBlinkGenPropertyTrees; BLINK_COMMON_EXPORT extern const base::Feature kLayoutNG;
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc b/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc index 05e3d02..573b37e7 100644 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc +++ b/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_record.h" +#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" namespace blink { @@ -18,12 +19,14 @@ const FloatRect& dest_rect, const FloatRect& src_rect, const PaintFlags& flags, + Image::ImageClampingMode clamping_mode, scoped_refptr<PaintWorkletInput> input) { - canvas->drawImage(PaintImageBuilder::WithDefault() - .set_paint_worklet_input(std::move(input)) - .set_id(PaintImage::GetNextId()) - .TakePaintImage(), - 0, 0, &flags); + canvas->drawImageRect(PaintImageBuilder::WithDefault() + .set_paint_worklet_input(std::move(input)) + .set_id(PaintImage::GetNextId()) + .TakePaintImage(), + src_rect, dest_rect, &flags, + WebCoreClampingModeToSkiaRectConstraint(clamping_mode)); } } // namespace @@ -32,15 +35,15 @@ const FloatRect& dest_rect, const FloatRect& src_rect, RespectImageOrientationEnum, - ImageClampingMode, + ImageClampingMode clamping_mode, ImageDecodingMode) { - DrawInternal(canvas, dest_rect, src_rect, flags, input_); + DrawInternal(canvas, dest_rect, src_rect, flags, clamping_mode, input_); } void PaintWorkletDeferredImage::DrawTile(GraphicsContext& context, const FloatRect& src_rect) { DrawInternal(context.Canvas(), FloatRect(), src_rect, context.FillFlags(), - input_); + kClampImageToSourceRect, input_); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc index 6573724..c5832fe 100644 --- a/third_party/blink/renderer/core/css/selector_checker.cc +++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -770,8 +770,7 @@ is_empty = false; break; } - if (n->IsTextNode()) { - Text* text_node = ToText(n); + if (auto* text_node = DynamicTo<Text>(n)) { if (!text_node->data().IsEmpty()) { if (text_node->ContainsOnlyWhitespaceOrEmpty()) { has_whitespace = true;
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index 4c15a15..02ecb3e 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -1422,15 +1422,15 @@ UpdateAllLifecyclePhases(); - ToText(t1->firstChild())->setData(""); + To<Text>(t1->firstChild())->setData(""); EXPECT_TRUE(t1->NeedsStyleInvalidation()); - ToText(t2->firstChild())->setData("Text"); + To<Text>(t2->firstChild())->setData("Text"); EXPECT_TRUE(t2->NeedsStyleInvalidation()); // This is not optimal. We do not detect that we change text to/from // non-empty string. - ToText(t3->firstChild())->setData("NewText"); + To<Text>(t3->firstChild())->setData("NewText"); EXPECT_TRUE(t3->NeedsStyleInvalidation()); } @@ -1455,13 +1455,13 @@ UpdateAllLifecyclePhases(); - ToText(t1->firstChild())->setData(""); + To<Text>(t1->firstChild())->setData(""); EXPECT_FALSE(t1->NeedsStyleInvalidation()); - ToText(t2->lastChild())->setData("Text"); + To<Text>(t2->lastChild())->setData("Text"); EXPECT_FALSE(t2->NeedsStyleInvalidation()); - ToText(t3->firstChild())->setData("NewText"); + To<Text>(t3->firstChild())->setData("NewText"); EXPECT_FALSE(t3->NeedsStyleInvalidation()); }
diff --git a/third_party/blink/renderer/core/dom/character_data.cc b/third_party/blink/renderer/core/dom/character_data.cc index f0f3ada..b8bdd0a 100644 --- a/third_party/blink/renderer/core/dom/character_data.cc +++ b/third_party/blink/renderer/core/dom/character_data.cc
@@ -209,8 +209,8 @@ data_ = new_data; DCHECK(!GetLayoutObject() || IsTextNode()); - if (IsTextNode()) - ToText(this)->UpdateTextLayoutObject(offset_of_replaced_data, old_length); + if (auto* text_node = DynamicTo<Text>(this)) + text_node->UpdateTextLayoutObject(offset_of_replaced_data, old_length); if (source != kUpdateFromParser) { if (getNodeType() == kProcessingInstructionNode)
diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc index 827906e..02f23c9 100644 --- a/third_party/blink/renderer/core/dom/container_node.cc +++ b/third_party/blink/renderer/core/dom/container_node.cc
@@ -1399,8 +1399,8 @@ for (Node* child = firstChild(); child; child = child->nextSibling()) { if (!change.TraverseChild(*child)) continue; - if (child->IsTextNode()) - ToText(child)->RecalcTextStyle(change); + if (auto* child_text_node = DynamicTo<Text>(child)) + child_text_node->RecalcTextStyle(change); else if (child->IsElementNode()) ToElement(child)->RecalcStyle(change); } @@ -1409,12 +1409,11 @@ void ContainerNode::RebuildLayoutTreeForChild( Node* child, WhitespaceAttacher& whitespace_attacher) { - if (child->IsTextNode()) { - Text* text_node = ToText(child); + if (auto* child_text_node = DynamicTo<Text>(child)) { if (child->NeedsReattachLayoutTree()) - text_node->RebuildTextLayoutTree(whitespace_attacher); + child_text_node->RebuildTextLayoutTree(whitespace_attacher); else - whitespace_attacher.DidVisitText(text_node); + whitespace_attacher.DidVisitText(child_text_node); return; }
diff --git a/third_party/blink/renderer/core/dom/document_statistics_collector.cc b/third_party/blink/renderer/core/dom/document_statistics_collector.cc index 6be49cd..80defe0 100644 --- a/third_party/blink/renderer/core/dom/document_statistics_collector.cc +++ b/third_party/blink/renderer/core/dom/document_statistics_collector.cc
@@ -48,10 +48,11 @@ // Given shadow DOM rarely appears in <P> elements in long-form articles, the // overall accuracy should not be largely affected. for (Node& node : NodeTraversal::InclusiveDescendantsOf(root)) { - if (!node.IsTextNode()) { + auto* text_node = DynamicTo<Text>(node); + if (!text_node) { continue; } - length += ToText(node).length(); + length += text_node->length(); if (length > kTextContentLengthSaturation) { return kTextContentLengthSaturation; }
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 319ab57..2b96acf 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3028,7 +3028,8 @@ for (; sibling; sibling = next_func(*sibling)) { if (sibling->IsElementNode()) return true; - if (sibling->IsTextNode() && !ToText(sibling)->data().IsEmpty()) + auto* text_node = DynamicTo<Text>(sibling); + if (text_node && !text_node->data().IsEmpty()) return true; } return false; @@ -3770,12 +3771,21 @@ return; parent->ReplaceChild(fragment, this, exception_state); - Node* node = next ? next->previousSibling() : nullptr; - if (!exception_state.HadException() && node && node->IsTextNode()) - MergeWithNextTextNode(ToText(node), exception_state); + if (exception_state.HadException()) + return; - if (!exception_state.HadException() && prev && prev->IsTextNode()) - MergeWithNextTextNode(ToText(prev), exception_state); + Node* node = next ? next->previousSibling() : nullptr; + if (auto* text = DynamicTo<Text>(node)) { + MergeWithNextTextNode(text, exception_state); + if (exception_state.HadException()) + return; + } + + if (auto* prev_text = DynamicTo<Text>(prev)) { + MergeWithNextTextNode(prev_text, exception_state); + if (exception_state.HadException()) + return; + } } void Element::setOuterHTML(const StringOrTrustedHTML& string_or_html, @@ -4002,14 +4012,14 @@ unsigned total_length = 0; for (Node* child = firstChild(); child; child = child->nextSibling()) { - if (!child->IsTextNode()) + auto* child_text_node = DynamicTo<Text>(child); + if (!child_text_node) continue; - Text* text = ToText(child); if (!first_text_node) - first_text_node = text; + first_text_node = child_text_node; else found_multiple_text_nodes = true; - unsigned length = text->data().length(); + unsigned length = child_text_node->data().length(); if (length > std::numeric_limits<unsigned>::max() - total_length) return g_empty_string; total_length += length; @@ -4026,9 +4036,10 @@ StringBuilder content; content.ReserveCapacity(total_length); for (Node* child = first_text_node; child; child = child->nextSibling()) { - if (!child->IsTextNode()) + auto* child_text_node = DynamicTo<Text>(child); + if (!child_text_node) continue; - content.Append(ToText(child)->data()); + content.Append(child_text_node->data()); } DCHECK_EQ(content.length(), total_length);
diff --git a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc index 9843488..38c9b9e 100644 --- a/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc +++ b/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc
@@ -268,7 +268,7 @@ void FirstLetterPseudoElement::DetachLayoutTree(const AttachContext& context) { if (remaining_text_layout_object_) { if (remaining_text_layout_object_->GetNode() && GetDocument().IsActive()) { - Text* text_node = ToText(remaining_text_layout_object_->GetNode()); + auto* text_node = To<Text>(remaining_text_layout_object_->GetNode()); remaining_text_layout_object_->SetTextFragment( text_node->DataImpl(), 0, text_node->DataImpl()->length()); }
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index 51a2afb..5436447 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -874,7 +874,7 @@ break; if (node->getNodeType() == kTextNode) - node = ToText(node)->MergeNextSiblingNodesIfPossible(); + node = To<Text>(node)->MergeNextSiblingNodesIfPossible(); else node = NodeTraversal::NextPostOrder(*node); } @@ -1814,8 +1814,8 @@ for (const Node& node : NodeTraversal::InclusiveDescendantsOf(*this)) { if (IsHTMLBRElement(node) && convert_brs_to_newlines) { content.Append('\n'); - } else if (node.IsTextNode()) { - content.Append(ToText(node).data()); + } else if (auto* text_node = DynamicTo<Text>(node)) { + content.Append(text_node->data()); } } return content.ToString(); @@ -1856,7 +1856,7 @@ // See crbug.com/352836 also. // No need to do anything if the text is identical. if (container->HasOneTextChild() && - ToText(container->firstChild())->data() == text && !text.IsEmpty()) + To<Text>(container->firstChild())->data() == text && !text.IsEmpty()) return; ChildListMutationScope mutation(*this); @@ -2356,8 +2356,8 @@ GetDocument().AddListenerTypeIfNeeded(type, *this); } } - if (IsTextNode()) - old_document.Markers().RemoveMarkersForNode(*ToText(this)); + if (auto* text_node = DynamicTo<Text>(this)) + old_document.Markers().RemoveMarkersForNode(*text_node); if (GetDocument().GetPage() && GetDocument().GetPage() != old_document.GetPage()) { GetDocument().GetFrame()->GetEventHandlerRegistry().DidMoveIntoPage(*this);
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc index fe24dfc..0b12bdff 100644 --- a/third_party/blink/renderer/core/dom/range.cc +++ b/third_party/blink/renderer/core/dom/range.cc
@@ -910,7 +910,7 @@ // splitting it with offset range’s start offset. if (start_is_text) { reference_node = - ToText(start_node).splitText(start_.Offset(), exception_state); + To<Text>(start_node).splitText(start_.Offset(), exception_state); if (exception_state.HadException()) return; } @@ -1703,9 +1703,10 @@ continue; } - if (!node->IsTextNode()) + auto* const text_node = DynamicTo<Text>(node); + if (!text_node) continue; - LayoutText* const layout_text = ToText(node)->GetLayoutObject(); + LayoutText* const layout_text = text_node->GetLayoutObject(); if (!layout_text) continue;
diff --git a/third_party/blink/renderer/core/dom/range_test.cc b/third_party/blink/renderer/core/dom/range_test.cc index 8c7f52d..35ade003 100644 --- a/third_party/blink/renderer/core/dom/range_test.cc +++ b/third_party/blink/renderer/core/dom/range_test.cc
@@ -103,7 +103,7 @@ V8TestingScope scope; GetDocument().body()->SetInnerHTMLFromString("1234"); - Text* old_text = ToText(GetDocument().body()->firstChild()); + auto* old_text = To<Text>(GetDocument().body()->firstChild()); Range* range04 = Range::Create(GetDocument(), old_text, 0, old_text, 4); Range* range02 = Range::Create(GetDocument(), old_text, 0, old_text, 2); @@ -111,7 +111,7 @@ Range* range24 = Range::Create(GetDocument(), old_text, 2, old_text, 4); old_text->splitText(2, ASSERT_NO_EXCEPTION); - Text* new_text = ToText(old_text->nextSibling()); + auto* new_text = To<Text>(old_text->nextSibling()); EXPECT_TRUE(range04->BoundaryPointsValid()); EXPECT_EQ(old_text, range04->startContainer()); @@ -153,7 +153,7 @@ GetDocument().getElementById(AtomicString::FromUTF8("inner-left")); Element* inner_right = GetDocument().getElementById(AtomicString::FromUTF8("inner-right")); - Text* old_text = ToText(outer->childNodes()->item(2)); + auto* old_text = To<Text>(outer->childNodes()->item(2)); Range* range_outer_outside = Range::Create(GetDocument(), outer, 0, outer, 5); Range* range_outer_inside = Range::Create(GetDocument(), outer, 1, outer, 4); @@ -167,7 +167,7 @@ Range::Create(GetDocument(), old_text, 6, outer, 3); old_text->splitText(3, ASSERT_NO_EXCEPTION); - Text* new_text = ToText(old_text->nextSibling()); + auto* new_text = To<Text>(old_text->nextSibling()); EXPECT_TRUE(range_outer_outside->BoundaryPointsValid()); EXPECT_EQ(outer, range_outer_outside->startContainer()); @@ -233,7 +233,7 @@ Element* div = GetDocument().QuerySelector("div"); Element* span1 = GetDocument().getElementById("span1"); Element* span2 = GetDocument().getElementById("span2"); - Text* text = ToText(div->childNodes()->item(1)); + auto* text = To<Text>(div->childNodes()->item(1)); Range* range = Range::Create(GetDocument(), span2, 0, div, 3); @@ -255,7 +255,7 @@ Element* div = GetDocument().QuerySelector("div"); Element* span1 = GetDocument().getElementById("span1"); Element* span2 = GetDocument().getElementById("span2"); - Text* text = ToText(div->childNodes()->item(1)); + auto* text = To<Text>(div->childNodes()->item(1)); Range* range = Range::Create(GetDocument(), span2, 0, div, 3);
diff --git a/third_party/blink/renderer/core/dom/slot_assignment_test.cc b/third_party/blink/renderer/core/dom/slot_assignment_test.cc index f85597d..e5c4dea6 100644 --- a/third_party/blink/renderer/core/dom/slot_assignment_test.cc +++ b/third_party/blink/renderer/core/dom/slot_assignment_test.cc
@@ -68,7 +68,7 @@ void RemoveWhiteSpaceOnlyTextNode(ContainerNode& container) { for (Node* descendant : CollectFromIterable(NodeTraversal::InclusiveDescendantsOf(container))) { - if (Text* text = ToTextOrNull(descendant)) { + if (auto* text = DynamicTo<Text>(descendant)) { if (text->ContainsOnlyWhitespaceOrEmpty()) text->remove(); } else if (Element* element = ToElementOrNull(descendant)) {
diff --git a/third_party/blink/renderer/core/dom/static_range_test.cc b/third_party/blink/renderer/core/dom/static_range_test.cc index 6f44e4cf..ced35af4c 100644 --- a/third_party/blink/renderer/core/dom/static_range_test.cc +++ b/third_party/blink/renderer/core/dom/static_range_test.cc
@@ -46,7 +46,7 @@ TEST_F(StaticRangeTest, SplitTextNodeRangeWithinText) { V8TestingScope scope; GetDocument().body()->SetInnerHTMLFromString("1234"); - Text* old_text = ToText(GetDocument().body()->firstChild()); + auto* old_text = To<Text>(GetDocument().body()->firstChild()); StaticRange* static_range04 = StaticRange::Create(GetDocument(), old_text, 0u, old_text, 4u); @@ -63,7 +63,7 @@ Range* range24 = static_range24->toRange(ASSERT_NO_EXCEPTION); old_text->splitText(2, ASSERT_NO_EXCEPTION); - Text* new_text = ToText(old_text->nextSibling()); + auto* new_text = To<Text>(old_text->nextSibling()); // Range should mutate. EXPECT_TRUE(range04->BoundaryPointsValid()); @@ -126,7 +126,7 @@ GetDocument().getElementById(AtomicString::FromUTF8("inner-left")); Element* inner_right = GetDocument().getElementById(AtomicString::FromUTF8("inner-right")); - Text* old_text = ToText(outer->childNodes()->item(2)); + auto* old_text = To<Text>(outer->childNodes()->item(2)); StaticRange* static_range_outer_outside = StaticRange::Create(GetDocument(), outer, 0u, outer, 5u); @@ -155,7 +155,7 @@ static_range_from_text_to_middle_of_element->toRange(ASSERT_NO_EXCEPTION); old_text->splitText(3, ASSERT_NO_EXCEPTION); - Text* new_text = ToText(old_text->nextSibling()); + auto* new_text = To<Text>(old_text->nextSibling()); // Range should mutate. EXPECT_TRUE(range_outer_outside->BoundaryPointsValid()); @@ -232,7 +232,7 @@ TEST_F(StaticRangeTest, InvalidToRange) { V8TestingScope scope; GetDocument().body()->SetInnerHTMLFromString("1234"); - Text* old_text = ToText(GetDocument().body()->firstChild()); + auto* old_text = To<Text>(GetDocument().body()->firstChild()); StaticRange* static_range04 = StaticRange::Create(GetDocument(), old_text, 0u, old_text, 4u);
diff --git a/third_party/blink/renderer/core/dom/text.cc b/third_party/blink/renderer/core/dom/text.cc index 67f8b5c..4609368 100644 --- a/third_party/blink/renderer/core/dom/text.cc +++ b/third_party/blink/renderer/core/dom/text.cc
@@ -69,7 +69,7 @@ if (next_sibling->getNodeType() != kTextNode) break; - Text* next_text = ToText(next_sibling); + auto* next_text = To<Text>(next_sibling); // Remove empty text nodes. if (!next_text->length()) {
diff --git a/third_party/blink/renderer/core/dom/text.h b/third_party/blink/renderer/core/dom/text.h index fcc3500..41bf23fc 100644 --- a/third_party/blink/renderer/core/dom/text.h +++ b/third_party/blink/renderer/core/dom/text.h
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/style_recalc.h" #include "third_party/blink/renderer/core/dom/character_data.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -87,6 +88,11 @@ DEFINE_NODE_TYPE_CASTS(Text, IsTextNode()); +template <> +struct DowncastTraits<Text> { + static bool AllowFrom(const Node& node) { return node.IsTextNode(); } +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_TEXT_H_
diff --git a/third_party/blink/renderer/core/dom/text_test.cc b/third_party/blink/renderer/core/dom/text_test.cc index ed16d8cd5..7a4f7b19 100644 --- a/third_party/blink/renderer/core/dom/text_test.cc +++ b/third_party/blink/renderer/core/dom/text_test.cc
@@ -19,7 +19,7 @@ "id=sample>a<span>b</span></pre>"); Node* sample = GetDocument().getElementById("sample"); - Text* text = ToText(sample->firstChild()); + auto* text = To<Text>(sample->firstChild()); text->setData(" "); UpdateAllLifecyclePhasesForTest(); @@ -30,7 +30,7 @@ SetBodyContent("<style>*::first-letter{font:icon;}</style><pre>AB\n</pre>"); Element* pre = GetDocument().QuerySelector("pre"); - Text* text = ToText(pre->firstChild()); + auto* text = To<Text>(pre->firstChild()); Range* range = Range::Create(GetDocument(), text, 0, text, 2); range->deleteContents(ASSERT_NO_EXCEPTION);
diff --git a/third_party/blink/renderer/core/dom/v0_insertion_point.cc b/third_party/blink/renderer/core/dom/v0_insertion_point.cc index 63327cb4..dae1722 100644 --- a/third_party/blink/renderer/core/dom/v0_insertion_point.cc +++ b/third_party/blink/renderer/core/dom/v0_insertion_point.cc
@@ -149,8 +149,8 @@ continue; if (node->IsElementNode()) ToElement(node)->RecalcStyle(change); - else if (node->IsTextNode()) - ToText(node)->RecalcTextStyle(change); + else if (auto* text_node = DynamicTo<Text>(node)) + text_node->RecalcTextStyle(change); } }
diff --git a/third_party/blink/renderer/core/dom/whitespace_attacher.cc b/third_party/blink/renderer/core/dom/whitespace_attacher.cc index df1a7ed..2334e8fc 100644 --- a/third_party/blink/renderer/core/dom/whitespace_attacher.cc +++ b/third_party/blink/renderer/core/dom/whitespace_attacher.cc
@@ -118,10 +118,10 @@ for (Node* sibling = last_text_node_; sibling; sibling = LayoutTreeBuilderTraversal::NextLayoutSibling(*sibling)) { LayoutObject* sibling_layout_object = sibling->GetLayoutObject(); - if (sibling->IsTextNode() && - ToText(sibling)->ContainsOnlyWhitespaceOrEmpty()) { + auto* text_node = DynamicTo<Text>(sibling); + if (text_node && text_node->ContainsOnlyWhitespaceOrEmpty()) { bool had_layout_object = !!sibling_layout_object; - ToText(sibling)->ReattachLayoutTreeIfNeeded(context); + text_node->ReattachLayoutTreeIfNeeded(context); sibling_layout_object = sibling->GetLayoutObject(); // If sibling's layout object status didn't change we don't need to // continue checking other siblings since their layout object status @@ -171,12 +171,10 @@ for (; sibling && sibling != last_text_node_; sibling = LayoutTreeBuilderTraversal::NextLayoutSibling(*sibling)) { LayoutObject* layout_object = sibling->GetLayoutObject(); - if (sibling->IsTextNode()) { - Text* text = ToText(sibling); - if (text->ContainsOnlyWhitespaceOrEmpty()) { - last_text_node_ = text; - return; - } + auto* text = DynamicTo<Text>(sibling); + if (text && text->ContainsOnlyWhitespaceOrEmpty()) { + last_text_node_ = text; + return; } if (layout_object && !layout_object->IsFloatingOrOutOfFlowPositioned()) { last_text_node_ = nullptr;
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc index 01550d1c..f634618 100644 --- a/third_party/blink/renderer/core/fetch/request.cc +++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -687,61 +687,7 @@ String Request::destination() const { // "The destination attribute’s getter must return request’s destination." - switch (request_->Context()) { - case mojom::RequestContextType::UNSPECIFIED: - case mojom::RequestContextType::BEACON: - case mojom::RequestContextType::DOWNLOAD: - case mojom::RequestContextType::EVENT_SOURCE: - case mojom::RequestContextType::FETCH: - case mojom::RequestContextType::PING: - case mojom::RequestContextType::XML_HTTP_REQUEST: - case mojom::RequestContextType::SUBRESOURCE: - case mojom::RequestContextType::PREFETCH: - return ""; - case mojom::RequestContextType::CSP_REPORT: - return "report"; - case mojom::RequestContextType::AUDIO: - return "audio"; - case mojom::RequestContextType::EMBED: - return "embed"; - case mojom::RequestContextType::FONT: - return "font"; - case mojom::RequestContextType::FRAME: - case mojom::RequestContextType::HYPERLINK: - case mojom::RequestContextType::IFRAME: - case mojom::RequestContextType::LOCATION: - case mojom::RequestContextType::FORM: - return "document"; - case mojom::RequestContextType::IMAGE: - case mojom::RequestContextType::FAVICON: - case mojom::RequestContextType::IMAGE_SET: - return "image"; - case mojom::RequestContextType::MANIFEST: - return "manifest"; - case mojom::RequestContextType::OBJECT: - return "object"; - case mojom::RequestContextType::SCRIPT: - return "script"; - case mojom::RequestContextType::SHARED_WORKER: - return "sharedworker"; - case mojom::RequestContextType::STYLE: - return "style"; - case mojom::RequestContextType::TRACK: - return "track"; - case mojom::RequestContextType::VIDEO: - return "video"; - case mojom::RequestContextType::WORKER: - return "worker"; - case mojom::RequestContextType::XSLT: - return "xslt"; - case mojom::RequestContextType::IMPORT: - case mojom::RequestContextType::INTERNAL: - case mojom::RequestContextType::PLUGIN: - case mojom::RequestContextType::SERVICE_WORKER: - return "unknown"; - } - NOTREACHED(); - return ""; + return FetchUtils::GetDestinationFromContext(request_->Context()); } String Request::referrer() const {
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc index fccd7475..24df817 100644 --- a/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
@@ -103,7 +103,7 @@ largest_image_record->paint_time, "data", std::move(value)); } -void ImagePaintTimingDetector::Analyze() { +void ImagePaintTimingDetector::UpdateCandidate() { ImageRecord* largest_image_record = records_manager_.FindLargestPaintCandidate(); // These conditions represents the following scenarios: @@ -132,7 +132,7 @@ frame_index_++; if (need_update_timing_at_frame_end_) { need_update_timing_at_frame_end_ = false; - Analyze(); + UpdateCandidate(); } if (!records_manager_.NeedMeausuringPaintTime()) return; @@ -191,7 +191,7 @@ DCHECK(ThreadState::Current()->IsMainThread()); records_manager_.AssignPaintTimeToRegisteredQueuedNodes( timestamp, last_queued_frame_index); - Analyze(); + UpdateCandidate(); } void ImageRecordsManager::AssignPaintTimeToRegisteredQueuedNodes( @@ -460,7 +460,7 @@ const Image& image) { // Background images attached to <body> or <html> are likely for background // purpose, so we rule them out. - if (object.IsLayoutView()) { + if (object.IsLayoutView() || object.IsBody() || object.IsDocumentElement()) { return false; } // Generated images are excluded here, as they are likely to serve for
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector.h b/third_party/blink/renderer/core/paint/image_paint_timing_detector.h index 353a9d32..a1b3594d 100644 --- a/third_party/blink/renderer/core/paint/image_paint_timing_detector.h +++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
@@ -208,7 +208,7 @@ void Deactivate(); void HandleTooManyNodes(); - void Analyze(); + void UpdateCandidate(); base::RepeatingCallback<void(WebWidgetClient::ReportTimeCallback)> notify_swap_time_override_for_testing_;
diff --git a/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc index ed03cb3..e4e84ac 100644 --- a/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc +++ b/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
@@ -108,8 +108,10 @@ .records_manager_.size_ordered_set_.size(); } - void Analyze() { - return GetPaintTimingDetector().GetImagePaintTimingDetector().Analyze(); + void UpdateCandidate() { + return GetPaintTimingDetector() + .GetImagePaintTimingDetector() + .UpdateCandidate(); } TimeTicks LargestPaintStoredResult() { @@ -596,7 +598,7 @@ )HTML"); SetImageAndPaint("target", 5, 5); UpdateAllLifecyclePhasesForTest(); - Analyze(); + UpdateCandidate(); } TEST_F(ImagePaintTimingDetectorTest, Iframe) {
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc index 45d02cf..be3f9495 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
@@ -73,21 +73,28 @@ } void TextPaintTimingDetector::TimerFired(TimerBase* time) { - // Wrap Analyze method in TimerFired so that we can drop |time| for Analyze - // in testing. - Analyze(); + // Wrap |UpdateCandidate| method in TimerFired so that we can drop |time| for + // |UpdateCandidate| in testing. + UpdateCandidate(); } -void TextPaintTimingDetector::Analyze() { +void TextPaintTimingDetector::UpdateCandidate() { TextRecord* candidate = records_manager_.FindLargestPaintCandidate(); - DCHECK(!candidate || !candidate->paint_time.is_null()); - if (candidate && candidate->paint_time != largest_text_paint_) { + if (!candidate) { + largest_text_paint_ = base::TimeTicks(); + largest_text_paint_size_ = 0; + frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming(); + } else if (candidate->paint_time != largest_text_paint_) { OnLargestTextDetected(*candidate); frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming(); } } void TextPaintTimingDetector::OnPaintFinished() { + if (need_update_timing_at_frame_end_) { + need_update_timing_at_frame_end_ = false; + UpdateCandidate(); + } if (records_manager_.NeedMeausuringPaintTime()) { // Start repeating timer only once at the first text paint. if (!timer_.IsActive()) @@ -106,11 +113,7 @@ if (!records_manager_.IsKnownVisibleNode(node_id)) return; records_manager_.SetNodeDetachedIfNeeded(node_id); - if (records_manager_.AreAllVisibleNodesDetached() && - largest_text_paint_ != base::TimeTicks()) { - largest_text_paint_ = base::TimeTicks(); - frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming(); - } + need_update_timing_at_frame_end_ = true; } void TextPaintTimingDetector::RegisterNotifySwapTime(
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h index 855dd93..edaf481 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
@@ -130,7 +130,7 @@ const TextRecord& first_text_paint, unsigned candidate_index) const; void TimerFired(TimerBase*); - void Analyze(); + void UpdateCandidate(); void ReportSwapTime(WebWidgetClient::SwapResult result, base::TimeTicks timestamp); @@ -145,6 +145,7 @@ bool is_recording_ = true; bool has_records_changed_ = true; + bool need_update_timing_at_frame_end_ = false; base::TimeTicks largest_text_paint_; uint64_t largest_text_paint_size_ = 0;
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc index 673ace70..6f36791 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
@@ -96,8 +96,8 @@ CurrentTimeTicks()); } - void SimulateAnalyze() { - GetPaintTimingDetector().GetTextPaintTimingDetector().Analyze(); + void UpdateCandidate() { + GetPaintTimingDetector().GetTextPaintTimingDetector().UpdateCandidate(); } Element* AppendFontElementToBody(String content) { @@ -204,7 +204,7 @@ <div>small text</div> )HTML"); UpdateAllLifecyclePhasesAndSimulateSwapTime(); - SimulateAnalyze(); + UpdateCandidate(); TimeTicks time2 = CurrentTimeTicks(); TimeTicks first_largest = LargestPaintStoredResult(); EXPECT_GE(first_largest, time1); @@ -213,7 +213,7 @@ Text* larger_text = GetDocument().createTextNode("a long-long-long text"); GetDocument().body()->AppendChild(larger_text); UpdateAllLifecyclePhasesAndSimulateSwapTime(); - SimulateAnalyze(); + UpdateCandidate(); TimeTicks time3 = CurrentTimeTicks(); TimeTicks second_largest = LargestPaintStoredResult(); EXPECT_GE(second_largest, time2); @@ -307,13 +307,13 @@ )HTML"); Element* text = AppendDivElementToBody("text to remove"); UpdateAllLifecyclePhasesAndSimulateSwapTime(); - SimulateAnalyze(); + UpdateCandidate(); EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, NodeIdOfText(text)); EXPECT_NE(LargestPaintStoredResult(), base::TimeTicks()); RemoveElement(text); UpdateAllLifecyclePhasesAndSimulateSwapTime(); - SimulateAnalyze(); + UpdateCandidate(); EXPECT_FALSE(TextRecordOfLargestTextPaint()); EXPECT_EQ(LargestPaintStoredResult(), base::TimeTicks()); }
diff --git a/third_party/blink/renderer/modules/notifications/OWNERS b/third_party/blink/renderer/modules/notifications/OWNERS index 2fd0e4b..a5683f2 100644 --- a/third_party/blink/renderer/modules/notifications/OWNERS +++ b/third_party/blink/renderer/modules/notifications/OWNERS
@@ -1,3 +1,4 @@ +knollr@chromium.org peter@chromium.org # TEAM: platform-capabilities@chromium.org
diff --git a/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc b/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc index 1f5d29d01..ab0d0e12 100644 --- a/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc +++ b/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc
@@ -35,7 +35,7 @@ return ScriptPromise::RejectWithDOMException( script_state, DOMException::Create( - DOMExceptionCode::kSecurityError, + DOMExceptionCode::kNotAllowedError, "Access to WakeLock features is disallowed by feature policy")); }
diff --git a/third_party/blink/renderer/modules/webgpu/BUILD.gn b/third_party/blink/renderer/modules/webgpu/BUILD.gn index c030c37..022639f 100644 --- a/third_party/blink/renderer/modules/webgpu/BUILD.gn +++ b/third_party/blink/renderer/modules/webgpu/BUILD.gn
@@ -7,8 +7,6 @@ blink_modules_sources("webgpu") { sources = [ "dawn_callback.h", - "dawn_control_client_holder.cc", - "dawn_control_client_holder.h", "dawn_conversions.cc", "dawn_conversions.h", "dawn_object.cc",
diff --git a/third_party/blink/renderer/modules/webgpu/DEPS b/third_party/blink/renderer/modules/webgpu/DEPS index f3113a02..9a81c895 100644 --- a/third_party/blink/renderer/modules/webgpu/DEPS +++ b/third_party/blink/renderer/modules/webgpu/DEPS
@@ -1,3 +1,10 @@ include_rules = [ + "+cc/layers/texture_layer.h", + "+cc/layers/texture_layer_client.h", + "+cc/resources/cross_thread_shared_bitmap.h", + "+gpu/command_buffer/common/mailbox.h", + "+gpu/command_buffer/common/shared_image_usage.h", + "+gpu/command_buffer/common/sync_token.h", + "+gpu/command_buffer/client/shared_image_interface.h", "+gpu/command_buffer/client/webgpu_interface.h", -] \ No newline at end of file +]
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_object.cc b/third_party/blink/renderer/modules/webgpu/dawn_object.cc index a3bd513..0521f0d 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_object.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_object.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" -#include "third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_object.h b/third_party/blink/renderer/modules/webgpu/dawn_object.h index 8dbec14..06c66ac 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_object.h +++ b/third_party/blink/renderer/modules/webgpu/dawn_object.h
@@ -8,8 +8,8 @@ #include <dawn/dawn.h> #include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h" namespace gpu { namespace webgpu {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu.cc b/third_party/blink/renderer/modules/webgpu/gpu.cc index 6cbc2d54..d4829e4 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu.cc
@@ -12,9 +12,9 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/inspector/console_message.h" -#include "third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h" #include "third_party/blink/renderer/modules/webgpu/gpu_adapter.h" #include "third_party/blink/renderer/modules/webgpu/gpu_request_adapter_options.h" +#include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc index d250d4e9..4e89c55 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_adapter.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" namespace blink {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc index c9fa73f4..5c5f063 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -29,6 +29,16 @@ GPUCanvasContext::~GPUCanvasContext() {} +void GPUCanvasContext::Trace(blink::Visitor* visitor) { + visitor->Trace(swapchain_); + CanvasRenderingContext::Trace(visitor); +} + +const IntSize& GPUCanvasContext::CanvasSize() const { + return Host()->Size(); +} + +// CanvasRenderingContext implementation CanvasRenderingContext::ContextType GPUCanvasContext::GetContextType() const { return CanvasRenderingContext::kContextGPUPresent; } @@ -37,4 +47,37 @@ result.SetGPUCanvasContext(this); } +void GPUCanvasContext::Stop() { + if (swapchain_) { + swapchain_->Neuter(); + swapchain_ = nullptr; + } + stopped_ = true; +} + +cc::Layer* GPUCanvasContext::CcLayer() const { + if (swapchain_) { + return swapchain_->CcLayer(); + } + return nullptr; +} + +// gpu_canvas_context.idl +GPUSwapChain* GPUCanvasContext::configureSwapChain( + const GPUSwapChainDescriptor* descriptor) { + // TODO(cwallez@chromium.org): This should probably throw an exception, + // implement the exception when the WebGPU group decided what it should be. + if (stopped_) { + return nullptr; + } + + if (swapchain_) { + // Tell any previous swapchain that it will no longer be used and can + // destroy all its resources (and produce errors when used). + swapchain_->Neuter(); + } + swapchain_ = GPUSwapChain::Create(this, descriptor); + return swapchain_; +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h index aa4b69d..0360222 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
@@ -7,14 +7,17 @@ #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" namespace blink { +class GPUSwapChain; +class GPUSwapChainDescriptor; + // A GPUCanvasContext does little by itself and basically just binds a canvas -// and a GPUSwapChain together and forwards calls from one to the other. The -// logic that are in other CanvasRenderingContext is in GPUSwapChain instead. +// and a GPUSwapChain together and forwards calls from one to the other. class GPUCanvasContext : public CanvasRenderingContext { DEFINE_WRAPPERTYPEINFO(); @@ -36,6 +39,9 @@ const CanvasContextCreationAttributesCore&); ~GPUCanvasContext() override; + void Trace(blink::Visitor*) override; + const IntSize& CanvasSize() const; + // CanvasRenderingContext implementation ContextType GetContextType() const override; void SetCanvasGetContextResult(RenderingContext&) final; @@ -51,14 +57,16 @@ void SetFilterQuality(SkFilterQuality) final {} bool IsPaintable() const final { return true; } int ExternallyAllocatedBufferCountPerPixel() final { return 1; } - void Stop() override {} - cc::Layer* CcLayer() const final { return nullptr; } + void Stop() final; + cc::Layer* CcLayer() const final; // gpu_canvas_context.idl - // TODO(crbug.com/877147): implement GPUCanvasContext. + GPUSwapChain* configureSwapChain(const GPUSwapChainDescriptor* descriptor); private: DISALLOW_COPY_AND_ASSIGN(GPUCanvasContext); + Member<GPUSwapChain> swapchain_; + bool stopped_ = false; }; DEFINE_TYPE_CASTS(GPUCanvasContext,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl index 406e125..71b4faf 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl
@@ -7,4 +7,5 @@ [ RuntimeEnabled=WebGPU ] interface GPUCanvasContext { + GPUSwapChain configureSwapChain(GPUSwapChainDescriptor descriptor); };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc index 25d194906..79a918eb 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h" -#include "third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h" #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h" #include "third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.h"
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc index a996f3d..3b76bec 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -8,8 +8,6 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/inspector/console_message.h" -#include "third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h" - #include "third_party/blink/renderer/modules/webgpu/gpu_adapter.h" #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h" #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.h"
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc index a39dbfc..799bdb1 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc
@@ -4,24 +4,82 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h" +#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h" namespace blink { // static -GPUSwapChain* GPUSwapChain::Create(GPUDevice* device, - DawnSwapChain swap_chain) { - return MakeGarbageCollected<GPUSwapChain>(device, swap_chain); +GPUSwapChain* GPUSwapChain::Create(GPUCanvasContext* context, + const GPUSwapChainDescriptor* descriptor) { + return MakeGarbageCollected<GPUSwapChain>(context, descriptor); } -GPUSwapChain::GPUSwapChain(GPUDevice* device, DawnSwapChain swap_chain) - : DawnObject<DawnSwapChain>(device, swap_chain) {} +GPUSwapChain::GPUSwapChain(GPUCanvasContext* context, + const GPUSwapChainDescriptor* descriptor) + : DawnObjectBase(descriptor->device()->GetDawnControlClient()), + device_(descriptor->device()), + context_(context), + usage_(AsDawnEnum<DawnTextureUsageBit>(descriptor->usage())) { + swap_buffers_ = base::AdoptRef( + new WebGPUSwapBufferProvider(this, GetDawnControlClient(), usage_)); +} GPUSwapChain::~GPUSwapChain() { - if (IsDawnControlClientDestroyed()) { - return; + Neuter(); +} + +void GPUSwapChain::Trace(blink::Visitor* visitor) { + visitor->Trace(device_); + visitor->Trace(context_); + visitor->Trace(texture_); + ScriptWrappable::Trace(visitor); +} + +void GPUSwapChain::Neuter() { + texture_ = nullptr; + + DCHECK(swap_buffers_); + if (!swap_buffers_) { + swap_buffers_->Neuter(); + swap_buffers_ = nullptr; } - GetProcs().swapChainRelease(GetHandle()); +} + +cc::Layer* GPUSwapChain::CcLayer() { + DCHECK(swap_buffers_); + return swap_buffers_->CcLayer(); +} + +// gpu_swap_chain.idl +GPUTexture* GPUSwapChain::getCurrentTexture() { + if (!swap_buffers_) { + // TODO(cwallez@chromium.org) return an error texture. + return nullptr; + } + + // Calling getCurrentTexture returns a texture that is valid until the + // animation frame it gets presented. If getCurrenTexture is called multiple + // time, the same texture should be returned. |texture_| is set to null when + // presented so that we know we should create a new one. + if (texture_) { + return texture_; + } + + DawnTexture dawn_client_texture = swap_buffers_->GetNewTexture( + device_->GetHandle(), context_->CanvasSize()); + DCHECK(dawn_client_texture); + texture_ = MakeGarbageCollected<GPUTexture>(device_, dawn_client_texture); + return texture_; +} + +// WebGPUSwapBufferProvider::Client implementation +void GPUSwapChain::OnTextureTransferred() { + DCHECK(texture_); + texture_ = nullptr; } } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h index 9a4c7ae..dcd998c4 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h
@@ -6,24 +6,51 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_SWAP_CHAIN_H_ #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" +#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h" + +namespace cc { +class Layer; +} namespace blink { +class GPUCanvasContext; class GPUDevice; +class GPUSwapChainDescriptor; +class GPUTexture; -class GPUSwapChain : public DawnObject<DawnSwapChain> { +class GPUSwapChain : public DawnObjectBase, + public WebGPUSwapBufferProvider::Client { DEFINE_WRAPPERTYPEINFO(); public: - static GPUSwapChain* Create(GPUDevice* device, DawnSwapChain swap_chain); - explicit GPUSwapChain(GPUDevice* devivce, DawnSwapChain swap_chain); + static GPUSwapChain* Create(GPUCanvasContext* context, + const GPUSwapChainDescriptor* descriptor); + explicit GPUSwapChain(GPUCanvasContext* context, + const GPUSwapChainDescriptor* descriptor); ~GPUSwapChain() override; + void Trace(blink::Visitor* visitor) override; + + void Neuter(); + cc::Layer* CcLayer(); + // gpu_swap_chain.idl - // TODO(crbug.com/877147): implement GPUSwapChain. + GPUTexture* getCurrentTexture(); + + // WebGPUSwapBufferProvider::Client implementation + void OnTextureTransferred() override; private: DISALLOW_COPY_AND_ASSIGN(GPUSwapChain); + + scoped_refptr<WebGPUSwapBufferProvider> swap_buffers_; + + Member<GPUDevice> device_; + Member<GPUCanvasContext> context_; + DawnTextureUsageBit usage_; + + Member<GPUTexture> texture_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.idl b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.idl index 5a20e4af..b3baf97 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.idl
@@ -7,4 +7,5 @@ [ RuntimeEnabled=WebGPU ] interface GPUSwapChain { + GPUTexture getCurrentTexture(); };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl index 84b443b..365a07ef 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl
@@ -5,7 +5,7 @@ // https://github.com/gpuweb/gpuweb/blob/master/design/sketch.webidl dictionary GPUSwapChainDescriptor { - required GPUCanvasContext context; + required GPUDevice device; required GPUTextureFormat format; GPUTextureUsageFlags usage = 16; // GPUTextureUsage.OUTPUT_ATTACHMENT };
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 8420081..277254a 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -963,6 +963,8 @@ "graphics/filters/spot_light_source.h", "graphics/generated_image.cc", "graphics/generated_image.h", + "graphics/gpu/dawn_control_client_holder.cc", + "graphics/gpu/dawn_control_client_holder.h", "graphics/gpu/drawing_buffer.cc", "graphics/gpu/drawing_buffer.h", "graphics/gpu/extensions_3d_util.cc", @@ -977,6 +979,8 @@ "graphics/gpu/shared_gpu_context.h", "graphics/gpu/webgl_image_conversion.cc", "graphics/gpu/webgl_image_conversion.h", + "graphics/gpu/webgpu_swap_buffer_provider.cc", + "graphics/gpu/webgpu_swap_buffer_provider.h", "graphics/gpu/xr_frame_transport.cc", "graphics/gpu/xr_frame_transport.h", "graphics/gpu/xr_webgl_drawing_buffer.cc", @@ -1736,6 +1740,7 @@ "graphics/gpu/drawing_buffer_test.cc", "graphics/gpu/shared_gpu_context_test.cc", "graphics/gpu/webgl_image_conversion_test.cc", + "graphics/gpu/webgpu_swap_buffer_provider_test.cc", "graphics/graphics_context_test.cc", "graphics/paint/cull_rect_test.cc", "graphics/paint/display_item_client_test.cc",
diff --git a/third_party/blink/renderer/platform/geometry/float_size.h b/third_party/blink/renderer/platform/geometry/float_size.h index 74f13ab..b5e26b5 100644 --- a/third_party/blink/renderer/platform/geometry/float_size.h +++ b/third_party/blink/renderer/platform/geometry/float_size.h
@@ -81,7 +81,10 @@ -std::numeric_limits<float>::epsilon() < height_ && height_ < std::numeric_limits<float>::epsilon(); } - bool IsValid() const { return !std::isnan(width_) && !std::isnan(height_); } + bool IsValid() const { + return width_ != -std::numeric_limits<float>::infinity() && + height_ != -std::numeric_limits<float>::infinity(); + } bool IsExpressibleAsIntSize() const; float AspectRatio() const { return width_ / height_; } @@ -232,11 +235,14 @@ STATIC_ONLY(DefaultHash); struct Hash { STATIC_ONLY(Hash); + typedef typename IntTypes<sizeof(float)>::UnsignedType Bits; static unsigned GetHash(const blink::FloatSize& key) { - return HashInts(key.Width(), key.Height()); + return HashInts(bit_cast<Bits>(key.Width()), + bit_cast<Bits>(key.Height())); } static bool Equal(const blink::FloatSize& a, const blink::FloatSize& b) { - return a == b; + return bit_cast<Bits>(a.Width()) == bit_cast<Bits>(b.Width()) && + bit_cast<Bits>(a.Height()) == bit_cast<Bits>(b.Height()); } static const bool safe_to_compare_to_empty_or_deleted = true; }; @@ -245,11 +251,14 @@ template <> struct HashTraits<blink::FloatSize> : GenericHashTraits<blink::FloatSize> { STATIC_ONLY(HashTraits); - static const bool kEmptyValueIsZero = true; - static blink::FloatSize EmptyValue() { return blink::FloatSize(); } + static const bool kEmptyValueIsZero = false; + static blink::FloatSize EmptyValue() { + return blink::FloatSize(std::numeric_limits<float>::infinity(), + std::numeric_limits<float>::infinity()); + } static void ConstructDeletedValue(blink::FloatSize& slot, bool) { - float quiet_nan = std::numeric_limits<float>::quiet_NaN(); - slot = blink::FloatSize(quiet_nan, quiet_nan); + slot = blink::FloatSize(-std::numeric_limits<float>::infinity(), + -std::numeric_limits<float>::infinity()); } static bool IsDeletedValue(const blink::FloatSize& value) { return !value.IsValid();
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc b/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc index e87d8af..ce5709eb 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc
@@ -59,7 +59,7 @@ return true; } -static void SaturateMatrix(float s, SkScalar matrix[kColorMatrixSize]) { +static void SaturateMatrix(float s, float matrix[kColorMatrixSize]) { matrix[0] = 0.213f + 0.787f * s; matrix[1] = 0.715f - 0.715f * s; matrix[2] = 0.072f - 0.072f * s; @@ -77,7 +77,7 @@ matrix[19] = 0; } -static void HueRotateMatrix(float hue, SkScalar matrix[kColorMatrixSize]) { +static void HueRotateMatrix(float hue, float matrix[kColorMatrixSize]) { float cos_hue = cosf(hue * kPiFloat / 180); float sin_hue = sinf(hue * kPiFloat / 180); matrix[0] = 0.213f + cos_hue * 0.787f - sin_hue * 0.213f; @@ -97,8 +97,8 @@ matrix[19] = 0; } -static void LuminanceToAlphaMatrix(SkScalar matrix[kColorMatrixSize]) { - memset(matrix, 0, kColorMatrixSize * sizeof(SkScalar)); +static void LuminanceToAlphaMatrix(float matrix[kColorMatrixSize]) { + memset(matrix, 0, kColorMatrixSize * sizeof(float)); matrix[15] = 0.2125f; matrix[16] = 0.7154f; matrix[17] = 0.0721f; @@ -107,8 +107,8 @@ static sk_sp<SkColorFilter> CreateColorFilter(ColorMatrixType type, const Vector<float>& values) { // Use defaults if values contains too few/many values. - SkScalar matrix[kColorMatrixSize]; - memset(matrix, 0, kColorMatrixSize * sizeof(SkScalar)); + float matrix[kColorMatrixSize]; + memset(matrix, 0, kColorMatrixSize * sizeof(float)); matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1; switch (type) { @@ -119,10 +119,6 @@ for (unsigned i = 0; i < kColorMatrixSize; ++i) matrix[i] = values[i]; } - matrix[4] *= SkScalar(255); - matrix[9] *= SkScalar(255); - matrix[14] *= SkScalar(255); - matrix[19] *= SkScalar(255); break; case FECOLORMATRIX_TYPE_SATURATE: if (values.size() == 1) @@ -136,7 +132,7 @@ LuminanceToAlphaMatrix(matrix); break; } - return SkColorFilters::MatrixRowMajor255(matrix); + return SkColorFilters::Matrix(matrix); } bool FEColorMatrix::AffectsTransparentPixels() const {
diff --git a/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc b/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc index b1d52cb2..a23b3fd 100644 --- a/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc +++ b/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc
@@ -38,9 +38,9 @@ sk_sp<PaintFilter> SourceAlpha::CreateImageFilter() { sk_sp<PaintFilter> source_graphic(paint_filter_builder::Build( InputEffect(0), OperatingInterpolationSpace())); - SkScalar matrix[20] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1, 0}; - sk_sp<SkColorFilter> color_filter = SkColorFilters::MatrixRowMajor255(matrix); + float matrix[20] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}; + sk_sp<SkColorFilter> color_filter = SkColorFilters::Matrix(matrix); return sk_make_sp<ColorFilterPaintFilter>(std::move(color_filter), std::move(source_graphic)); }
diff --git a/third_party/blink/renderer/platform/graphics/gpu/DEPS b/third_party/blink/renderer/platform/graphics/gpu/DEPS index 5effcc4e..b7824e6 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/DEPS +++ b/third_party/blink/renderer/platform/graphics/gpu/DEPS
@@ -6,6 +6,8 @@ "+gpu/command_buffer/client/gles2_interface.h", "+gpu/command_buffer/client/gles2_interface_stub.h", "+gpu/command_buffer/client/shared_image_interface.h", + "+gpu/command_buffer/client/webgpu_interface.h", + "+gpu/command_buffer/client/webgpu_interface_stub.h", "+gpu/command_buffer/common/capabilities.h", "+gpu/command_buffer/common/gpu_memory_buffer_support.h", "+gpu/command_buffer/common/mailbox_holder.h",
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.cc b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc similarity index 92% rename from third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.cc rename to third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.cc index 063cb30..594e4408 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.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 "third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h" +#include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h" #include "base/logging.h" #include "gpu/command_buffer/client/webgpu_interface.h"
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h similarity index 73% rename from third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h rename to third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h index 07fd46fe..20e93d3e 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_control_client_holder.h +++ b/third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h
@@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_DAWN_CONTROL_CLIENT_HOLDER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_DAWN_CONTROL_CLIENT_HOLDER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DAWN_CONTROL_CLIENT_HOLDER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DAWN_CONTROL_CLIENT_HOLDER_H_ #include <dawn/dawn.h> #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" +#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" namespace gpu { @@ -23,7 +24,8 @@ // This class holds the WebGPUInterface and a |destroyed_| flag. // DawnControlClientHolder::MarkDestroyed() should be called if the // backing WebGPUInterface has been destroyed. -class DawnControlClientHolder : public RefCounted<DawnControlClientHolder> { +class PLATFORM_EXPORT DawnControlClientHolder + : public RefCounted<DawnControlClientHolder> { public: DawnControlClientHolder( std::unique_ptr<WebGraphicsContext3DProvider> context_provider); @@ -46,4 +48,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_DAWN_CONTROL_CLIENT_HOLDER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DAWN_CONTROL_CLIENT_HOLDER_H_
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h index ab95665..fd518c3 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h +++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h
@@ -8,6 +8,7 @@ #include "build/build_config.h" #include "cc/test/stub_decode_cache.h" #include "components/viz/test/test_context_provider.h" +#include "gpu/command_buffer/client/webgpu_interface.h" #include "gpu/command_buffer/common/capabilities.h" #include "gpu/config/gpu_feature_info.h" #include "testing/gmock/include/gmock/gmock.h" @@ -37,12 +38,15 @@ WebGraphicsContext3DProviderForTests( std::unique_ptr<gpu::gles2::GLES2Interface> gl) : gl_(std::move(gl)) {} + WebGraphicsContext3DProviderForTests( + std::unique_ptr<gpu::webgpu::WebGPUInterface> webgpu) + : webgpu_(std::move(webgpu)) {} gpu::gles2::GLES2Interface* ContextGL() override { return gl_.get(); } - - // Not used by WebGL code. GrContext* GetGrContext() override { return nullptr; } - gpu::webgpu::WebGPUInterface* WebGPUInterface() override { return nullptr; } + gpu::webgpu::WebGPUInterface* WebGPUInterface() override { + return webgpu_.get(); + } bool BindToCurrentThread() override { return false; } const gpu::Capabilities& GetCapabilities() const override { return capabilities_; @@ -66,27 +70,12 @@ private: cc::StubDecodeCache image_decode_cache_; std::unique_ptr<gpu::gles2::GLES2Interface> gl_; + std::unique_ptr<gpu::webgpu::WebGPUInterface> webgpu_; gpu::Capabilities capabilities_; gpu::GpuFeatureInfo gpu_feature_info_; viz::TestSharedImageInterface test_shared_image_interface_; }; -// The target to use when binding a texture to a Chromium image. -GLenum ImageCHROMIUMTextureTarget() { -#if defined(OS_MACOSX) - return GC3D_TEXTURE_RECTANGLE_ARB; -#else - return GL_TEXTURE_2D; -#endif -} - -// The target to use when preparing a mailbox texture. -GLenum DrawingBufferTextureTarget() { - if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) - return ImageCHROMIUMTextureTarget(); - return GL_TEXTURE_2D; -} - class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub, public DrawingBuffer::Client { public: @@ -243,7 +232,7 @@ MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); void BindTexImage2DCHROMIUM(GLenum target, GLint image_id) override { - if (target == ImageCHROMIUMTextureTarget()) { + if (target == kImageCHROMIUMTarget) { texture_sizes_.Set(bound_textures_[target], image_sizes_.find(image_id)->value); image_to_texture_map_.Set(image_id, bound_textures_[target]); @@ -253,7 +242,7 @@ MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); void ReleaseTexImage2DCHROMIUM(GLenum target, GLint image_id) override { - if (target == ImageCHROMIUMTextureTarget()) { + if (target == kImageCHROMIUMTarget) { image_sizes_.Set(current_image_id_, IntSize()); image_to_texture_map_.erase(image_id); ReleaseTexImage2DMock(image_id); @@ -377,6 +366,13 @@ } private: + // The target to use when binding a texture to a Chromium image. +#if defined(OS_MACOSX) + static constexpr GLuint kImageCHROMIUMTarget = GC3D_TEXTURE_RECTANGLE_ARB; +#else + static constexpr GLuint kImageCHROMIUMTarget = GL_TEXTURE_2D; +#endif + std::map<GLenum, GLuint> bound_textures_; // State tracked to verify that it is restored correctly.
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc new file mode 100644 index 0000000..39789d5 --- /dev/null +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
@@ -0,0 +1,187 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h" + +#include "gpu/GLES2/gl2extchromium.h" +#include "gpu/command_buffer/client/shared_image_interface.h" +#include "gpu/command_buffer/client/webgpu_interface.h" +#include "gpu/command_buffer/common/shared_image_usage.h" +#include "third_party/blink/renderer/platform/graphics/graphics_layer.h" + +namespace blink { + +WebGPUSwapBufferProvider::WebGPUSwapBufferProvider( + Client* client, + scoped_refptr<DawnControlClientHolder> dawn_control_client, + DawnTextureUsageBit usage) + : dawn_control_client_(dawn_control_client), + client_(client), + usage_(usage) { + // Create a layer that will be used by the canvas and will ask for a + // SharedImage each frame. + layer_ = cc::TextureLayer::CreateForMailbox(this); + + layer_->SetIsDrawable(true); + layer_->SetBlendBackgroundColor(false); + layer_->SetNearestNeighbor(true); + // TODO(cwallez@chromium.org): These flags aren't taken into account when the + // layer is promoted to an overlay. Make sure we have fallback / emulation + // paths to keep the rendering correct in that cases. + layer_->SetContentsOpaque(true); + layer_->SetPremultipliedAlpha(true); + + GraphicsLayer::RegisterContentsLayer(layer_.get()); +} + +WebGPUSwapBufferProvider::~WebGPUSwapBufferProvider() { + Neuter(); +} + +cc::Layer* WebGPUSwapBufferProvider::CcLayer() { + DCHECK(!neutered_); + return layer_.get(); +} + +void WebGPUSwapBufferProvider::Neuter() { + if (neutered_) { + return; + } + + if (layer_) { + GraphicsLayer::UnregisterContentsLayer(layer_.get()); + layer_->ClearClient(); + layer_ = nullptr; + } + + if (current_swap_buffer_) { + // Ensure we wait for previous WebGPU commands before destroying the shared + // image. + gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface(); + webgpu->GenUnverifiedSyncTokenCHROMIUM( + current_swap_buffer_->access_finished_token.GetData()); + current_swap_buffer_ = nullptr; + } + + client_ = nullptr; + neutered_ = true; +} + +DawnTexture WebGPUSwapBufferProvider::GetNewTexture(DawnDevice device, + const IntSize& size) { + DCHECK(!current_swap_buffer_); + + gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface(); + gpu::SharedImageInterface* sii = + dawn_control_client_->GetContextProvider()->SharedImageInterface(); + + // Create a new swap buffer. + // TODO(cwallez@chromium.org): have some recycling mechanism. + gpu::Mailbox mailbox = sii->CreateSharedImage( + viz::RGBA_8888, static_cast<gfx::Size>(size), + gfx::ColorSpace::CreateSRGB(), + gpu::SHARED_IMAGE_USAGE_WEBGPU | gpu::SHARED_IMAGE_USAGE_DISPLAY); + gpu::SyncToken creation_token = sii->GenUnverifiedSyncToken(); + + current_swap_buffer_ = base::AdoptRef(new SwapBuffer( + this, mailbox, creation_token, static_cast<gfx::Size>(size))); + + // Make sure previous Dawn wire commands are sent so that for example the ID + // is freed before we associate the SharedImage. + webgpu->FlushCommands(); + + // Ensure the shared image is allocated service-side before working with it + webgpu->WaitSyncTokenCHROMIUM( + current_swap_buffer_->access_finished_token.GetConstData()); + + // Associate the mailbox to a dawn_wire client DawnTexture object + gpu::webgpu::ReservedTexture reservation = webgpu->ReserveTexture(device); + DCHECK(reservation.texture); + wire_texture_id_ = reservation.id; + wire_texture_generation_ = reservation.generation; + + webgpu->AssociateMailbox( + 0, 0, reservation.id, reservation.generation, usage_, + reinterpret_cast<GLbyte*>(¤t_swap_buffer_->mailbox)); + + // When the page request a texture it means we'll need to present it on the + // next animation frame. + layer_->SetNeedsDisplay(); + + return reservation.texture; +} + +bool WebGPUSwapBufferProvider::PrepareTransferableResource( + cc::SharedBitmapIdRegistrar* bitmap_registrar, + viz::TransferableResource* out_resource, + std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) { + DCHECK(!neutered_); + + if (!current_swap_buffer_ || neutered_) { + return false; + } + + DCHECK(client_); + client_->OnTextureTransferred(); + + // Make Dawn relinquish access to the texture so it can be used by the + // compositor. This will call dawn::Texture::Destroy so that further accesses + // to the texture are errors. + gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface(); + DCHECK_NE(wire_texture_id_, 0u); + webgpu->DissociateMailbox(wire_texture_id_, wire_texture_generation_); + + // Make the compositor wait on previous Dawn commands. + webgpu->GenUnverifiedSyncTokenCHROMIUM( + current_swap_buffer_->access_finished_token.GetData()); + + // Populate the output resource + *out_resource = viz::TransferableResource::MakeGLOverlay( + current_swap_buffer_->mailbox, GL_LINEAR, GL_TEXTURE_RECTANGLE_ARB, + current_swap_buffer_->access_finished_token, current_swap_buffer_->size, + false); + out_resource->color_space = gfx::ColorSpace::CreateSRGB(); + out_resource->format = viz::RGBA_8888; + + // This holds a ref on the SwapBuffers that will keep it alive until the + // mailbox is released (and while the release callback is running). + auto func = WTF::Bind(&WebGPUSwapBufferProvider::MailboxReleased, + scoped_refptr<WebGPUSwapBufferProvider>(this), + current_swap_buffer_); + *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func)); + + current_swap_buffer_ = nullptr; + wire_texture_id_ = 0; + wire_texture_generation_ = 0; + + return true; +} + +void WebGPUSwapBufferProvider::MailboxReleased( + scoped_refptr<SwapBuffer> swap_buffer, + const gpu::SyncToken& sync_token, + bool lost_resource) { + // Update the SyncToken to ensure that we will wait for it even if we + // immediately destroy this buffer. + swap_buffer->access_finished_token = sync_token; +} + +WebGPUSwapBufferProvider::SwapBuffer::SwapBuffer( + WebGPUSwapBufferProvider* swap_buffers, + gpu::Mailbox mailbox, + gpu::SyncToken creation_token, + gfx::Size size) + : size(size), + mailbox(mailbox), + swap_buffers(swap_buffers), + access_finished_token(creation_token) {} + +WebGPUSwapBufferProvider::SwapBuffer::~SwapBuffer() { + gpu::SharedImageInterface* sii = + swap_buffers->dawn_control_client_->GetContextProvider() + ->SharedImageInterface(); + sii->DestroySharedImage(access_finished_token, mailbox); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h new file mode 100644 index 0000000..6729a082 --- /dev/null +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
@@ -0,0 +1,95 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_SWAP_BUFFER_PROVIDER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_SWAP_BUFFER_PROVIDER_H_ + +#include "cc/layers/texture_layer.h" +#include "cc/layers/texture_layer_client.h" +#include "gpu/command_buffer/common/mailbox.h" +#include "gpu/command_buffer/common/sync_token.h" +#include "third_party/blink/renderer/platform/geometry/int_size.h" +#include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h" +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" +#include "third_party/blink/renderer/platform/wtf/ref_counted.h" + +namespace blink { + +// WebGPUSwapBufferProvider contains the cc::Layer used by the swapchain as well +// as the resources used for the layer. It is separate from GPUSwapChain so that +// it can be kept alive via refcounting instead of garbage collection and so it +// can live in blink_platform and use gpu:: or viz:: types. +class PLATFORM_EXPORT WebGPUSwapBufferProvider + : public cc::TextureLayerClient, + public RefCounted<WebGPUSwapBufferProvider> { + public: + class Client { + public: + // Called to make the WebGPU/Dawn stop accessing the texture prior to its + // transfer to the compositor. + virtual void OnTextureTransferred() = 0; + }; + + WebGPUSwapBufferProvider( + Client* client, + scoped_refptr<DawnControlClientHolder> dawn_control_client, + DawnTextureUsageBit usage); + ~WebGPUSwapBufferProvider() override; + + cc::Layer* CcLayer(); + void Neuter(); + DawnTexture GetNewTexture(DawnDevice device, const IntSize& size); + + // cc::TextureLayerClient implementation. + bool PrepareTransferableResource( + cc::SharedBitmapIdRegistrar* bitmap_registrar, + viz::TransferableResource* out_resource, + std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) + override; + + private: + // Holds resources and synchronization for one of the swapchain images. + struct SwapBuffer : public RefCounted<SwapBuffer> { + SwapBuffer(WebGPUSwapBufferProvider*, + gpu::Mailbox mailbox, + gpu::SyncToken creation_token, + gfx::Size size); + ~SwapBuffer(); + + gfx::Size size; + gpu::Mailbox mailbox; + + // A reference back to the swap buffers to keep it alive while this image + // is in flight so that the destructor can access data in the swap + // buffers. + scoped_refptr<WebGPUSwapBufferProvider> swap_buffers; + + // A token signaled when the previous user of the image is finished using + // it. It could be WebGPU, the compositor or the shared image creation. + gpu::SyncToken access_finished_token; + + private: + DISALLOW_COPY_AND_ASSIGN(SwapBuffer); + }; + + void MailboxReleased(scoped_refptr<SwapBuffer> swap_buffer, + const gpu::SyncToken& sync_token, + bool lost_resource); + + scoped_refptr<DawnControlClientHolder> dawn_control_client_; + Client* client_; + scoped_refptr<cc::TextureLayer> layer_; + bool neutered_ = false; + + DawnTextureUsageBit usage_; + + uint32_t wire_texture_id_ = 0; + uint32_t wire_texture_generation_ = 0; + scoped_refptr<SwapBuffer> current_swap_buffer_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_SWAP_BUFFER_PROVIDER_H_
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc new file mode 100644 index 0000000..5d9bafb --- /dev/null +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
@@ -0,0 +1,210 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h" + +#include "gpu/command_buffer/client/webgpu_interface_stub.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" +#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h" + +using testing::_; +using testing::Return; + +namespace blink { + +namespace { + +class MockWebGPUInterface : public gpu::webgpu::WebGPUInterfaceStub { + public: + MOCK_METHOD1(ReserveTexture, gpu::webgpu::ReservedTexture(DawnDevice device)); + + // It is hard to use GMock with SyncTokens represented as GLByte*, instead we + // remember which were the last sync tokens generated or waited upon. + void GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) override { + most_recent_generated_token = + gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, + gpu::CommandBufferId(), ++token_id_); + memcpy(sync_token, &most_recent_generated_token, sizeof(gpu::SyncToken)); + } + void GenSyncTokenCHROMIUM(GLbyte* sync_token) override { + most_recent_generated_token = + gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO, + gpu::CommandBufferId(), ++token_id_); + most_recent_generated_token.SetVerifyFlush(); + memcpy(sync_token, &most_recent_generated_token, sizeof(gpu::SyncToken)); + } + + void WaitSyncTokenCHROMIUM(const GLbyte* sync_token_data) override { + memcpy(&most_recent_waited_token, sync_token_data, sizeof(gpu::SyncToken)); + } + gpu::SyncToken most_recent_generated_token; + gpu::SyncToken most_recent_waited_token; + + private: + uint64_t token_id_ = 42; +}; + +class FakeProviderClient : public WebGPUSwapBufferProvider::Client { + public: + void OnTextureTransferred() override {} +}; + +class WebGPUSwapBufferProviderForTests : public WebGPUSwapBufferProvider { + public: + WebGPUSwapBufferProviderForTests( + bool* alive, + Client* client, + scoped_refptr<DawnControlClientHolder> dawn_control_client, + DawnTextureUsageBit usage) + : WebGPUSwapBufferProvider(client, dawn_control_client, usage), + alive_(alive) {} + ~WebGPUSwapBufferProviderForTests() override { *alive_ = false; } + + private: + bool* alive_; +}; + +} // anonymous namespace + +class WebGPUSwapBufferProviderTest : public testing::Test { + protected: + void SetUp() override { + auto webgpu = std::make_unique<MockWebGPUInterface>(); + webgpu_ = webgpu.get(); + + auto provider = std::make_unique<WebGraphicsContext3DProviderForTests>( + std::move(webgpu)); + sii_ = provider->SharedImageInterface(); + + dawn_control_client_ = + base::MakeRefCounted<DawnControlClientHolder>(std::move(provider)); + provider_ = base::MakeRefCounted<WebGPUSwapBufferProviderForTests>( + &provider_alive_, &client_, dawn_control_client_, + DAWN_TEXTURE_USAGE_BIT_OUTPUT_ATTACHMENT); + } + + scoped_refptr<DawnControlClientHolder> dawn_control_client_; + MockWebGPUInterface* webgpu_; + viz::TestSharedImageInterface* sii_; + FakeProviderClient client_; + scoped_refptr<WebGPUSwapBufferProviderForTests> provider_; + bool provider_alive_ = true; +}; + +TEST_F(WebGPUSwapBufferProviderTest, + VerifyDestructionCompleteAfterAllResourceReleased) { + const IntSize kSize(10, 10); + + viz::TransferableResource resource1; + gpu::webgpu::ReservedTexture reservation1 = { + reinterpret_cast<DawnTexture>(&resource1), 1, 1}; + std::unique_ptr<viz::SingleReleaseCallback> release_callback1; + + viz::TransferableResource resource2; + gpu::webgpu::ReservedTexture reservation2 = { + reinterpret_cast<DawnTexture>(&resource2), 2, 2}; + std::unique_ptr<viz::SingleReleaseCallback> release_callback2; + + viz::TransferableResource resource3; + gpu::webgpu::ReservedTexture reservation3 = { + reinterpret_cast<DawnTexture>(&resource3), 3, 3}; + std::unique_ptr<viz::SingleReleaseCallback> release_callback3; + + // Produce resources. + EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation1)); + provider_->GetNewTexture(nullptr, kSize); + EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource1, + &release_callback1)); + + EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation2)); + provider_->GetNewTexture(nullptr, kSize); + EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource2, + &release_callback2)); + + EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation3)); + provider_->GetNewTexture(nullptr, kSize); + EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource3, + &release_callback3)); + + // Release resources one by one, the provider should only be freed when the + // last one is called. + provider_ = nullptr; + release_callback1->Run(gpu::SyncToken(), false /* lostResource */); + ASSERT_EQ(provider_alive_, true); + + release_callback2->Run(gpu::SyncToken(), false /* lostResource */); + ASSERT_EQ(provider_alive_, true); + + release_callback3->Run(gpu::SyncToken(), false /* lostResource */); + ASSERT_EQ(provider_alive_, false); +} + +TEST_F(WebGPUSwapBufferProviderTest, VerifyResizingProperlyAffectsResources) { + const IntSize kSize(10, 10); + const IntSize kOtherSize(20, 20); + + viz::TransferableResource resource; + gpu::webgpu::ReservedTexture reservation = { + reinterpret_cast<DawnTexture>(&resource), 1, 1}; + std::unique_ptr<viz::SingleReleaseCallback> release_callback; + + // Produce one resource of size kSize. + EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation)); + provider_->GetNewTexture(nullptr, static_cast<IntSize>(kSize)); + EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource, + &release_callback)); + EXPECT_EQ(static_cast<gfx::Size>(kSize), sii_->MostRecentSize()); + release_callback->Run(gpu::SyncToken(), false /* lostResource */); + + // Produce one resource of size kOtherSize. + EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation)); + provider_->GetNewTexture(nullptr, static_cast<IntSize>(kOtherSize)); + EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource, + &release_callback)); + EXPECT_EQ(static_cast<gfx::Size>(kOtherSize), sii_->MostRecentSize()); + release_callback->Run(gpu::SyncToken(), false /* lostResource */); + + // Produce one resource of size kSize again. + EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation)); + provider_->GetNewTexture(nullptr, static_cast<IntSize>(kSize)); + EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource, + &release_callback)); + EXPECT_EQ(static_cast<gfx::Size>(kSize), sii_->MostRecentSize()); + release_callback->Run(gpu::SyncToken(), false /* lostResource */); +} + +TEST_F(WebGPUSwapBufferProviderTest, VerifyInsertAndWaitSyncTokenCorrectly) { + const IntSize kSize(10, 10); + + viz::TransferableResource resource; + gpu::webgpu::ReservedTexture reservation = { + reinterpret_cast<DawnTexture>(&resource), 1, 1}; + std::unique_ptr<viz::SingleReleaseCallback> release_callback; + + // Produce the first resource, check that WebGPU will wait for the creation of + // the shared image + EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation)); + provider_->GetNewTexture(nullptr, static_cast<IntSize>(kSize)); + EXPECT_EQ(sii_->MostRecentGeneratedToken(), + webgpu_->most_recent_waited_token); + + // WebGPU should produce a token so that the next of user of the resource can + // synchronize properly + EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource, + &release_callback)); + EXPECT_EQ(webgpu_->most_recent_generated_token, + resource.mailbox_holder.sync_token); + + // Check that the release token is used to synchronize the shared image + // destruction + gpu::SyncToken release_token; + webgpu_->GenSyncTokenCHROMIUM(release_token.GetData()); + release_callback->Run(release_token, false /* lostResource */); + release_callback = nullptr; + EXPECT_EQ(sii_->MostRecentDestroyToken(), release_token); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.cc b/third_party/blink/renderer/platform/heap/heap_compact.cc index dfb69fd..efacd56 100644 --- a/third_party/blink/renderer/platform/heap/heap_compact.cc +++ b/third_party/blink/renderer/platform/heap/heap_compact.cc
@@ -43,13 +43,67 @@ relocatable_pages_.insert(page); } - void AddInteriorFixup(MovableReference* slot) { - auto it = interior_fixups_.find(slot); - // Ephemeron fixpoint iterations may cause repeated registrations. - if (UNLIKELY(it != interior_fixups_.end())) { - DCHECK(!it->second); + void Add(MovableReference* slot) { + MovableReference reference = *slot; + CHECK(reference); + + // All slots and references are part of Oilpan's heap. + CHECK(heap_->LookupPageForAddress(reinterpret_cast<Address>(slot))); + CHECK(heap_->LookupPageForAddress(reinterpret_cast<Address>(reference))); + + BasePage* const reference_page = PageFromObject(reference); + // The following cases are not compacted and do not require recording: + // - Backings in large pages. + // - Inline backings that are part of a non-backing arena. + if (reference_page->IsLargeObjectPage() || + !HeapCompact::IsCompactableArena(reference_page->Arena()->ArenaIndex())) + return; + + // Slots may have been recorded already but must point to the same + // reference. Example: Ephemeron iterations may register slots multiple + // times. + auto fixup_it = fixups_.find(reference); + if (UNLIKELY(fixup_it != fixups_.end())) { + CHECK_EQ(slot, fixup_it->second); return; } + + // References must always point to live objects at this point. + // Slots must reside in live objects + + // Add regular fixup. + fixups_.insert({reference, slot}); + + BasePage* const slot_page = PageFromObject(slot); + + // Slots must reside in and references must point to live objects at this + // point, with the exception of slots in eagerly swept arenas where objects + // have already been processed. |reference| usually points to a separate + // backing store but can also point to inlined storage which is why the + // dynamic header lookup is required. + CHECK(reference_page->Arena()->ArenaIndex() != + BlinkGC::kEagerSweepArenaIndex); + CHECK(static_cast<NormalPage*>(reference_page) + ->FindHeaderFromAddress(reinterpret_cast<Address>(reference)) + ->IsMarked()); + CHECK(slot_page->Arena()->ArenaIndex() == BlinkGC::kEagerSweepArenaIndex || + static_cast<NormalPage*>(slot_page) + ->FindHeaderFromAddress(reinterpret_cast<Address>(slot)) + ->IsMarked()); + + // Check whether the slot itself resides on a page that is compacted. + if (LIKELY(!relocatable_pages_.Contains(slot_page))) + return; + + // Interior slots are recorded as follows: + // - Storing it in the interior map, which maps the slot to its (eventual) + // location. Initially nullptr. + // - Mark it as being interior pointer within the page's interior bitmap. + // This bitmap is used when moving a backing store to check whether an + // interior slot is to be redirected. + auto interior_it = interior_fixups_.find(slot); + // Repeated registrations have been filtered above. + CHECK(interior_fixups_.end() == interior_it); interior_fixups_.insert({slot, nullptr}); LOG_HEAP_COMPACTION() << "Interior slot: " << slot; Address slot_address = reinterpret_cast<Address>(slot); @@ -60,62 +114,6 @@ interiors_->Add(slot_address); } - void Add(MovableReference* slot) { - DCHECK(*slot); - MovableReference reference = *slot; - BasePage* ref_page = - heap_->LookupPageForAddress(reinterpret_cast<Address>(reference)); - - // ref_page is null if *slot is pointing to an off-heap region. This may - // happy if *slot is pointing to an inline buffer of HeapVector with inline - // capacity. - if (!ref_page) - return; - // Nothing to compact on a large object's page. - if (ref_page->IsLargeObjectPage()) - return; - - if (!HeapCompact::IsCompactableArena(ref_page->Arena()->ArenaIndex())) - return; -#if DCHECK_IS_ON() - auto it = fixups_.find(reference); - DCHECK(it == fixups_.end() || it->second == slot); -#endif - - // TODO: when updateHeapResidency() becomes more discriminating about - // leaving out arenas that aren't worth compacting, a check for - // isCompactingArena() would be appropriate here, leaving early if - // |refPage|'s arena isn't in the set. - - fixups_.insert({reference, slot}); - - // Note: |slot| will reside outside the Oilpan heap if it is a - // PersistentHeapCollectionBase. Hence pageFromObject() cannot be - // used, as it sanity checks the |BasePage| it returns. Simply - // derive the raw BasePage address here and check if it is a member - // of the compactable and relocatable page address set. - Address slot_address = reinterpret_cast<Address>(slot); - void* slot_page_address = - BlinkPageAddress(slot_address) + kBlinkGuardPageSize; - if (LIKELY(!relocatable_pages_.Contains(slot_page_address))) - return; -#if DCHECK_IS_ON() - BasePage* slot_page = reinterpret_cast<BasePage*>(slot_page_address); - DCHECK(slot_page->Contains(slot_address)); -#endif - // Unlikely case, the slot resides on a compacting arena's page. - // => It is an 'interior slot' (interior to a movable backing store.) - // Record it as an interior slot, which entails: - // - // - Storing it in the interior map, which maps the slot to - // its (eventual) location. Initially nullptr. - // - Mark it as being interior pointer within the page's - // "interior" bitmap. This bitmap is used when moving a backing - // store, quickly/ier checking if interior slots will have to - // be additionally redirected. - AddInteriorFixup(slot); - } - void AddFixupCallback(MovableReference* slot, MovingObjectCallback callback, void* callback_data) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_utils.cc b/third_party/blink/renderer/platform/loader/fetch/fetch_utils.cc index 89eee30..de359ca2 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_utils.cc +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_utils.cc
@@ -68,4 +68,64 @@ return value.StripWhiteSpace(IsHTTPWhitespace); } +const char* FetchUtils::GetDestinationFromContext( + mojom::RequestContextType context) { + switch (context) { + case mojom::RequestContextType::UNSPECIFIED: + case mojom::RequestContextType::BEACON: + case mojom::RequestContextType::DOWNLOAD: + case mojom::RequestContextType::EVENT_SOURCE: + case mojom::RequestContextType::FETCH: + case mojom::RequestContextType::PING: + case mojom::RequestContextType::XML_HTTP_REQUEST: + case mojom::RequestContextType::SUBRESOURCE: + case mojom::RequestContextType::PREFETCH: + return ""; + case mojom::RequestContextType::CSP_REPORT: + return "report"; + case mojom::RequestContextType::AUDIO: + return "audio"; + case mojom::RequestContextType::EMBED: + return "embed"; + case mojom::RequestContextType::FONT: + return "font"; + case mojom::RequestContextType::FRAME: + case mojom::RequestContextType::HYPERLINK: + case mojom::RequestContextType::IFRAME: + case mojom::RequestContextType::LOCATION: + case mojom::RequestContextType::FORM: + return "document"; + case mojom::RequestContextType::IMAGE: + case mojom::RequestContextType::FAVICON: + case mojom::RequestContextType::IMAGE_SET: + return "image"; + case mojom::RequestContextType::MANIFEST: + return "manifest"; + case mojom::RequestContextType::OBJECT: + return "object"; + case mojom::RequestContextType::SCRIPT: + return "script"; + case mojom::RequestContextType::SERVICE_WORKER: + return "serviceworker"; + case mojom::RequestContextType::SHARED_WORKER: + return "sharedworker"; + case mojom::RequestContextType::STYLE: + return "style"; + case mojom::RequestContextType::TRACK: + return "track"; + case mojom::RequestContextType::VIDEO: + return "video"; + case mojom::RequestContextType::WORKER: + return "worker"; + case mojom::RequestContextType::XSLT: + return "xslt"; + case mojom::RequestContextType::IMPORT: + case mojom::RequestContextType::INTERNAL: + case mojom::RequestContextType::PLUGIN: + return "unknown"; + } + NOTREACHED(); + return ""; +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_utils.h b/third_party/blink/renderer/platform/loader/fetch/fetch_utils.h index f5ab97e..bfbcabd 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_utils.h +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_utils.h
@@ -20,6 +20,11 @@ static bool IsForbiddenResponseHeaderName(const String& name); static AtomicString NormalizeMethod(const AtomicString& method); static String NormalizeHeaderValue(const String& value); + + // This function maps from Blink's internal "request context" concept to + // Fetch's notion of a request's "destination": + // https://fetch.spec.whatwg.org/#concept-request-destination. + static const char* GetDestinationFromContext(mojom::RequestContextType); }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index bdd0251..b66e4fe 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -50,6 +50,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h" +#include "third_party/blink/renderer/platform/loader/fetch/fetch_utils.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h" @@ -277,68 +278,6 @@ } } -// This function maps from Blink's internal "request context" concept to Fetch's -// notion of a request's "destination": -// https://fetch.spec.whatwg.org/#concept-request-destination. -const char* GetDestinationFromContext(mojom::RequestContextType context) { - switch (context) { - case mojom::RequestContextType::UNSPECIFIED: - case mojom::RequestContextType::BEACON: - case mojom::RequestContextType::DOWNLOAD: - case mojom::RequestContextType::EVENT_SOURCE: - case mojom::RequestContextType::FETCH: - case mojom::RequestContextType::PING: - case mojom::RequestContextType::XML_HTTP_REQUEST: - case mojom::RequestContextType::SUBRESOURCE: - case mojom::RequestContextType::PREFETCH: - return ""; - case mojom::RequestContextType::CSP_REPORT: - return "report"; - case mojom::RequestContextType::AUDIO: - return "audio"; - case mojom::RequestContextType::EMBED: - return "embed"; - case mojom::RequestContextType::FONT: - return "font"; - case mojom::RequestContextType::FRAME: - case mojom::RequestContextType::HYPERLINK: - case mojom::RequestContextType::IFRAME: - case mojom::RequestContextType::LOCATION: - case mojom::RequestContextType::FORM: - return "document"; - case mojom::RequestContextType::IMAGE: - case mojom::RequestContextType::FAVICON: - case mojom::RequestContextType::IMAGE_SET: - return "image"; - case mojom::RequestContextType::MANIFEST: - return "manifest"; - case mojom::RequestContextType::OBJECT: - return "object"; - case mojom::RequestContextType::SCRIPT: - return "script"; - case mojom::RequestContextType::SERVICE_WORKER: - return "serviceworker"; - case mojom::RequestContextType::SHARED_WORKER: - return "sharedworker"; - case mojom::RequestContextType::STYLE: - return "style"; - case mojom::RequestContextType::TRACK: - return "track"; - case mojom::RequestContextType::VIDEO: - return "video"; - case mojom::RequestContextType::WORKER: - return "worker"; - case mojom::RequestContextType::XSLT: - return "xslt"; - case mojom::RequestContextType::IMPORT: - case mojom::RequestContextType::INTERNAL: - case mojom::RequestContextType::PLUGIN: - return "unknown"; - } - NOTREACHED(); - return ""; -} - // This maps the network::mojom::FetchRequestMode to a string that can be used // in a `Sec-Fetch-Mode` header. const char* FetchRequestModeToString(network::mojom::FetchRequestMode mode) { @@ -365,7 +304,7 @@ if (blink::RuntimeEnabledFeatures::FetchMetadataEnabled() && url_origin->IsPotentiallyTrustworthy()) { const char* destination_value = - GetDestinationFromContext(request.GetRequestContext()); + FetchUtils::GetDestinationFromContext(request.GetRequestContext()); // If the request's destination is the empty string (e.g. `fetch()`), then // we'll use the identifier "empty" instead.
diff --git a/third_party/blink/renderer/platform/memory_pressure_listener.cc b/third_party/blink/renderer/platform/memory_pressure_listener.cc index ca6f0493..8872352 100644 --- a/third_party/blink/renderer/platform/memory_pressure_listener.cc +++ b/third_party/blink/renderer/platform/memory_pressure_listener.cc
@@ -97,18 +97,12 @@ TRACE_EVENT0("blink", "MemoryPressureListenerRegistry::onMemoryPressure"); for (auto& client : clients_) client->OnMemoryPressure(level); - if (level == kWebMemoryPressureLevelCritical) - ClearMemory(); WTF::Partitions::DecommitFreeableMemory(); } void MemoryPressureListenerRegistry::OnPurgeMemory() { for (auto& client : clients_) client->OnPurgeMemory(); - // Don't call clearMemory() because font cache invalidation always causes full - // layout. This increases tab switching cost significantly (e.g. - // en.wikipedia.org/wiki/Wikipedia). So we should not invalidate the font - // cache in purge+throttle. ImageDecodingStore::Instance().Clear(); WTF::Partitions::DecommitFreeableMemory(); @@ -125,13 +119,6 @@ } } -void MemoryPressureListenerRegistry::ClearMemory() { - // TODO(tasak|bashi): Make FontCache a MemoryPressureListener rather than - // clearing caches here. - if (base::FeatureList::IsEnabled(features::kInvalidateFontCacheOnPurge)) - FontGlobalContext::ClearMemory(); -} - void MemoryPressureListenerRegistry::ClearThreadSpecificMemory() { FontGlobalContext::ClearMemory(); }
diff --git a/third_party/blink/renderer/platform/memory_pressure_listener.h b/third_party/blink/renderer/platform/memory_pressure_listener.h index 0730adec..2a42261 100644 --- a/third_party/blink/renderer/platform/memory_pressure_listener.h +++ b/third_party/blink/renderer/platform/memory_pressure_listener.h
@@ -63,7 +63,6 @@ static void SetIsLowEndDeviceForTesting(bool); - void ClearMemory(); static void ClearThreadSpecificMemory(); static bool is_low_end_device_;
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 64a5222..a05f4614 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -6076,6 +6076,7 @@ crbug.com/948257 external/wpt/console/console-label-conversion.any.html [ Pass Failure ] crbug.com/948257 external/wpt/console/console-label-conversion.any.worker.html [ Pass Failure ] crbug.com/948678 external/wpt/console/idlharness.any.html [ Pass Failure ] +crbug.com/948678 external/wpt/console/idlharness.any.worker.html [ Pass Failure ] ### external/wpt/fetch/sec-metadata/ crbug.com/947023 external/wpt/fetch/sec-metadata/font.tentative.https.sub.html [ Pass Failure ] @@ -6158,3 +6159,6 @@ crbug.com/956547 fast/dom/raf-throttling-out-of-view-cross-origin-page.html [ Pass Timeout ] crbug.com/956547 fast/dom/timer-throttling-out-of-view-cross-origin-page.html [ Pass Timeout ] crbug.com/956736 [ Linux Win ] virtual/gpu-rasterization/images/imagemap-focus-ring-outline-color-not-inherited-from-map.html [ Pass Failure ] + +# Sheriff 2019-04-25 +crbug.com/956547 http/tests/dom/raf-throttling-out-of-view-cross-origin-page.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/OWNERS b/third_party/blink/web_tests/external/wpt/mediacapture-streams/OWNERS index bffa2b1..31acf62 100644 --- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/OWNERS +++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/OWNERS
@@ -1,3 +1,4 @@ # COMPONENT: Blink>MediaStream # WPT-NOTIFY: true guidou@chromium.org +armax@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-disabled-by-feature-policy.https.sub.html b/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-disabled-by-feature-policy.https.sub.html index 75064767..ad7eeb0 100644 --- a/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-disabled-by-feature-policy.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/wake-lock/wakelock-disabled-by-feature-policy.https.sub.html
@@ -12,7 +12,7 @@ "https://{{domains[www]}}:{{ports[https][0]}}" + same_origin_src; promise_test(t => { - return promise_rejects(t, "SecurityError", navigator.getWakeLock("screen")); + return promise_rejects(t, "NotAllowedError", navigator.getWakeLock("screen")); }, 'Feature-Policy header {"wake-lock" : []} disallows the top-level document.'); async_test(t => {
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html index 2389b33..23222e4 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-biquadfilternode-interface/biquad-getFrequencyResponse.html
@@ -36,12 +36,6 @@ let filterQ = 1; let filterGain = 5; // Decibels. - // The maximum allowed error in the magnitude response. - let maxAllowedMagError = 1.09931e-6; - - // The maximum allowed error in the phase response. - let maxAllowedPhaseError = 6.4724e-8; - // The magnitudes and phases of the reference frequency response. let expectedMagnitudes; let expectedPhases; @@ -148,6 +142,10 @@ } } + function decibelsToLinear(x) { + return Math.pow(10, x/20); + } + // Look through the array and find any NaN or infinity. Returns the index // of the first occurence or -1 if none. function findBadNumber(signal) { @@ -171,8 +169,17 @@ } // Compare the frequency response with our expected response. + // + // should - The |should| method provided by audit.define + // filter - The filter node used in the test + // frequencies - array of frequencies provided to |getFrequencyResponse| + // magResponse - mag response from |getFrequencyResponse| + // phaseResponse - phase response from |getFrequencyResponse| + // maxAllowedMagError - error threshold for mag response, in dB + // maxAllowedPhaseError - error threshold for phase response, in rad. function compareResponses( - should, filter, frequencies, magResponse, phaseResponse) { + should, filter, frequencies, magResponse, phaseResponse, + maxAllowedMagError, maxAllowedPhaseError) { let expectedResponse = frequencyResponseReference(filter, frequencies); expectedMagnitudes = expectedResponse.magnitudes; @@ -188,16 +195,19 @@ let hasBadNumber; hasBadNumber = findBadNumber(magResponse); - badResponse = !should( - hasBadNumber >= 0 ? 1 : 0, - 'Number of non-finite values in magnitude response') - .beEqualTo(0); + badResponse = + !should( + hasBadNumber >= 0 ? 1 : 0, + filter.type + + ': Number of non-finite values in magnitude response') + .beEqualTo(0); hasBadNumber = findBadNumber(phaseResponse); - badResponse = !should( - hasBadNumber >= 0 ? 1 : 0, - 'Number of non-finte values in phase response') - .beEqualTo(0); + badResponse = + !should( + hasBadNumber >= 0 ? 1 : 0, + filter.type + ': Number of non-finte values in phase response') + .beEqualTo(0); // These aren't testing the implementation itself. Instead, these are // sanity checks on the reference. Failure here does not imply an error @@ -206,14 +216,16 @@ badResponse = !should( hasBadNumber >= 0 ? 1 : 0, - 'Number of non-finite values in the expected magnitude response') + filter.type + + ': Number of non-finite values in the expected magnitude response') .beEqualTo(0); hasBadNumber = findBadNumber(expectedPhases); badResponse = !should( hasBadNumber >= 0 ? 1 : 0, - 'Number of non-finite values in expected phase response') + filter.type + + ': Number of non-finite values in expected phase response') .beEqualTo(0); // If we found a NaN or infinity, the following tests aren't very @@ -221,7 +233,8 @@ // warning message. should( !badResponse, - 'Actual and expected results contained only finite values') + filter.type + + ': Actual and expected results contained only finite values') .beTrue(); for (k = 0; k < n; ++k) { @@ -236,7 +249,7 @@ should( linearToDecibels(maxMagError), - 'Max error (' + linearToDecibels(maxMagError) + + filter.type + ': Max error (' + linearToDecibels(maxMagError) + ' dB) of magnitude response at frequency ' + frequencies[maxMagErrorIndex] + ' Hz') .beLessThanOrEqualTo(linearToDecibels(maxAllowedMagError)); @@ -254,7 +267,7 @@ should( radToDegree(maxPhaseError), - 'Max error (' + radToDegree(maxPhaseError) + + filter.type + ': Max error (' + radToDegree(maxPhaseError) + ' deg) in phase response at frequency ' + frequencies[maxPhaseErrorIndex] + ' Hz') .beLessThanOrEqualTo(radToDegree(maxAllowedPhaseError)); @@ -265,32 +278,78 @@ return rad * 180 / Math.PI; } - audit.define( - {label: 'test', description: 'Biquad frequency response'}, - function(task, should) { - context = new AudioContext(); + // Test the getFrequencyResponse for each of filter types. Each entry in + // this array is a dictionary with these elements: + // + // type: filter type to be tested + // maxErrorInMagnitude: Allowed error in computed magnitude response + // maxErrorInPhase: Allowed error in computed magnitude phase + [{ + type: 'lowpass', + maxErrorInMagnitude: decibelsToLinear(-73.0178), + maxErrorInPhase: 8.04360e-6 + }, + { + type: 'highpass', + maxErrorInMagnitude: decibelsToLinear(-117.5461), + maxErrorInPhase: 6.9691e-6 + }, + { + type: 'bandpass', + maxErrorInMagnitude: decibelsToLinear(-79.0139), + maxErrorInPhase: 4.9371e-6 + }, + { + type: 'lowshelf', + maxErrorInMagnitude: decibelsToLinear(-120.4038), + maxErrorInPhase: 4.0724e-6 + }, + { + type: 'highshelf', + maxErrorInMagnitude: decibelsToLinear(-120, 1303), + maxErrorInPhase: 4.0724e-6 + }, + { + type: 'peaking', + maxErrorInMagnitude: decibelsToLinear(-119.1176), + maxErrorInPhase: 6.4724e-8 + }, + { + type: 'notch', + maxErrorInMagnitude: decibelsToLinear(-87.0808), + maxErrorInPhase: 6.6300e-6 + }, + { + type: 'allpass', + maxErrorInMagnitude: decibelsToLinear(-265.3517), + maxErrorInPhase: 1.3260e-5 + }].forEach(test => { + audit.define( + {label: test.type, description: 'Frequency response'}, + (task, should) => { + let context = new AudioContext(); - filter = context.createBiquadFilter(); + let filter = new BiquadFilterNode(context, { + type: test.type, + frequency: filterCutoff, + Q: filterQ, + gain: filterGain + }); - // Arbitrarily test a peaking filter, but any kind of filter can be - // tested. - filter.type = 'peaking'; - filter.frequency.value = filterCutoff; - filter.Q.value = filterQ; - filter.gain.value = filterGain; + let frequencies = + createFrequencies(numberOfFrequencies, context.sampleRate); + magResponse = new Float32Array(numberOfFrequencies); + phaseResponse = new Float32Array(numberOfFrequencies); - let frequencies = - createFrequencies(numberOfFrequencies, context.sampleRate); - magResponse = new Float32Array(numberOfFrequencies); - phaseResponse = new Float32Array(numberOfFrequencies); + filter.getFrequencyResponse( + frequencies, magResponse, phaseResponse); + compareResponses( + should, filter, frequencies, magResponse, phaseResponse, + test.maxErrorInMagnitude, test.maxErrorInPhase); - filter.getFrequencyResponse( - frequencies, magResponse, phaseResponse); - compareResponses( - should, filter, frequencies, magResponse, phaseResponse); - - task.done(); - }); + task.done(); + }); + }); audit.define( {
diff --git a/third_party/blink/web_tests/platform/mac/css3/filters/effect-contrast-expected.png b/third_party/blink/web_tests/platform/mac/css3/filters/effect-contrast-expected.png index d11af81..69f0c9f 100644 --- a/third_party/blink/web_tests/platform/mac/css3/filters/effect-contrast-expected.png +++ b/third_party/blink/web_tests/platform/mac/css3/filters/effect-contrast-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/filters/effect-contrast-expected.png b/third_party/blink/web_tests/platform/win/css3/filters/effect-contrast-expected.png index 4e164371..62db196 100644 --- a/third_party/blink/web_tests/platform/win/css3/filters/effect-contrast-expected.png +++ b/third_party/blink/web_tests/platform/win/css3/filters/effect-contrast-expected.png Binary files differ
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py index ee54015..7180ca91 100644 --- a/tools/binary_size/libsupersize/archive.py +++ b/tools/binary_size/libsupersize/archive.py
@@ -359,6 +359,13 @@ for symbol in raw_symbols: ret.append(symbol) full_name = symbol.full_name + # '__typeid_' symbols appear in linker .map only, and not nm output. + if full_name.startswith('__typeid_'): + if object_paths_by_name.get(full_name): + logging.warning('Found unexpected __typeid_ symbol in nm output: %s', + full_name) + continue + # Don't skip if symbol.IsBss(). This is needed for LLD-LTO to work, since # .bss object_path data are unavailable for linker_map_parser, and need to # be extracted here. For regular LLD flow, incorrect aliased symbols can @@ -651,12 +658,15 @@ # Don't alias padding-only symbols (e.g. ** symbol gap) if s.size_without_padding == 0: continue + # Also skip artificial symbols that won't appear in nm output. + if s.full_name.startswith('** CFI jump table'): + continue name_list = names_by_address.get(s.address) if name_list: if s.full_name not in name_list: missing_names[s.full_name].append(s.address) - logging.warning('Name missing from aliases: %s %s', s.full_name, - name_list) + logging.warning('Name missing from aliases: %08x %s %s', s.address, + s.full_name, name_list) continue replacements.append((i, name_list)) num_new_symbols += len(name_list) - 1
diff --git a/tools/binary_size/libsupersize/demangle.py b/tools/binary_size/libsupersize/demangle.py index e155748..9e8b6700 100644 --- a/tools/binary_size/libsupersize/demangle.py +++ b/tools/binary_size/libsupersize/demangle.py
@@ -50,9 +50,11 @@ if pos > 0: name = name[pos:] - # Some mangled symbols end with '$' followed by 32 lower-case hex digits. - # These interfere with demangling by c++filt. This function is an adaptor - # for iterable |name| to detect and strip these hash suffixes. + # Some mangled symbols end with '$' followed by 32 lower-case hex digits, + # and possibly '.cfi'. These interfere with demangling by c++filt, and + # should be stripped. + if name.endswith('.cfi'): + name = name[:-4] if len(name) > 33 and name[-33] == '$' and _IsLowerHex(name[-32:]): yield name[:-33] else:
diff --git a/tools/binary_size/libsupersize/linker_map_parser.py b/tools/binary_size/libsupersize/linker_map_parser.py index 14488be6..a6267d2 100755 --- a/tools/binary_size/libsupersize/linker_map_parser.py +++ b/tools/binary_size/libsupersize/linker_map_parser.py
@@ -73,6 +73,8 @@ return '** outlined function' if name.startswith('.L.str'): return models.STRING_LITERAL_NAME + if name.endswith(' (.cfi)'): + return name[:-7] return name @@ -483,6 +485,11 @@ thin_map = {} tokenizer = self.Tokenize(lines) + + in_jump_table = False + jump_tables_count = 0 + jump_entries_count = 0 + for (line, address, size, level, span, tok) in tokenizer: # Level 1 data match the "Out" column. They specify sections or # PROVIDE_HIDDEN lines. @@ -504,28 +511,37 @@ if level == 2: # E.g., 'path.o:(.text._name)' => ['path.o', '(.text._name)']. cur_obj, paren_value = tok.split(':') - # E.g., '(.text.unlikely._name)' -> '_name'. - mangled_name = paren_value[mangled_start_idx:-1] - cur_flags = _FlagsFromMangledName(mangled_name) - is_partial = True - # As of 2017/11 LLD does not distinguish merged strings from other - # merged data. Feature request is filed under: - # https://bugs.llvm.org/show_bug.cgi?id=35248 - if cur_obj == '<internal>': - if cur_section == '.rodata' and mangled_name == '': - # Treat all <internal> sections within .rodata as as string - # literals. Some may hold numeric constants or other data, but - # there is currently no way to distinguish them. - mangled_name = '** lld merge strings' - else: - # e.g. <internal>:(.text.thunk) - mangled_name = '** ' + mangled_name - is_partial = False - cur_obj = None - elif cur_obj == 'lto.tmp' or 'thinlto-cache' in cur_obj: - thin_map[address] = os.path.basename(cur_obj) - cur_obj = None + in_jump_table = '.L.cfi.jumptable' in paren_value + if in_jump_table: + # Store each CFI jump table as a Level 2 symbol, whose Level 3 + # details are discarded. + jump_tables_count += 1 + cur_obj = '' # Replaces 'lto.tmp' to prevent problem later. + mangled_name = '** CFI jump table' + else: + # E.g., '(.text.unlikely._name)' -> '_name'. + mangled_name = paren_value[mangled_start_idx:-1] + cur_flags = _FlagsFromMangledName(mangled_name) + is_partial = True + # As of 2017/11 LLD does not distinguish merged strings from other + # merged data. Feature request is filed under: + # https://bugs.llvm.org/show_bug.cgi?id=35248 + if cur_obj == '<internal>': + if cur_section == '.rodata' and mangled_name == '': + # Treat all <internal> sections within .rodata as as string + # literals. Some may hold numeric constants or other data, but + # there is currently no way to distinguish them. + mangled_name = '** lld merge strings' + else: + # e.g. <internal>:(.text.thunk) + mangled_name = '** ' + mangled_name + + is_partial = False + cur_obj = None + elif cur_obj == 'lto.tmp' or 'thinlto-cache' in cur_obj: + thin_map[address] = os.path.basename(cur_obj) + cur_obj = None # Create a symbol here since there may be no ensuing Level 3 lines. # But if there are, then the symbol can be modified later as sym[-1]. @@ -542,6 +558,17 @@ # '$t.42' also appear at Level 3, but they are consumed by |tokenizer|, # so don't appear hear. elif level == 3: + # Handle .L.cfi.jumptable. + if in_jump_table: + # Level 3 entries in CFI jump tables are thunks with mangled names. + # Extracting them as symbols is not worthwhile; we only store the + # Level 2 symbol, and print the count for verbose output. For + # counting, '__typeid_' entries are excluded since they're likely + # just annotations. + if not tok.startswith('__typeid_'): + jump_entries_count += 1 + continue + # Ignore anything with '.L_MergedGlobals' prefix. This seems to only # happen for ARM (32-bit) builds. if tok.startswith('.L_MergedGlobals'): @@ -578,8 +605,23 @@ next_usable_address = address + syms[-1].size is_partial = False elif address >= next_usable_address: - # Prefer |size|, and only fall back to |span| if |size == 0|. - size_to_use = size if size > 0 else span + if tok.startswith('__typeid_'): + assert size == 1 + if tok.endswith('_byte_array'): + # CFI byte array table: |size| is inaccurate, so use |span|. + size_to_use = span + else: + # Likely '_global_addr' or '_unique_member'. These should be: + # * Skipped since they're in CFI tables. + # * Suppressed (via |next_usable_address|) by another Level 3 + # symbol. + # Anything that makes it here would be an anomaly worthy of + # investigation, so print warnings. + logging.warn('Unrecognized __typeid_ symbol at %08X', address) + continue + else: + # Prefer |size|, and only fall back to |span| if |size == 0|. + size_to_use = size if size > 0 else span sym = models.Symbol(cur_section, size_to_use, address=address, full_name=tok, flags=cur_flags) syms.append(sym) @@ -595,6 +637,9 @@ if promoted_name_count: logging.info('Found %d promoted global names', promoted_name_count) + if jump_tables_count: + logging.info('Found %d CFI jump tables with %d total entries', + jump_tables_count, jump_entries_count) return self._section_sizes, syms, {'thin_map': thin_map}
diff --git a/tools/binary_size/libsupersize/linker_map_parser_test.py b/tools/binary_size/libsupersize/linker_map_parser_test.py index 31252fec..a050df9 100755 --- a/tools/binary_size/libsupersize/linker_map_parser_test.py +++ b/tools/binary_size/libsupersize/linker_map_parser_test.py
@@ -14,6 +14,7 @@ _SCRIPT_DIR = os.path.dirname(__file__) _TEST_DATA_DIR = os.path.join(_SCRIPT_DIR, 'testdata', 'linker_map_parser') _TEST_MAP_PATH = os.path.join(_TEST_DATA_DIR, 'test_lld-lto_v1.map') +_TEST_CFI_MAP_PATH = os.path.join(_TEST_DATA_DIR, 'test_lld-lto_v1_cfi.map') def _CompareWithGolden(name=None): @@ -45,23 +46,35 @@ return ret +def _RenderSectionSizesAndRawSymbols(section_sizes, raw_symbols): + ret = [] + ret.append('******** section_sizes ********') + for k, v in sorted(section_sizes.iteritems()): + ret.append('%-24s %d' % (k, v)) + ret.append('') + ret.append('******** raw_symbols ********') + for sym in raw_symbols: + ret.append(repr(sym)) + return ret + + class LinkerMapParserTest(unittest.TestCase): @_CompareWithGolden() def test_Parser(self): - ret = [] map_file = _ReadMapFile(_TEST_MAP_PATH) linker_name = linker_map_parser.DetectLinkerNameFromMapFile(iter(map_file)) section_sizes, raw_symbols, _ = ( linker_map_parser.MapFileParser().Parse(linker_name, iter(map_file))) - ret.append('******** section_sizes ********') - for k, v in sorted(section_sizes.iteritems()): - ret.append('%-24s %d' % (k, v)) - ret.append('') - ret.append('******** raw_symbols ********') - for sym in raw_symbols: - ret.append(repr(sym)) - return ret + return _RenderSectionSizesAndRawSymbols(section_sizes, raw_symbols) + + @_CompareWithGolden() + def test_ParserCfi(self): + map_file = _ReadMapFile(_TEST_CFI_MAP_PATH) + linker_name = linker_map_parser.DetectLinkerNameFromMapFile(iter(map_file)) + section_sizes, raw_symbols, _ = ( + linker_map_parser.MapFileParser().Parse(linker_name, iter(map_file))) + return _RenderSectionSizesAndRawSymbols(section_sizes, raw_symbols) def test_ParseArmAnnotations(self): fun = linker_map_parser.MapFileParserLld.ParseArmAnnotations
diff --git a/tools/binary_size/libsupersize/testdata/linker_map_parser/ParserCfi.golden b/tools/binary_size/libsupersize/testdata/linker_map_parser/ParserCfi.golden new file mode 100644 index 0000000..9368733 --- /dev/null +++ b/tools/binary_size/libsupersize/testdata/linker_map_parser/ParserCfi.golden
@@ -0,0 +1,55 @@ +******** section_sizes ******** +.ARM.extab 24100 +.data.rel.ro 2430180 +.rodata 6759914 +.text 43636188 + +******** raw_symbols ******** +.rodata@23dd00(size_without_padding=4,padding=0,full_name=v8_Default_embedded_blob_size_,object_path=obj/v8/v8_external_snapshot/embedded.o,source_path=,flags={},num_aliases=1,component=) +.rodata@23dd08(size_without_padding=8,padding=0,full_name=CRASHPAD_NOTE_REFERENCE,object_path=obj/third_party/crashpad/crashpad/client/libclient.a(client/crashpad_info_note.o),source_path=,flags={},num_aliases=1,component=) +.rodata@23dd10(size_without_padding=16,padding=0,full_name=pmmp,object_path=obj/third_party/ffmpeg/libffmpeg_internal.a(ffmpeg_internal/fft_neon.o),source_path=,flags={},num_aliases=1,component=) +.rodata@23dd20(size_without_padding=16,padding=0,full_name=mppm,object_path=obj/third_party/ffmpeg/libffmpeg_internal.a(ffmpeg_internal/fft_neon.o),source_path=,flags={},num_aliases=1,component=) +.rodata@23dd30(size_without_padding=3007385,padding=0,full_name=** lld merge strings,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@51c0cc(size_without_padding=4,padding=0,full_name=__emutls_t._ZL16g_current_locale,object_path=../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libandroid_support.a(locale.o),source_path=,flags={},num_aliases=1,component=) +.rodata@51d2a0(size_without_padding=1,padding=0,full_name=__typeid__ZTSN7content19WebContentsObserverE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@52b7f9(size_without_padding=3404,padding=0,full_name=__typeid__ZTSN4base16SupportsUserData4DataE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@52c545(size_without_padding=1520,padding=0,full_name=__typeid__ZTSN5blink21ImageResourceObserverE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@52cb35(size_without_padding=1030,padding=0,full_name=__typeid__ZTS12KeyedService_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@52cf3b(size_without_padding=29674,padding=0,full_name=__typeid__ZTSN3IPC6SenderE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@534325(size_without_padding=7384,padding=0,full_name=__typeid__ZTSN5blink15ScriptWrappableE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@535ffd(size_without_padding=1501,padding=0,full_name=__typeid__ZTSN4base11trace_event18MemoryDumpProviderE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@5365da(size_without_padding=4735,padding=0,full_name=__typeid__ZTSN5blink23MediaControlElementBaseE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@537859(size_without_padding=5257,padding=0,full_name=__typeid__ZTSN5blink11EventTargetE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@538ce2(size_without_padding=184,padding=0,full_name=__typeid__ZTSN5blink4NodeE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@538d9a(size_without_padding=4759,padding=0,full_name=__typeid__ZTSN5blink13ContainerNodeE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@53a031(size_without_padding=5237,padding=0,full_name=__typeid__ZTSN5blink7ElementE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@53b4a6(size_without_padding=4830,padding=0,full_name=__typeid__ZTSN5blink10SupplementINS_8DocumentEEE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@53c784(size_without_padding=588,padding=0,full_name=__typeid__ZTSN5blink13ListedElementE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@53c9d0(size_without_padding=4453,padding=0,full_name=__typeid__ZTSN5blink11HTMLElementE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@53db35(size_without_padding=1928,padding=0,full_name=__typeid__ZTSN5blink14FormAssociatedE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@53e2bd(size_without_padding=1969,padding=0,full_name=__typeid__ZTSN7content20NotificationObserverE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@53ea6e(size_without_padding=42,padding=0,full_name=__typeid__ZTSN7network5mojom16URLLoaderFactoryE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@53ea98(size_without_padding=48563,padding=0,full_name=__typeid__ZTSN7network5mojom15URLLoaderClientE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@54a84b(size_without_padding=1,padding=0,full_name=__typeid__ZTSN7content31BrowserChildProcessHostDelegateE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.rodata@54a84c(size_without_padding=65,padding=0,full_name=__typeid__ZTSN5blink10SupplementINS_16ExecutionContextEEE_byte_array,object_path=,source_path=,flags={},num_aliases=1,component=) +.text@8b6140(size_without_padding=64,padding=0,full_name=,object_path=obj/third_party/boringssl/boringssl_asm/chacha-armv4.o,source_path=,flags={},num_aliases=1,component=) +.text@8b6180(size_without_padding=1008,padding=0,full_name=ChaCha20_ctr32,object_path=obj/third_party/boringssl/boringssl_asm/chacha-armv4.o,source_path=,flags={},num_aliases=1,component=) +.text@8b6580(size_without_padding=2204,padding=0,full_name=ChaCha20_neon,object_path=obj/third_party/boringssl/boringssl_asm/chacha-armv4.o,source_path=,flags={},num_aliases=1,component=) +.text@29da300(size_without_padding=16,padding=0,full_name=** CFI jump table,object_path=,source_path=,flags={},num_aliases=1,component=) +.text@29da310(size_without_padding=40,padding=0,full_name=** CFI jump table,object_path=,source_path=,flags={},num_aliases=1,component=) +.text@29da340(size_without_padding=8,padding=0,full_name=** CFI jump table,object_path=,source_path=,flags={},num_aliases=1,component=) +.text@29da350(size_without_padding=5,padding=0,full_name=main,object_path=,source_path=,flags={},num_aliases=1,component=) +.text@2a59fb0(size_without_padding=24,padding=0,full_name=base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentGpuClient>::New(void*),object_path=,source_path=,flags={},num_aliases=1,component=) +.text@2a59fd0(size_without_padding=31,padding=0,full_name=base::LazyInstance<ChromeContentGpuClient, base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentGpuClient> >::OnExit(void*),object_path=,source_path=,flags={},num_aliases=1,component=) +.text@2a59ff0(size_without_padding=24,padding=0,full_name=base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentRendererClient>::New(void*),object_path=,source_path=,flags={},num_aliases=1,component=) +.text@2a5a010(size_without_padding=31,padding=0,full_name=base::LazyInstance<ChromeContentRendererClient, base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentRendererClient> >::OnExit(void*),object_path=,source_path=,flags={},num_aliases=1,component=) +.text@2a5a030(size_without_padding=24,padding=0,full_name=base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentUtilityClient>::New(void*),object_path=,source_path=,flags={},num_aliases=1,component=) +.data.rel.ro@3255000(size_without_padding=60,padding=0,full_name=fft_tab_vfp,object_path=obj/third_party/ffmpeg/libffmpeg_internal.a(ffmpeg_internal/fft_vfp.o),source_path=,flags={},num_aliases=1,component=) +.data.rel.ro@325503c(size_without_padding=60,padding=0,full_name=fft_tab_neon,object_path=obj/third_party/ffmpeg/libffmpeg_internal.a(ffmpeg_internal/fft_neon.o),source_path=,flags={},num_aliases=1,component=) +.data.rel.ro@325e5c0(size_without_padding=28,padding=0,full_name=vtable for content::BackgroundSyncContextImpl,object_path=,source_path=,flags={},num_aliases=1,component=) +.data.rel.ro@325e5e0(size_without_padding=24,padding=0,full_name=vtable for content::BackgroundSyncContext,object_path=,source_path=,flags={},num_aliases=1,component=) +.data.rel.ro@325e600(size_without_padding=100,padding=0,full_name=vtable for content::BackgroundSyncManager,object_path=,source_path=,flags={},num_aliases=1,component=) +.data.rel.ro@326e3a0(size_without_padding=20,padding=0,full_name=_ZTVN12v8_inspector12_GLOBAL__N_120HeapSnapshotProgressE$5c43413d323f2f7febefe6cf2f4ba25c,object_path=,source_path=,flags={},num_aliases=1,component=) +.data.rel.ro@923d5e0(size_without_padding=16,padding=0,full_name=.L__unnamed_1426,object_path=,source_path=,flags={},num_aliases=1,component=) +.data.rel.ro@923d5f0(size_without_padding=120,padding=0,full_name=vtable for media::ClearKeyProperties,object_path=,source_path=,flags={},num_aliases=1,component=) +.data.rel.ro@923d690(size_without_padding=120,padding=0,full_name=vtable for cdm::ExternalClearKeyProperties,object_path=,source_path=,flags={},num_aliases=1,component=)
diff --git a/tools/binary_size/libsupersize/testdata/linker_map_parser/test_lld-lto_v1_cfi.map b/tools/binary_size/libsupersize/testdata/linker_map_parser/test_lld-lto_v1_cfi.map new file mode 100644 index 0000000..23c753e7 --- /dev/null +++ b/tools/binary_size/libsupersize/testdata/linker_map_parser/test_lld-lto_v1_cfi.map
@@ -0,0 +1,138 @@ +# Test Linker map for LLD with ThinLTO, "v1" format, focusing on changes +# introduced CFI. +# .map files actually don't have comments and blank lines! These are added to +# improve documentation, and are stripped by tests. + +# First line is needed to identify .map file type. + VMA LMA Size Align Out In Symbol +# .rodata can have CFI byte arrays (start with other symbols). + 23dd00 23dd00 6725ea 256 .rodata + 23dd00 23dd00 4 8 obj/v8/v8_external_snapshot/embedded.o:(.rodata) + 23dd00 23dd00 0 1 v8_Default_embedded_blob_size_ + 23dd08 23dd08 8 8 obj/third_party/crashpad/crashpad/client/libclient.a(client/crashpad_info_note.o):(.rodata) + 23dd08 23dd08 0 1 CRASHPAD_NOTE_REFERENCE + 23dd10 23dd10 20 16 obj/third_party/ffmpeg/libffmpeg_internal.a(ffmpeg_internal/fft_neon.o):(.rodata) + 23dd10 23dd10 10 1 pmmp + 23dd20 23dd20 10 1 mppm + 23dd30 23dd30 2de399 1 <internal>:(.rodata) + 51c0cc 51c0cc 4 4 ../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libandroid_support.a(locale.o):(.rodata.__emutls_t._ZL16g_current_locale) + 51c0cc 51c0cc 4 1 __emutls_t._ZL16g_current_locale + 51c0cc 51c0cc 0 1 $d + +# CFI byte arrays. +# See: https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html + 51d2a0 51d2a0 2d5ed 16 lto.tmp:(.rodata..L__unnamed_3117) + 51d2a0 51d2a0 1 1 __typeid__ZTSN3IPC8ListenerE_byte_array + 51d2a0 51d2a0 1 1 __typeid__ZTSN4mojo15MessageReceiverE_byte_array + 51d2a0 51d2a0 1 1 __typeid__ZTSN5blink10NameClientE_byte_array + 51d2a0 51d2a0 1 1 __typeid__ZTSN5blink17DisplayItemClientE_byte_array + 51d2a0 51d2a0 1 1 __typeid__ZTSN5blink21GarbageCollectedMixinE_byte_array + 51d2a0 51d2a0 1 1 __typeid__ZTSN5blink24ContextLifecycleObserverE_byte_array + 51d2a0 51d2a0 1 1 __typeid__ZTSN5blink25ActiveScriptWrappableBaseE_byte_array + 51d2a0 51d2a0 1 1 __typeid__ZTSN7content19WebContentsObserverE_byte_array + 52b7f9 52b7f9 1 1 __typeid__ZTSN4base16SupportsUserData4DataE_byte_array + 52c545 52c545 1 1 __typeid__ZTSN5blink21ImageResourceObserverE_byte_array + 52cb35 52cb35 1 1 __typeid__ZTS12KeyedService_byte_array + 52cf3b 52cf3b 1 1 __typeid__ZTSN3IPC6SenderE_byte_array + 534325 534325 1 1 __typeid__ZTSN5blink15ScriptWrappableE_byte_array + 535ffd 535ffd 1 1 __typeid__ZTSN4base11trace_event18MemoryDumpProviderE_byte_array + 5365da 5365da 1 1 __typeid__ZTSN5blink23MediaControlElementBaseE_byte_array + 537859 537859 1 1 __typeid__ZTSN5blink11EventTargetE_byte_array + 538ce2 538ce2 1 1 .Lbits_use.897 + 538ce2 538ce2 1 1 .Lbits_use.898 + 538ce2 538ce2 1 1 .Lbits_use.899 + 538ce2 538ce2 1 1 .Lbits_use.900 + 538ce2 538ce2 1 1 .Lbits_use.902 + 538ce2 538ce2 1 1 .Lbits_use.903 + 538ce2 538ce2 1 1 .Lbits_use.904 + 538ce2 538ce2 1 1 __typeid__ZTSN5blink4NodeE_byte_array + 538d9a 538d9a 1 1 __typeid__ZTSN5blink13ContainerNodeE_byte_array + 53a031 53a031 1 1 .Lbits_use.905 + 53a031 53a031 1 1 __typeid__ZTSN5blink7ElementE_byte_array + 53b4a6 53b4a6 1 1 __typeid__ZTSN5blink10SupplementINS_8DocumentEEE_byte_array + 53c784 53c784 1 1 __typeid__ZTSN5blink13ListedElementE_byte_array + 53c9d0 53c9d0 1 1 __typeid__ZTSN5blink11HTMLElementE_byte_array + 53db35 53db35 1 1 __typeid__ZTSN5blink14FormAssociatedE_byte_array + 53e2bd 53e2bd 1 1 __typeid__ZTSN7content20NotificationObserverE_byte_array + 53ea6e 53ea6e 1 1 __typeid__ZTSN7network5mojom16URLLoaderFactoryE_byte_array + 53ea98 53ea98 1 1 __typeid__ZTSN7network5mojom15URLLoaderClientE_byte_array +# Snip out many examples (pretend that the previous symbol was huge). + 54a84b 54a84b 1 1 __typeid__ZTSN5blink32PresentationAvailabilityObserverE_byte_array + 54a84b 54a84b 1 1 __typeid__ZTSN5blink7UIEventE_byte_array + 54a84b 54a84b 1 1 __typeid__ZTSN6syncer15ChangeProcessorE_byte_array + 54a84b 54a84b 1 1 __typeid__ZTSN7content20ServiceWorkerVersion8ObserverE_byte_array + 54a84b 54a84b 1 1 __typeid__ZTSN7content31BrowserChildProcessHostDelegateE_byte_array + 54a84c 54a84c 1 1 __typeid__ZTSN5blink10SupplementINS_16ExecutionContextEEE_byte_array + +# Other sections. + 8b02ec 8b02ec 5e24 4 .ARM.extab + 8b02ec 8b02ec c 4 ../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libandroid_support.a(locale.o):(.ARM.extab.text.uselocale) + 8b02ec 8b02ec 0 1 $d + 8b02f8 8b02f8 c 4 ../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libandroid_support.a(locale.o):(.ARM.extab.text.newlocale) + 8b02f8 8b02f8 0 1 $d + +# .text can contain L.cfi.jumptable (start with other symbols). + 8b6140 8b6140 299d5dc 64 .text + 8b6140 8b6140 cdc 32 obj/third_party/boringssl/boringssl_asm/chacha-armv4.o:(.text) + 8b6144 8b6144 0 1 $d.0 + 8b6180 8b6180 0 1 $a.1 + 8b6180 8b6180 3f0 1 ChaCha20_ctr32 + 8b6580 8b6580 89c 1 ChaCha20_neon + +# Sample L.cfi.jumptable. + 29da300 29da300 10 16 lto.tmp:(.text..L.cfi.jumptable.2091) + 29da300 29da300 1 1 __typeid__ZTSF15vpx_codec_err_tP18vpx_codec_alg_privPK9vpx_imagelmlmE_global_addr + 29da300 29da300 10 1 vp8e_encode$7d077cb90f9945e3a735fb4eb6fe8afc + 29da308 29da308 10 1 encoder_encode$34c1039d90d239ad455f8ef2e0009211 + 29da310 29da310 28 16 lto.tmp:(.text..L.cfi.jumptable.2093) + 29da310 29da310 28 1 base::internal::Invoker<base::internal::BindState<void (extensions::image_writer::WriteFromUrlOperation::*)(base::FilePath), base::internal::UnretainedWrapper<extensions::image_writer::WriteFromUrlOperation> >, void (base::FilePath)>::RunOnce(base::internal::BindStateBase*, base::FilePath&&) + 29da310 29da310 1 1 __typeid__ZTSFvPN4base8internal13BindStateBaseEONS_8FilePathEE_global_addr + 29da318 29da318 28 1 base::internal::Invoker<base::internal::BindState<void (extensions::ExtensionDownloader::*)(base::FilePath), base::internal::UnretainedWrapper<extensions::ExtensionDownloader> >, void (base::FilePath)>::RunOnce(base::internal::BindStateBase*, base::FilePath&&) + 29da320 29da320 28 1 base::internal::Invoker<base::internal::BindState<void (cloud_print::PrivetURLLoader::*)(base::FilePath), base::WeakPtr<cloud_print::PrivetURLLoader> >, void (base::FilePath)>::RunOnce(base::internal::BindStateBase*, base::FilePath&&) + 29da328 29da328 28 1 base::internal::Invoker<base::internal::BindState<void (FileDownloader::*)(base::FilePath), base::internal::UnretainedWrapper<FileDownloader> >, void (base::FilePath)>::RunOnce(base::internal::BindStateBase*, base::FilePath&&) + 29da330 29da330 28 1 _ZN4base8internal7InvokerINS0_9BindStateIZN13update_client18NetworkFetcherImpl14DownloadToFileERK4GURLRKNS_8FilePathENS_12OnceCallbackIFvS7_ilEEENS_17RepeatingCallbackIFvlEEENSB_IFvS8_ilEEEE3$_1JPN7network15SimpleURLLoaderESI_EEEFvS8_EE7RunOnceEPNS0_13BindStateBaseEOS8_$465b209000b54f7cf2bdcf6c53188e38 + 29da340 29da340 8 16 lto.tmp:(.text..L.cfi.jumptable.2094) + 29da340 29da340 1 1 __typeid__ZTSFlPvS_miE_global_addr + 29da340 29da340 8 1 fseek_file_func$bb5c8d26f6b2986183d5943acbc61f67 + 29da350 29da350 5 16 thinlto-cache/Thin-82ee80.tmp.o:(.text.main) + 29da350 29da350 5 1 main + +# Demangled symbols that end with ' (.cfi)'. + 2a59fb0 2a59fb0 18 16 thinlto-cache/Thin-7c598e.tmp.o:(.text._ZN4base8internal34DestructorAtExitLazyInstanceTraitsI22ChromeContentGpuClientE3NewEPv.cfi) + 2a59fb0 2a59fb0 18 1 base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentGpuClient>::New(void*) (.cfi) + 2a59fd0 2a59fd0 1f 16 thinlto-cache/Thin-7c598e.tmp.o:(.text._ZN4base12LazyInstanceI22ChromeContentGpuClientNS_8internal34DestructorAtExitLazyInstanceTraitsIS1_EEE6OnExitEPv.cfi) + 2a59fd0 2a59fd0 1f 1 base::LazyInstance<ChromeContentGpuClient, base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentGpuClient> >::OnExit(void*) (.cfi) + 2a59ff0 2a59ff0 18 16 thinlto-cache/Thin-7c598e.tmp.o:(.text._ZN4base8internal34DestructorAtExitLazyInstanceTraitsI27ChromeContentRendererClientE3NewEPv.cfi) + 2a59ff0 2a59ff0 18 1 base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentRendererClient>::New(void*) (.cfi) + 2a5a010 2a5a010 1f 16 thinlto-cache/Thin-7c598e.tmp.o:(.text._ZN4base12LazyInstanceI27ChromeContentRendererClientNS_8internal34DestructorAtExitLazyInstanceTraitsIS1_EEE6OnExitEPv.cfi) + 2a5a010 2a5a010 1f 1 base::LazyInstance<ChromeContentRendererClient, base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentRendererClient> >::OnExit(void*) (.cfi) + 2a5a030 2a5a030 18 16 thinlto-cache/Thin-7c598e.tmp.o:(.text._ZN4base8internal34DestructorAtExitLazyInstanceTraitsI26ChromeContentUtilityClientE3NewEPv.cfi) + 2a5a030 2a5a030 18 1 base::internal::DestructorAtExitLazyInstanceTraits<ChromeContentUtilityClient>::New(void*) (.cfi) + +# .data.re.ro can have __typeid_ usages that are unrelated to CFI (start with other symbols). + 3255000 3255000 2514e4 16 .data.rel.ro + 3255000 3255000 3c 4 obj/third_party/ffmpeg/libffmpeg_internal.a(ffmpeg_internal/fft_vfp.o):(.data.rel.ro) + 3255000 3255000 3c 1 fft_tab_vfp + 325503c 325503c 3c 4 obj/third_party/ffmpeg/libffmpeg_internal.a(ffmpeg_internal/fft_neon.o):(.data.rel.ro) + 325503c 325503c 3c 1 fft_tab_neon + +# __typeid_ usages that are unrelated to CFI. + 325e5c0 325e5c0 38 16 lto.tmp:(.data.rel.ro..L__unnamed_306) + 325e5c0 325e5c0 1c 1 vtable for content::BackgroundSyncContextImpl + 325e5c8 325e5c8 1 1 __typeid__ZTSN7content21BackgroundSyncContextE_global_addr + 325e5c8 325e5c8 1 1 __typeid__ZTSN7content25BackgroundSyncContextImplE_global_addr + 325e5e0 325e5e0 18 1 vtable for content::BackgroundSyncContext + 325e600 325e600 64 16 lto.tmp:(.data.rel.ro..L__unnamed_307) + 325e600 325e600 64 1 vtable for content::BackgroundSyncManager + 325e608 325e608 1 1 __typeid__ZTSN7content21BackgroundSyncManagerE_global_addr + + 326e3a0 326e3a0 14 16 lto.tmp:(.data.rel.ro..L__unnamed_769) + 326e3a0 326e3a0 14 1 _ZTVN12v8_inspector12_GLOBAL__N_120HeapSnapshotProgressE$5c43413d323f2f7febefe6cf2f4ba25c + 326e3a8 326e3a8 1 1 __typeid_1$5c43413d323f2f7febefe6cf2f4ba25c_global_addr + 326e3a8 326e3a8 1 1 __typeid__ZTSN2v815ActivityControlE_global_addr + + 923d5e0 923d5e0 128 16 lto.tmp:(.data.rel.ro..L__unnamed_1426) + 923d5f0 923d5f0 78 1 vtable for media::ClearKeyProperties + 923d600 923d600 1 1 __typeid__ZTSN5media19KeySystemPropertiesE_96_unique_member + 923d600 923d600 1 1 __typeid__ZTSN5media19KeySystemPropertiesE_global_addr + 923d690 923d690 78 1 vtable for cdm::ExternalClearKeyProperties
diff --git a/tools/perf/cli_tools/soundwave/studies/health_study.py b/tools/perf/cli_tools/soundwave/studies/health_study.py index eb5711a4..ba2d8385 100644 --- a/tools/perf/cli_tools/soundwave/studies/health_study.py +++ b/tools/perf/cli_tools/soundwave/studies/health_study.py
@@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -CLOUD_PATH = 'gs://chome-health-tvdata/datasets/health_study.csv' +CLOUD_PATH = 'gs://chrome-health-tvdata/datasets/health_study.csv' OVERALL_PSS = ('memory:{browser}:all_processes:reported_by_os:system_memory' ':proportional_resident_size_avg') @@ -28,7 +28,7 @@ def IterSystemHealthBots(): yield 'ChromiumPerf/android-go-perf' - yield 'ChromiumPerfFyi/android-go_webview-perf' + yield 'ChromiumPerf/android-go_webview-perf' def GetBrowserFromBot(bot):
diff --git a/tools/perf/cli_tools/soundwave/studies/v8_study.py b/tools/perf/cli_tools/soundwave/studies/v8_study.py index 5a09749..ea50583 100644 --- a/tools/perf/cli_tools/soundwave/studies/v8_study.py +++ b/tools/perf/cli_tools/soundwave/studies/v8_study.py
@@ -6,7 +6,7 @@ from cli_tools.soundwave.tables import timeseries -CLOUD_PATH = 'gs://chome-health-tvdata/datasets/v8_report.csv' +CLOUD_PATH = 'gs://chrome-health-tvdata/datasets/v8_report.csv' ANDROID_GO = 'ChromiumPerf:android-go-perf' V8_EFFECTIVE_SIZE = (
diff --git a/ui/android/resources/resource_manager_impl.cc b/ui/android/resources/resource_manager_impl.cc index e79d19f..78e6e86 100644 --- a/ui/android/resources/resource_manager_impl.cc +++ b/ui/android/resources/resource_manager_impl.cc
@@ -159,13 +159,12 @@ // Build a color filter to use on the base resource. This filter multiplies // the RGB components by the components of the new color but retains the // alpha of the original image. - SkScalar color_matrix[20] = { - 0, 0, 0, 0, SkColorGetR(tint_color), - 0, 0, 0, 0, SkColorGetG(tint_color), - 0, 0, 0, 0, SkColorGetB(tint_color), - 0, 0, 0, 1, 0}; + float color_matrix[20] = {0, 0, 0, 0, SkColorGetR(tint_color) * (1.0f / 255), + 0, 0, 0, 0, SkColorGetG(tint_color) * (1.0f / 255), + 0, 0, 0, 0, SkColorGetB(tint_color) * (1.0f / 255), + 0, 0, 0, 1, 0}; SkPaint color_filter; - color_filter.setColorFilter(SkColorFilters::MatrixRowMajor255(color_matrix)); + color_filter.setColorFilter(SkColorFilters::Matrix(color_matrix)); // Draw the resource and make it immutable. base_image->ui_resource()
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn index d2169dbf..f23dded 100644 --- a/ui/aura/BUILD.gn +++ b/ui/aura/BUILD.gn
@@ -157,6 +157,7 @@ "window_port_for_shutdown.cc", "window_port_for_shutdown.h", "window_targeter.cc", + "window_tracker.cc", "window_tree_host.cc", "window_tree_host_platform.cc", ]
diff --git a/ui/aura/window_tracker.cc b/ui/aura/window_tracker.cc new file mode 100644 index 0000000..8b43559 --- /dev/null +++ b/ui/aura/window_tracker.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 "ui/aura/window_tracker.h" + +#include "ui/aura/window.h" + +namespace aura { + +WindowTracker::WindowTracker(const WindowList& windows) { + for (Window* window : windows) + Add(window); +} + +WindowTracker::WindowTracker() = default; + +WindowTracker::~WindowTracker() { + RemoveAll(); +} + +void WindowTracker::Add(Window* window) { + if (base::ContainsValue(windows_, window)) + return; + + window->AddObserver(this); + windows_.push_back(window); +} + +void WindowTracker::RemoveAll() { + for (Window* window : windows_) + window->RemoveObserver(this); + windows_.clear(); +} + +void WindowTracker::Remove(Window* window) { + auto iter = std::find(windows_.begin(), windows_.end(), window); + if (iter != windows_.end()) { + window->RemoveObserver(this); + windows_.erase(iter); + } +} + +Window* WindowTracker::Pop() { + DCHECK(!windows_.empty()); + Window* result = windows_[0]; + Remove(result); + return result; +} + +bool WindowTracker::Contains(Window* window) const { + return base::ContainsValue(windows_, window); +} + +void WindowTracker::OnWindowDestroying(Window* window) { + DCHECK(Contains(window)); + Remove(window); +} + +} // namespace aura
diff --git a/ui/aura/window_tracker.h b/ui/aura/window_tracker.h index d44ec3f..591816b 100644 --- a/ui/aura/window_tracker.h +++ b/ui/aura/window_tracker.h
@@ -7,14 +7,49 @@ #include <vector> -#include "base/compiler_specific.h" #include "base/macros.h" +#include "ui/aura/aura_export.h" #include "ui/aura/window_observer.h" -#include "ui/base/window_tracker_template.h" namespace aura { -using WindowTracker = ui::WindowTrackerTemplate<Window, WindowObserver>; +// This class is used to track an ordered list of Windows. When a Window is +// destroyed it is removed from the list of Windows. +class AURA_EXPORT WindowTracker : public WindowObserver { + public: + // A vector is used for tracking the windows (instead of a set) as some places + // care about ordering. + using WindowList = std::vector<Window*>; + + explicit WindowTracker(const WindowList& windows); + WindowTracker(); + ~WindowTracker() override; + + // Returns the set of windows being observed. + const WindowList& windows() const { return windows_; } + + // Adds |window| to the set of Windows being tracked. + void Add(Window* window); + + void RemoveAll(); + + // Removes |window| from the set of windows being tracked. + void Remove(Window* window); + + Window* Pop(); + + // Returns true if |window| was previously added and has not been removed or + // deleted. + bool Contains(Window* window) const; + + // WindowObserver overrides: + void OnWindowDestroying(Window* window) override; + + private: + WindowList windows_; + + DISALLOW_COPY_AND_ASSIGN(WindowTracker); +}; } // namespace aura
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index 960d583..098da250 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -484,11 +484,6 @@ } } - if (use_aura) { - deps += [ "//ui/events" ] - sources += [ "window_tracker_template.h" ] - } - if (!use_aura || !is_linux) { sources -= [ "resource/resource_bundle_auralinux.cc" ] }
diff --git a/ui/base/window_tracker_template.h b/ui/base/window_tracker_template.h deleted file mode 100644 index e91bdac..0000000 --- a/ui/base/window_tracker_template.h +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_BASE_WINDOW_TRACKER_TEMPLATE_H_ -#define UI_BASE_WINDOW_TRACKER_TEMPLATE_H_ - -#include <vector> - -#include "base/macros.h" -#include "base/stl_util.h" - -namespace ui { - -// This class is used to track an ordered list of objects that support an -// observer interface with the function OnWindowDestroying(). When the object -// is destroyed it is removed from the ordered list of objects. -// Examples of T include aura::Window and its corresponding -// aura::WindowObserver interface. -template <class T, class TObserver> -class WindowTrackerTemplate : public TObserver { - public: - // A vector<> is used for tracking the windows (instead of a set<>) because - // the user may want to know about the order of the windows that have been - // added. - using WindowList = std::vector<T*>; - - explicit WindowTrackerTemplate(const WindowList& windows) { - for (T* window : windows) - Add(window); - } - WindowTrackerTemplate() {} - ~WindowTrackerTemplate() override { RemoveAll(); } - - // Returns the set of windows being observed. - const WindowList& windows() const { return windows_; } - - // Adds |window| to the set of Windows being tracked. - void Add(T* window) { - if (base::ContainsValue(windows_, window)) - return; - - window->AddObserver(this); - windows_.push_back(window); - } - - void RemoveAll() { - for (T* window : windows_) - window->RemoveObserver(this); - windows_.clear(); - } - - // Removes |window| from the set of windows being tracked. - void Remove(T* window) { - auto iter = std::find(windows_.begin(), windows_.end(), window); - if (iter != windows_.end()) { - window->RemoveObserver(this); - windows_.erase(iter); - } - } - - T* Pop() { - DCHECK(!windows_.empty()); - T* result = windows_[0]; - Remove(result); - return result; - } - - // Returns true if |window| was previously added and has not been removed or - // deleted. - bool Contains(T* window) const { - return base::ContainsValue(windows_, window); - } - - // Observer overrides: - void OnWindowDestroying(T* window) override { - DCHECK(Contains(window)); - Remove(window); - } - - private: - WindowList windows_; - - DISALLOW_COPY_AND_ASSIGN(WindowTrackerTemplate); -}; - -} // namespace ui - -#endif // UI_BASE_WINDOW_TRACKER_TEMPLATE_H_
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc index c3eeff37..e13d0026 100644 --- a/ui/compositor/test/in_process_context_factory.cc +++ b/ui/compositor/test/in_process_context_factory.cc
@@ -129,6 +129,8 @@ bool HasExternalStencilTest() const override { return false; } void ApplyExternalStencil() override {} unsigned UpdateGpuFence() override { return 0; } + void SetUpdateVSyncParametersCallback( + viz::UpdateVSyncParametersCallback callback) override {} private: void OnSwapBuffersComplete() {