diff --git a/BUILD.gn b/BUILD.gn index 497f91e4..39b9075 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1108,6 +1108,9 @@ } data = [ + "//testing/scripts/common.py", + "//testing/scripts/run_isolated_script_test.py", + "//testing/xvfb.py", "//third_party/blink/tools/", "//third_party/blink/web_tests/VirtualTestSuites", "//third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json", @@ -1143,38 +1146,25 @@ } # https://chromium.googlesource.com/chromium/src/+/master/docs/testing/web_tests.md - script_test("blink_web_tests") { - script = "//testing/scripts/run_isolated_script_test.py" - - args = [ "@WrappedPath(" + - rebase_path("//third_party/blink/tools/run_web_tests.py", - root_build_dir) + ")" ] + generate_wrapper("blink_web_tests") { + testonly = true + wrapper_script = "${root_build_dir}/bin/run_blink_web_tests" + executable = "//third_party/blink/tools/run_web_tests.py" + executable_args = [] if (is_debug) { - args += [ "--debug" ] + executable_args += [ "--debug" ] } else { - args += [ "--release" ] + executable_args += [ "--release" ] } if (is_android) { - args += [ + executable_args += [ "--platform", "android", ] } - args += [ - "--seed", - "4", - "--no-show-results", - "--zero-tests-executed-ok", - "--clobber-old-results", - "--exit-after-n-failures", - "5000", - "--exit-after-n-crashes-or-timeouts", - "100", - ] - data_deps = [ ":blink_web_tests_support_data" ] data = [ "//third_party/blink/perf_tests/", @@ -1237,15 +1227,14 @@ deps = [ "//mojo/public/js:bindings_lite" ] } - script_test("blink_python_tests") { - script = "//testing/scripts/run_isolated_script_test.py" - args = [ "@WrappedPath(" + - rebase_path("//third_party/blink/tools/run_blinkpy_tests.py", - root_build_dir) + ")" ] - + group("blink_python_tests") { data = [ "//build/android/", "//components/crash/content/tools/generate_breakpad_symbols.py", + "//testing/scripts/common.py", + "//testing/scripts/run_isolated_script_test.py", + "//testing/test_env.py", + "//testing/xvfb.py", "//third_party/blink/renderer/bindings/scripts/", "//third_party/blink/renderer/build/scripts/", "//third_party/blink/tools/",
diff --git a/DEPS b/DEPS index 09b5791..daa57bf 100644 --- a/DEPS +++ b/DEPS
@@ -195,11 +195,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': '4f09dd47da6ee00643d15de9396dceceef5439df', + 'skia_revision': 'c73bff39bd21ae9b54b198a6dbf361ea3ceab591', # 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': 'e9a57883aeb0307c0417ce98deb2188afcf34515', + 'v8_revision': '0d81cd72688512abcbe1601015baee390c484a6a', # 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. @@ -207,7 +207,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '11d94d866e23cdda9f040eebb66c09c4d9850064', + 'angle_revision': '3d5e8c4c466d5ec179f4d88e4ea566d6c4683ae6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -266,7 +266,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '95949e4c8ae857512cf0e45f492fcbd5110204f0', + 'devtools_frontend_revision': '0d0e5bfe429c3b6cb79c977dbec15ff3ce18bea2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -1254,7 +1254,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '492d4a85a2f047b81686fed792a722160584c7bd', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f01bf538a4ff420c223043482aa455e6974d3de0', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1332,7 +1332,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': 'Skpt9_SolooAXKJ9NtT-_thteKsC-3X1-IwAh55EYW4C' + 'version': 'ExOy6Vlzx-dwIqNTNzIfOKNavzc1k0qJL5M0J2LT_ckC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1486,7 +1486,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'e39b378d4a921e9982f39ebb02a6145afb653956', + Var('webrtc_git') + '/src.git' + '@' + '281fb1ed7ba9f43f69462b57205a1906d1702cbc', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'),
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 84798b1..c66349a 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -323,7 +323,6 @@ '^chrome/browser/captive_portal/captive_portal_browsertest.cc', '^chrome/browser/chromeos/', '^chrome/browser/component_updater/', - '^chrome/browser/custom_handlers/protocol_handler_registry.cc', '^chrome/browser/device_identity/chromeos/device_oauth2_token_store_chromeos.cc', # pylint: disable=line-too-long '^chrome/browser/devtools/', '^chrome/browser/download/',
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc index 7f5a2f3a..643a2c0b 100644 --- a/android_webview/browser/aw_browser_main_parts.cc +++ b/android_webview/browser/aw_browser_main_parts.cc
@@ -82,7 +82,7 @@ browser_process_ = std::make_unique<AwBrowserProcess>( browser_client_->aw_feature_list_creator()); - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } int AwBrowserMainParts::PreCreateThreads() { @@ -118,7 +118,7 @@ crash_reporter::InitializeCrashKeys(); variations::InitCrashKeys(); - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } void AwBrowserMainParts::PreMainMessageLoopRun() {
diff --git a/ash/app_list/app_list_presenter_delegate_impl.cc b/ash/app_list/app_list_presenter_delegate_impl.cc index e01950cb..a0c27bf 100644 --- a/ash/app_list/app_list_presenter_delegate_impl.cc +++ b/ash/app_list/app_list_presenter_delegate_impl.cc
@@ -310,6 +310,10 @@ if (view_->IsShowingEmbeddedAssistantUI()) return; + // Don't absorb the first event when renaming folder. + if (view_->IsFolderBeingRenamed()) + return; + // Arrow keys or Tab will engage the traversal mode. if ((IsUnhandledArrowKeyEvent(*event) || event->key_code() == ui::VKEY_TAB)) { // Handle the first arrow key event to just show the focus rings.
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index 121107a..6cccc64 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -845,6 +845,13 @@ return app_list_main_view()->contents_view()->IsShowingEmbeddedAssistantUI(); } +bool AppListView::IsFolderBeingRenamed() { + return GetAppsContainerView() + ->app_list_folder_view() + ->folder_header_view() + ->HasTextFocus(); +} + void AppListView::UpdatePageResetTimer(bool app_list_visibility) { if (app_list_visibility || !delegate_->IsInTabletMode()) { page_reset_timer_.Stop(); @@ -2127,14 +2134,10 @@ views::Textfield* search_box = search_box_view_->search_box(); const bool is_search_box_focused = search_box->HasFocus(); - const bool is_folder_header_view_focused = GetAppsContainerView() - ->app_list_folder_view() - ->folder_header_view() - ->HasTextFocus(); // Do not redirect the key event to the |search_box_| when focus is on a // text field. - if (is_search_box_focused || is_folder_header_view_focused) + if (is_search_box_focused || IsFolderBeingRenamed()) return; // Do not redirect the arrow keys in app list as they are are used for focus
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h index 73f2cf65..a42c284 100644 --- a/ash/app_list/views/app_list_view.h +++ b/ash/app_list/views/app_list_view.h
@@ -370,6 +370,9 @@ // Returns true if the Embedded Assistant UI is currently being shown. bool IsShowingEmbeddedAssistantUI() const; + // Returns true if a folder is being renamed. + bool IsFolderBeingRenamed(); + // Starts or stops a timer which will reset the app list to the initial apps // page. Called when the app list's visibility changes. void UpdatePageResetTimer(bool app_list_visibility);
diff --git a/ash/app_list/views/folder_header_view.cc b/ash/app_list/views/folder_header_view.cc index 9777ad77..3d3137e 100644 --- a/ash/app_list/views/folder_header_view.cc +++ b/ash/app_list/views/folder_header_view.cc
@@ -119,6 +119,9 @@ if (!DoesMouseEventActuallyIntersect(event)) return false; + if (!HasFocus()) + defer_select_all_ = true; + return Textfield::OnMousePressed(event); } @@ -159,6 +162,8 @@ if (!HasSelection()) SelectAll(false); } + + Textfield::OnMouseReleased(event); } bool DoesIntersectRect(const views::View* target,
diff --git a/ash/frame/default_frame_header_unittest.cc b/ash/frame/default_frame_header_unittest.cc index 76d6df3..608c061 100644 --- a/ash/frame/default_frame_header_unittest.cc +++ b/ash/frame/default_frame_header_unittest.cc
@@ -184,9 +184,8 @@ ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); wm::ActivateWindow(win0.get()); - auto* header_view = NonClientFrameViewAsh::Get(win0.get())->GetHeaderView(); - ASSERT_TRUE(header_view); - auto* animating_layer_holding_view = header_view->children()[0]; + auto* frame_view = NonClientFrameViewAsh::Get(win0.get()); + auto* animating_layer_holding_view = frame_view->children()[0]; EXPECT_TRUE(!std::strcmp(animating_layer_holding_view->GetClassName(), "FrameAnimatorView")); ASSERT_TRUE(animating_layer_holding_view->layer()); @@ -220,17 +219,18 @@ ui::ScopedAnimationDurationScaleMode non_zero_duration_mode( ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); - auto* header_view_0 = - NonClientFrameViewAsh::Get(win_0.get())->GetHeaderView(); - auto* animating_layer_holding_view_0 = header_view_0->children()[0]; + auto* frame_view_0 = NonClientFrameViewAsh::Get(win_0.get()); + auto* animating_layer_holding_view_0 = frame_view_0->children()[0]; EXPECT_TRUE(!std::strcmp(animating_layer_holding_view_0->GetClassName(), "FrameAnimatorView")); size_t original_layers_count_0 = animating_layer_holding_view_0->layer()->parent()->children().size(); - auto* header_view_1 = - NonClientFrameViewAsh::Get(win_1.get())->GetHeaderView(); - auto* animating_layer_holding_view_1 = header_view_1->children()[0]; + auto* frame_view_1 = NonClientFrameViewAsh::Get(win_1.get()); + auto* extra_view_1 = + frame_view_1->AddChildView(std::make_unique<views::View>()); + + auto* animating_layer_holding_view_1 = frame_view_1->children()[0]; EXPECT_TRUE(!std::strcmp(animating_layer_holding_view_1->GetClassName(), "FrameAnimatorView")); size_t original_layers_count_1 = @@ -259,7 +259,7 @@ } { - // wind_1 should still be animating. + // win_1 should still be animating. EXPECT_EQ( animating_layer_holding_view_1->layer()->parent()->children().size(), original_layers_count_1 + 1); @@ -269,8 +269,8 @@ LayerDestroyedChecker checker(animating_layer); // Change the view's stacking order should stop the animation. - ASSERT_EQ(3u, header_view_1->children().size()); - header_view_1->ReorderChildView(header_view_1->children()[2], 0); + ASSERT_EQ(2u, frame_view_1->children().size()); + frame_view_1->ReorderChildView(extra_view_1, 0); EXPECT_EQ( animating_layer_holding_view_1->layer()->parent()->children().size(),
diff --git a/ash/frame/header_view.cc b/ash/frame/header_view.cc index eaff0b8..9a62b54b 100644 --- a/ash/frame/header_view.cc +++ b/ash/frame/header_view.cc
@@ -19,6 +19,7 @@ #include "ui/base/ui_base_features.h" #include "ui/views/controls/image_view.h" #include "ui/views/widget/widget.h" +#include "ui/views/window/non_client_view.h" namespace ash { @@ -50,7 +51,8 @@ DISALLOW_COPY_AND_ASSIGN(HeaderContentView); }; -HeaderView::HeaderView(views::Widget* target_widget) +HeaderView::HeaderView(views::Widget* target_widget, + views::NonClientFrameView* frame_view) : target_widget_(target_widget) { header_content_view_ = AddChildView(std::make_unique<HeaderContentView>(this)); @@ -61,7 +63,9 @@ aura::Window* window = target_widget->GetNativeWindow(); frame_header_ = std::make_unique<DefaultFrameHeader>( - target_widget, this, caption_button_container_); + target_widget, + (frame_view ? static_cast<views::View*>(frame_view) : this), + caption_button_container_); UpdateBackButton();
diff --git a/ash/frame/header_view.h b/ash/frame/header_view.h index a4e89fd..35707b55 100644 --- a/ash/frame/header_view.h +++ b/ash/frame/header_view.h
@@ -28,6 +28,7 @@ class FrameCaptionButton; class ImageView; class Widget; +class NonClientFrameView; } namespace ash { @@ -48,7 +49,8 @@ // placed in. For example, in immersive fullscreen this view may be painted in // a widget that slides in and out on top of the main app or browser window. // However, clicking a caption button should act on the target widget. - explicit HeaderView(views::Widget* target_widget); + HeaderView(views::Widget* target_widget, + views::NonClientFrameView* frame_view); ~HeaderView() override; METADATA_HEADER(HeaderView);
diff --git a/ash/frame/non_client_frame_view_ash.cc b/ash/frame/non_client_frame_view_ash.cc index 77c8eb06..71d57868 100644 --- a/ash/frame/non_client_frame_view_ash.cc +++ b/ash/frame/non_client_frame_view_ash.cc
@@ -203,7 +203,7 @@ NonClientFrameViewAsh::NonClientFrameViewAsh(views::Widget* frame) : frame_(frame), - header_view_(new HeaderView(frame)), + header_view_(new HeaderView(frame, this)), overlay_view_(new OverlayView(header_view_)) { DCHECK(frame_);
diff --git a/ash/frame/wide_frame_view.cc b/ash/frame/wide_frame_view.cc index 85dbd256..611500c 100644 --- a/ash/frame/wide_frame_view.cc +++ b/ash/frame/wide_frame_view.cc
@@ -91,7 +91,9 @@ aura::Window* target_window = target->GetNativeWindow(); target_window->AddObserver(this); - header_view_ = new HeaderView(target); + // Use the HeaderView itself as a frame view because WideFrameView is + // is the frame only. + header_view_ = new HeaderView(target, /*frame view=*/nullptr); AddChildView(header_view_); GetTargetHeaderView()->SetShouldPaintHeader(false);
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index 9ba7080..42021d8 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -62,8 +62,8 @@ const base::Feature kHideArcMediaNotifications{ "HideArcMediaNotifications", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kInteractiveWindowCycleList{"InteractiveWindowCycleList", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kInteractiveWindowCycleList{ + "InteractiveWindowCycleList", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kManagedDeviceUIRedesign{"ManagedDeviceUIRedesign", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/wm/window_cycle_controller_unittest.cc b/ash/wm/window_cycle_controller_unittest.cc index 19ffd5b6..79ab60b 100644 --- a/ash/wm/window_cycle_controller_unittest.cc +++ b/ash/wm/window_cycle_controller_unittest.cc
@@ -690,6 +690,9 @@ // While the UI is active, mouse events are captured. TEST_F(WindowCycleControllerTest, MouseEventsCaptured) { + if (features::IsInteractiveWindowCycleListEnabled()) + return; + // Set up a second root window UpdateDisplay("1000x600,600x400"); aura::Window::Windows root_windows = Shell::GetAllRootWindows();
diff --git a/base/allocator/partition_allocator/partition_alloc.h b/base/allocator/partition_allocator/partition_alloc.h index 549451e2..3db28af 100644 --- a/base/allocator/partition_allocator/partition_alloc.h +++ b/base/allocator/partition_allocator/partition_alloc.h
@@ -1111,8 +1111,10 @@ << (sizeof(size_t) * 8 - base::bits::CountLeadingZeroBits(size - 1)); } + // TODO(tasak): Clean up the following condition and PA_CHECK(requested_size + // >= size). #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) - if (requested_size > MaxDirectMapped()) { + if (size > MaxDirectMapped()) { if (flags & PartitionAllocReturnNull) return nullptr; // OutOfMemoryDeathTest.AlignedAlloc requires base::OnNoMemoryInternal
diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm index be12912..e63f0ec 100644 --- a/base/mac/foundation_util.mm +++ b/base/mac/foundation_util.mm
@@ -13,6 +13,7 @@ #include "base/mac/bundle_locations.h" #include "base/mac/mac_logging.h" #include "base/notreached.h" +#include "base/numerics/checked_math.h" #include "base/numerics/safe_conversions.h" #include "base/stl_util.h" #include "base/strings/sys_string_conversions.h" @@ -477,12 +478,13 @@ } bool CFRangeToNSRange(CFRange range, NSRange* range_out) { + decltype(range_out->location) end; if (base::IsValueInRangeForNumericType<decltype(range_out->location)>( range.location) && base::IsValueInRangeForNumericType<decltype(range_out->length)>( range.length) && - base::IsValueInRangeForNumericType<decltype(range_out->location)>( - range.location + range.length)) { + base::CheckAdd(range.location, range.length).AssignIfValid(&end) && + base::IsValueInRangeForNumericType<decltype(range_out->location)>(end)) { *range_out = NSMakeRange(range.location, range.length); return true; }
diff --git a/base/process/launch_fuchsia.cc b/base/process/launch_fuchsia.cc index bd5c56f..17ea46f 100644 --- a/base/process/launch_fuchsia.cc +++ b/base/process/launch_fuchsia.cc
@@ -153,7 +153,8 @@ // |clear_environment|, |environment| or |current_directory| are set then we // construct a new (possibly empty) environment, otherwise we let fdio_spawn() // clone the caller's environment into the new process. - uint32_t spawn_flags = FDIO_SPAWN_DEFAULT_LDSVC | options.spawn_flags; + uint32_t spawn_flags = FDIO_SPAWN_DEFAULT_LDSVC | FDIO_SPAWN_CLONE_UTC_CLOCK | + options.spawn_flags; EnvironmentMap environ_modifications = options.environment; if (!options.current_directory.empty()) {
diff --git a/base/task/thread_pool/test_utils.cc b/base/task/thread_pool/test_utils.cc index 8d70f53..738f1d24 100644 --- a/base/task/thread_pool/test_utils.cc +++ b/base/task/thread_pool/test_utils.cc
@@ -205,7 +205,7 @@ bool MockPooledTaskRunnerDelegate::ShouldYield( const TaskSource* task_source) const { - return thread_group_->ShouldYield(task_source->priority_racy()); + return thread_group_->ShouldYield(task_source->GetSortKey()); } bool MockPooledTaskRunnerDelegate::EnqueueJobTaskSource(
diff --git a/base/task/thread_pool/thread_group.cc b/base/task/thread_pool/thread_group.cc index 69f2412..a6f0c73 100644 --- a/base/task/thread_pool/thread_group.cc +++ b/base/task/thread_pool/thread_group.cc
@@ -245,13 +245,26 @@ replacement_thread_group_ = destination_thread_group; } -bool ThreadGroup::ShouldYield(TaskPriority priority) const { - // It is safe to read |min_allowed_priority_| without a lock since this +bool ThreadGroup::ShouldYield(TaskSourceSortKey sort_key) const { + if (!task_tracker_->CanRunPriority(sort_key.priority())) + return true; + // It is safe to read |max_allowed_sort_key_| without a lock since this // variable is atomic, keeping in mind that threads may not immediately see // the new value when it is updated. - return !task_tracker_->CanRunPriority(priority) || - priority < TS_UNCHECKED_READ(min_allowed_priority_) - .load(std::memory_order_relaxed); + auto max_allowed_sort_key = + TS_UNCHECKED_READ(max_allowed_sort_key_).load(std::memory_order_relaxed); + if (sort_key.priority() < max_allowed_sort_key.priority) + return true; + // To reduce unnecessary yielding, a task will never yield to a BEST_EFFORT + // task regardless of its worker_count. + if (sort_key.priority() > max_allowed_sort_key.priority || + max_allowed_sort_key.priority == TaskPriority::BEST_EFFORT) { + return false; + } + // Otherwise, a task only yields to a task of equal priority if its + // worker_count would be greater still after yielding, e.g. a job with 1 + // worker doesn't yield to a job with 0 workers. + return sort_key.worker_count() > max_allowed_sort_key.worker_count + 1; } #if defined(OS_WIN)
diff --git a/base/task/thread_pool/thread_group.h b/base/task/thread_pool/thread_group.h index db70139..59cc62d 100644 --- a/base/task/thread_pool/thread_group.h +++ b/base/task/thread_pool/thread_group.h
@@ -92,12 +92,12 @@ void InvalidateAndHandoffAllTaskSourcesToOtherThreadGroup( ThreadGroup* destination_thread_group); - // Returns true if a task with |priority| running in this thread group should - // return ASAP, either because this priority is not allowed to run or because + // Returns true if a task with |sort_key| running in this thread group should + // return ASAP, either because its priority is not allowed to run or because // work of higher priority is pending. Thread-safe but may return an outdated // result (if a task unnecessarily yields due to this, it will simply be // re-scheduled). - bool ShouldYield(TaskPriority priority) const; + bool ShouldYield(TaskSourceSortKey sort_key) const; // Prevents new tasks from starting to run and waits for currently running // tasks to complete their execution. It is guaranteed that no thread will do @@ -224,13 +224,21 @@ // PriorityQueue from which all threads of this ThreadGroup get work. PriorityQueue priority_queue_ GUARDED_BY(lock_); - // Minimum priority allowed to run below which tasks should yield. This is - // expected to be always kept up-to-date by derived classes when |lock_| is - // released. It is annotated as GUARDED_BY(lock_) because it is always updated - // under the lock (to avoid races with other state during the update) but it - // is nonetheless always safe to read it without the lock (since it's atomic). - std::atomic<TaskPriority> min_allowed_priority_ GUARDED_BY(lock_){ - TaskPriority::BEST_EFFORT}; + struct YieldSortKey { + TaskPriority priority; + uint8_t worker_count; + }; + + // When the thread group is at or above capacity and has pending work, this + // contains the priority and worker count of the next TaskSource to schedule. + // Otherwise, it contains |priority| = BEST_EFFORT and |worker_count| = 0. + // This is used to decide whether a TaskSource should yield. This is expected + // to be always kept up-to-date by derived classes when |lock_| is released. + // It is annotated as GUARDED_BY(lock_) because it is always updated under the + // lock (to avoid races with other state during the update) but it is + // nonetheless always safe to read it without the lock (since it's atomic). + std::atomic<YieldSortKey> max_allowed_sort_key_ GUARDED_BY(lock_){ + {TaskPriority::BEST_EFFORT, 0U}}; // If |replacement_thread_group_| is non-null, this ThreadGroup is invalid and // all task sources should be scheduled on |replacement_thread_group_|. Used
diff --git a/base/task/thread_pool/thread_group_impl.cc b/base/task/thread_pool/thread_group_impl.cc index ee42e9db..131ec78 100644 --- a/base/task/thread_pool/thread_group_impl.cc +++ b/base/task/thread_pool/thread_group_impl.cc
@@ -1139,10 +1139,11 @@ void ThreadGroupImpl::UpdateMinAllowedPriorityLockRequired() { if (priority_queue_.IsEmpty() || num_running_tasks_ < max_tasks_) { - min_allowed_priority_.store(TaskPriority::BEST_EFFORT, + max_allowed_sort_key_.store({TaskPriority::BEST_EFFORT, 0}, std::memory_order_relaxed); } else { - min_allowed_priority_.store(priority_queue_.PeekSortKey().priority(), + max_allowed_sort_key_.store({priority_queue_.PeekSortKey().priority(), + priority_queue_.PeekSortKey().worker_count()}, std::memory_order_relaxed); } }
diff --git a/base/task/thread_pool/thread_group_impl_unittest.cc b/base/task/thread_pool/thread_group_impl_unittest.cc index 7f9b9490c..a73bf75 100644 --- a/base/task/thread_pool/thread_group_impl_unittest.cc +++ b/base/task/thread_pool/thread_group_impl_unittest.cc
@@ -296,8 +296,7 @@ TestWaitableEvent threads_continue; // Saturate workers with USER_VISIBLE tasks to ensure ShouldYield() returns - // true when a tasks of higher priority - // is posted. + // true when a tasks of higher priority is posted. RepeatingClosure threads_running_barrier = BarrierClosure( kMaxTasks, BindOnce(&TestWaitableEvent::Signal, Unretained(&threads_running))); @@ -331,35 +330,57 @@ &mock_pooled_task_runner_delegate_) ->PostTask( FROM_HERE, BindLambdaForTesting([&]() { - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::BEST_EFFORT, TimeTicks(), /* worker_count=*/1})); })); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::USER_BLOCKING)); + // A BEST_EFFORT task with more workers shouldn't have to yield. + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::BEST_EFFORT, TimeTicks(), /* worker_count=*/2})); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::BEST_EFFORT, TimeTicks(), /* worker_count=*/0})); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_VISIBLE, TimeTicks(), /* worker_count=*/0})); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_BLOCKING, TimeTicks(), /* worker_count=*/0})); - // Posting a USER_VISIBLE task should cause BEST_EFFORT tasks to yield. + // Posting a USER_VISIBLE task should cause BEST_EFFORT and USER_VISIBLE with + // higher worker_count tasks to yield. test::CreatePooledTaskRunner({TaskPriority::USER_VISIBLE}, &mock_pooled_task_runner_delegate_) ->PostTask(FROM_HERE, BindLambdaForTesting([&]() { - EXPECT_FALSE( - thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_VISIBLE, TimeTicks(), + /* worker_count=*/1})); })); - EXPECT_TRUE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::USER_BLOCKING)); + // A USER_VISIBLE task with too many workers should yield. + EXPECT_TRUE(thread_group_->ShouldYield( + {TaskPriority::USER_VISIBLE, TimeTicks(), /* worker_count=*/2})); + EXPECT_TRUE(thread_group_->ShouldYield( + {TaskPriority::BEST_EFFORT, TimeTicks(), /* worker_count=*/0})); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_VISIBLE, TimeTicks(), /* worker_count=*/1})); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_BLOCKING, TimeTicks(), /* worker_count=*/0})); - // Posting a USER_BLOCKING task should cause BEST_EFFORT and USER_VISIBLE - // tasks to yield. + // Posting a USER_BLOCKING task should cause BEST_EFFORT, USER_VISIBLE and + // USER_BLOCKING with higher worker_count tasks to yield. test::CreatePooledTaskRunner({TaskPriority::USER_BLOCKING}, &mock_pooled_task_runner_delegate_) ->PostTask(FROM_HERE, BindLambdaForTesting([&]() { // Once this task got to start, no other task needs to yield. - EXPECT_FALSE( - thread_group_->ShouldYield(TaskPriority::USER_BLOCKING)); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_BLOCKING, TimeTicks(), + /* worker_count=*/1})); })); - EXPECT_TRUE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); - EXPECT_TRUE(thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::USER_BLOCKING)); + // A USER_BLOCKING task with too many workers should have to yield. + EXPECT_TRUE(thread_group_->ShouldYield( + {TaskPriority::USER_BLOCKING, TimeTicks(), /* worker_count=*/2})); + EXPECT_TRUE(thread_group_->ShouldYield( + {TaskPriority::BEST_EFFORT, TimeTicks(), /* worker_count=*/0})); + EXPECT_TRUE(thread_group_->ShouldYield( + {TaskPriority::USER_VISIBLE, TimeTicks(), /* worker_count=*/0})); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_BLOCKING, TimeTicks(), /* worker_count=*/1})); threads_continue.Signal(); task_tracker_.FlushForTesting(); @@ -1239,36 +1260,41 @@ ASSERT_EQ(thread_group_->GetMaxTasksForTesting(), kMaxTasks); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); + EXPECT_FALSE( + thread_group_->ShouldYield({TaskPriority::BEST_EFFORT, TimeTicks()})); SaturateWithBlockingTasks(GetParam()); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); + EXPECT_FALSE( + thread_group_->ShouldYield({TaskPriority::BEST_EFFORT, TimeTicks()})); // Forces |kMaxTasks| extra workers to be instantiated by posting tasks. This // should not block forever. SaturateWithBusyTasks(); // All tasks can run, hence ShouldYield returns false. - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); + EXPECT_FALSE( + thread_group_->ShouldYield({TaskPriority::BEST_EFFORT, TimeTicks()})); // Post a USER_VISIBLE task that can't run since workers are saturated. This // should cause BEST_EFFORT tasks to yield. test::CreatePooledTaskRunner({TaskPriority::USER_VISIBLE}, &mock_pooled_task_runner_delegate_) - ->PostTask( - FROM_HERE, BindLambdaForTesting([&]() { - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); - })); - EXPECT_TRUE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); + ->PostTask(FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::BEST_EFFORT, TimeTicks()})); + })); + EXPECT_TRUE( + thread_group_->ShouldYield({TaskPriority::BEST_EFFORT, TimeTicks()})); // Post a USER_BLOCKING task that can't run since workers are saturated. This // should cause USER_VISIBLE tasks to yield. test::CreatePooledTaskRunner({TaskPriority::USER_BLOCKING}, &mock_pooled_task_runner_delegate_) ->PostTask(FROM_HERE, BindLambdaForTesting([&]() { - EXPECT_FALSE( - thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_VISIBLE, TimeTicks()})); })); - EXPECT_TRUE(thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); + EXPECT_TRUE( + thread_group_->ShouldYield({TaskPriority::USER_VISIBLE, TimeTicks()})); UnblockBusyTasks(); UnblockBlockingTasks();
diff --git a/base/task/thread_pool/thread_group_native.cc b/base/task/thread_pool/thread_group_native.cc index 89d60e2..39d8828 100644 --- a/base/task/thread_pool/thread_group_native.cc +++ b/base/task/thread_pool/thread_group_native.cc
@@ -102,10 +102,14 @@ void ThreadGroupNative::UpdateMinAllowedPriorityLockRequired() { // Tasks should yield as soon as there is work of higher priority in // |priority_queue_|. - min_allowed_priority_.store(priority_queue_.IsEmpty() - ? TaskPriority::BEST_EFFORT - : priority_queue_.PeekSortKey().priority(), - std::memory_order_relaxed); + if (priority_queue_.IsEmpty()) { + max_allowed_sort_key_.store({TaskPriority::BEST_EFFORT, 0}, + std::memory_order_relaxed); + } else { + max_allowed_sort_key_.store({priority_queue_.PeekSortKey().priority(), + priority_queue_.PeekSortKey().worker_count()}, + std::memory_order_relaxed); + } } RegisteredTaskSource ThreadGroupNative::GetWork() {
diff --git a/base/task/thread_pool/thread_group_unittest.cc b/base/task/thread_pool/thread_group_unittest.cc index a8c79ca..3f8ebcb 100644 --- a/base/task/thread_pool/thread_group_unittest.cc +++ b/base/task/thread_pool/thread_group_unittest.cc
@@ -404,18 +404,24 @@ task_tracker_.SetCanRunPolicy(CanRunPolicy::kNone); thread_group_->DidUpdateCanRunPolicy(); - EXPECT_TRUE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); - EXPECT_TRUE(thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); + EXPECT_TRUE( + thread_group_->ShouldYield({TaskPriority::BEST_EFFORT, TimeTicks()})); + EXPECT_TRUE( + thread_group_->ShouldYield({TaskPriority::USER_VISIBLE, TimeTicks()})); task_tracker_.SetCanRunPolicy(CanRunPolicy::kForegroundOnly); thread_group_->DidUpdateCanRunPolicy(); - EXPECT_TRUE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); + EXPECT_TRUE( + thread_group_->ShouldYield({TaskPriority::BEST_EFFORT, TimeTicks()})); + EXPECT_FALSE( + thread_group_->ShouldYield({TaskPriority::USER_VISIBLE, TimeTicks()})); task_tracker_.SetCanRunPolicy(CanRunPolicy::kAll); thread_group_->DidUpdateCanRunPolicy(); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); + EXPECT_FALSE( + thread_group_->ShouldYield({TaskPriority::BEST_EFFORT, TimeTicks()})); + EXPECT_FALSE( + thread_group_->ShouldYield({TaskPriority::USER_VISIBLE, TimeTicks()})); } // Verify that the maximum number of BEST_EFFORT tasks that can run concurrently @@ -565,14 +571,14 @@ test::CreatePooledTaskRunner({TaskPriority::USER_BLOCKING}, &mock_pooled_task_runner_delegate_) - ->PostTask( - FROM_HERE, BindLambdaForTesting([&]() { - EXPECT_FALSE(thread_group_->ShouldYield(TaskPriority::BEST_EFFORT)); - EXPECT_FALSE( - thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); - EXPECT_FALSE( - thread_group_->ShouldYield(TaskPriority::USER_VISIBLE)); - })); + ->PostTask(FROM_HERE, BindLambdaForTesting([&]() { + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::BEST_EFFORT, TimeTicks::Now()})); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_VISIBLE, TimeTicks::Now()})); + EXPECT_FALSE(thread_group_->ShouldYield( + {TaskPriority::USER_VISIBLE, TimeTicks::Now()})); + })); task_tracker_.FlushForTesting(); }
diff --git a/base/task/thread_pool/thread_pool_impl.cc b/base/task/thread_pool/thread_pool_impl.cc index d615269..cce0da5 100644 --- a/base/task/thread_pool/thread_pool_impl.cc +++ b/base/task/thread_pool/thread_pool_impl.cc
@@ -438,7 +438,7 @@ if (!thread_group->IsBoundToCurrentThread()) return true; return GetThreadGroupForTraits({priority, task_source->thread_policy()}) - ->ShouldYield(priority); + ->ShouldYield(task_source->GetSortKey()); } bool ThreadPoolImpl::EnqueueJobTaskSource(
diff --git a/build/util/generate_wrapper.gni b/build/util/generate_wrapper.gni index 157c09c..32e6d5b 100644 --- a/build/util/generate_wrapper.gni +++ b/build/util/generate_wrapper.gni
@@ -92,9 +92,5 @@ "--", ] args += _wrapped_arguments - - if (defined(invoker.write_runtime_deps)) { - write_runtime_deps = invoker.write_runtime_deps - } } }
diff --git a/cc/metrics/dropped_frame_counter.cc b/cc/metrics/dropped_frame_counter.cc index 022c140..79f68b7 100644 --- a/cc/metrics/dropped_frame_counter.cc +++ b/cc/metrics/dropped_frame_counter.cc
@@ -56,10 +56,16 @@ TRACE_EVENT2("cc,benchmark", "SmoothnessDroppedFrame", "total", total_frames, "smoothness", total_smoothness_dropped_); - if (ukm_smoothness_data_) { - // TODO(sad): Use atomic memcpy here to write to the shared memory, instead - // of writing individual fields in the shared memory. - // https://chromium-review.googlesource.com/c/chromium/src/+/1572369 + if (ukm_smoothness_data_ && total_frames > 0) { + UkmSmoothnessData smoothness_data; + smoothness_data.avg_smoothness = + static_cast<double>(total_smoothness_dropped_) * 100 / total_frames; + + ukm_smoothness_data_->seq_lock.WriteBegin(); + device::OneWriterSeqLock::AtomicWriterMemcpy(&ukm_smoothness_data_->data, + &smoothness_data, + sizeof(UkmSmoothnessData)); + ukm_smoothness_data_->seq_lock.WriteEnd(); } }
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index f19a60d..ddb268c 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -9324,8 +9324,14 @@ auto mapping = shmem_region_.Map(); auto* smoothness = mapping.GetMemoryAs<UkmSmoothnessDataShared>(); ASSERT_TRUE(smoothness); - // TODO(sad): Validate the content in |smoothness| once - // |DroppedFrameCounter| writes to the shared memory. + // It is not always possible to guarantee an exact number of dropped frames. + // So validate that there are non-zero dropped frames. + EXPECT_GT(smoothness->data.avg_smoothness, 0); + } + + void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, + const viz::BeginFrameArgs& args) override { + host_impl->dropped_frame_counter()->OnFcpReceived(); } void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
diff --git a/chrome/android/DEPS b/chrome/android/DEPS index 8d31e58..7d49efe 100644 --- a/chrome/android/DEPS +++ b/chrome/android/DEPS
@@ -22,6 +22,7 @@ "+chrome/browser/ui/android/favicon/java", "+chrome/browser/ui/android/native_page", "+chrome/browser/ui/messages/android", + "+chrome/browser/user_education", "+chrome/browser/util/android/java", "+chrome/browser/webauthn/android", "+components/browser_ui/android/bottomsheet",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 3def34d55..4751642 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -52,7 +52,6 @@ "java/src/org/chromium/chrome/browser/SynchronousInitializationActivity.java", "java/src/org/chromium/chrome/browser/TabThemeColorProvider.java", "java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java", - "java/src/org/chromium/chrome/browser/ThemeColorProvider.java", "java/src/org/chromium/chrome/browser/WarmupManager.java", "java/src/org/chromium/chrome/browser/WebContentsFactory.java", "java/src/org/chromium/chrome/browser/WindowDelegate.java", @@ -1560,6 +1559,7 @@ "java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonView.java", "java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonViewBinder.java", "java/src/org/chromium/chrome/browser/toolbar/TabSwitcherDrawable.java", + "java/src/org/chromium/chrome/browser/toolbar/ThemeColorProvider.java", "java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java", "java/src/org/chromium/chrome/browser/toolbar/ToolbarColors.java", "java/src/org/chromium/chrome/browser/toolbar/ToolbarCommonPropertiesModel.java",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantAutostartTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantAutostartTest.java index 7500af5..242c99d 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantAutostartTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantAutostartTest.java
@@ -20,6 +20,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto; import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto; import org.chromium.chrome.browser.autofill_assistant.proto.ChipType; @@ -52,6 +53,7 @@ */ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/1134118") public void testAutostart() { mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent( InstrumentationRegistry.getTargetContext(), "http://www.example.com"));
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java index cf52be3c..cb300cb5 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java
@@ -54,7 +54,6 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard; import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto; @@ -902,7 +901,6 @@ */ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1130016") public void testCreateAndEnterAddress() throws Exception { ArrayList<ActionProto> list = new ArrayList<>(); list.add((ActionProto) ActionProto.newBuilder()
diff --git a/chrome/android/features/keyboard_accessory/BUILD.gn b/chrome/android/features/keyboard_accessory/BUILD.gn index fea88b4..cb647457 100644 --- a/chrome/android/features/keyboard_accessory/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/BUILD.gn
@@ -122,6 +122,7 @@ "//components/autofill/android:autofill_java", "//components/browser_ui/android/bottomsheet:java", "//components/embedder_support/android:content_view_java", + "//components/embedder_support/android:util_java", "//components/feature_engagement/public:public_java", "//components/module_installer/android:module_installer_java", "//content/public/android:content_java",
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetMediator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetMediator.java index c2307e2..d8f99e1f 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetMediator.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetMediator.java
@@ -7,6 +7,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.SHEET_ITEMS; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.VISIBLE; +import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogProperties; @@ -14,6 +15,7 @@ import org.chromium.ui.modelutil.MVCListAdapter.ListItem; import org.chromium.ui.modelutil.PropertyModel; +import java.util.Arrays; import java.util.Locale; /** @@ -57,6 +59,8 @@ void setCredentials(Credential[] credentials, boolean isPasswordField) { assert credentials != null; + Arrays.sort(credentials, AllPasswordsBottomSheetMediator::compareCredentials); + mCredentials = credentials; mIsPasswordField = isPasswordField; @@ -135,4 +139,14 @@ mModel.set(VISIBLE, false); mDelegate.onDismissed(); } + + private static int compareCredentials(Credential credential1, Credential credential2) { + String displayOrigin1 = credential1.isAndroidCredential() + ? credential1.getAppDisplayName().toLowerCase(Locale.ENGLISH) + : UrlUtilities.getDomainAndRegistry(credential1.getOriginUrl(), false); + String displayOrigin2 = credential2.isAndroidCredential() + ? credential2.getAppDisplayName().toLowerCase(Locale.ENGLISH) + : UrlUtilities.getDomainAndRegistry(credential2.getOriginUrl(), false); + return displayOrigin1.compareTo(displayOrigin2); + } }
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetControllerTest.java index 2213eb9..cf75aeb 100644 --- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetControllerTest.java +++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/all_passwords_bottom_sheet/AllPasswordsBottomSheetControllerTest.java
@@ -7,7 +7,10 @@ import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.CredentialProperties.CREDENTIAL; import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.DISMISS_HANDLER; @@ -15,17 +18,22 @@ import static org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.VISIBLE; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.keyboard_accessory.all_passwords_bottom_sheet.AllPasswordsBottomSheetProperties.ItemType; import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.components.embedder_support.util.UrlUtilities; +import org.chromium.components.embedder_support.util.UrlUtilitiesJni; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogProperties; import org.chromium.ui.modaldialog.ModalDialogProperties.ButtonType; @@ -41,14 +49,20 @@ @Features.EnableFeatures(ChromeFeatureList.FILLING_PASSWORDS_FROM_ANY_ORIGIN) public class AllPasswordsBottomSheetControllerTest { private static final Credential ANA = - new Credential("Ana", "S3cr3t", "Ana", "https://m.a.xyz/", false, ""); + new Credential("Ana", "S3cr3t", "Ana", "https://m.domain.xyz/", false, ""); private static final Credential BOB = new Credential("Bob", "*****", "Bob", "https://subdomain.example.xyz", false, ""); private static final Credential CARL = - new Credential("Carl", "G3h3!m", "Carl", "https://www.example.xyz", false, ""); - private static final Credential[] TEST_CREDENTIALS = new Credential[] {ANA, BOB, CARL}; + new Credential("Carl", "G3h3!m", "Carl", "https://www.origin.xyz", false, ""); + private static final Credential[] TEST_CREDENTIALS = new Credential[] {BOB, CARL, ANA}; private static final boolean IS_PASSWORD_FIELD = true; + @Rule + public JniMocker mJniMocker = new JniMocker(); + @Rule + public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor(); + @Mock + private UrlUtilities.Natives mUrlUtilitiesJniMock; @Mock private AllPasswordsBottomSheetCoordinator.Delegate mMockDelegate; @@ -62,11 +76,15 @@ @Before public void setUp() { MockitoAnnotations.initMocks(this); + mJniMocker.mock(UrlUtilitiesJni.TEST_HOOKS, mUrlUtilitiesJniMock); mMediator = new AllPasswordsBottomSheetMediator(); mModalDialogModel = getModalDialogModel(mMediator); mModel = AllPasswordsBottomSheetProperties.createDefaultModel( mMediator::onDismissed, mMediator::onQueryTextChange); mMediator.initialize(mModalDialogManager, mModalDialogModel, mMockDelegate, mModel); + + when(mUrlUtilitiesJniMock.getDomainAndRegistry(anyString(), anyBoolean())) + .then(inv -> getDomainAndRegistry(inv.getArgument(0))); } @Test @@ -148,10 +166,32 @@ assertThat(mModel.get(SHEET_ITEMS).size(), is(1)); } + @Test + public void testCredentialSortedByOrigin() { + mMediator.setCredentials(TEST_CREDENTIALS, IS_PASSWORD_FIELD); + + ListModel<ListItem> itemList = mModel.get(SHEET_ITEMS); + + assertThat(itemList.get(0).model.get(CREDENTIAL), is(ANA)); + assertThat(itemList.get(1).model.get(CREDENTIAL), is(BOB)); + assertThat(itemList.get(2).model.get(CREDENTIAL), is(CARL)); + } + private PropertyModel getModalDialogModel(AllPasswordsBottomSheetMediator mediator) { return new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) .with(ModalDialogProperties.CONTROLLER, mediator) .with(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY, true) .build(); } + + /** + * Helper to get organization-identifying host from URLs. The real implementation calls + * {@link UrlUtilities}. It's not useful to actually reimplement it, so just return a string in + * a trivial way. + * @param origin A URL. + * @return The organization-identifying host from the given URL. + */ + private String getDomainAndRegistry(String origin) { + return origin.replaceAll(".*\\.(.+\\.[^.]+$)", "$1"); + } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java index 931c4e9..49cf675 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
@@ -14,7 +14,6 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.ChromeTabbedActivity; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; @@ -29,6 +28,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupUtils; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator; import org.chromium.chrome.tab_ui.R; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java index afb4c681..116068da 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java
@@ -18,7 +18,6 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.supplier.OneshotSupplier; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.infobar.InfoBarIdentifier; @@ -40,6 +39,7 @@ import org.chromium.chrome.browser.tasks.ConditionalTabStripUtils.ReasonToShow; import org.chromium.chrome.browser.tasks.tab_groups.EmptyTabGroupModelFilterObserver; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator; import org.chromium.chrome.browser.ui.messages.infobar.SimpleConfirmInfoBarBuilder; import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java index 25a887b..addf78b 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegate.java
@@ -10,7 +10,6 @@ import androidx.annotation.IntDef; import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.compositor.layouts.Layout; @@ -21,6 +20,7 @@ import org.chromium.chrome.browser.tasks.TasksSurfaceProperties; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; import org.chromium.chrome.browser.tasks.tab_management.suggestions.TabSuggestions; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.features.start_surface.StartSurface; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java index 84833add..32a6c98 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabManagementDelegateImpl.java
@@ -12,7 +12,6 @@ import org.chromium.base.SysUtils; import org.chromium.base.annotations.UsedByReflection; import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.compositor.layouts.Layout; @@ -26,6 +25,7 @@ import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; import org.chromium.chrome.browser.tasks.tab_management.suggestions.TabSuggestions; import org.chromium.chrome.browser.tasks.tab_management.suggestions.TabSuggestionsOrchestrator; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.features.start_surface.StartSurface; import org.chromium.chrome.features.start_surface.StartSurfaceDelegate; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java index 6b4ba5de..91c9ad2 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java
@@ -42,7 +42,6 @@ import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; @@ -64,6 +63,7 @@ import org.chromium.chrome.browser.tasks.ConditionalTabStripUtils; import org.chromium.chrome.browser.tasks.ConditionalTabStripUtils.FeatureStatus; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator; import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
diff --git a/chrome/android/java/res/drawable/ic_google_services_48dp.xml b/chrome/android/java/res/drawable/ic_google_services_48dp.xml index c409429c..9386532 100644 --- a/chrome/android/java/res/drawable/ic_google_services_48dp.xml +++ b/chrome/android/java/res/drawable/ic_google_services_48dp.xml
@@ -13,5 +13,5 @@ <path android:pathData="M19.9998,21.5834V18.4834H27.7998C27.9165,19.0084 28.0082,19.5 28.0082,20.1917C28.0082,24.95 24.8165,28.3334 20.0082,28.3334C15.3998,28.3334 11.6665,24.6 11.6665,20C11.6665,15.4 15.3998,11.6667 19.9998,11.6667C22.2498,11.6667 24.1332,12.4917 25.5748,13.8417L23.2082,16.1417C22.6082,15.575 21.5665,14.9 19.9998,14.9C17.2415,14.9 14.9915,17.1917 14.9915,20C14.9915,22.8084 17.2415,25.1 19.9998,25.1C23.1915,25.1 24.3665,22.8917 24.5832,21.5834H19.9998V21.5834Z" - android:fillColor="@color/default_icon_color_secondary"/> + android:fillColor="@color/default_icon_color"/> </vector>
diff --git a/chrome/android/java/res/drawable/ic_signout_40dp.xml b/chrome/android/java/res/drawable/ic_signout_40dp.xml index 30ad189..f4ce681 100644 --- a/chrome/android/java/res/drawable/ic_signout_40dp.xml +++ b/chrome/android/java/res/drawable/ic_signout_40dp.xml
@@ -13,6 +13,6 @@ <path android:pathData="M24.166 15.833l-1.175 1.175 2.15 2.159h-8.474v1.666h8.474l-2.15 2.15 1.175 1.184L28.334 20l-4.166-4.167zm-10.833-1.666H20V12.5h-6.667c-0.917 0-1.667 0.75-1.667 1.667v11.666c0 0.917 0.75 1.667 1.667 1.667H20v-1.667h-6.667V14.167z" - android:fillColor="@color/default_icon_color_secondary" + android:fillColor="@color/default_icon_color" android:fillType="evenOdd"/> </vector>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TabThemeColorProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/TabThemeColorProvider.java index 078f070..9c5e6138 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/TabThemeColorProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/TabThemeColorProvider.java
@@ -9,6 +9,7 @@ import org.chromium.chrome.browser.ActivityTabProvider.ActivityTabTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabThemeColorHelper; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; /** A ThemeColorProvider for the current tab's theming. */ public class TabThemeColorProvider extends ThemeColorProvider {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegate.java index 6078223..a91c396 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegate.java
@@ -24,6 +24,9 @@ import org.chromium.components.signin.AccountUtils; import org.chromium.components.signin.base.CoreAccountInfo; import org.chromium.components.signin.base.GoogleServiceAuthError; +import org.chromium.components.signin.identitymanager.ConsentLevel; +import org.chromium.components.signin.identitymanager.IdentityManager; +import org.chromium.components.signin.metrics.SignoutReason; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.base.WindowAndroid; @@ -40,6 +43,7 @@ private final WebSigninBridge.Factory mWebSigninBridgeFactory; private final String mContinueUrl; private final SigninManager mSigninManager; + private final IdentityManager mIdentityManager; private @Nullable WebSigninBridge mWebSigninBridge; private Callback<GoogleServiceAuthError> mOnSignInErrorCallback; @@ -60,6 +64,8 @@ mContinueUrl = continueUrl; mSigninManager = IdentityServicesProvider.get().getSigninManager( Profile.getLastUsedRegularProfile()); + mIdentityManager = IdentityServicesProvider.get().getIdentityManager( + Profile.getLastUsedRegularProfile()); } /** @@ -75,6 +81,14 @@ */ public void signIn(CoreAccountInfo coreAccountInfo, Callback<GoogleServiceAuthError> onSignInErrorCallback) { + if (mIdentityManager.getPrimaryAccountInfo(ConsentLevel.NOT_REQUIRED) != null) { + // In case an error is fired because cookies are taking longer to generate than usual, + // if user retries the sign-in from the error screen, we need to sign out the user + // first before signing in again. + destroyWebSigninBridge(); + // TODO(https://crbug.com/1133752): Revise sign-out reason + mSigninManager.signOut(SignoutReason.ABORT_SIGNIN); + } mOnSignInErrorCallback = onSignInErrorCallback; mWebSigninBridge = mWebSigninBridgeFactory.create( Profile.getLastUsedRegularProfile(), coreAccountInfo, this); @@ -152,7 +166,6 @@ public void onSigninFailed(GoogleServiceAuthError error) { ThreadUtils.assertOnUiThread(); mOnSignInErrorCallback.onResult(error); - destroyWebSigninBridge(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java index de8931a..009effc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java
@@ -305,12 +305,17 @@ R.color.default_icon_color); } + if (!profileSyncService.isFirstSetupComplete() || profileSyncService.hasUnrecoverableError() + || profileSyncService.getAuthError() != GoogleServiceAuthError.State.NONE) { + return useNewIcon + ? AppCompatResources.getDrawable(context, R.drawable.ic_sync_error_48dp) + : UiUtils.getTintedDrawable( + context, R.drawable.ic_sync_error_legacy_40dp, R.color.default_red); + } + if (profileSyncService.isEngineInitialized() - && (profileSyncService.hasUnrecoverableError() - || profileSyncService.getAuthError() != GoogleServiceAuthError.State.NONE - || profileSyncService.isPassphraseRequiredForPreferredDataTypes() - || profileSyncService.isTrustedVaultKeyRequiredForPreferredDataTypes() - || !profileSyncService.isFirstSetupComplete())) { + && (profileSyncService.isPassphraseRequiredForPreferredDataTypes() + || profileSyncService.isTrustedVaultKeyRequiredForPreferredDataTypes())) { return useNewIcon ? AppCompatResources.getDrawable(context, R.drawable.ic_sync_error_48dp) : UiUtils.getTintedDrawable(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/AppThemeColorProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/AppThemeColorProvider.java index e107649..e2cbdfc7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/AppThemeColorProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/AppThemeColorProvider.java
@@ -6,7 +6,6 @@ import android.content.Context; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java index 3a08a2e0..3afa2bb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java
@@ -22,8 +22,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.ActivityTabProvider.ActivityTabTabObserver; -import org.chromium.chrome.browser.ThemeColorProvider; -import org.chromium.chrome.browser.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeState; @@ -35,6 +33,7 @@ import org.chromium.chrome.browser.settings.SettingsLauncher; import org.chromium.chrome.browser.settings.SettingsLauncherImpl; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider.TintObserver; import org.chromium.ui.widget.ChromeImageButton; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/SettableThemeColorProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/SettableThemeColorProvider.java index d3beffcd..7524ff9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/SettableThemeColorProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/SettableThemeColorProvider.java
@@ -6,8 +6,6 @@ import android.content.Context; -import org.chromium.chrome.browser.ThemeColorProvider; - /** * {@link ThemeColorProvider} that blindly tracks whatever primary color it's set to. * It contains no actual tracking logic; to function properly, setPrimaryColor must be called each
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java index 9280207..9637c31 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java
@@ -7,9 +7,8 @@ import android.content.res.ColorStateList; import android.view.View.OnClickListener; -import org.chromium.chrome.browser.ThemeColorProvider; -import org.chromium.chrome.browser.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.toolbar.TabCountProvider.TabCountObserver; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider.TintObserver; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ThemeColorProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ThemeColorProvider.java similarity index 97% rename from chrome/android/java/src/org/chromium/chrome/browser/ThemeColorProvider.java rename to chrome/android/java/src/org/chromium/chrome/browser/toolbar/ThemeColorProvider.java index 06fad401..ac4d263 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ThemeColorProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ThemeColorProvider.java
@@ -2,7 +2,7 @@ // 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; +package org.chromium.chrome.browser.toolbar; import android.content.Context; import android.content.res.ColorStateList; @@ -11,7 +11,6 @@ import androidx.annotation.Nullable; import org.chromium.base.ObserverList; -import org.chromium.chrome.browser.toolbar.ToolbarColors; import org.chromium.ui.util.ColorUtils; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index e52b89b..dbffdea2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -30,9 +30,6 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.TabLoadStatus; -import org.chromium.chrome.browser.ThemeColorProvider; -import org.chromium.chrome.browser.ThemeColorProvider.ThemeColorObserver; -import org.chromium.chrome.browser.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.WindowDelegate; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.bookmarks.BookmarkBridge; @@ -76,6 +73,8 @@ import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider.ThemeColorObserver; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator; import org.chromium.chrome.browser.toolbar.load_progress.LoadProgressCoordinator; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java index ff4c9fb..43d168e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java
@@ -18,7 +18,6 @@ import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabProvider; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.browser_controls.BrowserControlsSizer; import org.chromium.chrome.browser.compositor.layouts.LayoutManager; @@ -30,6 +29,7 @@ import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.toolbar.TabCountProvider; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.toolbar.bottom.BottomControlsViewBinder.ViewHolder; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java index 465c3910..3dd5951 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButton.java
@@ -20,14 +20,16 @@ import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; + import androidx.annotation.DrawableRes; import androidx.annotation.VisibleForTesting; import androidx.core.view.ViewCompat; + import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper.MenuButtonState; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.toolbar.ToolbarColors; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; import org.chromium.components.browser_ui.widget.animation.Interpolators;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java index 3b57b8e..de113bf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinator.java
@@ -13,8 +13,8 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.OneshotSupplier; import org.chromium.base.supplier.Supplier; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ShowBadgeProperty; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ThemeProperty; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java index 80a88e52..40f8ceb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediator.java
@@ -15,11 +15,11 @@ import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.OneshotSupplier; import org.chromium.base.supplier.Supplier; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper.MenuButtonState; import org.chromium.chrome.browser.omnibox.LocationBar; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator.SetFocusFunction; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ShowBadgeProperty; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ThemeProperty;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java index cb349040..a71ef41 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
@@ -17,7 +17,6 @@ import org.chromium.base.supplier.OneshotSupplier; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.incognito.IncognitoUtils; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; @@ -26,6 +25,7 @@ import org.chromium.chrome.browser.toolbar.TabCountProvider; import org.chromium.chrome.browser.toolbar.TabSwitcherButtonCoordinator; import org.chromium.chrome.browser.toolbar.TabSwitcherButtonView; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator; import org.chromium.chrome.browser.user_education.UserEducationHelper; import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java index 99113d8..5cee380 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -27,9 +27,6 @@ import org.chromium.base.ObserverList; import org.chromium.base.TraceEvent; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ThemeColorProvider; -import org.chromium.chrome.browser.ThemeColorProvider.ThemeColorObserver; -import org.chromium.chrome.browser.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.omnibox.LocationBar; @@ -40,6 +37,9 @@ import org.chromium.chrome.browser.toolbar.ButtonData; import org.chromium.chrome.browser.toolbar.HomeButton; import org.chromium.chrome.browser.toolbar.TabCountProvider; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider.ThemeColorObserver; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider.TintObserver; import org.chromium.chrome.browser.toolbar.ToolbarColors; import org.chromium.chrome.browser.toolbar.ToolbarDataProvider; import org.chromium.chrome.browser.toolbar.ToolbarProgressBar;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 0075d29..782151c8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -20,7 +20,6 @@ import org.chromium.base.supplier.OneshotSupplier; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.omnibox.LocationBar; import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider; @@ -28,6 +27,7 @@ import org.chromium.chrome.browser.toolbar.ButtonData; import org.chromium.chrome.browser.toolbar.ButtonDataProvider; import org.chromium.chrome.browser.toolbar.TabCountProvider; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.toolbar.ToolbarDataProvider; import org.chromium.chrome.browser.toolbar.ToolbarProgressBar; import org.chromium.chrome.browser.toolbar.ToolbarTabController;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java index 5860106e..fe026212 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java
@@ -12,6 +12,7 @@ import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.createTestBitmap; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; @@ -20,6 +21,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.drawable.Drawable; +import android.os.Build; import android.support.test.InstrumentationRegistry; import android.view.Menu; import android.view.MenuItem; @@ -194,6 +196,7 @@ @Test @MediumTest @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + @TargetApi(Build.VERSION_CODES.M) @SuppressLint("NewApi") public void closeAllIncognitoNotificationIsNotDisplayed() throws Exception { // It may happen that some previous incognito notification from tabbed activity may be
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java index a0a5d19..a80557d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java
@@ -7,10 +7,12 @@ import static org.junit.Assert.assertEquals; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; import android.content.Context; +import android.os.Build; import android.support.test.InstrumentationRegistry; import android.util.Pair; @@ -185,8 +187,9 @@ } @Test - @Feature("Incognito") @MediumTest + @Feature("Incognito") + @TargetApi(Build.VERSION_CODES.M) @SuppressLint("NewApi") public void testCloseAllIncognitoNotificationIsDisplayed() { mActivityTestRule.startMainActivityOnBlankPage();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java index df97d599..3048bee 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
@@ -234,7 +234,8 @@ } public void signinAndEnableSync(final Account account) { - SigninTestUtil.signinAndEnableSync(account, mProfileSyncService); + SigninTestUtil.signinAndEnableSync( + mAccountManagerTestRule.toCoreAccountInfo(account.name), mProfileSyncService); enableUKM(); SyncTestUtil.waitForSyncActive(); SyncTestUtil.triggerSyncAndWaitForCompletion();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateTest.java index 186a862..5f61ba1 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegateTest.java
@@ -5,10 +5,12 @@ package org.chromium.chrome.browser.signin.account_picker; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -73,6 +75,9 @@ private SigninManager mSigninManagerMock; @Mock + private IdentityManager mIdentityManagerMock; + + @Mock private Profile mProfileMock; @Mock @@ -88,9 +93,6 @@ private AccountPickerDelegate mDelegate; - private final IdentityManager mIdentityManager = - new IdentityManager(/* nativeIdentityManager= */ 0, /* OAuth2TokenService= */ null); - @Before public void setUp() { initMocks(this); @@ -99,7 +101,8 @@ Profile.setLastUsedProfileForTesting(mProfileMock); IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class)); - when(IdentityServicesProvider.get().getIdentityManager(any())).thenReturn(mIdentityManager); + when(IdentityServicesProvider.get().getIdentityManager(any())) + .thenReturn(mIdentityManagerMock); when(IdentityServicesProvider.get().getSigninManager(any())).thenReturn(mSigninManagerMock); mDelegate = new AccountPickerDelegate( @@ -146,6 +149,27 @@ } @Test + public void testSigninTriggersSignoutIfAlreadySignedIn() { + // In case an error is fired because cookies are taking longer to generate than usual, + // if user retries the sign-in from the error screen, we need to sign out the user + // first before signing in again. + Account account = + mAccountManagerTestRule.addAccount(AccountManagerTestRule.TEST_ACCOUNT_EMAIL); + CoreAccountInfo coreAccountInfo = mAccountManagerTestRule.toCoreAccountInfo(account.name); + mDelegate.signIn(coreAccountInfo, error -> {}); + when(mIdentityManagerMock.getPrimaryAccountInfo(anyInt())).thenReturn(coreAccountInfo); + + mDelegate.signIn(coreAccountInfo, error -> {}); + InOrder calledInOrder = inOrder(mWebSigninBridgeMock, mSigninManagerMock, + mWebSigninBridgeFactoryMock, mSigninManagerMock); + calledInOrder.verify(mWebSigninBridgeMock).destroy(); + calledInOrder.verify(mSigninManagerMock).signOut(anyInt()); + calledInOrder.verify(mWebSigninBridgeFactoryMock) + .create(mProfileMock, coreAccountInfo, mDelegate); + calledInOrder.verify(mSigninManagerMock).signin(eq(coreAccountInfo), any()); + } + + @Test public void testSignInFailedWithConnectionError() { Account account = mAccountManagerTestRule.addAccount(AccountManagerTestRule.TEST_ACCOUNT_EMAIL); @@ -155,7 +179,9 @@ mDelegate.signIn(coreAccountInfo, mockCallback); mDelegate.onSigninFailed(error); verify(mockCallback).onResult(error); - verify(mWebSigninBridgeMock).destroy(); + // WebSigninBridge should be kept alive in case cookies are taking longer to + // generate than usual + verify(mWebSigninBridgeMock, never()).destroy(); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java index 95c97ab..826e2b9 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonCoordinatorTest.java
@@ -19,9 +19,9 @@ import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator; import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java index 3fdf2628..b0004a9 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonMediatorTest.java
@@ -22,10 +22,10 @@ import org.chromium.base.supplier.OneshotSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.chrome.browser.ThemeColorProvider; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; import org.chromium.chrome.browser.omnibox.LocationBar; +import org.chromium.chrome.browser.toolbar.ThemeColorProvider; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ShowBadgeProperty; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonProperties.ThemeProperty; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper;
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 96c6fcd..d976981 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2178,6 +2178,7 @@ "//crypto", "//crypto:platform", "//device/base", + "//device/base/synchronization", "//device/fido", "//device/gamepad/public/cpp:switches", "//device/vr/buildflags", @@ -2224,7 +2225,6 @@ "//services/proxy_resolver/public/mojom", "//services/resource_coordinator/public/cpp:resource_coordinator_cpp", "//services/resource_coordinator/public/cpp/memory_instrumentation:browser", - "//services/service_manager/embedder:embedder_result_codes", "//services/service_manager/public/cpp", "//services/shape_detection/public/mojom", "//services/strings",
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 1d42316..c9bf1947 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -491,7 +491,7 @@ StartupData* startup_data) : parameters_(parameters), parsed_command_line_(parameters.command_line), - result_code_(service_manager::RESULT_CODE_NORMAL_EXIT), + result_code_(content::RESULT_CODE_NORMAL_EXIT), should_call_pre_main_loop_start_startup_on_variations_service_( !parameters.ui_task), profile_(nullptr), @@ -687,7 +687,7 @@ } // Continue on and show error later (once UI has been initialized and main // message loop is running). - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } return load_local_state_result; } @@ -748,7 +748,7 @@ TRACE_EVENT0("startup", "ChromeBrowserMainParts::PreCreateThreads"); result_code_ = PreCreateThreadsImpl(); - if (result_code_ == service_manager::RESULT_CODE_NORMAL_EXIT) { + if (result_code_ == content::RESULT_CODE_NORMAL_EXIT) { // These members must be initialized before exiting this function normally. #if !defined(OS_ANDROID) DCHECK(browser_creator_.get()); @@ -797,7 +797,7 @@ browser_process_->SetApplicationLocale(locale); const int apply_first_run_result = ApplyFirstRunPrefs(); - if (apply_first_run_result != service_manager::RESULT_CODE_NORMAL_EXIT) + if (apply_first_run_result != content::RESULT_CODE_NORMAL_EXIT) return apply_first_run_result; SetupOriginTrialsCommandLine(browser_process_->local_state()); @@ -805,7 +805,7 @@ metrics::EnableExpiryChecker(chrome_metrics::kExpiredHistogramsHashes, chrome_metrics::kNumExpiredHistograms); - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } int ChromeBrowserMainParts::ApplyFirstRunPrefs() { @@ -817,7 +817,7 @@ std::unique_ptr<installer::InitialPreferences> installer_initial_prefs = startup_data_->chrome_feature_list_creator()->TakeInitialPrefs(); if (!installer_initial_prefs) - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; // On first run, we need to process the predictor preferences before the // browser's profile_manager object is created, but after ResourceBundle @@ -843,7 +843,7 @@ } #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } int ChromeBrowserMainParts::PreCreateThreadsImpl() { @@ -999,7 +999,7 @@ // which is used in SetupMetrics(). SetupMetrics(); - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } void ChromeBrowserMainParts::PostCreateThreads() { @@ -1197,7 +1197,7 @@ } return shell_integration::SetAsDefaultBrowser() - ? static_cast<int>(service_manager::RESULT_CODE_NORMAL_EXIT) + ? static_cast<int>(content::RESULT_CODE_NORMAL_EXIT) : static_cast<int>(chrome::RESULT_CODE_SHELL_INTEGRATION_FAILED); } @@ -1213,7 +1213,7 @@ if (parsed_command_line().HasSwitch(switches::kPackExtension)) { extensions::StartupHelper extension_startup_helper; if (extension_startup_helper.PackExtension(parsed_command_line())) - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; return chrome::RESULT_CODE_PACK_EXTENSION_ERROR; } @@ -1244,7 +1244,7 @@ // expected. if (parsed_command_line().HasSwitch(switches::kTestType)) return chrome::RESULT_CODE_NORMAL_EXIT_PROCESS_NOTIFIED; - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; case ProcessSingleton::PROFILE_IN_USE: return chrome::RESULT_CODE_PROFILE_IN_USE; @@ -1336,7 +1336,7 @@ } #else // We don't support retention experiments on Mac or Linux. - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; #endif // defined(OS_WIN) } #endif // !defined(OS_ANDROID) @@ -1344,7 +1344,7 @@ #if defined(OS_WIN) // Do the tasks if chrome has been upgraded while it was last running. if (!already_running && upgrade_util::DoUpgradeTasks(parsed_command_line())) - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; // Check if there is any machine level Chrome installed on the current // machine. If yes and the current Chrome process is user level, we do not @@ -1365,7 +1365,7 @@ user_data_dir_, parsed_command_line()); if (!profile_) - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; #if defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER) if (first_run::IsChromeFirstRun()) { @@ -1445,7 +1445,7 @@ // The first run dialog is modal, and spins a RunLoop, which could receive // a SIGTERM, and call chrome::AttemptExit(). Exit cleanly in that case. if (browser_shutdown::IsTryingToQuit()) - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
diff --git a/chrome/browser/chrome_browser_main_posix.cc b/chrome/browser/chrome_browser_main_posix.cc index a2049e9..a29a692 100644 --- a/chrome/browser/chrome_browser_main_posix.cc +++ b/chrome/browser/chrome_browser_main_posix.cc
@@ -140,7 +140,7 @@ int ChromeBrowserMainPartsPosix::PreEarlyInitialization() { const int result = ChromeBrowserMainParts::PreEarlyInitialization(); - if (result != service_manager::RESULT_CODE_NORMAL_EXIT) + if (result != content::RESULT_CODE_NORMAL_EXIT) return result; // We need to accept SIGCHLD, even though our handler is a no-op because @@ -150,7 +150,7 @@ action.sa_handler = SIGCHLDHandler; CHECK_EQ(0, sigaction(SIGCHLD, &action, NULL)); - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } void ChromeBrowserMainPartsPosix::PostMainMessageLoopStart() {
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index e99fe811..c5bd51f 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc
@@ -789,7 +789,7 @@ ShellExecute(NULL, NULL, L"appwiz.cpl", NULL, NULL, SW_SHOWNORMAL); // Exit as we are not launching the browser. - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } // We don't hide icons so we shouldn't do anything special to show them return chrome::RESULT_CODE_UNSUPPORTED_PARAM;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 40ad3491f..c5c7a66 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -4021,8 +4021,8 @@ content::WebContents* web_contents = handle->GetWebContents(); if (auto* subresource_filter_client = ChromeSubresourceFilterClient::FromWebContents(web_contents)) { - subresource_filter_client->MaybeAppendNavigationThrottles(handle, - &throttles); + subresource_filter_client->GetThrottleManager() + ->MaybeAppendNavigationThrottles(handle, &throttles); } #if !defined(OS_ANDROID)
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 10a0091..08a76f9 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1952,6 +1952,8 @@ "platform_keys/key_permissions/extension_key_permissions_service_factory.h", "platform_keys/key_permissions/key_permissions_policy_handler.cc", "platform_keys/key_permissions/key_permissions_policy_handler.h", + "platform_keys/key_permissions/key_permissions_pref_util.cc", + "platform_keys/key_permissions/key_permissions_pref_util.h", "platform_keys/key_permissions/key_permissions_service.cc", "platform_keys/key_permissions/key_permissions_service.h", "platform_keys/key_permissions/key_permissions_service_factory.cc",
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc index 9fe1fd5a..49a2fe36 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
@@ -523,8 +523,8 @@ std::get<1>(added_extensions[0])[0].id())); EXPECT_EQ(display_name1, std::get<1>(added_extensions[0])[0].name()); ASSERT_EQ(1u, std::get<1>(added_extensions[0])[0].language_codes().size()); - EXPECT_TRUE(chromeos::extension_ime_util::IsLanguageForArcIME( - (std::get<1>(added_extensions[0])[0].language_codes())[0])); + EXPECT_TRUE(chromeos::extension_ime_util::IsArcIME( + std::get<1>(added_extensions[0])[0].id())); // Emulate enabling ARC IME from chrome://settings. const std::string& arc_ime_id = std::get<1>(added_extensions[0])[0].id();
diff --git a/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_pref_util.cc b/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_pref_util.cc new file mode 100644 index 0000000..f6501c9 --- /dev/null +++ b/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_pref_util.cc
@@ -0,0 +1,92 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <memory> +#include <string> +#include <utility> + +#include "base/base64.h" +#include "base/values.h" +#include "chrome/common/pref_names.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/scoped_user_pref_update.h" + +namespace { +// The profile pref prefs::kPlatformKeys stores a dictionary mapping from +// public key (base64 encoding of an DER-encoded SPKI) to key properties. The +// currently only key property is the key usage, which can either be undefined +// or "corporate". If a key is not present in the pref, the default for the key +// usage is undefined, which in particular means "not for corporate usage". +// E.g. the entry in the profile pref might look like: +// "platform_keys" : { +// "ABCDEF123" : { +// "keyUsage" : "corporate" +// }, +// "abcdef567" : { +// "keyUsage" : "corporate" +// } +// } +const char kPrefKeyUsage[] = "keyUsage"; +const char kPrefKeyUsageCorporate[] = "corporate"; + +const base::DictionaryValue* GetPrefsEntry( + const std::string& public_key_spki_der_b64, + const PrefService* const profile_prefs) { + if (!profile_prefs) + return nullptr; + + const base::DictionaryValue* platform_keys = + profile_prefs->GetDictionary(prefs::kPlatformKeys); + if (!platform_keys) + return nullptr; + + const base::Value* key_entry_value = + platform_keys->FindKey(public_key_spki_der_b64); + if (!key_entry_value) + return nullptr; + + const base::DictionaryValue* key_entry = nullptr; + key_entry_value->GetAsDictionary(&key_entry); + return key_entry; +} + +} // namespace + +namespace chromeos { +namespace platform_keys { +namespace internal { + +bool IsUserKeyMarkedCorporateInPref(const std::string& public_key_spki_der, + PrefService* profile_prefs) { + std::string public_key_spki_der_b64; + base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64); + + const base::DictionaryValue* prefs_entry = + GetPrefsEntry(public_key_spki_der_b64, profile_prefs); + if (prefs_entry) { + const base::Value* key_usage = prefs_entry->FindKey(kPrefKeyUsage); + if (!key_usage || !key_usage->is_string()) + return false; + return key_usage->GetString() == kPrefKeyUsageCorporate; + } + return false; +} + +void MarkUserKeyCorporateInPref(const std::string& public_key_spki_der, + PrefService* profile_prefs) { + std::string public_key_spki_der_b64; + base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64); + + DictionaryPrefUpdate update(profile_prefs, prefs::kPlatformKeys); + + auto new_pref_entry = std::make_unique<base::DictionaryValue>(); + new_pref_entry->SetKey(kPrefKeyUsage, base::Value(kPrefKeyUsageCorporate)); + + update->SetWithoutPathExpansion(public_key_spki_der_b64, + std::move(new_pref_entry)); +} + +} // namespace internal +} // namespace platform_keys +} // namespace chromeos
diff --git a/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_pref_util.h b/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_pref_util.h new file mode 100644 index 0000000..cdef266 --- /dev/null +++ b/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_pref_util.h
@@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_KEY_PERMISSIONS_KEY_PERMISSIONS_PREF_UTIL_H_ +#define CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_KEY_PERMISSIONS_KEY_PERMISSIONS_PREF_UTIL_H_ + +#include <string> + +class PrefService; + +namespace chromeos { +namespace platform_keys { + +// Note: Functions in this namespace are meant for internal use by key +// permissions classes. Please use KeyPermissionsService instead. +namespace internal { + +// Returns true if |public_key_spki_der| is marked for corporate usage in +// |profile_prefs|. Note: Only user keys are explicitly marked for corporate +// usage in the PrefService corresponding to the user's profile. +bool IsUserKeyMarkedCorporateInPref(const std::string& public_key_spki_der, + PrefService* profile_prefs); + +// Marks |public_key_spki_der| for corporate usage in |profile_prefs|. +// Note: This function will mark the key for corporate usage in |profile_prefs| +// even if the key is not accessible to that profile, so use it after making +// sure that the key is accessible to the user's profile. +void MarkUserKeyCorporateInPref(const std::string& public_key_spki_der, + PrefService* profile_prefs); + +} // namespace internal +} // namespace platform_keys +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_KEY_PERMISSIONS_KEY_PERMISSIONS_PREF_UTIL_H_
diff --git a/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_impl.cc b/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_impl.cc index 53e060f..19b0e39 100644 --- a/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_impl.cc +++ b/chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_impl.cc
@@ -17,6 +17,7 @@ #include "base/logging.h" #include "base/stl_util.h" #include "base/values.h" +#include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_pref_util.h" #include "chrome/browser/chromeos/platform_keys/platform_keys.h" #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" #include "chrome/browser/policy/profile_policy_connector.h" @@ -32,47 +33,6 @@ namespace chromeos { namespace platform_keys { -namespace { -// The profile pref prefs::kPlatformKeys stores a dictionary mapping from -// public key (base64 encoding of an DER-encoded SPKI) to key properties. The -// currently only key property is the key usage, which can either be undefined -// or "corporate". If a key is not present in the pref, the default for the key -// usage is undefined, which in particular means "not for corporate usage". -// E.g. the entry in the profile pref might look like: -// "platform_keys" : { -// "ABCDEF123" : { -// "keyUsage" : "corporate" -// }, -// "abcdef567" : { -// "keyUsage" : "corporate" -// } -// } -const char kPrefKeyUsage[] = "keyUsage"; -const char kPrefKeyUsageCorporate[] = "corporate"; - -const base::DictionaryValue* GetPrefsEntry( - const std::string& public_key_spki_der_b64, - const PrefService* const profile_prefs) { - if (!profile_prefs) - return nullptr; - - const base::DictionaryValue* platform_keys = - profile_prefs->GetDictionary(prefs::kPlatformKeys); - if (!platform_keys) - return nullptr; - - const base::Value* key_entry_value = - platform_keys->FindKey(public_key_spki_der_b64); - if (!key_entry_value) - return nullptr; - - const base::DictionaryValue* key_entry = nullptr; - key_entry_value->GetAsDictionary(&key_entry); - return key_entry; -} - -} // namespace - KeyPermissionsServiceImpl::KeyPermissionsServiceImpl( bool profile_is_managed, PrefService* profile_prefs, @@ -166,13 +126,11 @@ std::move(callback).Run(/*corporate=*/false); } - std::string public_key_spki_der_b64; - base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64); - for (const auto key_location : key_locations) { switch (key_location) { case TokenId::kUser: - if (IsUserKeyCorporate(public_key_spki_der_b64)) { + if (internal::IsUserKeyMarkedCorporateInPref(public_key_spki_der, + profile_prefs_)) { std::move(callback).Run(/*corporate=*/true); return; } @@ -221,36 +179,12 @@ std::move(callback).Run(Status::kSuccess); return; case TokenId::kUser: { - std::string public_key_spki_der_b64; - base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64); - - DictionaryPrefUpdate update(profile_prefs_, prefs::kPlatformKeys); - - std::unique_ptr<base::DictionaryValue> new_pref_entry( - new base::DictionaryValue); - new_pref_entry->SetKey(kPrefKeyUsage, - base::Value(kPrefKeyUsageCorporate)); - - update->SetWithoutPathExpansion(public_key_spki_der_b64, - std::move(new_pref_entry)); + internal::MarkUserKeyCorporateInPref(public_key_spki_der, profile_prefs_); std::move(callback).Run(Status::kSuccess); return; } } } -bool KeyPermissionsServiceImpl::IsUserKeyCorporate( - const std::string& public_key_spki_der_b64) const { - const base::DictionaryValue* prefs_entry = - GetPrefsEntry(public_key_spki_der_b64, profile_prefs_); - if (prefs_entry) { - const base::Value* key_usage = prefs_entry->FindKey(kPrefKeyUsage); - if (!key_usage || !key_usage->is_string()) - return false; - return key_usage->GetString() == kPrefKeyUsageCorporate; - } - return false; -} - } // namespace platform_keys } // namespace chromeos
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc index 618095f..5d5bd08 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry.cc +++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -788,7 +788,7 @@ shell_integration::DefaultWebClientWorkerCallback ProtocolHandlerRegistry::GetDefaultWebClientCallback( const std::string& protocol) { - return base::Bind( + return base::BindOnce( &ProtocolHandlerRegistry::OnSetAsDefaultProtocolClientFinished, weak_ptr_factory_.GetWeakPtr(), protocol); }
diff --git a/chrome/browser/downgrade/user_data_downgrade_browsertest.cc b/chrome/browser/downgrade/user_data_downgrade_browsertest.cc index 43de243..6359fdf 100644 --- a/chrome/browser/downgrade/user_data_downgrade_browsertest.cc +++ b/chrome/browser/downgrade/user_data_downgrade_browsertest.cc
@@ -31,7 +31,6 @@ #include "content/public/browser/browser_thread.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_utils.h" -#include "services/service_manager/embedder/result_codes.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/enterprise/connectors/common.cc b/chrome/browser/enterprise/connectors/common.cc index ad799634..04306f9 100644 --- a/chrome/browser/enterprise/connectors/common.cc +++ b/chrome/browser/enterprise/connectors/common.cc
@@ -87,4 +87,11 @@ : response(response) {} ScanResult::~ScanResult() = default; +bool ContainsMalwareVerdict(const ContentAnalysisResponse& response) { + const auto& results = response.results(); + return std::any_of(results.begin(), results.end(), [](const auto& result) { + return result.tag() == "malware" && !result.triggered_rules().empty(); + }); +} + } // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/common.h b/chrome/browser/enterprise/connectors/common.h index de53775d..d4f26ce 100644 --- a/chrome/browser/enterprise/connectors/common.h +++ b/chrome/browser/enterprise/connectors/common.h
@@ -90,6 +90,9 @@ ContentAnalysisResponse response; }; +// Checks if |response| contains a negative malware verdict. +bool ContainsMalwareVerdict(const ContentAnalysisResponse& response); + } // namespace enterprise_connectors #endif // CHROME_BROWSER_ENTERPRISE_CONNECTORS_COMMON_H_
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index 0e4b913..a65f3d9 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1949,6 +1949,14 @@ return set_init_result(SUCCESS); } +bool ExecuteCodeInTabFunction::ShouldInsertCSS() const { + return false; +} + +bool ExecuteCodeInTabFunction::ShouldRemoveCSS() const { + return false; +} + bool ExecuteCodeInTabFunction::CanExecuteScriptOnPage(std::string* error) { content::WebContents* contents = nullptr; @@ -2032,11 +2040,11 @@ return GURL::EmptyGURL(); } -bool TabsExecuteScriptFunction::ShouldInsertCSS() const { - return false; +bool TabsInsertCSSFunction::ShouldInsertCSS() const { + return true; } -bool TabsInsertCSSFunction::ShouldInsertCSS() const { +bool TabsRemoveCSSFunction::ShouldRemoveCSS() const { return true; }
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.h b/chrome/browser/extensions/api/tabs/tabs_api.h index 51a9961..9031c66 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.h +++ b/chrome/browser/extensions/api/tabs/tabs_api.h
@@ -248,7 +248,7 @@ DISALLOW_COPY_AND_ASSIGN(TabsCaptureVisibleTabFunction); }; -// Implement API call tabs.executeScript and tabs.insertCSS. +// Implement API calls tabs.executeScript, tabs.insertCSS, and tabs.removeCSS. class ExecuteCodeInTabFunction : public ExecuteCodeFunction { public: ExecuteCodeInTabFunction(); @@ -258,6 +258,8 @@ // Initializes |execute_tab_id_| and |details_|. InitResult Init() override; + bool ShouldInsertCSS() const override; + bool ShouldRemoveCSS() const override; bool CanExecuteScriptOnPage(std::string* error) override; ScriptExecutor* GetScriptExecutor(std::string* error) override; bool IsWebView() const override; @@ -271,9 +273,6 @@ }; class TabsExecuteScriptFunction : public ExecuteCodeInTabFunction { - protected: - bool ShouldInsertCSS() const override; - private: ~TabsExecuteScriptFunction() override {} @@ -289,6 +288,23 @@ DECLARE_EXTENSION_FUNCTION("tabs.insertCSS", TABS_INSERTCSS) }; +// TODO(https://crrev.com/c/608854): When a file URL is passed, this will do +// more work than needed: since the key is created based on the file URL in +// that case, we don't actually need to +// +// a) load the file or +// b) localize it +// +// ... hence, it could just go straight to the ScriptExecutor. +class TabsRemoveCSSFunction : public ExecuteCodeInTabFunction { + private: + ~TabsRemoveCSSFunction() override {} + + bool ShouldRemoveCSS() const override; + + DECLARE_EXTENSION_FUNCTION("tabs.removeCSS", TABS_REMOVECSS) +}; + class TabsSetZoomFunction : public ExtensionFunction { private: ~TabsSetZoomFunction() override {}
diff --git a/chrome/browser/extensions/execute_script_apitest.cc b/chrome/browser/extensions/execute_script_apitest.cc index a3390896..4daad36 100644 --- a/chrome/browser/extensions/execute_script_apitest.cc +++ b/chrome/browser/extensions/execute_script_apitest.cc
@@ -132,6 +132,10 @@ ASSERT_TRUE(RunTest("executescript/callback")) << message_; } +IN_PROC_BROWSER_TEST_P(ExecuteScriptApiTest, ExecuteScriptRemoveCSS) { + ASSERT_TRUE(RunExtensionTest("executescript/remove_css")) << message_; +} + IN_PROC_BROWSER_TEST_P(ExecuteScriptApiTest, UserGesture) { // TODO(https://crbug.com/977629): Gesture support for testing is not // available for Service Worker-based extensions.
diff --git a/chrome/browser/federated_learning/floc_id_provider_browsertest.cc b/chrome/browser/federated_learning/floc_id_provider_browsertest.cc index 2aeac6d..10e64e6 100644 --- a/chrome/browser/federated_learning/floc_id_provider_browsertest.cc +++ b/chrome/browser/federated_learning/floc_id_provider_browsertest.cc
@@ -337,7 +337,7 @@ EXPECT_EQ(1u, GetHistoryUrls().size()); - EXPECT_EQ(GetFlocId(), FlocId()); + EXPECT_FALSE(GetFlocId().IsValid()); InitializeBlocklist({}); @@ -367,12 +367,15 @@ EXPECT_EQ(1u, GetHistoryUrls().size()); - EXPECT_EQ(GetFlocId(), FlocId()); + EXPECT_FALSE(GetFlocId().IsValid()); InitializeBlocklist({}); - // Expect that the FlocIdComputed user event is not recorded. + // Expect that the FlocIdComputed user event is not recorded, as we won't + // record the 1st event after browser/sync startup if there are permission + // errors. The floc is should also be invalid. ASSERT_EQ(0u, user_event_service()->GetRecordedUserEvents().size()); + EXPECT_FALSE(GetFlocId().IsValid()); } IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest, @@ -387,7 +390,7 @@ EXPECT_EQ(1u, GetHistoryUrls().size()); - EXPECT_EQ(GetFlocId(), FlocId()); + EXPECT_FALSE(GetFlocId().IsValid()); InitializeBlocklist({}); @@ -424,13 +427,16 @@ EXPECT_EQ(1u, GetHistoryUrls().size()); - EXPECT_EQ(GetFlocId(), FlocId()); + EXPECT_FALSE(GetFlocId().IsValid()); // Load a blocklist that would block the upcoming floc. InitializeBlocklist({FlocId::CreateFromHistory({test_host()}).ToUint64()}); - // Expect that the FlocIdComputed user event is not recorded. - ASSERT_EQ(0u, user_event_service()->GetRecordedUserEvents().size()); + // Expect that the FlocIdComputed user event is recorded. + ASSERT_EQ(1u, user_event_service()->GetRecordedUserEvents().size()); + + // Expect that the API call would reject. + EXPECT_EQ("rejected", InvokeInterestCohortJsApi(web_contents())); } IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest, @@ -445,13 +451,20 @@ EXPECT_EQ(1u, GetHistoryUrls().size()); - EXPECT_EQ(GetFlocId(), FlocId()); + EXPECT_FALSE(GetFlocId().IsValid()); // Load a blocklist that would block a floc different from the upcoming floc. InitializeBlocklist({FlocId::CreateFromHistory({"b.test"}).ToUint64()}); + // Expect the current floc to have the expected value. + EXPECT_EQ(GetFlocId(), FlocId::CreateFromHistory({test_host()})); + // Expect that the FlocIdComputed user event is recorded. ASSERT_EQ(1u, user_event_service()->GetRecordedUserEvents().size()); + + // Expect that the API call would return the expected floc. + EXPECT_EQ(FlocId::CreateFromHistory({test_host()}).ToString(), + InvokeInterestCohortJsApi(web_contents())); } IN_PROC_BROWSER_TEST_F(FlocIdProviderWithCustomizedServicesBrowserTest,
diff --git a/chrome/browser/federated_learning/floc_id_provider_impl.cc b/chrome/browser/federated_learning/floc_id_provider_impl.cc index 0d84f33..352e7b3 100644 --- a/chrome/browser/federated_learning/floc_id_provider_impl.cc +++ b/chrome/browser/federated_learning/floc_id_provider_impl.cc
@@ -81,7 +81,7 @@ } void FlocIdProviderImpl::OnComputeFlocCompleted(ComputeFlocTrigger trigger, - FlocId floc_id) { + ComputeFlocResult result) { DCHECK(floc_computation_in_progress_); floc_computation_in_progress_ = false; @@ -94,10 +94,8 @@ return; } - if (floc_id_ != floc_id) { - floc_id_ = floc_id; - NotifyFlocUpdated(trigger); - } + LogFlocComputedEvent(trigger, result); + floc_id_ = result.final_hash; // Abandon the scheduled task if any, and schedule a new compute-floc task // that is |kFlocScheduledUpdateInterval| from now. @@ -107,10 +105,20 @@ weak_ptr_factory_.GetWeakPtr())); } -void FlocIdProviderImpl::NotifyFlocUpdated(ComputeFlocTrigger trigger) { +void FlocIdProviderImpl::LogFlocComputedEvent(ComputeFlocTrigger trigger, + const ComputeFlocResult& result) { if (!base::FeatureList::IsEnabled(features::kFlocIdComputedEventLogging)) return; + // Don't log if it's the 1st computation and sim_hash is not computed. This + // is likely due to sync just gets enabled but some floc permission settings + // are disabled. We don't want to mess up with the initial user event + // messagings (and some sync integration tests would fail otherwise). + if (trigger == ComputeFlocTrigger::kBrowserStart && + !result.sim_hash.IsValid()) { + return; + } + auto specifics = std::make_unique<sync_pb::UserEventSpecifics>(); specifics->set_event_time_usec( base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); @@ -136,8 +144,8 @@ floc_id_computed_event->set_event_trigger(event_trigger); - if (floc_id_.IsValid()) - floc_id_computed_event->set_floc_id(floc_id_.ToUint64()); + if (result.sim_hash.IsValid()) + floc_id_computed_event->set_floc_id(result.sim_hash.ToUint64()); user_event_service_->RecordUserEvent(std::move(specifics)); } @@ -249,7 +257,7 @@ ComputeFlocCompletedCallback callback, bool can_compute_floc) { if (!can_compute_floc) { - std::move(callback).Run(FlocId()); + std::move(callback).Run(ComputeFlocResult()); return; } @@ -347,29 +355,28 @@ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)); } - FlocId floc_id = domains.size() >= kMinHistoryDomainSizeToReportFlocId - ? FlocId::CreateFromHistory(domains) - : FlocId(); + if (domains.size() < kMinHistoryDomainSizeToReportFlocId) { + std::move(callback).Run(ComputeFlocResult()); + return; + } - ApplyAdditionalFiltering(std::move(callback), floc_id); + ApplyAdditionalFiltering(std::move(callback), + FlocId::CreateFromHistory(domains)); } void FlocIdProviderImpl::ApplyAdditionalFiltering( ComputeFlocCompletedCallback callback, - const FlocId& floc_id) { - if (!floc_id.IsValid()) { - std::move(callback).Run(floc_id); - return; - } + const FlocId& sim_hash) { + DCHECK(sim_hash.IsValid()); if (base::FeatureList::IsEnabled(features::kFlocIdBlocklistFiltering) && g_browser_process->floc_blocklist_service()->ShouldBlockFloc( - floc_id.ToUint64())) { - std::move(callback).Run(FlocId()); + sim_hash.ToUint64())) { + std::move(callback).Run(ComputeFlocResult(sim_hash, FlocId())); return; } - std::move(callback).Run(floc_id); + std::move(callback).Run(ComputeFlocResult(sim_hash, sim_hash)); } } // namespace federated_learning
diff --git a/chrome/browser/federated_learning/floc_id_provider_impl.h b/chrome/browser/federated_learning/floc_id_provider_impl.h index b01d55d0..12169e4 100644 --- a/chrome/browser/federated_learning/floc_id_provider_impl.h +++ b/chrome/browser/federated_learning/floc_id_provider_impl.h
@@ -54,8 +54,26 @@ kHistoryDelete, }; + struct ComputeFlocResult { + ComputeFlocResult() = default; + + ComputeFlocResult(const FlocId& sim_hash, const FlocId& final_hash) + : sim_hash(sim_hash), final_hash(final_hash) {} + + // Sim-hash of the browsing history. This is the baseline value where the + // |final_hash| field should be derived from. We'll log this field for the + // server to calculate the sorting-lsh cutting points and/or the blocklist. + FlocId sim_hash; + + // The floc to be exposed to JS API. It can be set to a value different from + // |sim_hash| if we use sorting-lsh based encoding, or can be invalid if the + // final value is blocked. + FlocId final_hash; + }; + using CanComputeFlocCallback = base::OnceCallback<void(bool)>; - using ComputeFlocCompletedCallback = base::OnceCallback<void(FlocId)>; + using ComputeFlocCompletedCallback = + base::OnceCallback<void(ComputeFlocResult)>; using GetRecentlyVisitedURLsCallback = history::HistoryService::QueryHistoryCallback; @@ -76,8 +94,9 @@ protected: // protected virtual for testing. virtual void OnComputeFlocCompleted(ComputeFlocTrigger trigger, - FlocId floc_id); - virtual void NotifyFlocUpdated(ComputeFlocTrigger trigger); + ComputeFlocResult result); + virtual void LogFlocComputedEvent(ComputeFlocTrigger trigger, + const ComputeFlocResult& result); private: friend class FlocIdProviderUnitTest; @@ -123,9 +142,11 @@ // Apply any additional filtering or transformation on a floc computed from // history. For example, invalidate it if it's in the blocklist. void ApplyAdditionalFiltering(ComputeFlocCompletedCallback callback, - const FlocId& floc_id); + const FlocId& sim_hash); + // The id to be exposed to the JS API. FlocId floc_id_; + bool floc_computation_in_progress_ = false; bool first_floc_computation_triggered_ = false;
diff --git a/chrome/browser/federated_learning/floc_id_provider_unittest.cc b/chrome/browser/federated_learning/floc_id_provider_unittest.cc index b0d5cb1..16c94e7 100644 --- a/chrome/browser/federated_learning/floc_id_provider_unittest.cc +++ b/chrome/browser/federated_learning/floc_id_provider_unittest.cc
@@ -31,6 +31,7 @@ namespace { using ComputeFlocTrigger = FlocIdProviderImpl::ComputeFlocTrigger; +using ComputeFlocResult = FlocIdProviderImpl::ComputeFlocResult; class FakeFlocRemotePermissionService : public FlocRemotePermissionService { public: @@ -88,48 +89,45 @@ using FlocIdProviderImpl::FlocIdProviderImpl; void OnComputeFlocCompleted(ComputeFlocTrigger trigger, - FlocId floc_id) override { + ComputeFlocResult result) override { if (should_pause_before_compute_floc_completed_) { DCHECK(!paused_); paused_ = true; paused_trigger_ = trigger; - paused_floc_id_ = floc_id; + paused_result_ = result; return; } ++compute_floc_completed_count_; - FlocIdProviderImpl::OnComputeFlocCompleted(trigger, floc_id); + FlocIdProviderImpl::OnComputeFlocCompleted(trigger, result); } void ContinueLastOnComputeFlocCompleted() { DCHECK(paused_); paused_ = false; ++compute_floc_completed_count_; - FlocIdProviderImpl::OnComputeFlocCompleted(paused_trigger_, - paused_floc_id_); + FlocIdProviderImpl::OnComputeFlocCompleted(paused_trigger_, paused_result_); } - void NotifyFlocUpdated(ComputeFlocTrigger trigger) override { - ++floc_update_notification_count_; - last_notification_trigger_ = trigger; - FlocIdProviderImpl::NotifyFlocUpdated(trigger); + void LogFlocComputedEvent(ComputeFlocTrigger trigger, + const ComputeFlocResult& result) override { + ++log_event_count_; + last_log_event_trigger_ = trigger; + last_log_event_result_ = result; + FlocIdProviderImpl::LogFlocComputedEvent(trigger, result); } size_t compute_floc_completed_count() const { return compute_floc_completed_count_; } - size_t floc_update_notification_count() const { - return floc_update_notification_count_; - } - void set_should_pause_before_compute_floc_completed(bool should_pause) { should_pause_before_compute_floc_completed_ = should_pause; } - FlocId paused_floc_id() const { + ComputeFlocResult paused_result() const { DCHECK(paused_); - return paused_floc_id_; + return paused_result_; } ComputeFlocTrigger paused_trigger() const { @@ -137,9 +135,16 @@ return paused_trigger_; } - ComputeFlocTrigger last_notification_trigger() const { - DCHECK_LT(0u, floc_update_notification_count_); - return last_notification_trigger_; + size_t log_event_count() const { return log_event_count_; } + + ComputeFlocTrigger last_log_event_trigger() const { + DCHECK_LT(0u, log_event_count_); + return last_log_event_trigger_; + } + + ComputeFlocResult last_log_event_result() const { + DCHECK_LT(0u, log_event_count_); + return last_log_event_result_; } private: @@ -150,11 +155,12 @@ bool should_pause_before_compute_floc_completed_ = false; bool paused_ = false; ComputeFlocTrigger paused_trigger_; - FlocId paused_floc_id_; + ComputeFlocResult paused_result_; size_t compute_floc_completed_count_ = 0u; - size_t floc_update_notification_count_ = 0u; - ComputeFlocTrigger last_notification_trigger_; + size_t log_event_count_ = 0u; + ComputeFlocTrigger last_log_event_trigger_; + ComputeFlocResult last_log_event_result_; }; } // namespace @@ -320,7 +326,7 @@ // Expect that the floc computation hasn't started, as the floc_id_provider // hasn't been notified about state of the sync_service. EXPECT_EQ(0u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(0u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(0u, floc_id_provider_->log_event_count()); EXPECT_FALSE(floc_id().IsValid()); EXPECT_FALSE(first_floc_computation_triggered()); @@ -331,19 +337,19 @@ task_environment_.RunUntilIdle(); - // Expect a floc id update notification. + // Expect that the 1st computation has completed. EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); EXPECT_TRUE(floc_id().IsValid()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id()); EXPECT_TRUE(first_floc_computation_triggered()); - // Advance the clock by 1 day. Expect a floc id update notification, as - // there's no history in the last 7 days so the id has been reset to empty. + // Advance the clock by 1 day. Expect a computation, as there's no history in + // the last 7 days so the id has been reset to empty. task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(2u, floc_id_provider_->log_event_count()); EXPECT_FALSE(floc_id().IsValid()); } @@ -362,7 +368,7 @@ // Expect that the floc computation hasn't started, as the floc_id_provider // hasn't been notified about state of the sync_service. EXPECT_EQ(0u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(0u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(0u, floc_id_provider_->log_event_count()); EXPECT_FALSE(floc_id().IsValid()); EXPECT_FALSE(first_floc_computation_triggered()); @@ -373,30 +379,28 @@ task_environment_.RunUntilIdle(); - // Expect no floc id update notification, as there is no qualified history - // entry. However, the 1st computation should already have started. + // Expect that the 1st computation has completed. EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(0u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); EXPECT_TRUE(first_floc_computation_triggered()); // Add a history entry with a timestamp 6 days back from now. add_page_args.time = base::Time::Now() - base::TimeDelta::FromDays(6); history_service_->AddPage(add_page_args); - // Advance the clock by 23 hours. Expect no floc id update notification, - // as the id refresh interval is 24 hours. + // Advance the clock by 23 hours. Expect no more computation, as the id + // refresh interval is 24 hours. task_environment_.FastForwardBy(base::TimeDelta::FromHours(23)); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(0u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); - // Advance the clock by 1 hour. Expect a floc id update notification, as the - // refresh time is reached and there's a valid history entry in the last 7 - // days. + // Advance the clock by 1 hour. Expect one more computation, as the refresh + // time is reached and there's a valid history entry in the last 7 days. task_environment_.FastForwardBy(base::TimeDelta::FromHours(1)); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(2u, floc_id_provider_->log_event_count()); EXPECT_TRUE(floc_id().IsValid()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id()); } @@ -426,40 +430,39 @@ task_environment_.RunUntilIdle(); - // Expect a floc id update notification. + // Expect that the 1st computation has completed. EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); EXPECT_TRUE(floc_id().IsValid()); EXPECT_EQ(FlocId::CreateFromHistory({domain1, domain2}), floc_id()); - // Advance the clock by 12 hours. Expect no floc id update notification. + // Advance the clock by 12 hours. Expect no more computation. task_environment_.FastForwardBy(base::TimeDelta::FromHours(12)); EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); // Expire the oldest history entry. ExpireHistoryBefore(base::Time::Now() - base::TimeDelta::FromDays(7)); task_environment_.RunUntilIdle(); - // Expect a floc id update notification as it was just recomputed due to the - // history deletion. + // Expect one more computation due to the history deletion. EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(2u, floc_id_provider_->log_event_count()); EXPECT_TRUE(floc_id().IsValid()); EXPECT_EQ(FlocId::CreateFromHistory({domain2}), floc_id()); - // Advance the clock by 23 hours. Expect no floc id update notification as the - // timer has been reset due to the recomputation from history deletion. + // Advance the clock by 23 hours. Expect no more computation, as the timer has + // been reset due to the recomputation from history deletion. task_environment_.FastForwardBy(base::TimeDelta::FromHours(23)); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(2u, floc_id_provider_->log_event_count()); - // Advance the clock by 1 hour. Expect an floc id update notification as the - // scheduled time is reached. Expect an invalid floc id as there is no history - // in the past 7 days. + // Advance the clock by 1 hour. Expect one more computation, as the scheduled + // time is reached. Expect an invalid floc id as there is no history in the + // past 7 days. task_environment_.FastForwardBy(base::TimeDelta::FromHours(1)); EXPECT_EQ(3u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(3u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(3u, floc_id_provider_->log_event_count()); EXPECT_FALSE(floc_id().IsValid()); } @@ -482,16 +485,18 @@ task_environment_.RunUntilIdle(); - // Expect a floc id update notification. + // Expect that the 1st computation has completed. EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); + EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id()); - // Advance the clock by 1 day. Expect no additional floc id update - // notification, as the floc didn't change. + // Advance the clock by 1 day. Expect one more computation, but the floc + // didn't change. task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(2u, floc_id_provider_->log_event_count()); + EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id()); } TEST_F(FlocIdProviderUnitTest, CheckCanComputeFloc_Success) { @@ -580,8 +585,10 @@ base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature(features::kFlocIdComputedEventLogging); - set_floc_id(FlocId(12345ULL)); - floc_id_provider_->NotifyFlocUpdated(ComputeFlocTrigger::kBrowserStart); + // Event logging for browser start. + floc_id_provider_->LogFlocComputedEvent( + ComputeFlocTrigger::kBrowserStart, + ComputeFlocResult(FlocId(12345ULL), FlocId(123ULL))); EXPECT_EQ(1u, fake_user_event_service_->GetRecordedUserEvents().size()); const sync_pb::UserEventSpecifics& specifics1 = @@ -600,8 +607,10 @@ task_environment_.FastForwardBy(base::TimeDelta::FromDays(3)); - set_floc_id(FlocId(999ULL)); - floc_id_provider_->NotifyFlocUpdated(ComputeFlocTrigger::kScheduledUpdate); + // Event logging for scheduled update. + floc_id_provider_->LogFlocComputedEvent( + ComputeFlocTrigger::kScheduledUpdate, + ComputeFlocResult(FlocId(999ULL), FlocId(777ULL))); EXPECT_EQ(2u, fake_user_event_service_->GetRecordedUserEvents().size()); const sync_pb::UserEventSpecifics& specifics2 = @@ -617,8 +626,10 @@ event2.event_trigger()); EXPECT_EQ(999ULL, event2.floc_id()); - set_floc_id(FlocId()); - floc_id_provider_->NotifyFlocUpdated(ComputeFlocTrigger::kScheduledUpdate); + // Event logging for invalid floc. + floc_id_provider_->LogFlocComputedEvent( + ComputeFlocTrigger::kScheduledUpdate, + ComputeFlocResult(FlocId(), FlocId())); EXPECT_EQ(3u, fake_user_event_service_->GetRecordedUserEvents().size()); const sync_pb::UserEventSpecifics& specifics3 = @@ -634,8 +645,10 @@ event3.event_trigger()); EXPECT_FALSE(event3.has_floc_id()); - set_floc_id(FlocId(555)); - floc_id_provider_->NotifyFlocUpdated(ComputeFlocTrigger::kHistoryDelete); + // Event logging for history delete. + floc_id_provider_->LogFlocComputedEvent( + ComputeFlocTrigger::kHistoryDelete, + ComputeFlocResult(FlocId(555), FlocId(444))); EXPECT_EQ(4u, fake_user_event_service_->GetRecordedUserEvents().size()); const sync_pb::UserEventSpecifics& specifics4 = @@ -650,6 +663,25 @@ EXPECT_EQ(sync_pb::UserEventSpecifics::FlocIdComputed::HISTORY_DELETE, event4.event_trigger()); EXPECT_EQ(555ULL, event4.floc_id()); + + // Event logging for blocked floc. + floc_id_provider_->LogFlocComputedEvent( + ComputeFlocTrigger::kScheduledUpdate, + ComputeFlocResult(FlocId(87654), FlocId(45678))); + + EXPECT_EQ(5u, fake_user_event_service_->GetRecordedUserEvents().size()); + const sync_pb::UserEventSpecifics& specifics5 = + fake_user_event_service_->GetRecordedUserEvents()[4]; + EXPECT_EQ(specifics5.event_time_usec(), + base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); + EXPECT_EQ(sync_pb::UserEventSpecifics::kFlocIdComputedEvent, + specifics5.event_case()); + + const sync_pb::UserEventSpecifics_FlocIdComputed& event5 = + specifics5.floc_id_computed_event(); + EXPECT_EQ(sync_pb::UserEventSpecifics::FlocIdComputed::REFRESHED, + event5.event_trigger()); + EXPECT_EQ(87654ULL, event5.floc_id()); } TEST_F(FlocIdProviderUnitTest, HistoryDelete_AllHistory) { @@ -808,7 +840,9 @@ TEST_F(FlocIdProviderUnitTest, BlocklistFilteringEnabled_BlockedFloc) { base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(features::kFlocIdBlocklistFiltering); + feature_list.InitWithFeatures({features::kFlocIdComputedEventLogging, + features::kFlocIdBlocklistFiltering}, + {}); std::string domain = "foo.com"; @@ -833,23 +867,46 @@ task_environment_.RunUntilIdle(); - // Expect a floc id update notification. The floc should be equal to the - // sim-hash of the history. + FlocId floc_from_history = FlocId::CreateFromHistory({domain}); + + // Expect a computation. The floc should be equal to the sim-hash of the + // history. EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); - EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); + EXPECT_EQ(floc_from_history, floc_id()); // Insert the current floc to blocklist and reload it. - blocklist.insert(FlocId::CreateFromHistory({domain}).ToUint64()); + blocklist.insert(floc_from_history.ToUint64()); OnBlocklistLoaded(blocklist); task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); - // Expect a floc id update notification, with an invalid floc because was - // blocked. + // Expect one more computation, where the result contains a valid sim_hash and + // an invalid final_hash, as it was blocked. The internal floc is set to the + // invalid one. EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count()); - EXPECT_EQ(FlocId(), floc_id()); + EXPECT_EQ(2u, floc_id_provider_->log_event_count()); + EXPECT_EQ(floc_id_provider_->last_log_event_result().sim_hash, + floc_from_history); + EXPECT_FALSE(floc_id_provider_->last_log_event_result().final_hash.IsValid()); + EXPECT_FALSE(floc_id().IsValid()); + + // In the event when the sim_hash is valid and final_hash is invalid, we'll + // still log it. + EXPECT_EQ(2u, fake_user_event_service_->GetRecordedUserEvents().size()); + const sync_pb::UserEventSpecifics& specifics = + fake_user_event_service_->GetRecordedUserEvents()[1]; + EXPECT_EQ(specifics.event_time_usec(), + base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); + + EXPECT_EQ(sync_pb::UserEventSpecifics::kFlocIdComputedEvent, + specifics.event_case()); + + const sync_pb::UserEventSpecifics_FlocIdComputed& event = + specifics.floc_id_computed_event(); + EXPECT_EQ(sync_pb::UserEventSpecifics::FlocIdComputed::REFRESHED, + event.event_trigger()); + EXPECT_EQ(floc_from_history.ToUint64(), event.floc_id()); // Reset and reload the blocklist. blocklist.clear(); @@ -857,10 +914,10 @@ task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); - // Expect a floc id update notification. The floc should be equal to the - // sim-hash of the history. + // Expect one more computation. The floc should be equal to the sim-hash of + // the history. EXPECT_EQ(3u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(3u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(3u, floc_id_provider_->log_event_count()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id()); } @@ -882,33 +939,32 @@ task_environment_.RunUntilIdle(); - // Expect a floc id update notification. + // Expect that the 1st computation has completed. EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id()); // Turn off sync. test_sync_service_->SetTransportState( syncer::SyncService::TransportState::DISABLED); - // Advance the clock by 1 day. Expect a floc id update notification, as - // the sync was turned off so the id has been reset to empty. + // Advance the clock by 1 day. Expect one more computation, as the sync was + // turned off so the id has been reset to empty. task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); EXPECT_EQ(2u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(2u, floc_id_provider_->log_event_count()); EXPECT_FALSE(floc_id().IsValid()); // Turn on sync. test_sync_service_->SetTransportState( syncer::SyncService::TransportState::ACTIVE); - // Advance the clock by 1 day. Expect a floc id update notification and a - // valid floc id. + // Advance the clock by 1 day. Expect one more floc computation. task_environment_.FastForwardBy(base::TimeDelta::FromDays(1)); EXPECT_EQ(3u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(3u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(3u, floc_id_provider_->log_event_count()); EXPECT_EQ(FlocId::CreateFromHistory({domain}), floc_id()); } @@ -995,9 +1051,9 @@ task_environment_.RunUntilIdle(); - // Expect a floc id update notification. + // Expect that the 1st computation has completed. EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); EXPECT_TRUE(floc_id().IsValid()); EXPECT_EQ(FlocId::CreateFromHistory({domain1, domain2, domain3}), floc_id()); @@ -1010,14 +1066,14 @@ EXPECT_FALSE(pending_recompute_event().has_value()); EXPECT_EQ(FlocId::CreateFromHistory({domain1, domain2, domain3}), floc_id()); EXPECT_EQ(FlocId::CreateFromHistory({domain2, domain3}), - floc_id_provider_->paused_floc_id()); + floc_id_provider_->paused_result().final_hash); EXPECT_EQ(ComputeFlocTrigger::kScheduledUpdate, floc_id_provider_->paused_trigger()); // Expire the "domain2" history entry right before the floc computation - // completes. Since the computation is still considered to be - // in-progress, a new recompute event due to this delete will be - // scheduled to happen right after this computation completes. + // completes. Since the computation is still considered to be in-progress, a + // new recompute event due to this delete will be scheduled to happen right + // after this computation completes. ExpireHistoryBefore(base::Time::Now() - base::TimeDelta::FromDays(7)); EXPECT_TRUE(pending_recompute_event().has_value()); @@ -1028,13 +1084,12 @@ floc_id_provider_->ContinueLastOnComputeFlocCompleted(); task_environment_.RunUntilIdle(); - // Expect 2 more compute completion events and 1 more update notification. - // This is because we won't send update notification if there's a recompute - // event scheduled. + // Expect 2 more compute completion events and 1 more log event. This is + // because we won't send log event if there's a recompute event scheduled. EXPECT_EQ(3u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(2u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(2u, floc_id_provider_->log_event_count()); EXPECT_EQ(ComputeFlocTrigger::kHistoryDelete, - floc_id_provider_->last_notification_trigger()); + floc_id_provider_->last_log_event_trigger()); EXPECT_FALSE(pending_recompute_event().has_value()); // The final floc should be derived from "domain3". @@ -1069,9 +1124,9 @@ task_environment_.RunUntilIdle(); - // Expect a floc id update notification. + // Expect that the 1st computation has completed. EXPECT_EQ(1u, floc_id_provider_->compute_floc_completed_count()); - EXPECT_EQ(1u, floc_id_provider_->floc_update_notification_count()); + EXPECT_EQ(1u, floc_id_provider_->log_event_count()); EXPECT_TRUE(floc_id().IsValid()); EXPECT_EQ(FlocId::CreateFromHistory({domain1}), floc_id()); }
diff --git a/chrome/browser/hid/chrome_hid_delegate.cc b/chrome/browser/hid/chrome_hid_delegate.cc index b4a26527..9ed76ebc 100644 --- a/chrome/browser/hid/chrome_hid_delegate.cc +++ b/chrome/browser/hid/chrome_hid_delegate.cc
@@ -95,6 +95,15 @@ observer_list_.RemoveObserver(observer); } +const device::mojom::HidDeviceInfo* ChromeHidDelegate::GetDeviceInfo( + content::WebContents* web_contents, + const std::string& guid) { + auto* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + auto* chooser_context = HidChooserContextFactory::GetForProfile(profile); + return chooser_context->GetDeviceInfo(guid); +} + void ChromeHidDelegate::OnPermissionRevoked( const url::Origin& requesting_origin, const url::Origin& embedding_origin) {
diff --git a/chrome/browser/hid/chrome_hid_delegate.h b/chrome/browser/hid/chrome_hid_delegate.h index 711eac6..1f9f9ce 100644 --- a/chrome/browser/hid/chrome_hid_delegate.h +++ b/chrome/browser/hid/chrome_hid_delegate.h
@@ -40,6 +40,9 @@ content::HidDelegate::Observer* observer) override; void RemoveObserver(content::RenderFrameHost* frame, content::HidDelegate::Observer* observer) override; + const device::mojom::HidDeviceInfo* GetDeviceInfo( + content::WebContents* web_contents, + const std::string& guid) override; // permissions::ChooserContextBase::PermissionObserver: void OnPermissionRevoked(const url::Origin& requesting_origin,
diff --git a/chrome/browser/hid/hid_chooser_context.cc b/chrome/browser/hid/hid_chooser_context.cc index b4111a6..fb2c4da 100644 --- a/chrome/browser/hid/hid_chooser_context.cc +++ b/chrome/browser/hid/hid_chooser_context.cc
@@ -251,6 +251,13 @@ FROM_HERE, base::BindOnce(std::move(callback), std::move(device_list))); } +const device::mojom::HidDeviceInfo* HidChooserContext::GetDeviceInfo( + const std::string& guid) { + DCHECK(is_initialized_); + auto it = devices_.find(guid); + return it == devices_.end() ? nullptr : it->second.get(); +} + device::mojom::HidManager* HidChooserContext::GetHidManager() { EnsureHidManagerConnection(); return hid_manager_.get(); @@ -344,6 +351,8 @@ for (auto& device : devices) devices_.insert({device->guid, std::move(device)}); + is_initialized_ = true; + while (!pending_get_devices_requests_.empty()) { std::vector<device::mojom::HidDeviceInfoPtr> device_list; device_list.reserve(devices.size());
diff --git a/chrome/browser/hid/hid_chooser_context.h b/chrome/browser/hid/hid_chooser_context.h index 73af4cb..4eaa7f1 100644 --- a/chrome/browser/hid/hid_chooser_context.h +++ b/chrome/browser/hid/hid_chooser_context.h
@@ -79,6 +79,11 @@ // Forward HidManager::GetDevices. void GetDevices(device::mojom::HidManager::GetDevicesCallback callback); + // Only call this if you're sure |devices_| has been initialized before-hand. + // The returned raw pointer is owned by |devices_| and will be destroyed when + // the device is removed. + const device::mojom::HidDeviceInfo* GetDeviceInfo(const std::string& guid); + device::mojom::HidManager* GetHidManager(); // Sets |manager| as the HidManager and registers this context as a
diff --git a/chrome/browser/metrics/chrome_feature_list_creator.cc b/chrome/browser/metrics/chrome_feature_list_creator.cc index 88fdfb8..5b37e71 100644 --- a/chrome/browser/metrics/chrome_feature_list_creator.cc +++ b/chrome/browser/metrics/chrome_feature_list_creator.cc
@@ -42,7 +42,6 @@ #include "components/variations/service/variations_service.h" #include "components/variations/variations_crash_keys.h" #include "content/public/common/content_switch_dependent_feature_overrides.h" -#include "services/service_manager/embedder/result_codes.h" #include "ui/base/resource/resource_bundle.h" #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/page_load_metrics/integration_tests/smoothness_metric_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/smoothness_metric_browsertest.cc new file mode 100644 index 0000000..c8071cb --- /dev/null +++ b/chrome/browser/page_load_metrics/integration_tests/smoothness_metric_browsertest.cc
@@ -0,0 +1,76 @@ +// Copyright 2020 The Chromium 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/page_load_metrics/integration_tests/metric_integration_test.h" + +#include "chrome/test/base/ui_test_utils.h" +#include "components/page_load_metrics/browser/page_load_metrics_util.h" +#include "content/public/test/browser_test.h" +#include "services/metrics/public/cpp/ukm_builders.h" + +using ukm::builders::Graphics_Smoothness_NormalizedPercentDroppedFrames; + +namespace { + +bool ExtractUKMSmoothnessMetric(const ukm::TestUkmRecorder& ukm_recorder, + base::StringPiece metric_name, + int64_t* extracted_value) { + std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries = + ukm_recorder.GetMergedEntriesByName( + Graphics_Smoothness_NormalizedPercentDroppedFrames::kEntryName); + EXPECT_EQ(1ul, merged_entries.size()); + if (merged_entries.size() != 1u) + return false; + const auto& kv = merged_entries.begin(); + auto* metric_value = + ukm::TestUkmRecorder::GetEntryMetric(kv->second.get(), metric_name); + if (!metric_value) + return false; + *extracted_value = *metric_value; + return true; +} + +} // namespace + +IN_PROC_BROWSER_TEST_F(MetricIntegrationTest, BasicSmoothnessAverage) { + LoadHTML(R"HTML(<div id='animate' style='width: 20px; height: 20px'></div> + <img src="images/green-16x16.png"></img> + <script> + runtest = async() => { + const promise = new Promise(resolve => { + var r = 0; + function run() { + if (r >= 200) { + resolve(true); + return; + } + const now = new Date(); + while ((new Date() - now) < 20) {} + animate.style.backgroundColor = `rgb(${r * 2}, 0, 0)`; + requestAnimationFrame(run); + ++r; + } + run(); + }); + return await promise; + }; + </script> + )HTML"); + + ASSERT_TRUE(EvalJs(web_contents(), "runtest()").ExtractBool()); + + // Finish session. + web_contents()->ClosePage(); + ui_test_utils::WaitForBrowserToClose(browser()); + + // Ensure that the smoothness UKM is reported. + int64_t avg_value; + ASSERT_TRUE(ExtractUKMSmoothnessMetric( + ukm_recorder(), + Graphics_Smoothness_NormalizedPercentDroppedFrames::kAverageName, + &avg_value)); + // Some of the frames should be dropped. It is not possible to measure the + // exact number of dropped frames, so validate that it is non-zero. + EXPECT_NE(avg_value, 0); +}
diff --git a/chrome/browser/page_load_metrics/integration_tests/sources.gni b/chrome/browser/page_load_metrics/integration_tests/sources.gni index 19c7463f..35aca14 100644 --- a/chrome/browser/page_load_metrics/integration_tests/sources.gni +++ b/chrome/browser/page_load_metrics/integration_tests/sources.gni
@@ -9,5 +9,6 @@ "//chrome/browser/page_load_metrics/integration_tests/layout_instability_browsertest.cc", "//chrome/browser/page_load_metrics/integration_tests/metric_integration_test.cc", "//chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h", + "//chrome/browser/page_load_metrics/integration_tests/smoothness_metric_browsertest.cc", "//chrome/browser/page_load_metrics/integration_tests/total_input_delay_browsertest.cc", ]
diff --git a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc index 82b58c1..ee3f0bb 100644 --- a/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/core/ukm_page_load_metrics_observer.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/feature_list.h" +#include "base/timer/elapsed_timer.h" #include "base/trace_event/common/trace_event_common.h" #include "cc/metrics/ukm_smoothness_data.h" #include "chrome/browser/browser_process.h" @@ -883,8 +884,35 @@ return; } - // TODO(sad): Use atomic memcpy here before reading from the shared memory. - // https://chromium-review.googlesource.com/c/chromium/src/+/1572369 + base::ElapsedTimer timer; + const uint32_t kMaxRetries = 5; + uint32_t retries = 0; + cc::UkmSmoothnessData smoothness_data; + base::subtle::Atomic32 version; + do { + const uint32_t kMaxReadAttempts = 32; + version = smoothness->seq_lock.ReadBegin(kMaxReadAttempts); + device::OneWriterSeqLock::AtomicReaderMemcpy( + &smoothness_data, &smoothness->data, sizeof(cc::UkmSmoothnessData)); + } while (smoothness->seq_lock.ReadRetry(version) && ++retries < kMaxRetries); + + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( + "Graphics.Smoothness.Diagnostic.ReadSharedMemoryDuration", + timer.Elapsed(), base::TimeDelta::FromMicroseconds(1), + base::TimeDelta::FromMilliseconds(5), 100); + UMA_HISTOGRAM_BOOLEAN( + "Graphics.Smoothness.Diagnostic.ReadSharedMemoryUKMSuccess", + retries < kMaxRetries); + + if (retries >= kMaxRetries) + return; + ukm::builders::Graphics_Smoothness_NormalizedPercentDroppedFrames( + GetDelegate().GetPageUkmSourceId()) + .SetAverage(smoothness_data.avg_smoothness) + .SetPercentile95(smoothness_data.percentile_95) + .SetAboveThreshold(smoothness_data.above_threshold) + .SetWorstCase(smoothness_data.worst_smoothness) + .Record(ukm::UkmRecorder::Get()); } void UkmPageLoadMetricsObserver::RecordPageEndMetrics(
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckCoordinator.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckCoordinator.java index e9ca5ae..afe4f400 100644 --- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckCoordinator.java +++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckCoordinator.java
@@ -103,6 +103,7 @@ @Override public void onResumeFragment() { + mMediator.onResumeFragment(); mReauthenticationHelper.onReauthenticationMaybeHappened(); } @@ -110,6 +111,8 @@ public void onDestroyFragment() { mMediator.stopCheck(); if (mFragmentView.getActivity() == null || mFragmentView.getActivity().isFinishing()) { + mMediator + .onUserLeavesCheckPage(); // Should be called only if the activity is finishing. mMediator.destroy(); mModel = null; }
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java index d4c0f63..b940c41 100644 --- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java +++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java
@@ -59,6 +59,7 @@ private HashSet<CompromisedCredential> mPreCheckSet; private final PasswordCheckIconHelper mIconHelper; private long mLastStatusUpdate; + private boolean mCctIsOpened; PasswordCheckMediator(PasswordCheckChangePasswordHelper changePasswordDelegate, PasswordCheckReauthenticationHelper reauthenticationHelper, @@ -73,6 +74,7 @@ mModel = model; mDelegate = delegate; mLaunchCheckupInAccount = launchCheckupInAccount; + mCctIsOpened = false; PasswordCheckMetricsRecorder.recordPasswordCheckReferrer(passwordCheckReferrer); @@ -89,8 +91,27 @@ } } + void onResumeFragment() { + // If the fragment is resumed, a CCT is closed. + mCctIsOpened = false; + } + + void onUserLeavesCheckPage() { + // A user can leave the page because they opened a CCT in browser. As a user is fixing a + // compromised credential, don't count such a case as a user |DID_NOTHING| for the remaining + // credentials. + if (!mCctIsOpened) { + // A user closes the check page. + ListModel<ListItem> items = mModel.get(ITEMS); + for (int i = 1; i < items.size(); i++) { + PasswordCheckMetricsRecorder.recordCheckResolutionAction( + PasswordCheckResolutionAction.DID_NOTHING, + items.get(i).model.get(COMPROMISED_CREDENTIAL)); + } + } + } + void destroy() { - // TODO(crbug.com/): Report PasswordCheckResolutionAction.DID_NOTHING. getPasswordCheck().removeObserver(this); } @@ -282,6 +303,7 @@ : PasswordCheckUserAction.CHANGE_PASSWORD); PasswordCheckMetricsRecorder.recordCheckResolutionAction( PasswordCheckResolutionAction.OPENED_SITE, credential); + mCctIsOpened = true; mChangePasswordDelegate.launchAppOrCctWithChangePasswordUrl(credential); } @@ -292,6 +314,7 @@ PasswordCheckUserAction.CHANGE_PASSWORD_AUTOMATICALLY); PasswordCheckMetricsRecorder.recordCheckResolutionAction( PasswordCheckResolutionAction.STARTED_SCRIPT, credential); + mCctIsOpened = true; mChangePasswordDelegate.launchCctWithScript(credential); }
diff --git a/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java b/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java index 51b964e..7f56d50 100644 --- a/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java +++ b/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java
@@ -691,6 +691,92 @@ is(1)); } + @Test + public void testRecordsDidNothingOnLeavingPage() { + when(mPasswordCheck.getCompromisedCredentials()) + .thenReturn(new CompromisedCredential[] {ANA, BOB, CHARLIE}); + when(mPasswordCheck.areScriptsRefreshed()).thenReturn(true); + when(mChangePasswordDelegate.canManuallyChangeCredential(any(CompromisedCredential.class))) + .thenReturn(true); + + mMediator.onPasswordCheckStatusChanged(IDLE); + mMediator.onCompromisedCredentialsFetchCompleted(); + + mMediator.onUserLeavesCheckPage(); + + assertThat(RecordHistogram.getHistogramValueCountForTesting( + PASSWORD_CHECK_RESOLUTION_HISTOGRAM_WITHOUT_AUTO_BUTTON, + PasswordCheckResolutionAction.DID_NOTHING), + is(2)); + assertThat(RecordHistogram.getHistogramValueCountForTesting( + PASSWORD_CHECK_RESOLUTION_HISTOGRAM_WITH_AUTO_BUTTON, + PasswordCheckResolutionAction.DID_NOTHING), + is(1)); + assertThat(RecordHistogram.getHistogramValueCountForTesting( + PASSWORD_CHECK_RESOLUTION_HISTOGRAM_FOR_SCRIPTED_SITES, + PasswordCheckResolutionAction.DID_NOTHING), + is(2)); + } + + @Test + public void testDoesntRecordDidNothingOnLeavingPageIfCctIsOpen() { + when(mPasswordCheck.getCompromisedCredentials()) + .thenReturn(new CompromisedCredential[] {ANA, BOB, CHARLIE}); + when(mPasswordCheck.areScriptsRefreshed()).thenReturn(true); + when(mChangePasswordDelegate.canManuallyChangeCredential(any(CompromisedCredential.class))) + .thenReturn(true); + + mMediator.onPasswordCheckStatusChanged(IDLE); + mMediator.onCompromisedCredentialsFetchCompleted(); + + // A user opens a CCT and then open the tab in browser => a user leaves the check page. + mMediator.onChangePasswordWithScriptButtonClick(BOB); + mMediator.onUserLeavesCheckPage(); + + assertThat(RecordHistogram.getHistogramValueCountForTesting( + PASSWORD_CHECK_RESOLUTION_HISTOGRAM_WITHOUT_AUTO_BUTTON, + PasswordCheckResolutionAction.DID_NOTHING), + is(0)); + assertThat(RecordHistogram.getHistogramValueCountForTesting( + PASSWORD_CHECK_RESOLUTION_HISTOGRAM_WITH_AUTO_BUTTON, + PasswordCheckResolutionAction.DID_NOTHING), + is(0)); + assertThat(RecordHistogram.getHistogramValueCountForTesting( + PASSWORD_CHECK_RESOLUTION_HISTOGRAM_FOR_SCRIPTED_SITES, + PasswordCheckResolutionAction.DID_NOTHING), + is(0)); + } + + @Test + public void testRecordDidNothingOnLeavingPageIfCctIsClosed() { + when(mPasswordCheck.getCompromisedCredentials()) + .thenReturn(new CompromisedCredential[] {ANA, BOB, CHARLIE}); + when(mPasswordCheck.areScriptsRefreshed()).thenReturn(true); + when(mChangePasswordDelegate.canManuallyChangeCredential(any(CompromisedCredential.class))) + .thenReturn(true); + + mMediator.onPasswordCheckStatusChanged(IDLE); + mMediator.onCompromisedCredentialsFetchCompleted(); + + // A user opens a CCT, closes it, and leaves the password check page. + mMediator.onChangePasswordWithScriptButtonClick(BOB); + mMediator.onResumeFragment(); + mMediator.onUserLeavesCheckPage(); + + assertThat(RecordHistogram.getHistogramValueCountForTesting( + PASSWORD_CHECK_RESOLUTION_HISTOGRAM_WITHOUT_AUTO_BUTTON, + PasswordCheckResolutionAction.DID_NOTHING), + is(2)); + assertThat(RecordHistogram.getHistogramValueCountForTesting( + PASSWORD_CHECK_RESOLUTION_HISTOGRAM_WITH_AUTO_BUTTON, + PasswordCheckResolutionAction.DID_NOTHING), + is(1)); + assertThat(RecordHistogram.getHistogramValueCountForTesting( + PASSWORD_CHECK_RESOLUTION_HISTOGRAM_FOR_SCRIPTED_SITES, + PasswordCheckResolutionAction.DID_NOTHING), + is(2)); + } + private void assertIdleHeader(MVCListAdapter.ListItem header) { assertHeaderTypeWithStatus(header, IDLE); assertNull(header.model.get(CHECK_PROGRESS));
diff --git a/chrome/browser/resources/new_tab_page/modules/module_descriptor.js b/chrome/browser/resources/new_tab_page/modules/module_descriptor.js index b006d75a..a77ab16d 100644 --- a/chrome/browser/resources/new_tab_page/modules/module_descriptor.js +++ b/chrome/browser/resources/new_tab_page/modules/module_descriptor.js
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {BrowserProxy} from '../browser_proxy.js'; + /** * @fileoverview Provides the module descriptor. Each module must create a * module descriptor and register it at the NTP. @@ -79,5 +81,7 @@ this.title_ = info.title; this.element_ = info.element; this.actions_ = info.actions || null; + BrowserProxy.getInstance().handler.onModuleLoaded( + this.id_, BrowserProxy.getInstance().now()); } }
diff --git a/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js b/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js index ba84a05..5eaf4890 100644 --- a/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js +++ b/chrome/browser/resources/pdf/elements/viewer-thumbnail-bar.js
@@ -20,7 +20,10 @@ static get properties() { return { - activePage: Number, + activePage: { + type: Number, + observer: 'activePageChanged_', + }, clockwiseRotations: Number, @@ -72,6 +75,29 @@ } /** + * Changes the focus to the thumbnail of the new active page if the focus was + * already on a thumbnail. + * @private + */ + activePageChanged_() { + if (this.shadowRoot.activeElement) { + this.getThumbnailForPage_(this.activePage).focusAndScroll(); + } + } + + /** + * @param {number} pageNumber + * @private + */ + clickThumbnailForPage(pageNumber) { + if (pageNumber < 1 || pageNumber > this.docLength) { + return; + } + + this.getThumbnailForPage_(pageNumber).getClickTarget().click(); + } + + /** * @return {!Array<number>} The array of page numbers. * @private */ @@ -89,6 +115,16 @@ } /** + * @param {number} pageNumber + * @return {ViewerThumbnailElement} + * @private + */ + getThumbnailForPage_(pageNumber) { + return /** @type {ViewerThumbnailElement} */ (this.shadowRoot.querySelector( + `viewer-thumbnail:nth-child(${pageNumber})`)); + } + + /** * @param {number} page * @return {boolean} Whether the page is the current page. * @private @@ -152,6 +188,14 @@ this.shadowRoot.querySelector('viewer-thumbnail:last-of-type').focus({ preventScroll: true }); + } else if (keyboardEvent.key === 'ArrowRight') { + // Prevent default arrow scroll behavior. + keyboardEvent.preventDefault(); + this.clickThumbnailForPage(this.activePage + 1); + } else if (keyboardEvent.key === 'ArrowLeft') { + // Prevent default arrow scroll behavior. + keyboardEvent.preventDefault(); + this.clickThumbnailForPage(this.activePage - 1); } } }
diff --git a/chrome/browser/resources/pdf/elements/viewer-thumbnail.js b/chrome/browser/resources/pdf/elements/viewer-thumbnail.js index 6e16956..b743e9d 100644 --- a/chrome/browser/resources/pdf/elements/viewer-thumbnail.js +++ b/chrome/browser/resources/pdf/elements/viewer-thumbnail.js
@@ -69,6 +69,12 @@ this.removeAttribute('pending'); } + /** @return {!HTMLElement} */ + getClickTarget() { + return /** @type {!HTMLElement} */ ( + this.shadowRoot.querySelector('#thumbnail')); + } + /** * @return {!HTMLCanvasElement} * @private @@ -164,13 +170,11 @@ const keyboardEvent = /** @type {!KeyboardEvent} */ (e); switch (keyboardEvent.key) { case 'ArrowDown': - case 'ArrowRight': // Prevent default arrow scroll behavior. keyboardEvent.preventDefault(); this.focusThumbnailNext_(); break; case 'ArrowUp': - case 'ArrowLeft': // Prevent default arrow scroll behavior. keyboardEvent.preventDefault(); this.focusThumbnailPrev_();
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc index c6f4b17..ee2d8d5a 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
@@ -253,6 +253,44 @@ }); } +void EventReportValidator:: + ExpectSensitiveDataEventAndDangerousDeepScanningResult( + const std::string& expected_url, + const std::string& expected_filename, + const std::string& expected_sha256, + const std::string& expected_threat_type, + const std::string& expected_trigger, + const enterprise_connectors::ContentAnalysisResponse::Result& + expected_dlp_verdict, + const std::set<std::string>* expected_mimetypes, + int expected_content_size, + const std::string& expected_result) { + event_key_ = SafeBrowsingPrivateEventRouter::kKeySensitiveDataEvent; + url_ = expected_url; + filename_ = expected_filename; + sha256_ = expected_sha256; + trigger_ = expected_trigger; + mimetypes_ = expected_mimetypes; + content_size_ = expected_content_size; + result_ = expected_result; + dlp_verdict_ = expected_dlp_verdict; + EXPECT_CALL(*client_, UploadRealtimeReport_(_, _)) + .WillOnce([this](base::Value& report, + base::OnceCallback<void(bool)>& callback) { + ValidateReport(&report); + }) + .WillOnce([this, expected_threat_type]( + base::Value& report, + base::OnceCallback<void(bool)>& callback) { + event_key_ = SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent; + threat_type_ = expected_threat_type; + dlp_verdict_ = base::nullopt; + ValidateReport(&report); + if (!done_closure_.is_null()) + done_closure_.Run(); + }); +} + void EventReportValidator::ExpectDangerousDownloadEvent( const std::string& expected_url, const std::string& expected_filename,
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h index 0221470..730c1cca 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h +++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h
@@ -67,6 +67,18 @@ int expected_content_size, const std::string& expected_result); + void ExpectSensitiveDataEventAndDangerousDeepScanningResult( + const std::string& expected_url, + const std::string& expected_filename, + const std::string& expected_sha256, + const std::string& expected_threat_type, + const std::string& expected_trigger, + const enterprise_connectors::ContentAnalysisResponse::Result& + expected_dlp_verdict, + const std::set<std::string>* expected_mimetypes, + int expected_content_size, + const std::string& expected_result); + void ExpectUnscannedFileEvent(const std::string& expected_url, const std::string& expected_filename, const std::string& expected_sha256,
diff --git a/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc b/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc index 4388c41..ca2ff88 100644 --- a/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc +++ b/chrome/browser/safe_browsing/download_protection/deep_scanning_browsertest.cc
@@ -688,6 +688,75 @@ true, 1); } +IN_PROC_BROWSER_TEST_F(DownloadDeepScanningBrowserTest, + DlpAndMalwareViolations) { + SetUpReporting(); + base::HistogramTester histograms; + + // The file is DANGEROUS_HOST according to the metadata check + ClientDownloadResponse metadata_response; + metadata_response.set_verdict(ClientDownloadResponse::DANGEROUS_HOST); + ExpectMetadataResponse(metadata_response); + + GURL url = embedded_test_server()->GetURL( + "/safe_browsing/download_protection/zipfile_two_archives.zip"); + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::CURRENT_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + + // The DLP scan finishes synchronously and find a violation. + enterprise_connectors::ContentAnalysisResponse sync_response; + auto* result = sync_response.add_results(); + result->set_tag("dlp"); + result->set_status( + enterprise_connectors::ContentAnalysisResponse::Result::SUCCESS); + auto* dlp_rule = result->add_triggered_rules(); + dlp_rule->set_action(enterprise_connectors::TriggeredRule::WARN); + dlp_rule->set_rule_name("dlp_rule_name"); + ExpectContentAnalysisSynchronousResponse(/*is_advanced_protection=*/false, + sync_response, {"dlp"}); + + WaitForMetadataCheck(); + WaitForDeepScanRequest(/*is_advanced_protection=*/false); + + // Both the DLP and malware violations generate an event. + std::set<std::string> zip_types = {"application/zip", + "application/x-zip-compressed"}; + EventReportValidator validator(client()); + validator.ExpectSensitiveDataEventAndDangerousDeepScanningResult( + /*url*/ url.spec(), + /*filename*/ + (*download_items().begin())->GetTargetFilePath().AsUTF8Unsafe(), + // sha256sum chrome/test/data/safe_browsing/download_protection/\ + // zipfile_two_archives.zip | tr '[:lower:]' '[:upper:]' + /*sha*/ + "339C8FFDAE735C4F1846D0E6FF07FBD85CAEE6D96045AAEF5B30F3220836643C", + /*threat_type*/ "DANGEROUS_HOST", + /*trigger*/ + extensions::SafeBrowsingPrivateEventRouter::kTriggerFileDownload, + /*dlp_verdict*/ *result, + /*mimetypes*/ &zip_types, + /*size*/ 276, + /*result*/ EventResultToString(EventResult::WARNED)); + WaitForDownloadToFinish(); + + // The file should be blocked. + ASSERT_EQ(download_items().size(), 1u); + download::DownloadItem* item = *download_items().begin(); + EXPECT_EQ(item->GetDangerType(), + download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST); + EXPECT_EQ(item->GetState(), download::DownloadItem::IN_PROGRESS); + + // UMAs for this request should only be recorded once. The malware metric + // should not be recorded since no deep malware scan occurred. + histograms.ExpectUniqueSample("SafeBrowsingBinaryUploadRequest.Result", + BinaryUploadService::Result::SUCCESS, 1); + histograms.ExpectUniqueSample("SafeBrowsingBinaryUploadRequest.DlpResult", + true, 1); + histograms.ExpectUniqueSample("SafeBrowsingBinaryUploadRequest.MalwareResult", + true, 0); +} + class DownloadRestrictionsDeepScanningBrowserTest : public DownloadDeepScanningBrowserTest { public:
diff --git a/chrome/browser/safe_browsing/download_protection/download_reporter.cc b/chrome/browser/safe_browsing/download_protection/download_reporter.cc index 0aeff87f..32fa9fc5 100644 --- a/chrome/browser/safe_browsing/download_protection/download_reporter.cc +++ b/chrome/browser/safe_browsing/download_protection/download_reporter.cc
@@ -54,7 +54,16 @@ } } -void ReportDangerousDownloadWarning(download::DownloadItem* download) { +void MaybeReportDangerousDownloadWarning(download::DownloadItem* download) { + // If |download| has a deep scanning malware verdict, then it means the + // dangerous file has already been reported. + auto* scan_result = static_cast<enterprise_connectors::ScanResult*>( + download->GetUserData(enterprise_connectors::ScanResult::kKey)); + if (scan_result && + enterprise_connectors::ContainsMalwareVerdict(scan_result->response)) { + return; + } + content::BrowserContext* browser_context = content::DownloadItemUtils::GetBrowserContext(download); Profile* profile = Profile::FromBrowserContext(browser_context); @@ -160,9 +169,8 @@ download::DownloadDangerType current_danger_type = download->GetDangerType(); if (!DangerTypeIsDangerous(old_danger_type) && - old_danger_type != download::DOWNLOAD_DANGER_TYPE_ASYNC_SCANNING && DangerTypeIsDangerous(current_danger_type)) { - ReportDangerousDownloadWarning(download); + MaybeReportDangerousDownloadWarning(download); } if (DangerTypeIsDangerous(old_danger_type) &&
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc index ec11f2c4f..7447494 100644 --- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc +++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
@@ -24,13 +24,10 @@ #include "components/safe_browsing/core/db/database_manager.h" #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" #include "components/subresource_filter/content/browser/ruleset_service.h" -#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h" #include "components/subresource_filter/core/browser/subresource_filter_features.h" #include "components/subresource_filter/core/common/activation_decision.h" #include "components/subresource_filter/core/common/activation_scope.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "services/metrics/public/cpp/ukm_source_id.h" @@ -67,23 +64,6 @@ } } -void ChromeSubresourceFilterClient::MaybeAppendNavigationThrottles( - content::NavigationHandle* navigation_handle, - std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles) { - safe_browsing::SafeBrowsingService* safe_browsing_service = - g_browser_process->safe_browsing_service(); - if (navigation_handle->IsInMainFrame() && safe_browsing_service) { - throttles->push_back( - std::make_unique<subresource_filter:: - SubresourceFilterSafeBrowsingActivationThrottle>( - navigation_handle, this, content::GetIOThreadTaskRunner({}), - safe_browsing_service->database_manager())); - } - - throttle_manager_->MaybeAppendNavigationThrottles(navigation_handle, - throttles); -} - void ChromeSubresourceFilterClient::OnReloadRequested() { LogAction(SubresourceFilterAction::kAllowlistedSite); AllowlistByContentSettings(web_contents()->GetLastCommittedURL()); @@ -185,6 +165,14 @@ profile_context_->settings_manager()->AllowlistSite(top_level_url); } +const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> +ChromeSubresourceFilterClient::GetSafeBrowsingDatabaseManager() { + safe_browsing::SafeBrowsingService* safe_browsing_service = + g_browser_process->safe_browsing_service(); + return safe_browsing_service ? safe_browsing_service->database_manager() + : nullptr; +} + void ChromeSubresourceFilterClient::ToggleForceActivationInCurrentWebContents( bool force_activation) { if (!activated_via_devtools_ && force_activation) @@ -192,7 +180,7 @@ activated_via_devtools_ = force_activation; } -const subresource_filter::ContentSubresourceFilterThrottleManager* +subresource_filter::ContentSubresourceFilterThrottleManager* ChromeSubresourceFilterClient::GetThrottleManager() const { return throttle_manager_.get(); }
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.h b/chrome/browser/subresource_filter/chrome_subresource_filter_client.h index cc150ae4..f6e50c5 100644 --- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.h +++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.h
@@ -19,7 +19,6 @@ namespace content { class NavigationHandle; -class NavigationThrottle; class WebContents; } // namespace content @@ -64,10 +63,6 @@ explicit ChromeSubresourceFilterClient(content::WebContents* web_contents); ~ChromeSubresourceFilterClient() override; - void MaybeAppendNavigationThrottles( - content::NavigationHandle* navigation_handle, - std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles); - void OnReloadRequested(); // content::WebContentsObserver: @@ -83,6 +78,8 @@ void OnAdsViolationTriggered( content::RenderFrameHost* rfh, subresource_filter::mojom::AdsViolation triggered_violation) override; + const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> + GetSafeBrowsingDatabaseManager() override; // Should be called by devtools in response to a protocol command to enable ad // blocking in this WebContents. Should only persist while devtools is @@ -93,7 +90,7 @@ return did_show_ui_for_navigation_; } - const subresource_filter::ContentSubresourceFilterThrottleManager* + subresource_filter::ContentSubresourceFilterThrottleManager* GetThrottleManager() const; static void LogAction(SubresourceFilterAction action);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 7291f33..bf4ca6cd 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2084,6 +2084,8 @@ "views/profiles/profile_indicator_icon.h", "views/relaunch_notification/relaunch_notification_controller_platform_impl_chromeos.cc", "views/relaunch_notification/relaunch_notification_controller_platform_impl_chromeos.h", + "views/relaunch_notification/relaunch_notification_metrics.cc", + "views/relaunch_notification/relaunch_notification_metrics.h", "views/sharesheet/sharesheet_bubble_view.cc", "views/sharesheet/sharesheet_bubble_view.h", "views/sharesheet/sharesheet_expand_button.cc", @@ -3849,8 +3851,6 @@ "views/reader_mode/reader_mode_icon_view.h", "views/relaunch_notification/relaunch_notification_controller.cc", "views/relaunch_notification/relaunch_notification_controller.h", - "views/relaunch_notification/relaunch_notification_metrics.cc", - "views/relaunch_notification/relaunch_notification_metrics.h", "views/relaunch_notification/relaunch_required_timer.cc", "views/relaunch_notification/relaunch_required_timer.h", "views/relaunch_notification/relaunch_required_timer_internal.cc",
diff --git a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc index 4dc46bc..711888fda 100644 --- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc +++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc
@@ -194,6 +194,7 @@ return; base::WeakPtr<PasswordGenerationPopupControllerImpl> weak_this = GetWeakPtr(); + CHECK(driver_); driver_->GeneratedPasswordAccepted(form_data_, generation_element_id_, current_password_); // |this| can be destroyed here because GeneratedPasswordAccepted pops up
diff --git a/chrome/browser/ui/search/ntp_user_data_logger.cc b/chrome/browser/ui/search/ntp_user_data_logger.cc index 8d47e7c..647773bf 100644 --- a/chrome/browser/ui/search/ntp_user_data_logger.cc +++ b/chrome/browser/ui/search/ntp_user_data_logger.cc
@@ -601,6 +601,14 @@ base::TimeDelta::FromSeconds(60), 100); } +void NTPUserDataLogger::LogModuleLoaded(const std::string& id, + base::TimeDelta time) { + UMA_HISTOGRAM_LOAD_TIME("NewTabPage.Modules.Loaded", time); + base::UmaHistogramCustomTimes("NewTabPage.Modules.Loaded." + id, time, + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromSeconds(60), 100); +} + void NTPUserDataLogger::LogModuleUsage(const std::string& id) { UMA_HISTOGRAM_EXACT_LINEAR("NewTabPage.Modules.Usage", 1, 1); base::UmaHistogramExactLinear("NewTabPage.Modules.Usage." + id, 1, 1);
diff --git a/chrome/browser/ui/search/ntp_user_data_logger.h b/chrome/browser/ui/search/ntp_user_data_logger.h index 39fe56a..31946df6 100644 --- a/chrome/browser/ui/search/ntp_user_data_logger.h +++ b/chrome/browser/ui/search/ntp_user_data_logger.h
@@ -57,6 +57,9 @@ // the user (scrolled into view). void LogModuleImpression(const std::string& id, base::TimeDelta time); + // Logs a module is loaded on the NTP. + void LogModuleLoaded(const std::string& id, base::TimeDelta time); + // Logs when a user interacts with a module which will result in a navigation. void LogModuleUsage(const std::string& id);
diff --git a/chrome/browser/ui/uninstall_browser_prompt.h b/chrome/browser/ui/uninstall_browser_prompt.h index 535e2e1e..15ce952 100644 --- a/chrome/browser/ui/uninstall_browser_prompt.h +++ b/chrome/browser/ui/uninstall_browser_prompt.h
@@ -8,7 +8,7 @@ namespace chrome { // Asks user for uninstall confirmation and returns one of these values: -// service_manager::RESULT_CODE_NORMAL_EXIT, +// content::RESULT_CODE_NORMAL_EXIT, // chrome::RESULT_CODE_UNINSTALL_DELETE_PROFILE or // chrome::RESULT_CODE_UNINSTALL_USER_CANCEL. int ShowUninstallBrowserPrompt();
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_button.cc b/chrome/browser/ui/views/extensions/extensions_menu_button.cc index e1dc1f2..0a23ee7f 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_button.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_button.cc
@@ -25,14 +25,18 @@ ExtensionsMenuItemView* parent, ToolbarActionViewController* controller, bool allow_pinning) - : views::LabelButton(this), + : views::LabelButton( + base::BindRepeating(&ExtensionsMenuButton::ButtonPressed, + base::Unretained(this))), browser_(browser), parent_(parent), controller_(controller), allow_pinning_(allow_pinning) { ConfigureBubbleMenuItem(this, 0); SetButtonController(std::make_unique<HoverButtonController>( - this, PressedCallback(this, this), + this, + base::BindRepeating(&ExtensionsMenuButton::ButtonPressed, + base::Unretained(this)), std::make_unique<views::Button::DefaultButtonControllerDelegate>(this))); controller_->SetDelegate(this); UpdateState(); @@ -52,14 +56,6 @@ return allow_pinning_; } -void ExtensionsMenuButton::ButtonPressed(Button* sender, - const ui::Event& event) { - base::RecordAction( - base::UserMetricsAction("Extensions.Toolbar.ExtensionActivatedFromMenu")); - controller_->ExecuteAction( - true, ToolbarActionViewController::InvocationSource::kMenuEntry); -} - // ToolbarActionViewDelegateViews: views::View* ExtensionsMenuButton::GetAsView() { return this; @@ -102,3 +98,10 @@ bool ExtensionsMenuButton::IsMenuRunning() const { return parent_->IsContextMenuRunning(); } + +void ExtensionsMenuButton::ButtonPressed() { + base::RecordAction( + base::UserMetricsAction("Extensions.Toolbar.ExtensionActivatedFromMenu")); + controller_->ExecuteAction( + true, ToolbarActionViewController::InvocationSource::kMenuEntry); +}
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_button.h b/chrome/browser/ui/views/extensions/extensions_menu_button.h index a52892d..e0cd62a9 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_button.h +++ b/chrome/browser/ui/views/extensions/extensions_menu_button.h
@@ -24,7 +24,6 @@ // the extensions menu. This includes the extension icon and name and triggers // the extension action. class ExtensionsMenuButton : public views::LabelButton, - public views::ButtonListener, public ToolbarActionViewDelegateViews { public: ExtensionsMenuButton(Browser* browser, @@ -47,7 +46,6 @@ private: // views::ButtonListener: const char* GetClassName() const override; - void ButtonPressed(Button* sender, const ui::Event& event) override; // ToolbarActionViewDelegateViews: views::View* GetAsView() override; @@ -57,6 +55,8 @@ void UpdateState() override; bool IsMenuRunning() const override; + void ButtonPressed(); + Browser* const browser_; // The container containing this view.
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc index 3ce957f..5d0b5f4 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
@@ -71,7 +71,10 @@ views::MaximumFlexSizeRule::kUnbounded)); if (primary_action_button_->CanShowIconInToolbar()) { - auto pin_button = CreateBubbleMenuItem(EXTENSION_PINNING, this); + auto pin_button = CreateBubbleMenuItem( + EXTENSION_PINNING, + base::BindRepeating(&ExtensionsMenuItemView::PinButtonPressed, + base::Unretained(this))); pin_button->SetBorder(views::CreateEmptyBorder(kSecondaryButtonInsets)); // Extension pinning is not available in Incognito as it leaves a trace of // user activity. @@ -89,35 +92,16 @@ l10n_util::GetStringUTF16(IDS_EXTENSIONS_MENU_CONTEXT_MENU_TOOLTIP)); context_menu_button->SetButtonController( std::make_unique<views::MenuButtonController>( - context_menu_button.get(), this, + context_menu_button.get(), + base::BindRepeating(&ExtensionsMenuItemView::ContextMenuPressed, + base::Unretained(this)), std::make_unique<views::Button::DefaultButtonControllerDelegate>( context_menu_button.get()))); - - context_menu_button_ = context_menu_button.get(); - AddChildView(std::move(context_menu_button)); + context_menu_button_ = AddChildView(std::move(context_menu_button)); } ExtensionsMenuItemView::~ExtensionsMenuItemView() = default; -void ExtensionsMenuItemView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - if (sender->GetID() == EXTENSION_PINNING) { - base::RecordAction( - base::UserMetricsAction("Extensions.Toolbar.PinButtonPressed")); - model_->SetActionVisibility(controller_->GetId(), !IsPinned()); - return; - } else if (sender->GetID() == EXTENSION_CONTEXT_MENU) { - base::RecordAction(base::UserMetricsAction( - "Extensions.Toolbar.MoreActionsButtonPressedFromMenu")); - // TODO(crbug.com/998298): Cleanup the menu source type. - context_menu_controller_->ShowContextMenuForViewImpl( - sender, sender->GetMenuPosition(), - ui::MenuSourceType::MENU_SOURCE_MOUSE); - return; - } - NOTREACHED(); -} - const char* ExtensionsMenuItemView::GetClassName() const { return kClassName; } @@ -160,9 +144,22 @@ bool ExtensionsMenuItemView::IsPinned() const { // |model_| can be null in unit tests. - if (!model_) - return false; - return model_->IsActionPinned(controller_->GetId()); + return model_ && model_->IsActionPinned(controller_->GetId()); +} + +void ExtensionsMenuItemView::ContextMenuPressed() { + base::RecordAction(base::UserMetricsAction( + "Extensions.Toolbar.MoreActionsButtonPressedFromMenu")); + // TODO(crbug.com/998298): Cleanup the menu source type. + context_menu_controller_->ShowContextMenuForViewImpl( + context_menu_button_, context_menu_button_->GetMenuPosition(), + ui::MenuSourceType::MENU_SOURCE_MOUSE); +} + +void ExtensionsMenuItemView::PinButtonPressed() { + base::RecordAction( + base::UserMetricsAction("Extensions.Toolbar.PinButtonPressed")); + model_->SetActionVisibility(controller_->GetId(), !IsPinned()); } ExtensionsMenuButton*
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.h b/chrome/browser/ui/views/extensions/extensions_menu_item_view.h index 63ff043..3032b76 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.h +++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.h
@@ -7,7 +7,6 @@ #include <memory> -#include "ui/views/controls/button/button.h" #include "ui/views/view.h" class Browser; @@ -24,8 +23,7 @@ // particular extension. Includes information about the extension in addition to // a button to pin the extension to the toolbar and a button for accessing the // associated context menu. -class ExtensionsMenuItemView : public views::View, - public views::ButtonListener { +class ExtensionsMenuItemView : public views::View { public: static constexpr int kMenuItemHeightDp = 40; static constexpr gfx::Size kIconSize{28, 28}; @@ -39,9 +37,6 @@ ExtensionsMenuItemView& operator=(const ExtensionsMenuItemView&) = delete; ~ExtensionsMenuItemView() override; - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // views::View: const char* GetClassName() const override; void OnThemeChanged() override; @@ -49,9 +44,11 @@ void UpdatePinButton(); bool IsContextMenuRunning() const; - bool IsPinned() const; + void ContextMenuPressed(); + void PinButtonPressed(); + ToolbarActionViewController* view_controller() { return controller_.get(); } const ToolbarActionViewController* view_controller() const { return controller_.get();
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc b/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc index d9ce49f..434116b 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc
@@ -22,6 +22,7 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image.h" #include "ui/views/controls/button/label_button.h" +#include "ui/views/test/button_test_api.h" #include "ui/views/view.h" // A view wrapper class that owns the ExtensionsToolbarContainer. @@ -111,10 +112,7 @@ ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0); - // ExtensionsMenuButton::ButtonPressed() is private; workaround by casting to - // to a ButtonListener. - static_cast<views::ButtonListener*>(primary_button) - ->ButtonPressed(primary_button, event); + views::test::ButtonTestApi(primary_button).NotifyClick(event); } std::string ExtensionsMenuTestUtil::GetExtensionId(int index) {
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_view.cc index e37701e5..719846c 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_view.cc
@@ -55,15 +55,6 @@ } // namespace -ExtensionsMenuView::ButtonListener::ButtonListener(Browser* browser) - : browser_(browser) {} - -void ExtensionsMenuView::ButtonListener::ButtonPressed(views::Button* sender, - const ui::Event& event) { - DCHECK_EQ(sender->GetID(), EXTENSIONS_SETTINGS_ID); - chrome::ShowExtensions(browser_, std::string()); -} - ExtensionsMenuView::ExtensionsMenuView( views::View* anchor_view, Browser* browser, @@ -76,7 +67,6 @@ allow_pinning_(allow_pinning), toolbar_model_(ToolbarActionsModel::Get(browser_->profile())), toolbar_model_observer_(this), - button_listener_(browser_), cant_access_{nullptr, nullptr, IDS_EXTENSIONS_MENU_CANT_ACCESS_SITE_DATA_SHORT, IDS_EXTENSIONS_MENU_CANT_ACCESS_SITE_DATA, @@ -154,7 +144,7 @@ constexpr int kSettingsIconSize = 16; auto footer = CreateBubbleMenuItem( EXTENSIONS_SETTINGS_ID, l10n_util::GetStringUTF16(IDS_MANAGE_EXTENSION), - &button_listener_); + base::BindRepeating(&chrome::ShowExtensions, browser_, std::string())); footer->SetImage( views::Button::STATE_NORMAL, gfx::CreateVectorIcon(vector_icons::kSettingsIcon, kSettingsIconSize,
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view.h b/chrome/browser/ui/views/extensions/extensions_menu_view.h index bf3f775..bf1ae29 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view.h +++ b/chrome/browser/ui/views/extensions/extensions_menu_view.h
@@ -15,7 +15,6 @@ #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" #include "ui/gfx/geometry/size.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" -#include "ui/views/controls/button/button.h" namespace views { class Button; @@ -104,18 +103,6 @@ // the view directly is more friendly to unit test setups. static base::AutoReset<bool> AllowInstancesForTesting(); - private: - class ButtonListener : public views::ButtonListener { - public: - explicit ButtonListener(Browser* browser); - - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - - private: - Browser* const browser_; - }; - // A "section" within the menu, based on the extension's current access to // the page. struct Section { @@ -178,7 +165,6 @@ ToolbarActionsModel* const toolbar_model_; ScopedObserver<ToolbarActionsModel, ToolbarActionsModel::Observer> toolbar_model_observer_; - ButtonListener button_listener_; std::vector<ExtensionsMenuItemView*> extensions_menu_items_; views::Button* manage_extensions_button_for_testing_ = nullptr;
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc index c5f4e66..bb1ed35 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc
@@ -23,12 +23,14 @@ ExtensionsToolbarButton::ExtensionsToolbarButton( Browser* browser, ExtensionsToolbarContainer* extensions_container) - : ToolbarButton(this), + : ToolbarButton(nullptr), browser_(browser), extensions_container_(extensions_container) { std::unique_ptr<views::MenuButtonController> menu_button_controller = std::make_unique<views::MenuButtonController>( - this, this, + this, + base::BindRepeating(&ExtensionsToolbarButton::ButtonPressed, + base::Unretained(this)), std::make_unique<views::Button::DefaultButtonControllerDelegate>( this)); menu_button_controller_ = menu_button_controller.get(); @@ -90,19 +92,6 @@ extensions_container_->GetIconColor(), GetIconSize())); } -void ExtensionsToolbarButton::ButtonPressed(views::Button* sender, - const ui::Event& event) { - if (ExtensionsMenuView::IsShowing()) { - ExtensionsMenuView::Hide(); - return; - } - pressed_lock_ = menu_button_controller_->TakeLock(); - base::RecordAction(base::UserMetricsAction("Extensions.Toolbar.MenuOpened")); - ExtensionsMenuView::ShowBubble(this, browser_, extensions_container_, - extensions_container_->CanShowIconInToolbar()) - ->AddObserver(this); -} - void ExtensionsToolbarButton::OnWidgetDestroying(views::Widget* widget) { widget->RemoveObserver(this); pressed_lock_.reset(); @@ -113,3 +102,15 @@ return (touch_ui && !browser_->app_controller()) ? kDefaultTouchableIconSize : kDefaultIconSize; } + +void ExtensionsToolbarButton::ButtonPressed() { + if (ExtensionsMenuView::IsShowing()) { + ExtensionsMenuView::Hide(); + return; + } + pressed_lock_ = menu_button_controller_->TakeLock(); + base::RecordAction(base::UserMetricsAction("Extensions.Toolbar.MenuOpened")); + ExtensionsMenuView::ShowBubble(this, browser_, extensions_container_, + extensions_container_->CanShowIconInToolbar()) + ->AddObserver(this); +}
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h index 7eb9006..dfe81b2 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h
@@ -18,7 +18,6 @@ // Button in the toolbar that provides access to the corresponding extensions // menu. class ExtensionsToolbarButton : public ToolbarButton, - public views::ButtonListener, public views::WidgetObserver { public: ExtensionsToolbarButton(Browser* browser, @@ -34,15 +33,14 @@ const char* GetClassName() const override; void UpdateIcon() override; - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // views::WidgetObserver: void OnWidgetDestroying(views::Widget* widget) override; private: int GetIconSize() const; + void ButtonPressed(); + // A lock to keep the button pressed when a popup is visible. std::unique_ptr<views::MenuButtonController::PressedLock> pressed_lock_;
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc index 567d9cec..c346a400 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
@@ -62,13 +62,6 @@ views::View::Layout(); } -std::unique_ptr<views::LabelButton> CreateAuxiliaryButton( - views::ButtonListener* listener, - const base::string16& label) { - return label.empty() ? nullptr - : std::make_unique<views::MdTextButton>(listener, label); -} - } // namespace MediaGalleriesDialogViews::MediaGalleriesDialogViews( @@ -85,8 +78,16 @@ SetShowCloseButton(false); SetTitle(controller_->GetHeader()); - auxiliary_button_ = SetExtraView( - CreateAuxiliaryButton(this, controller_->GetAuxiliaryButtonText())); + base::string16 label = controller_->GetAuxiliaryButtonText(); + if (!label.empty()) { + auxiliary_button_ = SetExtraView(std::make_unique<views::MdTextButton>( + base::BindRepeating( + &MediaGalleriesDialogViews::ButtonPressed, base::Unretained(this), + base::BindRepeating( + &MediaGalleriesDialogController::DidClickAuxiliaryButton, + base::Unretained(controller_))), + label)); + } InitChildViews(); if (ControllerHasWebContents()) { @@ -221,12 +222,19 @@ return false; } - MediaGalleryCheckboxView* gallery_view = new MediaGalleryCheckboxView( - gallery.pref_info, trailing_vertical_space, this, this); + auto* gallery_view = + container->AddChildView(std::make_unique<MediaGalleryCheckboxView>( + gallery.pref_info, trailing_vertical_space, this)); + gallery_view->checkbox()->set_callback(base::BindRepeating( + &MediaGalleriesDialogViews::ButtonPressed, base::Unretained(this), + base::BindRepeating( + [](MediaGalleriesDialogController* controller, + MediaGalleryPrefId pref_id, views::Checkbox* checkbox) { + controller->DidToggleEntry(pref_id, checkbox->GetChecked()); + }, + controller_, gallery.pref_info.pref_id, gallery_view->checkbox()))); gallery_view->checkbox()->SetChecked(gallery.selected); - container->AddChildView(gallery_view); checkbox_map_[gallery.pref_info.pref_id] = gallery_view; - return true; } @@ -255,28 +263,6 @@ return ui::MODAL_TYPE_CHILD; } -void MediaGalleriesDialogViews::ButtonPressed(views::Button* sender, - const ui::Event& /* event */) { - confirm_available_ = true; - - if (ControllerHasWebContents()) - DialogModelChanged(); - - if (sender == auxiliary_button_) { - controller_->DidClickAuxiliaryButton(); - return; - } - - for (CheckboxMap::const_iterator iter = checkbox_map_.begin(); - iter != checkbox_map_.end(); ++iter) { - if (sender == iter->second->checkbox()) { - controller_->DidToggleEntry(iter->first, - iter->second->checkbox()->GetChecked()); - return; - } - } -} - void MediaGalleriesDialogViews::ShowContextMenuForViewImpl( views::View* source, const gfx::Point& point, @@ -309,6 +295,15 @@ return controller_->WebContents() != nullptr; } +void MediaGalleriesDialogViews::ButtonPressed(base::RepeatingClosure closure) { + confirm_available_ = true; + + if (ControllerHasWebContents()) + DialogModelChanged(); + + closure.Run(); +} + void MediaGalleriesDialogViews::OnMenuClosed() { context_menu_runner_.reset(); }
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.h b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.h index 33a85748..05f66ff7 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.h +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "chrome/browser/media_galleries/media_galleries_dialog_controller.h" #include "ui/views/context_menu_controller.h" -#include "ui/views/controls/button/button.h" #include "ui/views/window/dialog_delegate.h" namespace views { @@ -27,7 +26,6 @@ // The media galleries configuration view for Views. It will immediately show // upon construction. class MediaGalleriesDialogViews : public MediaGalleriesDialog, - public views::ButtonListener, public views::ContextMenuController, public views::DialogDelegate { public: @@ -46,9 +44,6 @@ bool IsDialogButtonEnabled(ui::DialogButton button) const override; ui::ModalType GetModalType() const override; - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // views::ContextMenuController: void ShowContextMenuForViewImpl(views::View* source, const gfx::Point& point, @@ -60,7 +55,7 @@ FRIEND_TEST_ALL_PREFIXES(MediaGalleriesDialogTest, UpdateAdds); FRIEND_TEST_ALL_PREFIXES(MediaGalleriesDialogTest, ForgetDeletes); - typedef std::map<MediaGalleryPrefId, MediaGalleryCheckboxView*> CheckboxMap; + using CheckboxMap = std::map<MediaGalleryPrefId, MediaGalleryCheckboxView*>; // MediaGalleriesDialog: void AcceptDialogForTesting() override; @@ -82,6 +77,10 @@ // In unit tests, it may not. bool ControllerHasWebContents() const; + // Called when a button is pressed; does common preamble, then runs the + // supplied closure to execute the specific details of the particular button. + void ButtonPressed(base::RepeatingClosure closure); + // Callback for MenuRunner. void OnMenuClosed();
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc index 9a79bd7a..0177387 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views_unittest.cc
@@ -14,6 +14,7 @@ #include "components/storage_monitor/storage_info.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/controls/button/checkbox.h" +#include "ui/views/test/button_test_api.h" using ::testing::_; using ::testing::AnyNumber; @@ -100,14 +101,13 @@ views::Checkbox* checkbox = dialog.checkbox_map_[1]->checkbox(); EXPECT_TRUE(checkbox->GetChecked()); - ui::KeyEvent dummy_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); EXPECT_CALL(*controller(), DidToggleEntry(1, false)); - checkbox->SetChecked(false); - dialog.ButtonPressed(checkbox, dummy_event); + views::test::ButtonTestApi test_api(checkbox); + ui::KeyEvent dummy_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); + test_api.NotifyClick(dummy_event); // Toggles to unchecked before notifying. EXPECT_CALL(*controller(), DidToggleEntry(1, true)); - checkbox->SetChecked(true); - dialog.ButtonPressed(checkbox, dummy_event); + test_api.NotifyClick(dummy_event); // Toggles to checked before notifying. } // Tests that UpdateGallery will add a new checkbox, but only if it refers to
diff --git a/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc b/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc index 3e22fe4..c5aea63 100644 --- a/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc +++ b/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.cc
@@ -26,9 +26,7 @@ MediaGalleryCheckboxView::MediaGalleryCheckboxView( const MediaGalleryPrefInfo& pref_info, int trailing_vertical_space, - views::ButtonListener* button_listener, views::ContextMenuController* menu_controller) { - DCHECK(button_listener != NULL); SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal)); ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); @@ -39,8 +37,8 @@ if (menu_controller) set_context_menu_controller(menu_controller); - checkbox_ = - new views::Checkbox(pref_info.GetGalleryDisplayName(), button_listener); + checkbox_ = AddChildView(std::make_unique<views::Checkbox>( + pref_info.GetGalleryDisplayName(), views::Button::PressedCallback())); if (menu_controller) checkbox_->set_context_menu_controller(menu_controller); checkbox_->SetElideBehavior(gfx::ELIDE_MIDDLE); @@ -48,7 +46,7 @@ checkbox_->SetTooltipText(tooltip_text); base::string16 details = pref_info.GetGalleryAdditionalDetails(); - secondary_text_ = new views::Label(details); + secondary_text_ = AddChildView(std::make_unique<views::Label>(details)); if (menu_controller) secondary_text_->set_context_menu_controller(menu_controller); secondary_text_->SetVisible(details.length() > 0); @@ -58,12 +56,9 @@ secondary_text_->SetBorder(views::CreateEmptyBorder( 0, provider->GetDistanceMetric(DISTANCE_RELATED_CONTROL_HORIZONTAL_SMALL), 0, 0)); - - AddChildView(checkbox_); - AddChildView(secondary_text_); } -MediaGalleryCheckboxView::~MediaGalleryCheckboxView() {} +MediaGalleryCheckboxView::~MediaGalleryCheckboxView() = default; void MediaGalleryCheckboxView::Layout() { views::View::Layout();
diff --git a/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.h b/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.h index 6efba29c..8d723f0 100644 --- a/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.h +++ b/chrome/browser/ui/views/extensions/media_gallery_checkbox_view.h
@@ -8,12 +8,12 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "ui/gfx/geometry/size.h" +#include "ui/views/controls/button/button.h" #include "ui/views/view.h" struct MediaGalleryPrefInfo; namespace views { -class ButtonListener; class Checkbox; class ContextMenuController; class Label; @@ -26,16 +26,15 @@ public: MediaGalleryCheckboxView(const MediaGalleryPrefInfo& pref_info, int trailing_vertical_space, - views::ButtonListener* button_listener, views::ContextMenuController* menu_controller); ~MediaGalleryCheckboxView() override; - // Overrides from views::View. - void Layout() override; - views::Checkbox* checkbox() { return checkbox_; } views::Label* secondary_text() { return secondary_text_; } + // views::View: + void Layout() override; + private: // Owned by the parent class (views::View). views::Checkbox* checkbox_;
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_chromeos.cc b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_chromeos.cc index 98f3c32..4dcce46 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_chromeos.cc +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_chromeos.cc
@@ -33,8 +33,7 @@ void RelaunchNotificationControllerPlatformImpl::RecordRecommendedShowResult() { if (!recorded_shown_) { - relaunch_notification::RecordRecommendedShowResult( - relaunch_notification::ShowResult::kShown); + relaunch_notification::RecordRecommendedShowResult(); recorded_shown_ = true; } } @@ -49,8 +48,7 @@ RefreshRelaunchRequiredTitle, base::Unretained(this))); - relaunch_notification::RecordRequiredShowResult( - relaunch_notification::ShowResult::kShown); + relaunch_notification::RecordRequiredShowResult(); } RefreshRelaunchRequiredTitle();
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_desktop.cc b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_desktop.cc index 1acc23b..12eec469 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_desktop.cc +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_desktop.cc
@@ -5,37 +5,16 @@ #include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_desktop.h" #include "base/bind.h" -#include "chrome/browser/browser_process.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_metrics.h" #include "chrome/browser/ui/views/relaunch_notification/relaunch_recommended_bubble_view.h" #include "chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.h" -#include "chrome/common/buildflags.h" #include "ui/views/widget/widget.h" -#if BUILDFLAG(ENABLE_BACKGROUND_MODE) -#include "chrome/browser/background/background_mode_manager.h" -#endif // BUILDFLAG(ENABLE_BACKGROUND_MODE) - namespace { -// Returns the reason why a dialog was not shown when the conditions were ripe -// for such. -relaunch_notification::ShowResult GetNotShownReason() { -#if BUILDFLAG(ENABLE_BACKGROUND_MODE) - BackgroundModeManager* background_mode_manager = - g_browser_process->background_mode_manager(); - if (background_mode_manager && - background_mode_manager->IsBackgroundWithoutWindows()) { - return relaunch_notification::ShowResult::kBackgroundModeNoWindows; - } -#endif // BUILDFLAG(ENABLE_BACKGROUND_MODE) - return relaunch_notification::ShowResult::kUnknownNotShownReason; -} - // Returns the last active tabbed browser. Browser* FindLastActiveTabbedBrowser() { BrowserList* browser_list = BrowserList::GetInstance(); @@ -69,9 +48,6 @@ // Show the bubble in the most recently active browser. Browser* browser = FindLastActiveTabbedBrowser(); - relaunch_notification::RecordRecommendedShowResult( - browser ? relaunch_notification::ShowResult::kShown - : GetNotShownReason()); if (!browser) return; @@ -94,13 +70,9 @@ if (browser && browser->is_type_normal()) { DCHECK(!on_visible_); ShowRequiredNotification(browser, deadline); - relaunch_notification::RecordRequiredShowResult( - relaunch_notification::ShowResult::kShown); return; } - relaunch_notification::RecordRequiredShowResult(GetNotShownReason()); - // If the instance is not already waiting for one to become active from a // previous call, start observing now. if (!on_visible_)
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_metrics.cc b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_metrics.cc index cedf1851..0e05e085 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_metrics.cc +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_metrics.cc
@@ -14,20 +14,30 @@ constexpr char kRecommendedSuffix[] = ".Recommended"; constexpr char kRequiredSuffix[] = ".Required"; +// The result of an attempt to show a relaunch notification dialog. These values +// are persisted to logs. Entries should not be renumbered and numeric values +// should never be reused. +enum class ShowResult { + kShown = 0, + DEPRECATED_kUnknownNotShownReason = 1, + DEPRECATED_kBackgroundModeNoWindows = 2, + kCount +}; + } // namespace namespace relaunch_notification { -void RecordRecommendedShowResult(ShowResult show_result) { +void RecordRecommendedShowResult() { base::UmaHistogramEnumeration( - std::string(kShowResultHistogramPrefix) + kRecommendedSuffix, show_result, - ShowResult::kCount); + std::string(kShowResultHistogramPrefix) + kRecommendedSuffix, + ShowResult::kShown, ShowResult::kCount); } -void RecordRequiredShowResult(ShowResult show_result) { +void RecordRequiredShowResult() { base::UmaHistogramEnumeration( - std::string(kShowResultHistogramPrefix) + kRequiredSuffix, show_result, - ShowResult::kCount); + std::string(kShowResultHistogramPrefix) + kRequiredSuffix, + ShowResult::kShown, ShowResult::kCount); } } // namespace relaunch_notification
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_metrics.h b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_metrics.h index 639be57..643fb307 100644 --- a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_metrics.h +++ b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_metrics.h
@@ -7,23 +7,11 @@ namespace relaunch_notification { -// The result of an attempt to show a relaunch notification dialog. These values -// are persisted to logs. Entries should not be renumbered and numeric values -// should never be reused. -enum class ShowResult { - kShown = 0, - kUnknownNotShownReason = 1, - kBackgroundModeNoWindows = 2, - kCount -}; +// Record to UMA showing a relaunch recommended notification. +void RecordRecommendedShowResult(); -// Record to UMA showing a relaunch recommended notification with the given -// |show_result|. -void RecordRecommendedShowResult(ShowResult show_result); - -// Record to UMA showing a relaunch required notification with the given -// |show_result|. -void RecordRequiredShowResult(ShowResult show_result); +// Record to UMA showing a relaunch required notification. +void RecordRequiredShowResult(); } // namespace relaunch_notification
diff --git a/chrome/browser/ui/views/uninstall_view.cc b/chrome/browser/ui/views/uninstall_view.cc index 9356552..6d514cf 100644 --- a/chrome/browser/ui/views/uninstall_view.cc +++ b/chrome/browser/ui/views/uninstall_view.cc
@@ -136,7 +136,7 @@ } void UninstallView::OnDialogAccepted() { - user_selection_ = service_manager::RESULT_CODE_NORMAL_EXIT; + user_selection_ = content::RESULT_CODE_NORMAL_EXIT; if (delete_profile_->GetChecked()) user_selection_ = chrome::RESULT_CODE_UNINSTALL_DELETE_PROFILE; if (change_default_browser_ && change_default_browser_->GetChecked()) { @@ -177,7 +177,7 @@ int ShowUninstallBrowserPrompt() { DCHECK(base::CurrentUIThread::IsSet()); - int result = service_manager::RESULT_CODE_NORMAL_EXIT; + int result = content::RESULT_CODE_NORMAL_EXIT; base::RunLoop run_loop; UninstallView* view = new UninstallView(&result,
diff --git a/chrome/browser/ui/views/uninstall_view_unittest.cc b/chrome/browser/ui/views/uninstall_view_unittest.cc index 23435c3c..de30ea41 100644 --- a/chrome/browser/ui/views/uninstall_view_unittest.cc +++ b/chrome/browser/ui/views/uninstall_view_unittest.cc
@@ -7,7 +7,6 @@ #include "base/bind_helpers.h" #include "chrome/common/chrome_result_codes.h" #include "chrome/test/views/chrome_views_test_base.h" -#include "services/service_manager/embedder/result_codes.h" #include "testing/gtest/include/gtest/gtest.h" using UninstallViewTest = ChromeViewsTestBase; @@ -16,7 +15,7 @@ int result = -1; UninstallView view(&result, base::DoNothing()); view.Accept(); - EXPECT_EQ(result, service_manager::RESULT_CODE_NORMAL_EXIT); + EXPECT_EQ(result, content::RESULT_CODE_NORMAL_EXIT); } TEST_F(UninstallViewTest, Cancel) {
diff --git a/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc index ac73d17..909f06c 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.cc
@@ -52,7 +52,8 @@ void RefreshQRCode(base::span<const uint8_t> new_qr_data) { state_ = (state_ + 1) % 6; - base::Optional<QRCode::GeneratedCode> code = qr_.Generate(new_qr_data); + base::Optional<QRCode::GeneratedCode> code = + qr_.Generate(new_qr_data, /*mask=*/state_); DCHECK(code); qr_tiles_ = code->data; SchedulePaint();
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom b/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom index 9cc063d..6ade08d 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom
@@ -384,6 +384,8 @@ // Logs a module impression. Called when a module is loaded and can be seen by // the user (scrolled into view). OnModuleImpression(string module_id, double time); + // Logs when a module is loaded with data. + OnModuleLoaded(string module_id, double time); // Logs when a user interacts with a module which will result in a navigation. OnModuleUsage(string module_id); // Logs that the modules have been shown at |time|.
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc index 409c360..07652c01 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
@@ -936,6 +936,12 @@ module_id, base::Time::FromJsTime(time) - ntp_navigation_start_time_); } +void NewTabPageHandler::OnModuleLoaded(const std::string& module_id, + double time) { + logger_->LogModuleLoaded( + module_id, base::Time::FromJsTime(time) - ntp_navigation_start_time_); +} + void NewTabPageHandler::OnModuleUsage(const std::string& module_id) { logger_->LogModuleUsage(module_id); }
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h index 6b99d825..0ab0bd0 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h
@@ -125,6 +125,7 @@ new_tab_page::mojom::VoiceSearchAction action) override; void OnVoiceSearchError(new_tab_page::mojom::VoiceSearchError error) override; void OnModuleImpression(const std::string& module_id, double time) override; + void OnModuleLoaded(const std::string& module_id, double time) override; void OnModuleUsage(const std::string& module_id) override; void OnModulesRendered(double time) override; void QueryAutocomplete(const base::string16& input,
diff --git a/chrome/browser/user_education/java/src/org/chromium/chrome/browser/user_education/OWNERS b/chrome/browser/user_education/OWNERS similarity index 100% rename from chrome/browser/user_education/java/src/org/chromium/chrome/browser/user_education/OWNERS rename to chrome/browser/user_education/OWNERS
diff --git a/chrome/browser/video_tutorials/internal/BUILD.gn b/chrome/browser/video_tutorials/internal/BUILD.gn index 60e73fbf..1dab91ec 100644 --- a/chrome/browser/video_tutorials/internal/BUILD.gn +++ b/chrome/browser/video_tutorials/internal/BUILD.gn
@@ -140,13 +140,18 @@ # Skip platform checks since Robolectric depends on requires_android targets. bypass_platform_checks = true testonly = true - sources = [ "android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediatorUnitTest.java" ] + sources = [ + "android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediatorUnitTest.java", + "android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediatorUnitTest.java", + ] + deps = [ ":java", "//base:base_java", "//base:base_junit_test_support", "//chrome/browser/video_tutorials:java", "//chrome/browser/video_tutorials:test_support_java", + "//content/public/android:content_java", "//third_party/android_deps:robolectric_all_java", "//third_party/hamcrest:hamcrest_core_java", "//third_party/junit",
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialUtils.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialUtils.java index 8326eb3..72932af 100644 --- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialUtils.java +++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialUtils.java
@@ -24,12 +24,14 @@ } private static Tutorial getNextTutorial(List<Tutorial> tutorials, Tutorial currentTutorial) { - int currentTutorialIndex = 0; + int currentIndex = 0; for (int i = 0; i < tutorials.size(); i++) { - if (tutorials.get(i).featureType == currentTutorial.featureType) break; + if (tutorials.get(i).featureType == currentTutorial.featureType) { + currentIndex = i; + break; + } } - return currentTutorialIndex < tutorials.size() - 1 ? tutorials.get(currentTutorialIndex + 1) - : null; + return currentIndex < tutorials.size() - 1 ? tutorials.get(currentIndex + 1) : null; } }
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediator.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediator.java index d70efb3..c8ca3cf 100644 --- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediator.java +++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediator.java
@@ -110,8 +110,8 @@ public void onEnded() { VideoTutorialMetrics.recordWatchStateUpdate(mTutorial.featureType, WatchState.COMPLETED); mModel.set(VideoPlayerProperties.SHOW_MEDIA_CONTROLS, true); - mModel.set(VideoPlayerProperties.SHOW_WATCH_NEXT, true); mModel.set(VideoPlayerProperties.SHOW_CHANGE_LANGUAGE, true); + maybeShowWatchNextVideoButton(); updateChangeLanguageButtonText(); VideoTutorialUtils.getNextTutorial(mVideoTutorialService, mTutorial, nextTutorial -> { @@ -158,14 +158,21 @@ private void startVideo(Tutorial tutorial) { VideoTutorialMetrics.recordWatchStateUpdate(mTutorial.featureType, WatchState.STARTED); mVideoStartTime = System.currentTimeMillis(); + mTutorial = tutorial; LoadUrlParams loadUrlParams = new LoadUrlParams(VideoPlayerURLBuilder.buildFromTutorial(tutorial)); loadUrlParams.setHasUserGesture(true); mWebContents.getNavigationController().loadUrl(loadUrlParams); - mModel.set(VideoPlayerProperties.SHOW_LOADING_SCREEN, false); + mModel.set(VideoPlayerProperties.SHOW_LOADING_SCREEN, true); mModel.set(VideoPlayerProperties.SHOW_MEDIA_CONTROLS, false); } + private void maybeShowWatchNextVideoButton() { + VideoTutorialUtils.getNextTutorial(mVideoTutorialService, mTutorial, nextTutorial -> { + mModel.set(VideoPlayerProperties.SHOW_WATCH_NEXT, nextTutorial != null); + }); + } + private void onWatchNextClicked() { VideoTutorialMetrics.recordUserAction(mTutorial.featureType, UserAction.WATCH_NEXT_VIDEO); VideoTutorialUtils.getNextTutorial(mVideoTutorialService, mTutorial, this::startVideo);
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediatorUnitTest.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediatorUnitTest.java new file mode 100644 index 0000000..b5ea618 --- /dev/null +++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediatorUnitTest.java
@@ -0,0 +1,135 @@ +// Copyright 2020 The Chromium 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.video_tutorials.player; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.ArgumentMatchers.any; + +import android.content.Context; +import android.content.res.Resources; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import org.chromium.base.metrics.test.ShadowRecordHistogram; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.video_tutorials.Tutorial; +import org.chromium.chrome.browser.video_tutorials.languages.LanguagePickerCoordinator; +import org.chromium.chrome.browser.video_tutorials.test.TestVideoTutorialService; +import org.chromium.content_public.browser.NavigationController; +import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyObservable; + +/** + * Tests for {@link VideoPlayerMediator}. + */ +@RunWith(BaseRobolectricTestRunner.class) +public class VideoPlayerMediatorUnitTest { + private TestVideoTutorialService mTestVideoTutorialService; + private PropertyModel mModel; + private VideoPlayerMediator mMediator; + @Mock + Context mContext; + @Mock + Resources mResources; + @Mock + private LanguagePickerCoordinator mLanguagePicker; + @Mock + WebContents mWebContents; + @Mock + NavigationController mNavigationController; + @Mock + Runnable mCloseCallback; + + @Captor + ArgumentCaptor<Runnable> mLanguagePickerCallback; + @Mock + PropertyObservable.PropertyObserver<PropertyKey> mPropertyObserver; + + @Before + public void setUp() { + ShadowRecordHistogram.reset(); + MockitoAnnotations.initMocks(this); + + Mockito.doReturn(mNavigationController).when(mWebContents).getNavigationController(); + Mockito.doReturn(mResources).when(mContext).getResources(); + mModel = new PropertyModel(VideoPlayerProperties.ALL_KEYS); + mModel.addObserver(mPropertyObserver); + + mTestVideoTutorialService = new TestVideoTutorialService(); + mMediator = new VideoPlayerMediator(mContext, mModel, mTestVideoTutorialService, + mLanguagePicker, mWebContents, mCloseCallback); + } + + @Test + public void languagePickerShownFirstTime() { + mTestVideoTutorialService.setPreferredLocale(null); + Tutorial tutorial = mTestVideoTutorialService.getTestTutorials().get(0); + mMediator.playVideoTutorial(tutorial); + + assertThat(mModel.get(VideoPlayerProperties.SHOW_LANGUAGE_PICKER), equalTo(true)); + Mockito.verify(mLanguagePicker, Mockito.times(1)) + .showLanguagePicker(mLanguagePickerCallback.capture(), any()); + ((Runnable) mLanguagePickerCallback.getValue()).run(); + Mockito.verify(mNavigationController).loadUrl(any()); + } + + @Test + public void languagePickerNotShownIfPreferredLocaleSetAlready() { + mTestVideoTutorialService.setPreferredLocale(TestVideoTutorialService.ENGLISH.locale); + Tutorial tutorial = mTestVideoTutorialService.getTestTutorials().get(0); + mMediator.playVideoTutorial(tutorial); + + assertThat(mModel.get(VideoPlayerProperties.SHOW_LANGUAGE_PICKER), equalTo(false)); + Mockito.verify(mLanguagePicker, Mockito.never()).showLanguagePicker(any(), any()); + Mockito.verify(mNavigationController).loadUrl(any()); + } + + @Test + public void showLoadingScreenDuringStartup() { + Tutorial tutorial = mTestVideoTutorialService.getTestTutorials().get(0); + mMediator.playVideoTutorial(tutorial); + Mockito.verify(mNavigationController).loadUrl(any()); + assertThat(mModel.get(VideoPlayerProperties.SHOW_LOADING_SCREEN), equalTo(true)); + assertThat(mModel.get(VideoPlayerProperties.SHOW_MEDIA_CONTROLS), equalTo(false)); + + mMediator.onPlay(); + assertThat(mModel.get(VideoPlayerProperties.SHOW_LOADING_SCREEN), equalTo(false)); + assertThat(mModel.get(VideoPlayerProperties.SHOW_MEDIA_CONTROLS), equalTo(false)); + } + + @Test + public void verifyControlsAtPauseState() { + Tutorial tutorial = mTestVideoTutorialService.getTestTutorials().get(0); + mMediator.playVideoTutorial(tutorial); + mMediator.onPlay(); + mMediator.onPause(); + assertThat(mModel.get(VideoPlayerProperties.SHOW_MEDIA_CONTROLS), equalTo(true)); + assertThat(mModel.get(VideoPlayerProperties.SHOW_WATCH_NEXT), equalTo(false)); + assertThat(mModel.get(VideoPlayerProperties.SHOW_CHANGE_LANGUAGE), equalTo(false)); + } + + @Test + public void verifyControlsAtEndState() { + Tutorial tutorial = mTestVideoTutorialService.getTestTutorials().get(0); + mMediator.playVideoTutorial(tutorial); + mMediator.onPlay(); + assertThat(mModel.get(VideoPlayerProperties.SHOW_WATCH_NEXT), equalTo(false)); + assertThat(mModel.get(VideoPlayerProperties.SHOW_CHANGE_LANGUAGE), equalTo(false)); + + mMediator.onEnded(); + assertThat(mModel.get(VideoPlayerProperties.SHOW_WATCH_NEXT), equalTo(true)); + assertThat(mModel.get(VideoPlayerProperties.SHOW_CHANGE_LANGUAGE), equalTo(true)); + } +}
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index b90ac0ab..44651fc1 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-master-1601531335-92722dc44bbb5dcb3fdddbecff6eb0d1b4a38ee3.profdata +chrome-linux-master-1601553580-367c6f76c3cbdd1ced1ecc49db85241195c30ea6.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index e255c749..038f77e 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1601531335-6ddc6aeaa45d1043385555e19eae524fbb6fe60e.profdata +chrome-mac-master-1601553580-dedfc7e09ce8d42299369759d9da080930ec4031.profdata
diff --git a/chrome/common/extensions/api/tabs.json b/chrome/common/extensions/api/tabs.json index 6554046..fdaf5d8 100644 --- a/chrome/common/extensions/api/tabs.json +++ b/chrome/common/extensions/api/tabs.json
@@ -821,6 +821,32 @@ ] }, { + "name": "removeCSS", + "type": "function", + "description": "Removes from a page CSS that was previously injected by a call to $(ref:tabs.insertCSS).", + "parameters": [ + { + "type": "integer", + "name": "tabId", + "minimum": 0, + "optional": true, + "description": "The ID of the tab from which to remove the CSS; defaults to the active tab of the current window." + }, + { + "$ref": "extensionTypes.DeleteInjectionDetails", + "name": "details", + "description": "Details of the CSS text to remove. Either the code or the file property must be set, but both may not be set at the same time." + }, + { + "type": "function", + "name": "callback", + "optional": true, + "description": "Called when all the CSS has been removed.", + "parameters": [] + } + ] + }, + { "name": "setZoom", "type": "function", "description": "Zooms a specified tab.",
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index 762bfb9d8..bc5d7d12 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc
@@ -365,7 +365,7 @@ // box that Chrome pops up. InstallStatus IsChromeActiveOrUserCancelled( const InstallerState& installer_state) { - int32_t exit_code = service_manager::RESULT_CODE_NORMAL_EXIT; + int32_t exit_code = content::RESULT_CODE_NORMAL_EXIT; base::CommandLine options(base::CommandLine::NO_PROGRAM); options.AppendSwitch(installer::switches::kUninstall);
diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc index 2ccbf77..16cf4fe 100644 --- a/chrome/service/service_utility_process_host.cc +++ b/chrome/service/service_utility_process_host.cc
@@ -232,7 +232,7 @@ ServiceUtilityProcessHost::~ServiceUtilityProcessHost() { // We need to kill the child process when the host dies. - process_.Terminate(service_manager::RESULT_CODE_NORMAL_EXIT, false); + process_.Terminate(content::RESULT_CODE_NORMAL_EXIT, false); } bool ServiceUtilityProcessHost::StartRenderPDFPagesToMetafile(
diff --git a/chrome/services/sharing/nearby/nearby_connections.cc b/chrome/services/sharing/nearby/nearby_connections.cc index 2983648..0007c57 100644 --- a/chrome/services/sharing/nearby/nearby_connections.cc +++ b/chrome/services/sharing/nearby/nearby_connections.cc
@@ -154,37 +154,6 @@ // Note: |this| might be destroyed here. } -network::mojom::P2PSocketManager* -NearbyConnections::GetWebRtcP2PSocketManager() { - if (!socket_manager_.is_bound()) - return nullptr; - - return socket_manager_.get(); -} - -network::mojom::MdnsResponder* NearbyConnections::GetWebRtcMdnsResponder() { - if (!mdns_responder_.is_bound()) - return nullptr; - - return mdns_responder_.get(); -} - -sharing::mojom::IceConfigFetcher* -NearbyConnections::GetWebRtcIceConfigFetcher() { - if (!ice_config_fetcher_.is_bound()) - return nullptr; - - return ice_config_fetcher_.get(); -} - -sharing::mojom::WebRtcSignalingMessenger* -NearbyConnections::GetWebRtcSignalingMessenger() { - if (!webrtc_signaling_messenger_.is_bound()) - return nullptr; - - return webrtc_signaling_messenger_.get(); -} - void NearbyConnections::StartAdvertising( const std::vector<uint8_t>& endpoint_info, const std::string& service_id,
diff --git a/chrome/services/sharing/nearby/nearby_connections.h b/chrome/services/sharing/nearby/nearby_connections.h index 0e7fa3b..3b00022 100644 --- a/chrome/services/sharing/nearby/nearby_connections.h +++ b/chrome/services/sharing/nearby/nearby_connections.h
@@ -66,10 +66,22 @@ return bluetooth_adapter_; } - network::mojom::P2PSocketManager* GetWebRtcP2PSocketManager(); - network::mojom::MdnsResponder* GetWebRtcMdnsResponder(); - sharing::mojom::IceConfigFetcher* GetWebRtcIceConfigFetcher(); - sharing::mojom::WebRtcSignalingMessenger* GetWebRtcSignalingMessenger(); + const mojo::SharedRemote<network::mojom::P2PSocketManager>& socket_manager() + const { + return socket_manager_; + } + const mojo::SharedRemote<network::mojom::MdnsResponder>& mdns_responder() + const { + return mdns_responder_; + } + const mojo::SharedRemote<sharing::mojom::IceConfigFetcher>& + ice_config_fetcher() const { + return ice_config_fetcher_; + } + const mojo::SharedRemote<sharing::mojom::WebRtcSignalingMessenger>& + webrtc_signaling_messenger() const { + return webrtc_signaling_messenger_; + } // mojom::NearbyConnections: void StartAdvertising(
diff --git a/chrome/services/sharing/nearby/platform.cc b/chrome/services/sharing/nearby/platform.cc index 8b219c1..b48744df 100644 --- a/chrome/services/sharing/nearby/platform.cc +++ b/chrome/services/sharing/nearby/platform.cc
@@ -175,17 +175,19 @@ std::unique_ptr<WebRtcMedium> ImplementationPlatform::CreateWebRtcMedium() { auto& connections = connections::NearbyConnections::GetInstance(); - network::mojom::P2PSocketManager* socket_manager = - connections.GetWebRtcP2PSocketManager(); - network::mojom::MdnsResponder* mdns_responder = - connections.GetWebRtcMdnsResponder(); - sharing::mojom::IceConfigFetcher* ice_config_fetcher = - connections.GetWebRtcIceConfigFetcher(); - sharing::mojom::WebRtcSignalingMessenger* messenger = - connections.GetWebRtcSignalingMessenger(); + const mojo::SharedRemote<network::mojom::P2PSocketManager>& socket_manager = + connections.socket_manager(); + const mojo::SharedRemote<network::mojom::MdnsResponder>& mdns_responder = + connections.mdns_responder(); + const mojo::SharedRemote<sharing::mojom::IceConfigFetcher>& + ice_config_fetcher = connections.ice_config_fetcher(); + const mojo::SharedRemote<sharing::mojom::WebRtcSignalingMessenger>& + messenger = connections.webrtc_signaling_messenger(); - if (!socket_manager || !mdns_responder || !ice_config_fetcher || !messenger) + if (!socket_manager.is_bound() || !mdns_responder.is_bound() || + !ice_config_fetcher.is_bound() || !messenger.is_bound()) { return nullptr; + } return std::make_unique<chrome::WebRtcMedium>( socket_manager, mdns_responder, ice_config_fetcher, messenger,
diff --git a/chrome/services/sharing/nearby/platform_v2/webrtc.cc b/chrome/services/sharing/nearby/platform_v2/webrtc.cc index 1e195511..68f5c27 100644 --- a/chrome/services/sharing/nearby/platform_v2/webrtc.cc +++ b/chrome/services/sharing/nearby/platform_v2/webrtc.cc
@@ -86,7 +86,8 @@ WebRtcSignalingMessengerImpl( const std::string& self_id, - sharing::mojom::WebRtcSignalingMessenger* messenger) + const mojo::SharedRemote<sharing::mojom::WebRtcSignalingMessenger>& + messenger) : self_id_(self_id), messenger_(messenger) {} ~WebRtcSignalingMessengerImpl() override = default; @@ -145,7 +146,7 @@ } std::string self_id_; - sharing::mojom::WebRtcSignalingMessenger* messenger_; + mojo::SharedRemote<sharing::mojom::WebRtcSignalingMessenger> messenger_; mojo::Receiver<sharing::mojom::IncomingMessagesListener> incoming_messages_receiver_{this}; OnSignalingMessageCallback signaling_message_callback_; @@ -156,16 +157,24 @@ } // namespace WebRtcMedium::WebRtcMedium( - network::mojom::P2PSocketManager* socket_manager, - network::mojom::MdnsResponder* mdns_responder, - sharing::mojom::IceConfigFetcher* ice_config_fetcher, - sharing::mojom::WebRtcSignalingMessenger* webrtc_signaling_messenger, + const mojo::SharedRemote<network::mojom::P2PSocketManager>& socket_manager, + const mojo::SharedRemote<network::mojom::MdnsResponder>& mdns_responder, + const mojo::SharedRemote<sharing::mojom::IceConfigFetcher>& + ice_config_fetcher, + const mojo::SharedRemote<sharing::mojom::WebRtcSignalingMessenger>& + webrtc_signaling_messenger, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : p2p_socket_manager_(socket_manager), mdns_responder_(mdns_responder), ice_config_fetcher_(ice_config_fetcher), webrtc_signaling_messenger_(webrtc_signaling_messenger), - task_runner_(std::move(task_runner)) {} + task_runner_(std::move(task_runner)) { + DCHECK(p2p_socket_manager_.is_bound()); + DCHECK(mdns_responder_.is_bound()); + DCHECK(ice_config_fetcher_.is_bound()); + DCHECK(webrtc_signaling_messenger_.is_bound()); +} + WebRtcMedium::~WebRtcMedium() = default; void WebRtcMedium::CreatePeerConnection(
diff --git a/chrome/services/sharing/nearby/platform_v2/webrtc.h b/chrome/services/sharing/nearby/platform_v2/webrtc.h index 1870eb9dd..7c092d5 100644 --- a/chrome/services/sharing/nearby/platform_v2/webrtc.h +++ b/chrome/services/sharing/nearby/platform_v2/webrtc.h
@@ -12,6 +12,7 @@ #include "base/single_thread_task_runner.h" #include "chrome/services/sharing/public/mojom/webrtc.mojom.h" #include "chrome/services/sharing/public/mojom/webrtc_signaling_messenger.mojom.h" +#include "mojo/public/cpp/bindings/shared_remote.h" #include "services/network/public/mojom/mdns_responder.mojom.h" #include "services/network/public/mojom/p2p.mojom.h" #include "third_party/abseil-cpp/absl/strings/string_view.h" @@ -30,10 +31,13 @@ using PeerConnectionCallback = api::WebRtcMedium::PeerConnectionCallback; WebRtcMedium( - network::mojom::P2PSocketManager* socket_manager, - network::mojom::MdnsResponder* mdns_responder, - sharing::mojom::IceConfigFetcher* ice_config_fetcher, - sharing::mojom::WebRtcSignalingMessenger* webrtc_signaling_messenger, + const mojo::SharedRemote<network::mojom::P2PSocketManager>& + socket_manager, + const mojo::SharedRemote<network::mojom::MdnsResponder>& mdns_responder, + const mojo::SharedRemote<sharing::mojom::IceConfigFetcher>& + ice_config_fetcher, + const mojo::SharedRemote<sharing::mojom::WebRtcSignalingMessenger>& + webrtc_signaling_messenger, scoped_refptr<base::SingleThreadTaskRunner> task_runner); ~WebRtcMedium() override; @@ -51,10 +55,11 @@ PeerConnectionCallback callback, std::vector<sharing::mojom::IceServerPtr> ice_servers); - network::mojom::P2PSocketManager* p2p_socket_manager_; - network::mojom::MdnsResponder* mdns_responder_; - sharing::mojom::IceConfigFetcher* ice_config_fetcher_; - sharing::mojom::WebRtcSignalingMessenger* webrtc_signaling_messenger_; + mojo::SharedRemote<network::mojom::P2PSocketManager> p2p_socket_manager_; + mojo::SharedRemote<network::mojom::MdnsResponder> mdns_responder_; + mojo::SharedRemote<sharing::mojom::IceConfigFetcher> ice_config_fetcher_; + mojo::SharedRemote<sharing::mojom::WebRtcSignalingMessenger> + webrtc_signaling_messenger_; std::unique_ptr<sharing::IpcPacketSocketFactory> socket_factory_;
diff --git a/chrome/services/sharing/nearby/platform_v2/webrtc_test.cc b/chrome/services/sharing/nearby/platform_v2/webrtc_test.cc index 11f077e..82ea764 100644 --- a/chrome/services/sharing/nearby/platform_v2/webrtc_test.cc +++ b/chrome/services/sharing/nearby/platform_v2/webrtc_test.cc
@@ -7,7 +7,7 @@ #include "base/test/task_environment.h" #include "chrome/services/sharing/nearby/test_support/mock_webrtc_dependencies.h" #include "mojo/public/cpp/bindings/receiver.h" -#include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/bindings/shared_remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -47,10 +47,10 @@ ice_config_fetcher_( mojo_impl_.ice_config_fetcher_.BindNewPipeAndPassRemote()), messenger_(mojo_impl_.messenger_.BindNewPipeAndPassRemote()), - webrtc_medium_(socket_manager_.get(), - mdns_responder_.get(), - ice_config_fetcher_.get(), - messenger_.get(), + webrtc_medium_(socket_manager_, + mdns_responder_, + ice_config_fetcher_, + messenger_, base::ThreadTaskRunnerHandle::Get()) {} ~WebRtcMediumTest() override { @@ -69,10 +69,10 @@ base::test::SingleThreadTaskEnvironment task_environment_; testing::NiceMock<sharing::MockWebRtcDependencies> mojo_impl_; - mojo::Remote<network::mojom::P2PSocketManager> socket_manager_; - mojo::Remote<network::mojom::MdnsResponder> mdns_responder_; - mojo::Remote<sharing::mojom::IceConfigFetcher> ice_config_fetcher_; - mojo::Remote<sharing::mojom::WebRtcSignalingMessenger> messenger_; + mojo::SharedRemote<network::mojom::P2PSocketManager> socket_manager_; + mojo::SharedRemote<network::mojom::MdnsResponder> mdns_responder_; + mojo::SharedRemote<sharing::mojom::IceConfigFetcher> ice_config_fetcher_; + mojo::SharedRemote<sharing::mojom::WebRtcSignalingMessenger> messenger_; WebRtcMedium webrtc_medium_; };
diff --git a/chrome/services/sharing/webrtc/ipc_network_manager.cc b/chrome/services/sharing/webrtc/ipc_network_manager.cc index 5d71d364..a0dc2b7 100644 --- a/chrome/services/sharing/webrtc/ipc_network_manager.cc +++ b/chrome/services/sharing/webrtc/ipc_network_manager.cc
@@ -45,10 +45,11 @@ } // namespace IpcNetworkManager::IpcNetworkManager( - network::mojom::P2PSocketManager* socket_manager, + const mojo::SharedRemote<network::mojom::P2PSocketManager>& socket_manager, std::unique_ptr<webrtc::MdnsResponderInterface> mdns_responder) : p2p_socket_manager_(socket_manager), mdns_responder_(std::move(mdns_responder)) { + DCHECK(p2p_socket_manager_.is_bound()); p2p_socket_manager_->StartNetworkNotifications( network_notification_client_receiver_.BindNewPipeAndPassRemote()); }
diff --git a/chrome/services/sharing/webrtc/ipc_network_manager.h b/chrome/services/sharing/webrtc/ipc_network_manager.h index fb6963b..a8b80bc 100644 --- a/chrome/services/sharing/webrtc/ipc_network_manager.h +++ b/chrome/services/sharing/webrtc/ipc_network_manager.h
@@ -9,6 +9,7 @@ #include "base/memory/weak_ptr.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/shared_remote.h" #include "net/base/ip_address.h" #include "net/base/network_interfaces.h" #include "services/network/public/mojom/p2p.mojom.h" @@ -28,7 +29,8 @@ public network::mojom::P2PNetworkNotificationClient { public: IpcNetworkManager( - network::mojom::P2PSocketManager* socket_manager, + const mojo::SharedRemote<network::mojom::P2PSocketManager>& + socket_manager, std::unique_ptr<webrtc::MdnsResponderInterface> mdns_responder); IpcNetworkManager(const IpcNetworkManager&) = delete; IpcNetworkManager& operator=(const IpcNetworkManager&) = delete; @@ -48,7 +50,7 @@ private: void SendNetworksChangedSignal(); - network::mojom::P2PSocketManager* p2p_socket_manager_; + mojo::SharedRemote<network::mojom::P2PSocketManager> p2p_socket_manager_; std::unique_ptr<webrtc::MdnsResponderInterface> mdns_responder_; int start_count_ = 0; bool network_list_received_ = false;
diff --git a/chrome/services/sharing/webrtc/ipc_packet_socket_factory.cc b/chrome/services/sharing/webrtc/ipc_packet_socket_factory.cc index ad1d8ee..81f56f4 100644 --- a/chrome/services/sharing/webrtc/ipc_packet_socket_factory.cc +++ b/chrome/services/sharing/webrtc/ipc_packet_socket_factory.cc
@@ -203,7 +203,8 @@ class AsyncAddressResolverImpl : public rtc::AsyncResolverInterface { public: explicit AsyncAddressResolverImpl( - network::mojom::P2PSocketManager* socket_manager); + const mojo::SharedRemote<network::mojom::P2PSocketManager>& + socket_manager); ~AsyncAddressResolverImpl() override; // rtc::AsyncResolverInterface interface. @@ -615,7 +616,7 @@ } AsyncAddressResolverImpl::AsyncAddressResolverImpl( - network::mojom::P2PSocketManager* socket_manager) + const mojo::SharedRemote<network::mojom::P2PSocketManager>& socket_manager) : resolver_(socket_manager) {} AsyncAddressResolverImpl::~AsyncAddressResolverImpl() { @@ -681,10 +682,11 @@ } // namespace IpcPacketSocketFactory::IpcPacketSocketFactory( - network::mojom::P2PSocketManager* socket_manager, + const mojo::SharedRemote<network::mojom::P2PSocketManager>& socket_manager, const net::NetworkTrafficAnnotationTag& traffic_annotation) - : socket_manager_(socket_manager), - traffic_annotation_(traffic_annotation) {} + : socket_manager_(socket_manager), traffic_annotation_(traffic_annotation) { + DCHECK(socket_manager_.is_bound()); +} IpcPacketSocketFactory::~IpcPacketSocketFactory() = default;
diff --git a/chrome/services/sharing/webrtc/ipc_packet_socket_factory.h b/chrome/services/sharing/webrtc/ipc_packet_socket_factory.h index be4916a..63f0efd 100644 --- a/chrome/services/sharing/webrtc/ipc_packet_socket_factory.h +++ b/chrome/services/sharing/webrtc/ipc_packet_socket_factory.h
@@ -5,6 +5,7 @@ #ifndef CHROME_SERVICES_SHARING_WEBRTC_IPC_PACKET_SOCKET_FACTORY_H_ #define CHROME_SERVICES_SHARING_WEBRTC_IPC_PACKET_SOCKET_FACTORY_H_ +#include "mojo/public/cpp/bindings/shared_remote.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/public/mojom/p2p.mojom.h" #include "third_party/webrtc/api/packet_socket_factory.h" @@ -21,7 +22,8 @@ class IpcPacketSocketFactory : public rtc::PacketSocketFactory { public: IpcPacketSocketFactory( - network::mojom::P2PSocketManager* socket_manager, + const mojo::SharedRemote<network::mojom::P2PSocketManager>& + socket_manager, const net::NetworkTrafficAnnotationTag& traffic_annotation); IpcPacketSocketFactory(const IpcPacketSocketFactory&) = delete; IpcPacketSocketFactory& operator=(const IpcPacketSocketFactory&) = delete; @@ -45,7 +47,7 @@ rtc::AsyncResolverInterface* CreateAsyncResolver() override; private: - network::mojom::P2PSocketManager* socket_manager_; + mojo::SharedRemote<network::mojom::P2PSocketManager> socket_manager_; const net::NetworkTrafficAnnotationTag traffic_annotation_; };
diff --git a/chrome/services/sharing/webrtc/mdns_responder_adapter.cc b/chrome/services/sharing/webrtc/mdns_responder_adapter.cc index 83a41f02..ee08f31 100644 --- a/chrome/services/sharing/webrtc/mdns_responder_adapter.cc +++ b/chrome/services/sharing/webrtc/mdns_responder_adapter.cc
@@ -36,8 +36,10 @@ } // namespace MdnsResponderAdapter::MdnsResponderAdapter( - network::mojom::MdnsResponder* mdns_responder) - : mdns_responder_(mdns_responder) {} + const mojo::SharedRemote<network::mojom::MdnsResponder>& mdns_responder) + : mdns_responder_(mdns_responder) { + DCHECK(mdns_responder_.is_bound()); +} MdnsResponderAdapter::~MdnsResponderAdapter() = default;
diff --git a/chrome/services/sharing/webrtc/mdns_responder_adapter.h b/chrome/services/sharing/webrtc/mdns_responder_adapter.h index f8abd9ee..cdd5324 100644 --- a/chrome/services/sharing/webrtc/mdns_responder_adapter.h +++ b/chrome/services/sharing/webrtc/mdns_responder_adapter.h
@@ -6,6 +6,7 @@ #define CHROME_SERVICES_SHARING_WEBRTC_MDNS_RESPONDER_ADAPTER_H_ #include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/bindings/shared_remote.h" #include "services/network/public/mojom/mdns_responder.mojom.h" #include "third_party/webrtc/rtc_base/mdns_responder_interface.h" @@ -21,7 +22,8 @@ // TODO(crbug.com/1044522): reuse code from blink instead. class MdnsResponderAdapter : public webrtc::MdnsResponderInterface { public: - explicit MdnsResponderAdapter(network::mojom::MdnsResponder* mdns_responder); + explicit MdnsResponderAdapter( + const mojo::SharedRemote<network::mojom::MdnsResponder>& mdns_responder); MdnsResponderAdapter(const MdnsResponderAdapter&) = delete; MdnsResponderAdapter& operator=(const MdnsResponderAdapter&) = delete; ~MdnsResponderAdapter() override; @@ -33,7 +35,7 @@ NameRemovedCallback callback) override; private: - network::mojom::MdnsResponder* mdns_responder_; + mojo::SharedRemote<network::mojom::MdnsResponder> mdns_responder_; }; } // namespace sharing
diff --git a/chrome/services/sharing/webrtc/p2p_async_address_resolver.cc b/chrome/services/sharing/webrtc/p2p_async_address_resolver.cc index 66c65c85..2133cb97 100644 --- a/chrome/services/sharing/webrtc/p2p_async_address_resolver.cc +++ b/chrome/services/sharing/webrtc/p2p_async_address_resolver.cc
@@ -14,8 +14,10 @@ namespace sharing { P2PAsyncAddressResolver::P2PAsyncAddressResolver( - network::mojom::P2PSocketManager* socket_manager) - : socket_manager_(socket_manager), state_(STATE_CREATED) {} + const mojo::SharedRemote<network::mojom::P2PSocketManager>& socket_manager) + : socket_manager_(socket_manager), state_(STATE_CREATED) { + DCHECK(socket_manager_.is_bound()); +} P2PAsyncAddressResolver::~P2PAsyncAddressResolver() { DCHECK(state_ == STATE_CREATED || state_ == STATE_FINISHED);
diff --git a/chrome/services/sharing/webrtc/p2p_async_address_resolver.h b/chrome/services/sharing/webrtc/p2p_async_address_resolver.h index 30740df5..d3e8962 100644 --- a/chrome/services/sharing/webrtc/p2p_async_address_resolver.h +++ b/chrome/services/sharing/webrtc/p2p_async_address_resolver.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/threading/thread_checker.h" +#include "mojo/public/cpp/bindings/shared_remote.h" #include "net/base/ip_address.h" #include "services/network/public/mojom/p2p.mojom.h" #include "third_party/webrtc/rtc_base/async_resolver_interface.h" @@ -25,7 +26,8 @@ base::OnceCallback<void(const std::vector<net::IPAddress>&)>; explicit P2PAsyncAddressResolver( - network::mojom::P2PSocketManager* socket_manager); + const mojo::SharedRemote<network::mojom::P2PSocketManager>& + socket_manager); P2PAsyncAddressResolver(const P2PAsyncAddressResolver&) = delete; P2PAsyncAddressResolver& operator=(const P2PAsyncAddressResolver&) = delete; ~P2PAsyncAddressResolver(); @@ -44,7 +46,7 @@ void OnResponse(const std::vector<net::IPAddress>& address); - network::mojom::P2PSocketManager* socket_manager_; + mojo::SharedRemote<network::mojom::P2PSocketManager> socket_manager_; THREAD_CHECKER(thread_checker_);
diff --git a/chrome/services/sharing/webrtc/p2p_socket_client.cc b/chrome/services/sharing/webrtc/p2p_socket_client.cc index 9428b2e6..23f239fd 100644 --- a/chrome/services/sharing/webrtc/p2p_socket_client.cc +++ b/chrome/services/sharing/webrtc/p2p_socket_client.cc
@@ -25,7 +25,7 @@ namespace sharing { P2PSocketClient::P2PSocketClient( - network::mojom::P2PSocketManager* socket_manager, + const mojo::SharedRemote<network::mojom::P2PSocketManager>& socket_manager, const net::NetworkTrafficAnnotationTag& traffic_annotation) : socket_manager_(socket_manager), socket_id_(0), @@ -34,6 +34,7 @@ traffic_annotation_(traffic_annotation), random_socket_id_(0), next_packet_id_(0) { + DCHECK(socket_manager_.is_bound()); crypto::RandBytes(&random_socket_id_, sizeof(random_socket_id_)); }
diff --git a/chrome/services/sharing/webrtc/p2p_socket_client.h b/chrome/services/sharing/webrtc/p2p_socket_client.h index 44d40d1..5c8b8458 100644 --- a/chrome/services/sharing/webrtc/p2p_socket_client.h +++ b/chrome/services/sharing/webrtc/p2p_socket_client.h
@@ -12,6 +12,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/bindings/shared_remote.h" #include "net/base/ip_endpoint.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/public/cpp/p2p_socket_type.h" @@ -30,7 +31,8 @@ // TODO(crbug.com/1044522): reuse code from blink instead. class P2PSocketClient : public network::mojom::P2PSocketClient { public: - P2PSocketClient(network::mojom::P2PSocketManager* socket_manager, + P2PSocketClient(const mojo::SharedRemote<network::mojom::P2PSocketManager>& + socket_manager, const net::NetworkTrafficAnnotationTag& traffic_annotation); P2PSocketClient(const P2PSocketClient&) = delete; P2PSocketClient& operator=(const P2PSocketClient&) = delete; @@ -94,7 +96,7 @@ void OnConnectionError(); - network::mojom::P2PSocketManager* socket_manager_; + mojo::SharedRemote<network::mojom::P2PSocketManager> socket_manager_; THREAD_CHECKER(thread_checker_); int socket_id_; P2PSocketClientDelegate* delegate_;
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java index 988cfb5..7ed91bff 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/AccountManagerTestRule.java
@@ -178,7 +178,8 @@ @Nullable ProfileSyncService profileSyncService) { assert !mIsSignedIn : "An account is already signed in!"; Account account = addAccountAndWaitForSeeding(TEST_ACCOUNT_EMAIL); - SigninTestUtil.signinAndEnableSync(account, profileSyncService); + CoreAccountInfo coreAccountInfo = toCoreAccountInfo(account.name); + SigninTestUtil.signinAndEnableSync(coreAccountInfo, profileSyncService); mIsSignedIn = true; return account; }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java index 3f9b2bdb..a4299e1 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java
@@ -82,14 +82,14 @@ * @param profileSyncService Enable the sync with it if it is not null. */ public static void signinAndEnableSync( - Account account, @Nullable ProfileSyncService profileSyncService) { + CoreAccountInfo coreAccountInfo, @Nullable ProfileSyncService profileSyncService) { CallbackHelper callbackHelper = new CallbackHelper(); TestThreadUtils.runOnUiThreadBlocking(() -> { SigninManager signinManager = IdentityServicesProvider.get().getSigninManager( Profile.getLastUsedRegularProfile()); signinManager.onFirstRunCheckDone(); // Allow sign-in signinManager.signinAndEnableSync( - SigninAccessPoint.UNKNOWN, account, new SigninManager.SignInCallback() { + SigninAccessPoint.UNKNOWN, coreAccountInfo, new SigninManager.SignInCallback() { @Override public void onSignInComplete() { if (profileSyncService != null) { @@ -111,11 +111,10 @@ throw new RuntimeException("Timed out waiting for callback", e); } TestThreadUtils.runOnUiThreadBlocking(() -> { - Assert.assertEquals(account.name, + Assert.assertEquals(coreAccountInfo, IdentityServicesProvider.get() .getIdentityManager(Profile.getLastUsedRegularProfile()) - .getPrimaryAccountInfo(ConsentLevel.SYNC) - .getEmail()); + .getPrimaryAccountInfo(ConsentLevel.SYNC)); }); }
diff --git a/chrome/test/data/extensions/api_test/executescript/remove_css/content.js b/chrome/test/data/extensions/api_test/executescript/remove_css/content.js new file mode 100644 index 0000000..a37cb6d --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/remove_css/content.js
@@ -0,0 +1,12 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +'use strict'; + +chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + let element = document.getElementById('main'); + let style = getComputedStyle(element); + let color = style.getPropertyValue('color'); + sendResponse(color); +});
diff --git a/chrome/test/data/extensions/api_test/executescript/remove_css/file.css b/chrome/test/data/extensions/api_test/executescript/remove_css/file.css new file mode 100644 index 0000000..729bc83 --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/remove_css/file.css
@@ -0,0 +1,7 @@ +/* Copyright 2020 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +#main { + color: green !important; +}
diff --git a/chrome/test/data/extensions/api_test/executescript/remove_css/frame1.html b/chrome/test/data/extensions/api_test/executescript/remove_css/frame1.html new file mode 100644 index 0000000..e366406 --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/remove_css/frame1.html
@@ -0,0 +1,11 @@ +<html> + <style> + #main { + color: red; + } + </style> + <div id="main"> + Hello. + </div> + <iframe id="frame2" src="frame2.html"></iframe> +</html>
diff --git a/chrome/test/data/extensions/api_test/executescript/remove_css/frame2.html b/chrome/test/data/extensions/api_test/executescript/remove_css/frame2.html new file mode 100644 index 0000000..c6ab9ba --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/remove_css/frame2.html
@@ -0,0 +1,11 @@ +<html> + <style> + #main { + color: red; + } + </style> + <div id="main"> + Hello. + </div> + <iframe id="frame3" src="frame3.html"></iframe> +</html>
diff --git a/chrome/test/data/extensions/api_test/executescript/remove_css/frame3.html b/chrome/test/data/extensions/api_test/executescript/remove_css/frame3.html new file mode 100644 index 0000000..70d813f7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/remove_css/frame3.html
@@ -0,0 +1,11 @@ +<html> + <style> + #main { + color: red; + } + </style> + <div id="main"> + Hello. + </div> + <iframe id="frame4" srcdoc="<style>#main{color:red}</style><div id='main'>Hello.</div>"></iframe> +</html>
diff --git a/chrome/test/data/extensions/api_test/executescript/remove_css/manifest.json b/chrome/test/data/extensions/api_test/executescript/remove_css/manifest.json new file mode 100644 index 0000000..b70bdc3 --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/remove_css/manifest.json
@@ -0,0 +1,18 @@ +{ + "version": "1.0.0.0", + "manifest_version": 2, + "name": "removeCSS test", + "description": "Test extension API: removeCSS", + "background": { + "scripts": ["test.js"] + }, + "permissions": ["tabs", "webNavigation", "http://example.com/"], + "content_scripts": [ + { + "matches": ["http://*/*"], + "js": ["content.js"], + "all_frames": true, + "match_about_blank": true + } + ] +}
diff --git a/chrome/test/data/extensions/api_test/executescript/remove_css/other.css b/chrome/test/data/extensions/api_test/executescript/remove_css/other.css new file mode 100644 index 0000000..729bc83 --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/remove_css/other.css
@@ -0,0 +1,7 @@ +/* Copyright 2020 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +#main { + color: green !important; +}
diff --git a/chrome/test/data/extensions/api_test/executescript/remove_css/test.html b/chrome/test/data/extensions/api_test/executescript/remove_css/test.html new file mode 100644 index 0000000..6a501cf --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/remove_css/test.html
@@ -0,0 +1,11 @@ +<html> + <style> + #main { + color: red; + } + </style> + <div id="main"> + Hello. + </div> + <iframe id="frame1" src="frame1.html"></iframe> +</html>
diff --git a/chrome/test/data/extensions/api_test/executescript/remove_css/test.js b/chrome/test/data/extensions/api_test/executescript/remove_css/test.js new file mode 100644 index 0000000..a48449d --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/remove_css/test.js
@@ -0,0 +1,182 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +'use strict'; + +// Original color. +const originalColor = 'rgb(255, 0, 0)'; // red + +// Injected color. +const injectedColor = 'rgb(0, 128, 0)'; // green + +// Second injected color. +const injectedColor2 = 'rgb(255, 255, 0)'; // yellow + +// CSS to inject. +const code = '#main { color: green !important; }'; +const file = '/file.css'; + +function getFrameIds(tabId, callback) { + chrome.webNavigation.getAllFrames({tabId}, frames => { + let sortedFrames = frames.sort( + (a, b) => a.frameId < b.frameId ? -1 : a.frameId > b.frameId ? 1 : 0); + + // We make some assumptions about the frames returned. + chrome.test.assertEq(5, sortedFrames.length); + chrome.test.assertEq(sortedFrames[0].frameId, 0 /*main frame id*/); + chrome.test.assertTrue( + sortedFrames[1].frameId > 0 /* first non-main-frame id */); + // We rely on the about:srcdoc being in index 4. + // Currently this works because of the way frames are returned; + // if that changes, we could filter to find the correct frames. + chrome.test.assertEq('about:srcdoc', sortedFrames[4].url); + + callback(sortedFrames.map(frame => frame.frameId)); + }); +} + +// Helper called with either chrome.tab.insertCSS or chrome.tab.removeCSS +// as 'apiFunction'. +// +// 'details': Details of the CSS text to insert or remove. +// 'colorStateDelta': Delta of the expected value changes after 'apiFuncion' +// is called. +function makeCSSTester(apiFunction, tabId, frameIds, colorState) { + return (details, colorStateDelta = []) => { + return new Promise(resolve => { + apiFunction(tabId, details, () => { + chrome.test.assertNoLastError(); + // After the API call, modify the state with the given delta, then + // verify that the state here reflects the actual state as reported + // by the content script. + let expected = [...Object.assign(colorState, colorStateDelta)]; + let pending = []; + for (let frameId of frameIds) { + pending.push(new Promise(messageResolve => { + chrome.tabs.sendMessage(tabId, {}, {frameId}, color => { + chrome.test.assertEq(expected.shift(), color); + messageResolve(); + }); + })); + } + Promise.all(pending).then(resolve); + }); + }); + }; +} + +chrome.test.getConfig(config => { + let testUrl = 'http://example.com:' + config.testServer.port + + '/extensions/api_test/executescript/remove_css/test.html'; + chrome.tabs.onUpdated.addListener(function listener(tabId, {status}) { + if (status != 'complete') + return; + chrome.tabs.onUpdated.removeListener(listener); + getFrameIds(tabId, frameIds => { + // 'colorState' holds a snapshot of expected values of the CSS properties + // being inserted/removed. + // Values gets validated at the completion of the each test below. + // + // Each frame is a child of the frame preceding it. Frames 0 through 3 + // are <iframe src="..."> while frame 4 is <iframe srcdoc="..."> + // (about:srcdoc). + let colorState = [ + originalColor, originalColor, originalColor, originalColor, + originalColor + ]; + let testInsertCSS = + makeCSSTester(chrome.tabs.insertCSS, tabId, frameIds, colorState); + let testRemoveCSS = + makeCSSTester(chrome.tabs.removeCSS, tabId, frameIds, colorState); + chrome.test.runTests([ + async function insertCSSShouldSucceed() { + await testInsertCSS({code, allFrames: true, matchAboutBlank: true}, [ + injectedColor, injectedColor, injectedColor, injectedColor, + injectedColor + ]); + chrome.test.succeed(); + }, + async function removeCSSShouldSucceed() { + // When no frame ID is specified, the CSS is removed from the top + // frame. + await testRemoveCSS({code}, [originalColor, , , , , ]); + chrome.test.succeed(); + }, + async function removeCSSWithDifferentCodeShouldDoNothing() { + // If the specified code differs by even one character, it does not + // match any inserted CSS and therefore nothing is removed. + await testRemoveCSS({code: code + ' ', frameId: frameIds[0]}); + await testRemoveCSS({code: code + ' ', frameId: frameIds[1]}); + await testRemoveCSS({code: code + ' ', frameId: frameIds[2]}); + await testRemoveCSS({code: code + ' ', frameId: frameIds[3]}); + await testRemoveCSS( + {code: code + ' ', frameId: frameIds[4], matchAboutBlank: true}); + chrome.test.succeed(); + }, + async function removeCSSWithDifferentCSSOriginShouldDoNothing() { + // If only the CSS origin differs, nothing is removed. + await testRemoveCSS({code, frameId: frameIds[1], cssOrigin: 'user'}); + chrome.test.succeed(); + }, + async function removeCSSWithFrameIdShouldSucceed() { + // When a frame ID is specified, the CSS is removed from the given + // frame. + await testRemoveCSS({code, frameId: frameIds[1]}, + [ , originalColor, , , , ]); + chrome.test.succeed(); + }, + async function removeCSSWithAllFramesShouldSucceed() { + // When "allFrames" is set to true, the CSS is removed from all + // frames that match. + // + // By default "about:blank" and "about:srcdoc" frames do not match. + await testRemoveCSS({code, allFrames: true}, + [ , , originalColor, originalColor, , ]); + chrome.test.succeed(); + }, + async function removeCSSWithMatchAboutBlankShouldSucceed() { + // When "matchAboutBlank" is set to true, the CSS is also removed + // from "about:blank" and "about:srcdoc" frames. + await testRemoveCSS( + {code, frameId: frameIds[4], matchAboutBlank: true}, + [, , , , originalColor]); + chrome.test.succeed(); + }, + async function insertCSSWithFileShouldSucceed() { + await testInsertCSS({file, allFrames: true}, + [injectedColor, injectedColor, injectedColor, injectedColor, , ]); + chrome.test.succeed(); + }, + async function removeCSSWithFileShouldSucceed() { + // When no frame ID is specified, the CSS is removed from the top + // frame. + await testRemoveCSS({file}, [originalColor, , , , , ]); + chrome.test.succeed(); + }, + async function removeCSSWithDifferentFileShouldDoNothing() { + // The CSS is not removed even though "/file.css" and "/other.css" + // are identical. + await testRemoveCSS({file: '/other.css', allFrames: true}); + chrome.test.succeed(); + }, + async function insertCSSWithDuplicateCodeShouldSucceed() { + await testInsertCSS({ code }, [injectedColor, , , , , ]) + .then(() => testInsertCSS({ code: code.replace('green', 'yellow') }, + [injectedColor2, , , , , ])) + .then(() => testInsertCSS({ code }, [injectedColor, , , , , ])); + chrome.test.succeed(); + }, + async function removeCSSWithDuplicateCodeShouldSucceed() { + await testRemoveCSS({ code }, [injectedColor2, , , , , ]) + // Only the last CSS that matches is removed. + .then(() => testRemoveCSS({ code: code.replace('green', 'yellow') }, + [injectedColor, , , , , ])) + .then(() => testRemoveCSS({ code }, [originalColor, , , , , ])); + chrome.test.succeed(); + } + ]); + }); + }); + chrome.tabs.create({url: testUrl}); +});
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test.js index 74e9f0b..c04c97d 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_test.js
@@ -173,6 +173,15 @@ fakeBatteryChargeStatus[0].power_adapter_status, dataPoints[5].value); assertEquals(fakeBatteryHealth[0].cycle_count, dataPoints[6].value); + + const barChart = diagnostics_test_utils.getPercentBarChartElement( + batteryStatusElement); + assertEquals( + fakeBatteryChargeStatus[0].charge_full_now_milliamp_hours, + barChart.max); + assertEquals( + fakeBatteryChargeStatus[0].charge_now_milliamp_hours, + barChart.value); }); }); });
diff --git a/chromecast/app/android/DEPS b/chromecast/app/android/DEPS index 01e92c2..cf43394 100644 --- a/chromecast/app/android/DEPS +++ b/chromecast/app/android/DEPS
@@ -2,5 +2,4 @@ "+chromecast/android", "+chromecast/browser/android", "+jni", - "+services/service_manager/embedder", ]
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS index 92a7011..e932f06 100644 --- a/chromecast/browser/DEPS +++ b/chromecast/browser/DEPS
@@ -58,7 +58,6 @@ "+services/media_session/public", "+services/network/public/cpp", "+services/service_manager/public", - "+services/service_manager/embedder", "+storage/browser/quota/quota_settings.h", "+third_party/blink/public/common", "+third_party/blink/public/mojom/autoplay",
diff --git a/chromecast/browser/extensions/api/tabs/tabs_api.cc b/chromecast/browser/extensions/api/tabs/tabs_api.cc index a4a4b636..68c51ed9 100644 --- a/chromecast/browser/extensions/api/tabs/tabs_api.cc +++ b/chromecast/browser/extensions/api/tabs/tabs_api.cc
@@ -761,6 +761,14 @@ return set_init_result(SUCCESS); } +bool ExecuteCodeInTabFunction::ShouldInsertCSS() const { + return false; +} + +bool ExecuteCodeInTabFunction::ShouldRemoveCSS() const { + return false; +} + bool ExecuteCodeInTabFunction::CanExecuteScriptOnPage(std::string* error) { const CastWebContents* webview = GetWebViewForTab(execute_tab_id_); if (!webview) { @@ -835,11 +843,11 @@ return GURL::EmptyGURL(); } -bool TabsExecuteScriptFunction::ShouldInsertCSS() const { - return false; +bool TabsInsertCSSFunction::ShouldInsertCSS() const { + return true; } -bool TabsInsertCSSFunction::ShouldInsertCSS() const { +bool TabsRemoveCSSFunction::ShouldRemoveCSS() const { return true; }
diff --git a/chromecast/browser/extensions/api/tabs/tabs_api.h b/chromecast/browser/extensions/api/tabs/tabs_api.h index 4243c66..ac21447 100644 --- a/chromecast/browser/extensions/api/tabs/tabs_api.h +++ b/chromecast/browser/extensions/api/tabs/tabs_api.h
@@ -189,6 +189,8 @@ // Initializes |execute_tab_id_| and |details_|. InitResult Init() override; + bool ShouldInsertCSS() const override; + bool ShouldRemoveCSS() const override; bool CanExecuteScriptOnPage(std::string* error) override; ScriptExecutor* GetScriptExecutor(std::string* error) override; bool IsWebView() const override; @@ -200,9 +202,6 @@ }; class TabsExecuteScriptFunction : public ExecuteCodeInTabFunction { - protected: - bool ShouldInsertCSS() const override; - private: ~TabsExecuteScriptFunction() override {} @@ -218,6 +217,15 @@ DECLARE_EXTENSION_FUNCTION("tabs.insertCSS", TABS_INSERTCSS) }; +class TabsRemoveCSSFunction : public ExecuteCodeInTabFunction { + private: + ~TabsRemoveCSSFunction() override {} + + bool ShouldRemoveCSS() const override; + + DECLARE_EXTENSION_FUNCTION("tabs.removeCSS", TABS_REMOVECSS) +}; + class TabsSetZoomFunction : public ExtensionFunction { private: ~TabsSetZoomFunction() override {}
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index cc0265d..a99ad50 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13500.0.0 \ No newline at end of file +13502.0.0 \ No newline at end of file
diff --git a/chromeos/components/diagnostics_ui/backend/system_data_provider.cc b/chromeos/components/diagnostics_ui/backend/system_data_provider.cc index fd3c432..b005809 100644 --- a/chromeos/components/diagnostics_ui/backend/system_data_provider.cc +++ b/chromeos/components/diagnostics_ui/backend/system_data_provider.cc
@@ -12,6 +12,8 @@ #include "base/callback.h" #include "base/optional.h" #include "chromeos/components/diagnostics_ui/backend/cros_healthd_helpers.h" +#include "chromeos/components/diagnostics_ui/backend/power_manager_client_conversions.h" +#include "chromeos/dbus/power_manager/power_supply_properties.pb.h" #include "chromeos/services/cros_healthd/public/cpp/service_connection.h" #include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h" @@ -21,6 +23,7 @@ namespace healthd = cros_healthd::mojom; using PhysicalCpuInfos = std::vector<healthd::PhysicalCpuInfoPtr>; +using PowerSupplyProperties = power_manager::PowerSupplyProperties; using ProbeCategories = healthd::ProbeCategoryEnum; void PopulateBoardName(const healthd::SystemInfo& system_info, @@ -58,10 +61,20 @@ out_system_info.total_memory_kib = memory_info.total_memory_kib; } +bool DoesDeviceHaveBattery( + const PowerSupplyProperties& power_supply_properties) { + return power_supply_properties.battery_state() != + power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT; +} + +bool DoesDeviceHaveBattery(const healthd::TelemetryInfo& telemetry_info) { + return GetBatteryInfo(telemetry_info) != nullptr; +} + void PopulateDeviceCapabilities(const healthd::TelemetryInfo& telemetry_info, mojom::SystemInfo& out_system_info) { mojom::DeviceCapabilitiesPtr capabilities = mojom::DeviceCapabilities::New(); - capabilities->has_battery = GetBatteryInfo(telemetry_info) != nullptr; + capabilities->has_battery = DoesDeviceHaveBattery(telemetry_info); out_system_info.device_capabilities = std::move(capabilities); } @@ -73,10 +86,38 @@ battery_info.charge_full_design * 1000; } +void PopulatePowerInfo(const PowerSupplyProperties& power_supply_properties, + mojom::BatteryChargeStatus& out_charge_status) { + const mojom::BatteryState battery_state = + ConvertBatteryStateFromProto(power_supply_properties.battery_state()); + + out_charge_status.battery_state = battery_state; + out_charge_status.power_time = + ConstructPowerTime(battery_state, power_supply_properties); + out_charge_status.power_adapter_status = + ConvertPowerSourceFromProto(power_supply_properties.external_power()); +} + +void PopulateBatteryChargeStatus( + const healthd::BatteryInfo& battery_info, + const PowerSupplyProperties& power_supply_properties, + mojom::BatteryChargeStatus& out_charge_status) { + PopulatePowerInfo(power_supply_properties, out_charge_status); + + // Multiply by 1000 to convert amps to milliamps. + out_charge_status.current_now_milliamps = battery_info.current_now * 1000; + out_charge_status.charge_now_milliamp_hours = battery_info.charge_now * 1000; +} + } // namespace -SystemDataProvider::SystemDataProvider() = default; -SystemDataProvider::~SystemDataProvider() = default; +SystemDataProvider::SystemDataProvider() { + PowerManagerClient::Get()->AddObserver(this); +} + +SystemDataProvider::~SystemDataProvider() { + PowerManagerClient::Get()->RemoveObserver(this); +} void SystemDataProvider::GetSystemInfo(GetSystemInfoCallback callback) { BindCrosHealthdProbeServiceIfNeccessary(); @@ -97,6 +138,15 @@ base::Unretained(this), std::move(callback))); } +void SystemDataProvider::PowerChanged(const PowerSupplyProperties& proto) { + // Fetch updated data from CrosHealthd + BindCrosHealthdProbeServiceIfNeccessary(); + probe_service_->ProbeTelemetryInfo( + {ProbeCategories::kBattery}, + base::BindOnce(&SystemDataProvider::OnBatteryChargeStatusUpdated, + base::Unretained(this), proto)); +} + void SystemDataProvider::OnSystemInfoProbeResponse( GetSystemInfoCallback callback, healthd::TelemetryInfoPtr info_ptr) { @@ -164,6 +214,58 @@ std::move(callback).Run(std::move(battery_info)); } +void SystemDataProvider::UpdateBatteryChargeStatus() { + // Fetch updated data from PowerManagerClient + base::Optional<PowerSupplyProperties> properties = + PowerManagerClient::Get()->GetLastStatus(); + + // Fetch updated data from CrosHealthd + BindCrosHealthdProbeServiceIfNeccessary(); + + probe_service_->ProbeTelemetryInfo( + {ProbeCategories::kBattery}, + base::BindOnce(&SystemDataProvider::OnBatteryChargeStatusUpdated, + base::Unretained(this), properties)); +} + +void SystemDataProvider::OnBatteryChargeStatusUpdated( + const base::Optional<PowerSupplyProperties>& power_supply_properties, + healthd::TelemetryInfoPtr info_ptr) { + mojom::BatteryChargeStatusPtr battery_charge_status = + mojom::BatteryChargeStatus::New(); + + if (info_ptr.is_null()) { + LOG(ERROR) << "Null response from croshealthd::ProbeTelemetryInfo."; + NotifyBatteryChargeStatusObservers(battery_charge_status); + return; + } + + if (!power_supply_properties.has_value()) { + LOG(ERROR) << "Null response from power_manager_client::GetLastStatus."; + NotifyBatteryChargeStatusObservers(battery_charge_status); + return; + } + + if (!DoesDeviceHaveBattery(*info_ptr) || + !DoesDeviceHaveBattery(*power_supply_properties)) { + DCHECK_EQ(DoesDeviceHaveBattery(*info_ptr), + DoesDeviceHaveBattery(*power_supply_properties)) + << "Sources should not disagree about whether there is a battery."; + NotifyBatteryChargeStatusObservers(battery_charge_status); + return; + } + + PopulateBatteryChargeStatus(*diagnostics::GetBatteryInfo(*info_ptr), + *power_supply_properties, + *battery_charge_status.get()); + NotifyBatteryChargeStatusObservers(battery_charge_status); +} + +void SystemDataProvider::NotifyBatteryChargeStatusObservers( + const mojom::BatteryChargeStatusPtr& battery_charge_status) { + NOTIMPLEMENTED(); // Implemented in subsequent CL. +} + void SystemDataProvider::BindCrosHealthdProbeServiceIfNeccessary() { if (!probe_service_ || !probe_service_.is_connected()) { cros_healthd::ServiceConnection::GetInstance()->GetProbeService(
diff --git a/chromeos/components/diagnostics_ui/backend/system_data_provider.h b/chromeos/components/diagnostics_ui/backend/system_data_provider.h index b3ed40696..9624ecd8 100644 --- a/chromeos/components/diagnostics_ui/backend/system_data_provider.h +++ b/chromeos/components/diagnostics_ui/backend/system_data_provider.h
@@ -5,14 +5,19 @@ #ifndef CHROMEOS_COMPONENTS_DIAGNOSTICS_UI_BACKEND_SYSTEM_DATA_PROVIDER_H_ #define CHROMEOS_COMPONENTS_DIAGNOSTICS_UI_BACKEND_SYSTEM_DATA_PROVIDER_H_ +#include <memory> + +#include "base/optional.h" #include "chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom.h" +#include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.h" #include "mojo/public/cpp/bindings/remote.h" namespace chromeos { namespace diagnostics { -class SystemDataProvider : public mojom::SystemDataProvider { +class SystemDataProvider : public mojom::SystemDataProvider, + public PowerManagerClient::Observer { public: SystemDataProvider(); @@ -25,6 +30,9 @@ void GetSystemInfo(GetSystemInfoCallback callback) override; void GetBatteryInfo(GetBatteryInfoCallback callback) override; + // PowerManagerClient::Observer: + void PowerChanged(const power_manager::PowerSupplyProperties& proto) override; + private: void BindCrosHealthdProbeServiceIfNeccessary(); @@ -38,6 +46,16 @@ GetBatteryInfoCallback callback, cros_healthd::mojom::TelemetryInfoPtr info_ptr); + void UpdateBatteryChargeStatus(); + + void NotifyBatteryChargeStatusObservers( + const mojom::BatteryChargeStatusPtr& battery_charge_status); + + void OnBatteryChargeStatusUpdated( + const base::Optional<power_manager::PowerSupplyProperties>& + power_supply_properties, + cros_healthd::mojom::TelemetryInfoPtr info_ptr); + mojo::Remote<cros_healthd::mojom::CrosHealthdProbeService> probe_service_; };
diff --git a/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc b/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc index 79c874c..b1b7921 100644 --- a/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc +++ b/chromeos/components/diagnostics_ui/backend/system_data_provider_unittest.cc
@@ -14,6 +14,7 @@ #include "base/time/time.h" #include "chromeos/dbus/cros_healthd/cros_healthd_client.h" #include "chromeos/dbus/cros_healthd/fake_cros_healthd_client.h" +#include "chromeos/dbus/power/fake_power_manager_client.h" #include "chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.h" #include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h" #include "testing/gtest/include/gtest/gtest.h" @@ -144,12 +145,15 @@ class SystemDataProviderTest : public testing::Test { public: SystemDataProviderTest() { + chromeos::PowerManagerClient::InitializeFake(); chromeos::CrosHealthdClient::InitializeFake(); system_data_provider_ = std::make_unique<SystemDataProvider>(); } ~SystemDataProviderTest() override { + system_data_provider_.reset(); chromeos::CrosHealthdClient::Shutdown(); + chromeos::PowerManagerClient::Shutdown(); base::RunLoop().RunUntilIdle(); }
diff --git a/chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom b/chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom index 7321abb9..1fa0693 100644 --- a/chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom +++ b/chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom
@@ -4,6 +4,8 @@ module chromeos.diagnostics.mojom; +import "mojo/public/mojom/base/string16.mojom"; + // Contains the capabilities of the device. struct DeviceCapabilities { bool has_battery; @@ -42,6 +44,17 @@ kFull, }; +// Contains information about the charging state of the battery. +struct BatteryChargeStatus { + // String containing a localized time duration. If the time is unreliable + // the string will be empty. + mojo_base.mojom.String16 power_time; + int32 current_now_milliamps; + uint32 charge_now_milliamp_hours; + BatteryState battery_state; + ExternalPowerSource power_adapter_status; +}; + // Provides telemetric information about the system. This API is exposed to the // Diagnostics SWA. interface SystemDataProvider {
diff --git a/chromeos/components/diagnostics_ui/resources/battery_status_card.html b/chromeos/components/diagnostics_ui/resources/battery_status_card.html index 35411cd..1d8c0d5 100644 --- a/chromeos/components/diagnostics_ui/resources/battery_status_card.html +++ b/chromeos/components/diagnostics_ui/resources/battery_status_card.html
@@ -27,4 +27,9 @@ <data-point slot="body" id="cycleCount" value="[[batteryHealth_.cycle_count]]"> </data-point> + <!-- TODO(joonbug): Localize once strings are confirmed --> + <percent-bar-chart slot="body" title="Remaining charge" + value="[[batteryChargeStatus_.charge_now_milliamp_hours]]" + max="[[batteryChargeStatus_.charge_full_now_milliamp_hours]]"> + </percent-bar-chart> </diagnostics-card>
diff --git a/chromeos/components/diagnostics_ui/resources/battery_status_card.js b/chromeos/components/diagnostics_ui/resources/battery_status_card.js index c274f474..e59ec3f1 100644 --- a/chromeos/components/diagnostics_ui/resources/battery_status_card.js +++ b/chromeos/components/diagnostics_ui/resources/battery_status_card.js
@@ -5,6 +5,7 @@ import './data_point.js'; import './diagnostics_card.js'; import './diagnostics_shared_css.js'; +import './percent_bar_chart.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {BatteryChargeStatus, BatteryHealth, BatteryInfo, SystemDataProviderInterface} from './diagnostics_types.js'
diff --git a/chromeos/components/diagnostics_ui/resources/diagnostics_app.html b/chromeos/components/diagnostics_ui/resources/diagnostics_app.html index 47184d5..97cf92a 100644 --- a/chromeos/components/diagnostics_ui/resources/diagnostics_app.html +++ b/chromeos/components/diagnostics_ui/resources/diagnostics_app.html
@@ -37,9 +37,9 @@ <overview-card id="overviewCard"></overview-card> </div> <div class="diagonstics-cards-container"> - <memory-card id="memoryCard"></memory-card> - <cpu-card id="cpuCard"></cpu-card> <battery-status-card id="batteryStatusCard"></battery-status-card> + <cpu-card id="cpuCard"></cpu-card> + <memory-card id="memoryCard"></memory-card> </div> <div class="session-log-container"> <!-- TODO(michaelcheco): Localize string -->
diff --git a/components/autofill/core/browser/data_model/autofill_structured_address.cc b/components/autofill/core/browser/data_model/autofill_structured_address.cc index 0d6b680..c7453777 100644 --- a/components/autofill/core/browser/data_model/autofill_structured_address.cc +++ b/components/autofill/core/browser/data_model/autofill_structured_address.cc
@@ -4,6 +4,7 @@ #include "components/autofill/core/browser/data_model/autofill_structured_address.h" +#include <iostream> #include <utility> #include "base/i18n/case_conversion.h" #include "base/strings/strcat.h" @@ -364,12 +365,24 @@ Address::~Address() = default; void Address::MigrateLegacyStructure(bool is_verified_profile) { - VerificationStatus status = is_verified_profile - ? VerificationStatus::kUserVerified - : VerificationStatus::kObserved; - if (GetVerificationStatus() == VerificationStatus::kNoStatus && - !GetValue().empty()) { - SetValue(GetValue(), status); + // If this component already has a verification status, no profile is regarded + // as already verified. + std::cout << "APply migration" << std::endl; + if (GetVerificationStatus() != VerificationStatus::kNoStatus) + return; + + // Otherwise set the status of the subcomponents either to observed or + // verified depending on |is_verified_profile| if they already have a value + // assigned. Note, those are all the tokens that are already present in the + // unstructured address representation. + for (auto* component : Subcomponents()) { + if (!component->GetValue().empty() && + component->GetVerificationStatus() == VerificationStatus::kNoStatus) { + component->SetValue(component->GetValue(), + is_verified_profile + ? VerificationStatus::kUserVerified + : VerificationStatus::kObserved); + } } }
diff --git a/components/autofill/core/browser/data_model/autofill_structured_address_unittest.cc b/components/autofill/core/browser/data_model/autofill_structured_address_unittest.cc index 8bf7273..1a8bf50 100644 --- a/components/autofill/core/browser/data_model/autofill_structured_address_unittest.cc +++ b/components/autofill/core/browser/data_model/autofill_structured_address_unittest.cc
@@ -343,6 +343,145 @@ VerifyTestValues(&address, expectation); } +// Tests that a structured address gets successfully migrated and subsequently +// completed. +TEST(AutofillStructuredAddress, TestMigrationAndFinalization) { + Address address; + AddressComponentTestValues test_values = { + {.type = ADDRESS_HOME_STREET_ADDRESS, + .value = "123 Street name", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_COUNTRY, + .value = "US", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_STATE, + .value = "CA", + .status = VerificationStatus::kNoStatus}}; + + SetTestValues(&address, test_values, /*finalize=*/false); + + // Invoke the migration. This should only change the verification statuses of + // the set values. + address.MigrateLegacyStructure(/*is_verified_profile=*/false); + + AddressComponentTestValues expectation_after_migration = { + {.type = ADDRESS_HOME_STREET_ADDRESS, + .value = "123 Street name", + .status = VerificationStatus::kObserved}, + {.type = ADDRESS_HOME_COUNTRY, + .value = "US", + .status = VerificationStatus::kObserved}, + {.type = ADDRESS_HOME_STATE, + .value = "CA", + .status = VerificationStatus::kObserved}, + {.type = ADDRESS_HOME_ADDRESS, + .value = "", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_CITY, + .value = "", + .status = VerificationStatus::kNoStatus}, + }; + + VerifyTestValues(&address, expectation_after_migration); + + // Complete the address tree and check the expectations. + address.CompleteFullTree(); + + AddressComponentTestValues expectation_after_completion = { + {.type = ADDRESS_HOME_STREET_ADDRESS, + .value = "123 Street name", + .status = VerificationStatus::kObserved}, + {.type = ADDRESS_HOME_COUNTRY, + .value = "US", + .status = VerificationStatus::kObserved}, + {.type = ADDRESS_HOME_STATE, + .value = "CA", + .status = VerificationStatus::kObserved}, + {.type = ADDRESS_HOME_ADDRESS, + .value = "123 Street name CA US", + .status = VerificationStatus::kFormatted}, + {.type = ADDRESS_HOME_CITY, + .value = "", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_STREET_NAME, + .value = "Street name", + .status = VerificationStatus::kParsed}, + {.type = ADDRESS_HOME_HOUSE_NUMBER, + .value = "123", + .status = VerificationStatus::kParsed}, + }; + + VerifyTestValues(&address, expectation_after_completion); +} + +// Tests the migration of a structured address in a verified profile. +TEST(AutofillStructuredAddress, TestMigrationOfVerifiedProfile) { + Address address; + AddressComponentTestValues test_values = { + {.type = ADDRESS_HOME_STREET_ADDRESS, + .value = "123 Street name", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_COUNTRY, + .value = "US", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_STATE, + .value = "CA", + .status = VerificationStatus::kNoStatus}}; + + SetTestValues(&address, test_values, /*finalize=*/false); + + // Invoke the migration. All non-empty fields should be marked as + // user-verified. + address.MigrateLegacyStructure(/*is_verified_profile=*/true); + + AddressComponentTestValues expectation_after_migration = { + {.type = ADDRESS_HOME_STREET_ADDRESS, + .value = "123 Street name", + .status = VerificationStatus::kUserVerified}, + {.type = ADDRESS_HOME_COUNTRY, + .value = "US", + .status = VerificationStatus::kUserVerified}, + {.type = ADDRESS_HOME_STATE, + .value = "CA", + .status = VerificationStatus::kUserVerified}, + {.type = ADDRESS_HOME_ADDRESS, + .value = "", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_CITY, + .value = "", + .status = VerificationStatus::kNoStatus}, + }; + + VerifyTestValues(&address, expectation_after_migration); +} + +// Tests that the migration does not happen of the root node +// (ADDRESS_HOME_ADDRESS) already has a verification status. +TEST(AutofillStructuredAddress, TestMigrationAndFinalization_AlreadyMigrated) { + Address address; + AddressComponentTestValues test_values = { + {.type = ADDRESS_HOME_STREET_ADDRESS, + .value = "123 Street name", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_COUNTRY, + .value = "US", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_STATE, + .value = "CA", + .status = VerificationStatus::kNoStatus}, + {.type = ADDRESS_HOME_ADDRESS, + .value = "the address", + .status = VerificationStatus::kFormatted}}; + + SetTestValues(&address, test_values, /*finalize=*/false); + + // Invoke the migration. Since the ADDRESS_HOME_ADDRESS node already has a + // verification status, the address is considered as already migrated. + address.MigrateLegacyStructure(/*is_verified_profile=*/false); + + // Verify that the address was not changed by the migration. + VerifyTestValues(&address, test_values); +} } // namespace } // namespace structured_address } // namespace autofill
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc index a1f4520..31e772c 100644 --- a/components/autofill/core/browser/form_data_importer_unittest.cc +++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -415,9 +415,9 @@ TEST_P(FormDataImporterTest, ImportStructuredAddressProfile_GermanStreetNameAndHouseNumber) { - base::test::ScopedFeatureList structured_addresses_feature; - structured_addresses_feature.InitAndEnableFeature( - features::kAutofillEnableSupportForMoreStructureInAddresses); + // This test is only applicable if structured addresses are enabled. + if (!StructuredAddresses()) + return; FormData form; form.url = GURL("https://wwww.foo.com");
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index a986bcb..c107d71e 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -520,7 +520,7 @@ // action sent to the client after this one. Default is false. optional bool clean_contextual_ui = 33; - reserved 34, 46, 47, 48, 50, 51; + reserved 8, 13 to 17, 20 to 23, 25 to 27, 30, 34, 38, 46 to 48, 50, 51; } // Result of |CollectUserDataProto| to be sent to the server.
diff --git a/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc index dc9c2d0..1bc377d 100644 --- a/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc +++ b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
@@ -67,6 +67,10 @@ void OnAdsViolationTriggered( content::RenderFrameHost*, subresource_filter::mojom::AdsViolation) override {} + const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> + GetSafeBrowsingDatabaseManager() override { + return nullptr; + } // content::RenderViewHostTestHarness: void SetUp() override {
diff --git a/components/page_info/android/java/res/layout/page_info_v2.xml b/components/page_info/android/java/res/layout/page_info_v2.xml index 75cc876..8fdf5d1 100644 --- a/components/page_info/android/java/res/layout/page_info_v2.xml +++ b/components/page_info/android/java/res/layout/page_info_v2.xml
@@ -12,42 +12,7 @@ android:layout_height="match_parent" android:background="@color/sheet_bg_color" android:orientation="vertical" - android:divider="@android:color/transparent" - android:showDividers="middle" - android:dividerHeight="12dp"> - - <View - android:id="@+id/page_info_preview_separator" - android:layout_marginTop="4dp" - style="@style/HorizontalDivider" - android:visibility="gone" /> - - <TextView - android:id="@+id/page_info_preview_message" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginHorizontal="@dimen/page_info_popup_padding_sides" - android:paddingTop="2dp" - android:textAppearance="@style/TextAppearance.TextLarge.Primary" - android:text="@string/page_info_preview_message" - android:visibility="gone" /> - - <TextView - android:id="@+id/page_info_preview_load_original" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginHorizontal="@dimen/page_info_popup_padding_sides" - android:textAppearance="@style/TextAppearance.TextLarge.Primary" - android:visibility="gone" /> - - <TextView - android:id="@+id/page_info_lite_mode_https_image_compression_message" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginHorizontal="@dimen/page_info_popup_padding_sides" - android:text="@string/page_info_lite_mode_https_image_compression" - android:textAppearance="@style/TextAppearance.TextMedium.Primary" - android:visibility="gone" /> + android:layout_marginBottom="8dp"> <LinearLayout android:id="@+id/page_info_row_wrapper" @@ -74,14 +39,48 @@ android:layout_width="match_parent"/> </LinearLayout> + <View + android:id="@+id/page_info_preview_separator" + android:layout_marginTop="16dp" + style="@style/HorizontalDivider" + android:visibility="gone" /> + + <TextView + android:id="@+id/page_info_preview_message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginHorizontal="@dimen/page_info_popup_padding_sides" + android:layout_marginTop="12dp" + android:textAppearance="@style/TextAppearance.TextLarge.Primary" + android:text="@string/page_info_preview_message" + android:visibility="gone" /> + + <TextView + android:id="@+id/page_info_preview_load_original" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginVertical="12dp" + android:layout_marginHorizontal="@dimen/page_info_popup_padding_sides" + android:textAppearance="@style/TextAppearance.TextLarge.Primary" + android:visibility="gone" /> + + <TextView + android:id="@+id/page_info_lite_mode_https_image_compression_message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginVertical="12dp" + android:layout_marginHorizontal="@dimen/page_info_popup_padding_sides" + android:text="@string/page_info_lite_mode_https_image_compression" + android:textAppearance="@style/TextAppearance.TextMedium.Primary" + android:visibility="gone" /> + <org.chromium.ui.widget.ButtonCompat android:id="@+id/page_info_instant_app_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="start" android:layout_marginHorizontal="@dimen/page_info_popup_padding_sides" - android:paddingEnd="@dimen/page_info_popup_button_padding_sides" - android:paddingStart="@dimen/page_info_popup_button_padding_sides" + android:paddingHorizontal="@dimen/page_info_popup_button_padding_sides" android:text="@string/page_info_instant_app_button" app:buttonColor="@color/app_banner_install_button_bg" style="@style/FilledButton" /> @@ -92,8 +91,7 @@ android:layout_height="wrap_content" android:layout_gravity="end" android:layout_marginHorizontal="@dimen/page_info_popup_padding_sides" - android:paddingEnd="@dimen/page_info_popup_button_padding_sides" - android:paddingStart="@dimen/page_info_popup_button_padding_sides" + android:paddingHorizontal="@dimen/page_info_popup_button_padding_sides" android:text="@string/page_info_open_online_button" style="@style/TextButton" /> </LinearLayout>
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index e3a66b10..ee42c33 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -211,6 +211,8 @@ "site_affiliation/affiliation_service_impl.h", "site_affiliation/asset_link_data.cc", "site_affiliation/asset_link_data.h", + "site_affiliation/hash_affiliation_fetcher.cc", + "site_affiliation/hash_affiliation_fetcher.h", "sql_table_builder.cc", "sql_table_builder.h", "statistics_table.cc", @@ -648,6 +650,7 @@ "psl_matching_helper_unittest.cc", "site_affiliation/affiliation_service_impl_unittest.cc", "site_affiliation/asset_link_data_unittest.cc", + "site_affiliation/hash_affiliation_fetcher_unittest.cc", "sql_table_builder_unittest.cc", "statistics_table_unittest.cc", "store_metrics_reporter_unittest.cc",
diff --git a/components/password_manager/core/browser/site_affiliation/affiliation_service_impl.cc b/components/password_manager/core/browser/site_affiliation/affiliation_service_impl.cc index ff6243bf..0c50bcc 100644 --- a/components/password_manager/core/browser/site_affiliation/affiliation_service_impl.cc +++ b/components/password_manager/core/browser/site_affiliation/affiliation_service_impl.cc
@@ -7,6 +7,7 @@ #include "base/metrics/histogram_functions.h" #include "base/ranges/algorithm.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "components/password_manager/core/browser/android_affiliation/affiliation_fetcher.h" #include "components/password_manager/core/browser/password_store_factory_util.h" #include "components/sync/driver/sync_service.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -17,6 +18,10 @@ namespace { +void LogFetchResult(metrics_util::GetChangePasswordUrlMetric result) { + base::UmaHistogramEnumeration(kGetChangePasswordURLMetricName, result); +} + // Creates a look-up (Facet URI : change password URL) map for facets from // requested |groupings|. If a facet does not have change password URL it gets // paired with another facet's URL, which belongs to the same group. In case @@ -54,6 +59,33 @@ const char kGetChangePasswordURLMetricName[] = "PasswordManager.AffiliationService.GetChangePasswordUsage"; +struct AffiliationServiceImpl::FetchInfo { + FetchInfo(std::unique_ptr<AffiliationFetcherInterface> pending_fetcher, + std::vector<url::SchemeHostPort> tuple_origins, + base::OnceClosure result_callback) + : fetcher(std::move(pending_fetcher)), + requested_tuple_origins(std::move(tuple_origins)), + callback(std::move(result_callback)) {} + + FetchInfo(FetchInfo&& other) = default; + + FetchInfo& operator=(FetchInfo&& other) = default; + + ~FetchInfo() { + // The check is essential here, because emplace_back calls move constructor + // and destructor, respectively. Therefore, the check is necessary to + // prevent accessing already moved object. + if (callback) + std::move(callback).Run(); + } + + std::unique_ptr<AffiliationFetcherInterface> fetcher; + std::vector<url::SchemeHostPort> requested_tuple_origins; + // Callback is passed in PrefetchChangePasswordURLs and is run to indicate the + // prefetch has finished or got canceled. + base::OnceClosure callback; +}; + AffiliationServiceImpl::AffiliationServiceImpl( syncer::SyncService* sync_service, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) @@ -66,18 +98,17 @@ void AffiliationServiceImpl::PrefetchChangePasswordURLs( const std::vector<GURL>& urls, base::OnceClosure callback) { - result_callback_ = std::move(callback); if (ShouldAffiliationBasedMatchingBeActive(sync_service_)) { - RequestFacetsAffiliations(ConvertMissingURLsToFacets(urls), - {.change_password_info = true}); + RequestFacetsAffiliations(urls, {.change_password_info = true}, + std::move(callback)); } else { - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, std::move(result_callback_)); + base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(callback)); } } void AffiliationServiceImpl::Clear() { - fetcher_.reset(); + pending_fetches_.clear(); change_password_urls_.clear(); } @@ -85,23 +116,22 @@ auto it = change_password_urls_.find(url::SchemeHostPort(url)); if (it != change_password_urls_.end()) { if (it->second.group_url_override) { - base::UmaHistogramEnumeration( - kGetChangePasswordURLMetricName, + LogFetchResult( metrics_util::GetChangePasswordUrlMetric::kGroupUrlOverrideUsed); } else { - base::UmaHistogramEnumeration( - kGetChangePasswordURLMetricName, + LogFetchResult( metrics_util::GetChangePasswordUrlMetric::kUrlOverrideUsed); } return it->second.change_password_url; } - if (base::Contains(requested_tuple_origins_, url::SchemeHostPort(url))) { - base::UmaHistogramEnumeration( - kGetChangePasswordURLMetricName, - metrics_util::GetChangePasswordUrlMetric::kNotFetchedYet); + + url::SchemeHostPort tuple(url); + if (base::ranges::any_of(pending_fetches_, [&tuple](const auto& info) { + return base::Contains(info.requested_tuple_origins, tuple); + })) { + LogFetchResult(metrics_util::GetChangePasswordUrlMetric::kNotFetchedYet); } else { - base::UmaHistogramEnumeration( - kGetChangePasswordURLMetricName, + LogFetchResult( metrics_util::GetChangePasswordUrlMetric::kNoUrlOverrideAvailable); } return GURL(); @@ -110,10 +140,15 @@ void AffiliationServiceImpl::OnFetchSucceeded( AffiliationFetcherInterface* fetcher, std::unique_ptr<AffiliationFetcherDelegate::Result> result) { - fetcher_.reset(); + auto processed_fetch = + base::ranges::find(pending_fetches_, fetcher, + [](const auto& info) { return info.fetcher.get(); }); + if (processed_fetch == pending_fetches_.end()) + return; + std::map<FacetURI, AffiliationServiceImpl::ChangePasswordUrlMatch> uri_to_url = CreateFacetUriToChangePasswordUrlMap(result->groupings); - for (const url::SchemeHostPort& requested_tuple : requested_tuple_origins_) { + for (const auto& requested_tuple : processed_fetch->requested_tuple_origins) { auto it = uri_to_url.find( FacetURI::FromPotentiallyInvalidSpec(requested_tuple.Serialize())); if (it != uri_to_url.end()) { @@ -121,48 +156,44 @@ } } - requested_tuple_origins_.clear(); - std::move(result_callback_).Run(); + pending_fetches_.erase(processed_fetch); } void AffiliationServiceImpl::OnFetchFailed( AffiliationFetcherInterface* fetcher) { - fetcher_.reset(); - requested_tuple_origins_.clear(); - std::move(result_callback_).Run(); + base::EraseIf(pending_fetches_, [fetcher](const auto& info) { + return info.fetcher.get() == fetcher; + }); } void AffiliationServiceImpl::OnMalformedResponse( AffiliationFetcherInterface* fetcher) { - fetcher_.reset(); - requested_tuple_origins_.clear(); - std::move(result_callback_).Run(); + base::EraseIf(pending_fetches_, [fetcher](const auto& info) { + return info.fetcher.get() == fetcher; + }); } -std::vector<FacetURI> AffiliationServiceImpl::ConvertMissingURLsToFacets( - const std::vector<GURL>& urls) { +void AffiliationServiceImpl::RequestFacetsAffiliations( + const std::vector<GURL>& urls, + const AffiliationFetcherInterface::RequestInfo request_info, + base::OnceClosure callback) { std::vector<FacetURI> facets; + std::vector<url::SchemeHostPort> tuple_origins; for (const auto& url : urls) { if (url.is_valid()) { url::SchemeHostPort scheme_host_port(url); if (!base::Contains(change_password_urls_, scheme_host_port)) { facets.push_back( FacetURI::FromCanonicalSpec(scheme_host_port.Serialize())); - requested_tuple_origins_.push_back(std::move(scheme_host_port)); + tuple_origins.push_back(std::move(scheme_host_port)); } } } - return facets; -} - -// TODO(crbug.com/1117045): New request resets the pointer to -// AffiliationFetcher, therefore the previous request gets canceled. -void AffiliationServiceImpl::RequestFacetsAffiliations( - const std::vector<FacetURI>& facets, - const AffiliationFetcherInterface::RequestInfo request_info) { if (!facets.empty()) { - fetcher_ = fetcher_factory_->CreateInstance(url_loader_factory_, this); - fetcher_->StartRequest(facets, request_info); + auto fetcher = fetcher_factory_->CreateInstance(url_loader_factory_, this); + fetcher->StartRequest(facets, request_info); + pending_fetches_.emplace_back(std::move(fetcher), tuple_origins, + std::move(callback)); } }
diff --git a/components/password_manager/core/browser/site_affiliation/affiliation_service_impl.h b/components/password_manager/core/browser/site_affiliation/affiliation_service_impl.h index 8ba9163..394c74a 100644 --- a/components/password_manager/core/browser/site_affiliation/affiliation_service_impl.h +++ b/components/password_manager/core/browser/site_affiliation/affiliation_service_impl.h
@@ -48,19 +48,18 @@ // Prefetches change password URLs and saves them to |change_password_urls_| // map. The verification if affiliation based matching is enabled must be - // performed. Assigns the callback to |result_callback_|. + // performed. Creates a unique fetcher and appends it to |pending_fetches_| + // along with |urls| and |callback|. void PrefetchChangePasswordURLs(const std::vector<GURL>& urls, base::OnceClosure callback) override; - // Clears the |change_password_urls_| map and cancels prefetch if still - // running. + // Clears the |change_password_urls_| map and cancels prefetch requests if + // still running. void Clear() override; // In case no valid URL was found, a method returns an empty URL. GURL GetChangePasswordURL(const GURL& url) const override; - AffiliationFetcherInterface* GetFetcherForTesting() { return fetcher_.get(); } - void SetURLLoaderFactoryForTesting( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { url_loader_factory_ = std::move(url_loader_factory); @@ -76,6 +75,8 @@ } private: + struct FetchInfo; + // AffiliationFetcherDelegate: void OnFetchSucceeded( AffiliationFetcherInterface* fetcher, @@ -83,27 +84,20 @@ void OnFetchFailed(AffiliationFetcherInterface* fetcher) override; void OnMalformedResponse(AffiliationFetcherInterface* fetcher) override; - // Converts new |urls| to facets and inserts them to the - // |change_password_urls_|. - std::vector<FacetURI> ConvertMissingURLsToFacets( - const std::vector<GURL>& urls); - - // Calls Affiliation Fetcher and starts a request for |facets| affiliations. + // Creates AffiliationFetcher and starts a request to retrieve affiliations + // for given |urls|. |Request_info| defines what info should be requested. + // When prefetch is finished or a fetcher gets destroyed as a result of + // Clear() a callback is run. void RequestFacetsAffiliations( - const std::vector<FacetURI>& facets, - const AffiliationFetcherInterface::RequestInfo request_info); + const std::vector<GURL>& urls, + const AffiliationFetcherInterface::RequestInfo request_info, + base::OnceClosure callback); syncer::SyncService* sync_service_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; - std::vector<url::SchemeHostPort> requested_tuple_origins_; std::map<url::SchemeHostPort, ChangePasswordUrlMatch> change_password_urls_; - // TODO(crbug.com/1117045): A vector of pending fetchers to be created. - std::unique_ptr<AffiliationFetcherInterface> fetcher_; + std::vector<FetchInfo> pending_fetches_; std::unique_ptr<AffiliationFetcherFactory> fetcher_factory_; - // Callback is passed in PrefetchChangePasswordURLs and is run in - // OnFetchSucceeded, OnFetchMalformed, OnFetchFailed to indicate the prefetch - // has finished. - base::OnceClosure result_callback_; }; } // namespace password_manager
diff --git a/components/password_manager/core/browser/site_affiliation/affiliation_service_impl_unittest.cc b/components/password_manager/core/browser/site_affiliation/affiliation_service_impl_unittest.cc index fd2b668..c1a4e8e 100644 --- a/components/password_manager/core/browser/site_affiliation/affiliation_service_impl_unittest.cc +++ b/components/password_manager/core/browser/site_affiliation/affiliation_service_impl_unittest.cc
@@ -35,6 +35,7 @@ constexpr char kOneExampleChangePasswordURL[] = "https://one.example.com/settings/passwords"; constexpr char k2ExampleURL[] = "https://2.example.com"; +constexpr char k2ExampleChangePasswordURL[] = "https://2.example.com/pwd"; constexpr char k3ExampleURL[] = "https://3.example.com"; constexpr char k4ExampleURL[] = "https://4.example.com"; constexpr char k5ExampleURL[] = "https://5.example.com"; @@ -88,7 +89,7 @@ EXPECT_EQ(GURL(), service()->GetChangePasswordURL(GURL(k1ExampleURL))); } -TEST_F(AffiliationServiceImplTest, ClearStopsOngoingAffiliationFetcherRequest) { +TEST_F(AffiliationServiceImplTest, ClearStopsOngoingRequest) { const std::vector<GURL> origins = {GURL(k1ExampleURL), GURL(k2ExampleURL)}; auto mock_fetcher = std::make_unique<MockAffiliationFetcher>(); @@ -99,11 +100,11 @@ EXPECT_CALL(mock_fetcher_factory(), CreateInstance) .WillOnce(Return(ByMove(std::move(mock_fetcher)))); - service()->PrefetchChangePasswordURLs(origins, base::DoNothing()); - EXPECT_NE(nullptr, service()->GetFetcherForTesting()); + base::MockOnceClosure callback; + service()->PrefetchChangePasswordURLs(origins, callback.Get()); + EXPECT_CALL(callback, Run()); service()->Clear(); - EXPECT_EQ(nullptr, service()->GetFetcherForTesting()); } TEST_F(AffiliationServiceImplTest, @@ -210,12 +211,12 @@ EXPECT_CALL(mock_fetcher_factory(), CreateInstance) .WillOnce(Return(ByMove(std::move(mock_fetcher)))); - service()->PrefetchChangePasswordURLs(origins, base::DoNothing()); - EXPECT_NE(nullptr, service()->GetFetcherForTesting()); + base::MockOnceClosure callback; + service()->PrefetchChangePasswordURLs(origins, callback.Get()); + EXPECT_CALL(callback, Run()); static_cast<AffiliationFetcherDelegate*>(service())->OnFetchFailed( raw_mock_fetcher); - EXPECT_EQ(nullptr, service()->GetFetcherForTesting()); } TEST_F(AffiliationServiceImplTest, OnMalformedResponseResetsFetcher) { @@ -230,12 +231,12 @@ EXPECT_CALL(mock_fetcher_factory(), CreateInstance) .WillOnce(Return(ByMove(std::move(mock_fetcher)))); - service()->PrefetchChangePasswordURLs(origins, base::DoNothing()); - EXPECT_NE(nullptr, service()->GetFetcherForTesting()); + base::MockOnceClosure callback; + service()->PrefetchChangePasswordURLs(origins, callback.Get()); + EXPECT_CALL(callback, Run()); static_cast<AffiliationFetcherDelegate*>(service())->OnMalformedResponse( raw_mock_fetcher); - EXPECT_EQ(nullptr, service()->GetFetcherForTesting()); } TEST_F(AffiliationServiceImplTest, @@ -415,4 +416,49 @@ raw_mock_fetcher, std::make_unique<AffiliationFetcherDelegate::Result>()); } +TEST_F(AffiliationServiceImplTest, SupportForMultipleRequests) { + const GURL origin1(k1ExampleURL); + const GURL origin2(k2ExampleURL); + const std::vector<GURL> origins_1 = {origin1}; + const std::vector<GURL> origins_2 = {origin2}; + + auto mock_fetcher = std::make_unique<MockAffiliationFetcher>(); + auto* raw_mock_fetcher = mock_fetcher.get(); + auto new_mock_fetcher = std::make_unique<MockAffiliationFetcher>(); + auto* new_raw_mock_fetcher = new_mock_fetcher.get(); + + AffiliationFetcher::RequestInfo request_info{.change_password_info = true}; + + EXPECT_CALL(*mock_fetcher, + StartRequest(ToFacetsURIs(origins_1), request_info)); + EXPECT_CALL(*new_mock_fetcher, + StartRequest(ToFacetsURIs(origins_2), request_info)); + EXPECT_CALL(mock_fetcher_factory(), CreateInstance) + .WillOnce(Return(ByMove(std::move(mock_fetcher)))) + .WillOnce(Return(ByMove(std::move(new_mock_fetcher)))); + + service()->PrefetchChangePasswordURLs(origins_1, base::DoNothing()); + service()->PrefetchChangePasswordURLs(origins_2, base::DoNothing()); + + const GroupedFacets group1 = { + {.uri = FacetURI::FromPotentiallyInvalidSpec(k1ExampleURL), + .change_password_url = GURL(k1ExampleChangePasswordURL)}}; + auto test_result1 = std::make_unique<AffiliationFetcherDelegate::Result>(); + test_result1->groupings.push_back(group1); + static_cast<AffiliationFetcherDelegate*>(service())->OnFetchSucceeded( + raw_mock_fetcher, std::move(test_result1)); + EXPECT_EQ(GURL(k1ExampleChangePasswordURL), + service()->GetChangePasswordURL(origin1)); + + const GroupedFacets group2 = { + {.uri = FacetURI::FromPotentiallyInvalidSpec(k2ExampleURL), + .change_password_url = GURL(k2ExampleChangePasswordURL)}}; + auto test_result2 = std::make_unique<AffiliationFetcherDelegate::Result>(); + test_result2->groupings.push_back(group2); + static_cast<AffiliationFetcherDelegate*>(service())->OnFetchSucceeded( + new_raw_mock_fetcher, std::move(test_result2)); + EXPECT_EQ(GURL(k2ExampleChangePasswordURL), + service()->GetChangePasswordURL(origin2)); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.cc b/components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.cc new file mode 100644 index 0000000..4352c4412 --- /dev/null +++ b/components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.cc
@@ -0,0 +1,41 @@ +// Copyright 2020 The Chromium 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/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.h" + +#include <memory> + +#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h" +#include "google_apis/google_api_keys.h" +#include "net/base/url_util.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "url/gurl.h" + +namespace password_manager { + +HashAffiliationFetcher::HashAffiliationFetcher( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + AffiliationFetcherDelegate* delegate) + : AffiliationFetcherBase(std::move(url_loader_factory), delegate) {} + +HashAffiliationFetcher::~HashAffiliationFetcher() = default; + +// TODO: Add an implementation. +void HashAffiliationFetcher::StartRequest( + const std::vector<FacetURI>& facet_uris, + RequestInfo request_info) {} + +const std::vector<FacetURI>& HashAffiliationFetcher::GetRequestedFacetURIs() + const { + return requested_facet_uris_; +} +// static +GURL HashAffiliationFetcher::BuildQueryURL() { + return net::AppendQueryParameter( + GURL("https://www.googleapis.com/affiliation/v1/" + "affiliation:lookupByHashPrefix"), + "key", google_apis::GetAPIKey()); +} + +} // namespace password_manager
diff --git a/components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.h b/components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.h new file mode 100644 index 0000000..1539395 --- /dev/null +++ b/components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.h
@@ -0,0 +1,38 @@ +// Copyright 2020 The Chromium 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_PASSWORD_MANAGER_CORE_BROWSER_SITE_AFFILIATION_HASH_AFFILIATION_FETCHER_H_ +#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SITE_AFFILIATION_HASH_AFFILIATION_FETCHER_H_ + +#include "components/password_manager/core/browser/site_affiliation/affiliation_fetcher_base.h" + +namespace password_manager { + +// Fetches authoritative information about facets' affiliations with additional +// privacy layer. It uses SHA-256 to hash facet URLs and sends only a specified +// amount of hash prefixes to eventually retrieve a larger group of affiliations +// including those actually required. +class HashAffiliationFetcher : public AffiliationFetcherBase { + public: + HashAffiliationFetcher( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + AffiliationFetcherDelegate* delegate); + ~HashAffiliationFetcher() override; + + void StartRequest(const std::vector<FacetURI>& facet_uris, + RequestInfo request_info) override; + + // AffiliationFetcherInterface + const std::vector<FacetURI>& GetRequestedFacetURIs() const override; + + // Builds the URL for the Affiliation API's lookup method. + static GURL BuildQueryURL(); + + private: + std::vector<FacetURI> requested_facet_uris_; +}; + +} // namespace password_manager + +#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_SITE_AFFILIATION_HASH_AFFILIATION_FETCHER_H_
diff --git a/components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher_unittest.cc b/components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher_unittest.cc new file mode 100644 index 0000000..b03e783 --- /dev/null +++ b/components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher_unittest.cc
@@ -0,0 +1,35 @@ +// Copyright 2020 The Chromium 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/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.h" + +#include "components/password_manager/core/browser/android_affiliation/mock_affiliation_fetcher_delegate.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace password_manager { + +class HashAffiliationFetcherTest : public testing::Test { + public: + HashAffiliationFetcherTest() = default; + ~HashAffiliationFetcherTest() override = default; +}; + +TEST_F(HashAffiliationFetcherTest, BuildQueryURL) { + network::TestURLLoaderFactory test_url_loader_factory; + scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory); + MockAffiliationFetcherDelegate mock_delegate; + + HashAffiliationFetcher fetcher(test_shared_loader_factory, &mock_delegate); + + EXPECT_EQ(GURL("https://www.googleapis.com/affiliation/v1/" + "affiliation:lookupByHashPrefix?key=dummytoken"), + fetcher.BuildQueryURL()); +} + +} // namespace password_manager
diff --git a/components/password_manager/core/browser/well_known_change_password_state_unittest.cc b/components/password_manager/core/browser/well_known_change_password_state_unittest.cc index 61d32df..b9e16319 100644 --- a/components/password_manager/core/browser/well_known_change_password_state_unittest.cc +++ b/components/password_manager/core/browser/well_known_change_password_state_unittest.cc
@@ -9,6 +9,7 @@ #include "base/timer/mock_timer.h" #include "components/password_manager/core/browser/android_affiliation/mock_affiliation_fetcher.h" #include "components/password_manager/core/browser/site_affiliation/affiliation_service_impl.h" +#include "components/password_manager/core/browser/site_affiliation/mock_affiliation_fetcher_factory.h" #include "components/password_manager/core/browser/well_known_change_password_util.h" #include "components/sync/driver/test_sync_service.h" #include "net/base/isolation_info.h" @@ -230,11 +231,22 @@ TEST_P(WellKnownChangePasswordStateTest, PrefetchCallbackTriggersOnProcessingFinished) { + auto mock_fetcher = std::make_unique<MockAffiliationFetcher>(); + auto* raw_mock_fetcher = mock_fetcher.get(); + auto mock_fetcher_factory = std::make_unique<MockAffiliationFetcherFactory>(); + EXPECT_CALL(*(mock_fetcher_factory.get()), CreateInstance) + .WillOnce(testing::Return(testing::ByMove(std::move(mock_fetcher)))); + syncer::TestSyncService test_sync_service; + test_sync_service.SetFirstSetupComplete(true); + test_sync_service.SetIsUsingSecondaryPassphrase(false); AffiliationServiceImpl affiliation_service(&test_sync_service, test_shared_loader_factory()); + affiliation_service.SetFetcherFactoryForTesting( + std::move(mock_fetcher_factory)); - state()->PrefetchChangePasswordURLs(&affiliation_service, {}); + state()->PrefetchChangePasswordURLs(&affiliation_service, + {GURL("https://example.com")}); ResponseDelayParams params = GetParam(); RespondeToChangePasswordRequest(net::HTTP_NOT_FOUND, @@ -245,10 +257,9 @@ FastForwardBy(base::TimeDelta::FromMilliseconds(ms_to_forward)); EXPECT_CALL(*delegate(), OnProcessingFinished(false)); - auto mock_fetcher = std::make_unique<MockAffiliationFetcher>(); static_cast<AffiliationFetcherDelegate*>(&affiliation_service) ->OnFetchSucceeded( - mock_fetcher.get(), + raw_mock_fetcher, std::make_unique<AffiliationFetcherDelegate::Result>()); }
diff --git a/components/permissions/BUILD.gn b/components/permissions/BUILD.gn index dad98356..ea4ac97 100644 --- a/components/permissions/BUILD.gn +++ b/components/permissions/BUILD.gn
@@ -48,6 +48,7 @@ ] deps = [ "//base", + "//components/autofill_assistant/browser/public:public", "//components/content_settings/browser", "//components/content_settings/core/browser", "//components/keyed_service/content",
diff --git a/components/permissions/DEPS b/components/permissions/DEPS index 360d23a..509caaf 100644 --- a/components/permissions/DEPS +++ b/components/permissions/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/autofill_assistant/browser/public", "+components/content_settings/core", "+components/keyed_service/content", "+components/keyed_service/core",
diff --git a/components/permissions/permission_request_manager.cc b/components/permissions/permission_request_manager.cc index a842353..c61e7fd 100644 --- a/components/permissions/permission_request_manager.cc +++ b/components/permissions/permission_request_manager.cc
@@ -17,6 +17,7 @@ #include "base/strings/string16.h" #include "base/threading/sequenced_task_runner_handle.h" #include "build/build_config.h" +#include "components/autofill_assistant/browser/public/runtime_manager.h" #include "components/permissions/features.h" #include "components/permissions/permission_decision_auto_blocker.h" #include "components/permissions/permission_prompt.h" @@ -178,6 +179,16 @@ return; } + // Cancel permission requests wile Autofill Assistant's UI is shown. + auto* assistant_runtime_manager = + autofill_assistant::RuntimeManager::GetForWebContents(web_contents()); + if (assistant_runtime_manager && assistant_runtime_manager->GetState() == + autofill_assistant::UIState::kShown) { + request->Cancelled(); + request->RequestFinished(); + return; + } + // Don't re-add an existing request or one with a duplicate text request. PermissionRequest* existing_request = GetExistingRequest(request); if (existing_request) {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index b68d154..dfbb1a02 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -22932,7 +22932,7 @@ 'owners': ['tellier@google.com', 'rsorokin@chromium.org', 'cros-oac@google.com'], 'type': 'main', 'schema': { 'type': 'boolean' }, - 'supported_on': ['chrome_os:84-'], + 'supported_on': ['chrome_os:86-'], 'features': { 'dynamic_refresh': False, 'per_profile': True,
diff --git a/components/subresource_filter/content/browser/BUILD.gn b/components/subresource_filter/content/browser/BUILD.gn index 1f751190..3923b66 100644 --- a/components/subresource_filter/content/browser/BUILD.gn +++ b/components/subresource_filter/content/browser/BUILD.gn
@@ -107,6 +107,7 @@ ":test_support", "//base/test:test_support", "//components/prefs:test_support", + "//components/safe_browsing/core/db:database_manager", "//components/safe_browsing/core/db:util", "//components/subresource_filter/content/common", "//components/subresource_filter/core/browser",
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc index 7669e2e..c042f87 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
@@ -19,11 +19,14 @@ #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" #include "components/subresource_filter/content/browser/page_load_statistics.h" #include "components/subresource_filter/content/browser/subresource_filter_client.h" +#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h" #include "components/subresource_filter/content/common/subresource_filter_messages.h" #include "components/subresource_filter/content/common/subresource_filter_utils.h" #include "components/subresource_filter/content/mojom/subresource_filter_agent.mojom.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h" #include "components/subresource_filter/core/common/common_features.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/render_frame_host.h" @@ -308,6 +311,15 @@ content::NavigationHandle* navigation_handle, std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles) { DCHECK(!navigation_handle->IsSameDocument()); + + if (navigation_handle->IsInMainFrame() && + client_->GetSafeBrowsingDatabaseManager()) { + throttles->push_back( + std::make_unique<SubresourceFilterSafeBrowsingActivationThrottle>( + navigation_handle, client_, content::GetIOThreadTaskRunner({}), + client_->GetSafeBrowsingDatabaseManager())); + } + if (!dealer_handle_) return; if (auto filtering_throttle =
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc index 65ae5b3..4e874eda 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
@@ -21,6 +21,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "build/build_config.h" +#include "components/safe_browsing/core/db/database_manager.h" +#include "components/safe_browsing/core/db/test_database_manager.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" #include "components/subresource_filter/content/browser/subframe_navigation_test_utils.h" #include "components/subresource_filter/content/browser/subresource_filter_client.h" @@ -104,6 +106,17 @@ mojo::AssociatedReceiver<mojom::SubresourceFilterAgent> receiver_{this}; }; +// Overrides the TestSafeBrowsingDatabaseManager methods that are +// expected to be called to eliminate error logs. +class CustomTestSafeBrowsingDatabaseManager + : public safe_browsing::TestSafeBrowsingDatabaseManager { + public: + bool IsSupported() const override { return false; } + + private: + ~CustomTestSafeBrowsingDatabaseManager() override = default; +}; + // Simple throttle that sends page-level activation to the manager for a // specific set of URLs. class MockPageStateActivationThrottle : public content::NavigationThrottle { @@ -286,7 +299,14 @@ navigation_handle, state)); throttle_manager_->MaybeAppendNavigationThrottles(navigation_handle, &throttles); + + created_safe_browsing_throttle_for_last_navigation_ = false; for (auto& it : throttles) { + if (strcmp(it->GetNameForLogging(), + "SubresourceFilterSafeBrowsingActivationThrottle") == 0) { + created_safe_browsing_throttle_for_last_navigation_ = true; + } + navigation_handle->RegisterThrottleForTesting(std::move(it)); } } @@ -313,13 +333,28 @@ content::RenderFrameHost* rfh, mojom::AdsViolation triggered_violation) override {} + const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> + GetSafeBrowsingDatabaseManager() override { + return database_manager_; + } + ContentSubresourceFilterThrottleManager* throttle_manager() { return throttle_manager_.get(); } + bool created_safe_browsing_throttle_for_current_navigation() const { + return created_safe_browsing_throttle_for_last_navigation_; + } + + void CreateSafeBrowsingDatabaseManager() { + database_manager_ = + base::MakeRefCounted<CustomTestSafeBrowsingDatabaseManager>(); + } + private: testing::TestRulesetCreator test_ruleset_creator_; testing::TestRulesetPair test_ruleset_pair_; + scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_; std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_; @@ -331,6 +366,8 @@ std::unique_ptr<content::NavigationSimulator> navigation_simulator_; + bool created_safe_browsing_throttle_for_last_navigation_ = false; + // Incremented on every OnFirstSubresourceLoadDisallowed call. int disallowed_notification_count_ = 0; @@ -777,6 +814,29 @@ EXPECT_EQ(0, disallowed_notification_count()); } +TEST_F(ContentSubresourceFilterThrottleManagerTest, + SafeBrowsingThrottleCreation) { + // If no safe browsing database is present, the throttle should not be + // created on a navigation. + NavigateAndCommitMainFrame(GURL(kTestURLWithNoActivation)); + EXPECT_FALSE(created_safe_browsing_throttle_for_current_navigation()); + + CreateSafeBrowsingDatabaseManager(); + + // With a safe browsing database present, the throttle should be created on + // a main frame navigation. + NavigateAndCommitMainFrame(GURL(kTestURLWithNoActivation)); + EXPECT_TRUE(created_safe_browsing_throttle_for_current_navigation()); + + // However, it still should not be created on a subframe navigation. + CreateSubframeWithTestNavigation( + GURL("https://www.example.com/disallowed.html"), main_rfh()); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + + EXPECT_FALSE(created_safe_browsing_throttle_for_current_navigation()); +} + TEST_F(ContentSubresourceFilterThrottleManagerTest, LogActivation) { // This test assumes that we're not in DryRun mode. base::test::ScopedFeatureList scoped_feature;
diff --git a/components/subresource_filter/content/browser/subresource_filter_client.h b/components/subresource_filter/content/browser/subresource_filter_client.h index 4567548..0614894 100644 --- a/components/subresource_filter/content/browser/subresource_filter_client.h +++ b/components/subresource_filter/content/browser/subresource_filter_client.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_CLIENT_H_ #define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBRESOURCE_FILTER_CLIENT_H_ +#include "base/memory/scoped_refptr.h" #include "components/subresource_filter/content/browser/verified_ruleset_dealer.h" #include "components/subresource_filter/core/common/activation_decision.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" @@ -15,6 +16,10 @@ class NavigationHandle; } // namespace content +namespace safe_browsing { +class SafeBrowsingDatabaseManager; +} + namespace subresource_filter { class SubresourceFilterClient { @@ -43,6 +48,11 @@ virtual void OnAdsViolationTriggered( content::RenderFrameHost* rfh, mojom::AdsViolation triggered_violation) = 0; + + // Returns the SafeBrowsingDatabaseManager instance associated with this + // client, or null if there is no such instance. + virtual const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> + GetSafeBrowsingDatabaseManager() = 0; }; } // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc index 4435878e..fa7538e7 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
@@ -19,6 +19,7 @@ #include "base/test/test_mock_time_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "components/safe_browsing/core/db/database_manager.h" #include "components/safe_browsing/core/db/test_database_manager.h" #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" #include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h" @@ -90,6 +91,9 @@ MOCK_METHOD2(OnAdsViolationTriggered, void(content::RenderFrameHost*, subresource_filter::mojom::AdsViolation)); + MOCK_METHOD0( + GetSafeBrowsingDatabaseManager, + const scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>()); void AllowlistInCurrentWebContents(const GURL& url) { ASSERT_TRUE(url.SchemeIsHTTPOrHTTPS());
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index b0454a7..85d7d69fd 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -206,7 +206,6 @@ "engine_impl/syncer.h", "engine_impl/syncer_proto_util.cc", "engine_impl/syncer_proto_util.h", - "engine_impl/syncer_types.h", "engine_impl/traffic_logger.cc", "engine_impl/traffic_logger.h", "engine_impl/update_handler.cc",
diff --git a/components/sync/base/unique_position_unittest.cc b/components/sync/base/unique_position_unittest.cc index a7ac2f1..73d76e7 100644 --- a/components/sync/base/unique_position_unittest.cc +++ b/components/sync/base/unique_position_unittest.cc
@@ -381,7 +381,7 @@ VLOG(1) << "Lengths: " << GetLength(left_pos) << ", " << GetLength(right_pos); } -// Generates suffixes similar to those generated by the directory. +// Generates suffixes similar to those generated by the legacy Directory. // This may become obsolete if the suffix generation code is modified. class SuffixGenerator { public:
diff --git a/components/sync/driver/data_type_manager_impl.cc b/components/sync/driver/data_type_manager_impl.cc index 5bc7dac3..88de703 100644 --- a/components/sync/driver/data_type_manager_impl.cc +++ b/components/sync/driver/data_type_manager_impl.cc
@@ -559,8 +559,7 @@ // - Types which are newly enabled are downloaded. // - Types which have encountered a cryptographer error (crypto_types) are // unapplied (local state is purged but sync state is not). - // - All other types not in the routing info (types just disabled) are deleted - // from the directory. + // - All types not in the routing info (types just disabled) are deleted. // - Everything else (enabled types and already disabled types) is not // touched. const DataTypeConfigStateMap config_state_map = @@ -612,7 +611,7 @@ // One common way to end up in this situation used to be types which // downloaded some or all of their data but have not applied it yet. We avoid // problems with those types by purging the data of any such partially synced - // types soon after we load the directory. + // types soon after we load the Directory. // // Another possible scenario is that we have newly supported or newly enabled // data types being downloaded here but the nigori type, which is always
diff --git a/components/sync/driver/glue/sync_engine_backend.cc b/components/sync/driver/glue/sync_engine_backend.cc index 0eed1720..4b13850 100644 --- a/components/sync/driver/glue/sync_engine_backend.cc +++ b/components/sync/driver/glue/sync_engine_backend.cc
@@ -316,7 +316,6 @@ sync_manager_->AddObserver(this); SyncManager::InitArgs args; - args.database_location = sync_data_folder_; args.event_handler = params.event_handler; args.service_url = params.service_url; args.enable_local_sync_backend = params.enable_local_sync_backend;
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc index b9e1837..66ca47c 100644 --- a/components/sync/driver/profile_sync_service.cc +++ b/components/sync/driver/profile_sync_service.cc
@@ -655,7 +655,7 @@ void ProfileSyncService::ShutdownImpl(ShutdownReason reason) { if (!engine_) { // If the engine hasn't started or is already shut down when a DISABLE_SYNC - // happens, the data directory needs to be cleaned up here. + // happens, the Directory needs to be cleaned up here. if (reason == ShutdownReason::DISABLE_SYNC) { // Clearing the Directory via DeleteLegacyDirectoryFilesAndNigoriStorage() // means there's IO involved which may we considerable overhead if
diff --git a/components/sync/engine/fake_sync_manager.h b/components/sync/engine/fake_sync_manager.h index 5b6545e..744ad1a 100644 --- a/components/sync/engine/fake_sync_manager.h +++ b/components/sync/engine/fake_sync_manager.h
@@ -110,7 +110,7 @@ base::ObserverList<SyncManager::Observer>::Unchecked observers_; bool should_fail_on_init_; - // Faked directory state. + // Faked data state. ModelTypeSet initial_sync_ended_types_; ModelTypeSet progress_marker_types_;
diff --git a/components/sync/engine/sync_backend_registrar.cc b/components/sync/engine/sync_backend_registrar.cc index 9c1e66f6..a0f70c8 100644 --- a/components/sync/engine/sync_backend_registrar.cc +++ b/components/sync/engine/sync_backend_registrar.cc
@@ -42,7 +42,7 @@ // routing info at that point is expected to be empty. DCHECK(routing_info_.empty()); - // Set our initial state to reflect the current status of the sync directory. + // Set our initial state to reflect the current status of the sync Directory. // This will ensure that our calculations in ConfigureDataTypes() will always // return correct results. for (ModelType type : initial_types) {
diff --git a/components/sync/engine/sync_backend_registrar.h b/components/sync/engine/sync_backend_registrar.h index fe81005..25dc9055 100644 --- a/components/sync/engine/sync_backend_registrar.h +++ b/components/sync/engine/sync_backend_registrar.h
@@ -49,8 +49,8 @@ // Adds |type| to set of non-blocking types. These types are assigned to // GROUP_NON_BLOCKING model safe group and will be treated differently in - // ModelTypeRegistry. Unlike directory types, non-blocking types always stay - // assigned to GROUP_NON_BLOCKING group. + // ModelTypeRegistry. Unlike the legacy Directory types, non-blocking types + // always stay assigned to GROUP_NON_BLOCKING group. void RegisterNonBlockingType(ModelType type); // Informs the SyncBackendRegistrar of the currently enabled set of types.
diff --git a/components/sync/engine/sync_manager.h b/components/sync/engine/sync_manager.h index 5041fa0e..c41a9df 100644 --- a/components/sync/engine/sync_manager.h +++ b/components/sync/engine/sync_manager.h
@@ -93,10 +93,6 @@ InitArgs(); ~InitArgs(); - // Path in which to create or open sync's sqlite database (aka the - // directory). - base::FilePath database_location; - // Used to propagate events to chrome://sync-internals. Optional. WeakHandle<JsEventHandler> event_handler;
diff --git a/components/sync/engine_impl/all_status.h b/components/sync/engine_impl/all_status.h index a1e03b1..53985c0 100644 --- a/components/sync/engine_impl/all_status.h +++ b/components/sync/engine_impl/all_status.h
@@ -16,7 +16,6 @@ #include "components/sync/engine/sync_status.h" #include "components/sync/engine_impl/nudge_source.h" #include "components/sync/engine_impl/sync_engine_event_listener.h" -#include "components/sync/engine_impl/syncer_types.h" namespace syncer {
diff --git a/components/sync/engine_impl/model_type_registry.h b/components/sync/engine_impl/model_type_registry.h index 3c942f9..b2ccd05 100644 --- a/components/sync/engine_impl/model_type_registry.h +++ b/components/sync/engine_impl/model_type_registry.h
@@ -124,10 +124,10 @@ // The known ModelSafeWorkers. std::map<ModelSafeGroup, scoped_refptr<ModelSafeWorker>> workers_map_; - // A copy of the directory's most recent cryptographer. + // A copy of the most recent cryptographer. std::unique_ptr<Cryptographer> cryptographer_; - // A copy of the directory's most recent passphrase type. + // A copy of the most recent passphrase type. PassphraseType passphrase_type_ = SyncEncryptionHandler::kInitialPassphraseType;
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index e722182..53f16c5 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -28,7 +28,6 @@ #include "components/sync/engine_impl/model_type_connector_proxy.h" #include "components/sync/engine_impl/net/sync_server_connection_manager.h" #include "components/sync/engine_impl/sync_scheduler.h" -#include "components/sync/engine_impl/syncer_types.h" #include "components/sync/nigori/cryptographer.h" #include "components/sync/nigori/keystore_keys_handler.h" #include "components/sync/nigori/nigori.h"
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc index 6765ec7c..f1361b9 100644 --- a/components/sync/engine_impl/sync_manager_impl_unittest.cc +++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -175,7 +175,6 @@ encryption_observer_ = encryption_observer.get(); SyncManager::InitArgs args; - args.database_location = temp_dir_.GetPath(); args.service_url = GURL("https://example.com/"); args.post_factory = std::make_unique<TestHttpPostProviderFactory>(); args.workers = workers;
diff --git a/components/sync/engine_impl/syncer_proto_util.cc b/components/sync/engine_impl/syncer_proto_util.cc index 6ec00cb5..ddb08eb 100644 --- a/components/sync/engine_impl/syncer_proto_util.cc +++ b/components/sync/engine_impl/syncer_proto_util.cc
@@ -15,7 +15,6 @@ #include "components/sync/engine_impl/cycle/sync_cycle_context.h" #include "components/sync/engine_impl/net/server_connection_manager.h" #include "components/sync/engine_impl/syncer.h" -#include "components/sync/engine_impl/syncer_types.h" #include "components/sync/engine_impl/traffic_logger.h" #include "components/sync/protocol/sync_enums.pb.h" #include "components/sync/protocol/sync_protocol_error.h"
diff --git a/components/sync/engine_impl/syncer_types.h b/components/sync/engine_impl/syncer_types.h index 723b711..bc1cf571 100644 --- a/components/sync/engine_impl/syncer_types.h +++ b/components/sync/engine_impl/syncer_types.h
@@ -9,42 +9,6 @@ // in a single place without having dependencies between other files. namespace syncer { -enum UpdateAttemptResponse { - // Update was applied or safely ignored. - SUCCESS, - - // The conditions described by the following enum values are not mutually - // exclusive. The list has been ordered according to priority in the case of - // overlap, with highest priority first. - // - // For example, in the case where an item had both the IS_UNSYCNED and - // IS_UNAPPLIED_UPDATE flags set (CONFLICT_SIMPLE), and a SERVER_PARENT_ID - // that, if applied, would cause a directory loop (CONFLICT_HIERARCHY), and - // specifics that we can't decrypt right now (CONFLICT_ENCRYPTION), the - // UpdateApplicator would return CONFLICT_ENCRYPTION when attempting to - // process the item. - // - // We do not attempt to resolve CONFLICT_HIERARCHY or CONFLICT_ENCRYPTION - // items. We will leave these updates unapplied and wait for the server - // to send us newer updates that will resolve the conflict. - - // We were unable to decrypt/encrypt this server data. As such, we can't make - // forward progress on this node, but because the passphrase may not arrive - // until later we don't want to get the syncer stuck. See UpdateApplicator - // for how this is handled. - CONFLICT_ENCRYPTION, - - // These are some updates that, if applied, would violate the tree's - // invariants. Examples of this include the server adding children to locally - // deleted directories and directory moves that would create loops. - CONFLICT_HIERARCHY, - - // This indicates that item was modified both remotely (IS_UNAPPLIED_UPDATE) - // and locally (IS_UNSYNCED). We use the ConflictResolver to decide which of - // the changes should take priority, or if we can possibly merge the data. - CONFLICT_SIMPLE -}; - // Different results from the verify phase will yield different methods of // processing in the ProcessUpdates phase. The SKIP result means the entry // doesn't go to the ProcessUpdates phase.
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index 9f85d2a2..e3ad3fb 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -1059,7 +1059,7 @@ // |entity| could be null if there are some unapplied changes. if (entity != nullptr) { const sync_pb::EntityMetadata& metadata = entity->metadata(); - // Set id value as directory, "s" means server. + // Set id value as the legacy Directory implementation, "s" means server. data->id = "s" + metadata.server_id(); data->creation_time = ProtoTimeToTime(metadata.creation_time()); data->modification_time = ProtoTimeToTime(metadata.modification_time()); @@ -1077,8 +1077,8 @@ } // Create a permanent folder for this data type. Since sync server no longer - // create root folders, and USS won't migrate root folders from directory, we - // create root folders for each data type here. + // creates root folders, and USS won't migrate root folders from the + // Directory, we create root folders for each data type here. std::unique_ptr<base::DictionaryValue> rootnode = std::make_unique<base::DictionaryValue>(); // Function isTypeRootNode in sync_node_browser.js use PARENT_ID and
diff --git a/components/sync/model_impl/processor_entity.cc b/components/sync/model_impl/processor_entity.cc index 8c5ab2b..cbc4288c 100644 --- a/components/sync/model_impl/processor_entity.cc +++ b/components/sync/model_impl/processor_entity.cc
@@ -244,7 +244,7 @@ // - Original centity was committed to server, but client crashed before // receiving response. // - Entity was deleted while client was offline. - // Correct behavior is to send tombstone anyway, but directory based + // Correct behavior is to send tombstone anyway, but the legacy Directory // implementation doesn't and it is unclear how server will react to such // tombstones. Change the behavior to always sending tombstone after // experimenting with server.
diff --git a/components/sync/model_impl/syncable_service_based_bridge.h b/components/sync/model_impl/syncable_service_based_bridge.h index 6afaef9..c84d7ab 100644 --- a/components/sync/model_impl/syncable_service_based_bridge.h +++ b/components/sync/model_impl/syncable_service_based_bridge.h
@@ -31,8 +31,8 @@ // Implementation of ModelTypeSyncBridge that allows integrating legacy // datatypes that implement SyncableService. Internally, it uses a database to -// persist and mimic the legacy directory's behavior, but as opposed to the -// legacy directory, it's not exposed anywhere outside this bridge, and is +// persist and mimic the legacy Directory's behavior, but as opposed to the +// legacy Directory, it's not exposed anywhere outside this bridge, and is // considered an implementation detail. class SyncableServiceBasedBridge : public ModelTypeSyncBridge { public:
diff --git a/components/sync/nigori/nigori_model_type_processor.cc b/components/sync/nigori/nigori_model_type_processor.cc index 7948b9a..04b977cb 100644 --- a/components/sync/nigori/nigori_model_type_processor.cc +++ b/components/sync/nigori/nigori_model_type_processor.cc
@@ -237,7 +237,7 @@ if (entity_) { const sync_pb::EntityMetadata& metadata = entity_->metadata(); - // Set id value as directory, "s" means server. + // Set id value as the legacy Directory implementation, "s" means server. entity_data->id = "s" + metadata.server_id(); entity_data->creation_time = ProtoTimeToTime(metadata.creation_time()); entity_data->modification_time =
diff --git a/components/sync/protocol/persisted_entity_data.proto b/components/sync/protocol/persisted_entity_data.proto index 812070a9..95a3266f 100644 --- a/components/sync/protocol/persisted_entity_data.proto +++ b/components/sync/protocol/persisted_entity_data.proto
@@ -13,8 +13,8 @@ import "components/sync/protocol/sync.proto"; -// Sync proto to store entity data similar to what directory stores, used to -// persist data locally and never sent through the wire. +// Sync proto to store entity data similar to what the legacy Directory used +// to store, used to persist data locally and never sent through the wire. // // Because it's conceptually similar to SyncEntity (actual protocol) and it's // unclear how big this'll grow, we've kept compatibility with SyncEntity by
diff --git a/components/sync/protocol/sync_protocol_error.h b/components/sync/protocol/sync_protocol_error.h index 5101433..79b08a1 100644 --- a/components/sync/protocol/sync_protocol_error.h +++ b/components/sync/protocol/sync_protocol_error.h
@@ -63,7 +63,7 @@ STOP_SYNC_FOR_DISABLED_ACCOUNT, // Generated in response to CLIENT_DATA_OBSOLETE error. ProfileSyncService - // should stop sync engine, delete directory and restart sync engine. + // should stop sync engine, delete the data and restart sync engine. RESET_LOCAL_SYNC_DATA, // The default. No action.
diff --git a/components/sync/test/fake_server/entity_builder_factory.h b/components/sync/test/fake_server/entity_builder_factory.h index e8799a90..e3d7df0 100644 --- a/components/sync/test/fake_server/entity_builder_factory.h +++ b/components/sync/test/fake_server/entity_builder_factory.h
@@ -35,7 +35,7 @@ private: // An identifier used when creating entities. This value is used similarly to - // the value in the Sync directory code. + // the value in the legacy Sync Directory code. const std::string cache_guid_; };
diff --git a/components/viz/service/display_embedder/image_context_impl.cc b/components/viz/service/display_embedder/image_context_impl.cc index 2aa3836..2173d66 100644 --- a/components/viz/service/display_embedder/image_context_impl.cc +++ b/components/viz/service/display_embedder/image_context_impl.cc
@@ -12,6 +12,7 @@ #include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/command_buffer/service/shared_image_factory.h" #include "gpu/command_buffer/service/skia_utils.h" +#include "gpu/command_buffer/service/texture_manager.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" @@ -48,6 +49,11 @@ } void ImageContextImpl::OnContextLost() { + if (texture_passthrough_) { + texture_passthrough_->MarkContextLost(); + texture_passthrough_.reset(); + } + if (representation_) { representation_->OnContextLost(); representation_scoped_read_access_.reset(); @@ -144,6 +150,16 @@ return; } set_promise_image_texture(SkPromiseImageTexture::Make(backend_texture)); + + // Hold onto a reference to legacy GL textures while still in use, see + // https://crbug.com/1118166 for why this is necessary. + if (texture_base->GetType() == gpu::TextureBase::Type::kPassthrough) { + texture_passthrough_ = + gpu::gles2::TexturePassthrough::CheckedCast(texture_base); + } + // TODO(crbug.com/1118166): The case above handles textures with the + // passthrough command decoder, verify if something is required for the + // validating command decoder as well. } bool ImageContextImpl::BeginAccessIfNecessaryForSharedImage(
diff --git a/components/viz/service/display_embedder/image_context_impl.h b/components/viz/service/display_embedder/image_context_impl.h index 724eef3f..f18b93ca 100644 --- a/components/viz/service/display_embedder/image_context_impl.h +++ b/components/viz/service/display_embedder/image_context_impl.h
@@ -10,6 +10,7 @@ #include <vector> #include "base/macros.h" +#include "base/memory/ref_counted.h" #include "base/optional.h" #include "components/viz/common/quads/aggregated_render_pass.h" #include "components/viz/common/resources/resource_format.h" @@ -31,6 +32,9 @@ class SharedContextState; class SharedImageRepresentationFactory; class TextureBase; +namespace gles2 { +class TexturePassthrough; +} } // namespace gpu namespace viz { @@ -107,6 +111,8 @@ gpu::SharedContextState* fallback_context_state_ = nullptr; GrBackendTexture fallback_texture_; + // Only one of the follow should be non-null at the same time. + scoped_refptr<gpu::gles2::TexturePassthrough> texture_passthrough_; std::unique_ptr<gpu::SharedImageRepresentationSkia> representation_; // For scoped read accessing |representation|. It is only accessed on GPU
diff --git a/content/DEPS b/content/DEPS index 3d28a90b..23307a2 100644 --- a/content/DEPS +++ b/content/DEPS
@@ -41,7 +41,6 @@ "+printing", "+sandbox", "+services/proxy_resolver/public/mojom", - "+services/service_manager/embedder", "+services/service_manager/zygote", "+skia",
diff --git a/content/app/DEPS b/content/app/DEPS index 86a432d5..4674fd7 100644 --- a/content/app/DEPS +++ b/content/app/DEPS
@@ -11,6 +11,5 @@ "+gin/v8_initializer.h", "+services/network/public/cpp/features.h", "+services/resource_coordinator/public", - "+services/service_manager/embedder", "+services/tracing/public/cpp", ]
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 411a4d5..fcf6229 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -187,7 +187,6 @@ "//services/resource_coordinator:lib", "//services/resource_coordinator/public/cpp:resource_coordinator_cpp", "//services/service_manager", - "//services/service_manager/embedder:embedder_result_codes", "//services/service_manager/public/cpp", "//services/service_manager/public/mojom", "//services/shape_detection:lib", @@ -929,10 +928,6 @@ "font_access/font_access_manager_impl.h", "font_access/font_enumeration_cache.cc", "font_access/font_enumeration_cache.h", - "font_access/font_enumeration_cache_mac.h", - "font_access/font_enumeration_cache_mac.mm", - "font_access/font_enumeration_cache_win.cc", - "font_access/font_enumeration_cache_win.h", "font_list_async.cc", "generic_sensor/sensor_provider_proxy_impl.cc", "generic_sensor/sensor_provider_proxy_impl.h", @@ -2176,6 +2171,8 @@ sources += [ "../app_shim_remote_cocoa/web_contents_ns_view_bridge.h", "../app_shim_remote_cocoa/web_contents_ns_view_bridge.mm", + "font_access/font_enumeration_cache_mac.h", + "font_access/font_enumeration_cache_mac.mm", "gpu/ca_transaction_gpu_coordinator.cc", "gpu/ca_transaction_gpu_coordinator.h", "sandbox_support_mac_impl.h", @@ -2251,6 +2248,8 @@ if (is_win) { sources += [ + "font_access/font_enumeration_cache_win.cc", + "font_access/font_enumeration_cache_win.h", "installedapp/installed_app_provider_impl_win.cc", "installedapp/installed_app_provider_impl_win.h", "renderer_host/virtual_keyboard_controller_win.cc",
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 0c286cd8..7242f264 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -511,7 +511,7 @@ scoped_execution_fence) : parameters_(parameters), parsed_command_line_(parameters.command_line), - result_code_(service_manager::RESULT_CODE_NORMAL_EXIT), + result_code_(RESULT_CODE_NORMAL_EXIT), created_threads_(false), scoped_execution_fence_(std::move(scoped_execution_fence)) #if !defined(OS_ANDROID) @@ -605,7 +605,7 @@ if (parts_) { const int pre_early_init_error_code = parts_->PreEarlyInitialization(); - if (pre_early_init_error_code != service_manager::RESULT_CODE_NORMAL_EXIT) + if (pre_early_init_error_code != RESULT_CODE_NORMAL_EXIT) return pre_early_init_error_code; } @@ -674,7 +674,7 @@ if (parts_) parts_->PostEarlyInitialization(); - return service_manager::RESULT_CODE_NORMAL_EXIT; + return RESULT_CODE_NORMAL_EXIT; } void BrowserMainLoop::PreMainMessageLoopStart() {
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc index 2a99bb0..3f23bd2 100644 --- a/content/browser/child_process_launcher.cc +++ b/content/browser/child_process_launcher.cc
@@ -17,7 +17,6 @@ #include "content/public/browser/child_process_launcher_utils.h" #include "content/public/common/content_features.h" #include "content/public/common/sandboxed_process_launcher_delegate.h" -#include "services/service_manager/embedder/result_codes.h" namespace content {
diff --git a/content/browser/child_process_launcher_helper_fuchsia.cc b/content/browser/child_process_launcher_helper_fuchsia.cc index 8827cf7..d736bd3c 100644 --- a/content/browser/child_process_launcher_helper_fuchsia.cc +++ b/content/browser/child_process_launcher_helper_fuchsia.cc
@@ -10,7 +10,6 @@ #include "content/browser/child_process_launcher.h" #include "content/public/browser/child_process_launcher_utils.h" #include "content/public/common/sandboxed_process_launcher_delegate.h" -#include "services/service_manager/embedder/result_codes.h" namespace content { namespace internal { @@ -119,7 +118,7 @@ void ChildProcessLauncherHelper::ForceNormalProcessTerminationSync( ChildProcessLauncherHelper::Process process) { DCHECK(CurrentlyOnProcessLauncherTaskRunner()); - process.process.Terminate(service_manager::RESULT_CODE_NORMAL_EXIT, true); + process.process.Terminate(RESULT_CODE_NORMAL_EXIT, true); } } // namespace internal
diff --git a/content/browser/child_process_launcher_helper_linux.cc b/content/browser/child_process_launcher_helper_linux.cc index c1b5d30f..f3d40b62 100644 --- a/content/browser/child_process_launcher_helper_linux.cc +++ b/content/browser/child_process_launcher_helper_linux.cc
@@ -139,7 +139,7 @@ void ChildProcessLauncherHelper::ForceNormalProcessTerminationSync( ChildProcessLauncherHelper::Process process) { DCHECK(CurrentlyOnProcessLauncherTaskRunner()); - process.process.Terminate(service_manager::RESULT_CODE_NORMAL_EXIT, false); + process.process.Terminate(RESULT_CODE_NORMAL_EXIT, false); // On POSIX, we must additionally reap the child. if (process.zygote) { // If the renderer was created via a zygote, we have to proxy the reaping
diff --git a/content/browser/child_process_launcher_helper_mac.cc b/content/browser/child_process_launcher_helper_mac.cc index 9b72b3e..29248eb 100644 --- a/content/browser/child_process_launcher_helper_mac.cc +++ b/content/browser/child_process_launcher_helper_mac.cc
@@ -26,7 +26,6 @@ #include "sandbox/policy/sandbox.h" #include "sandbox/policy/sandbox_type.h" #include "sandbox/policy/switches.h" -#include "services/service_manager/embedder/result_codes.h" namespace content { namespace internal { @@ -160,7 +159,7 @@ DCHECK(CurrentlyOnProcessLauncherTaskRunner()); // Client has gone away, so just kill the process. Using exit code 0 means // that UMA won't treat this as a crash. - process.process.Terminate(service_manager::RESULT_CODE_NORMAL_EXIT, false); + process.process.Terminate(RESULT_CODE_NORMAL_EXIT, false); base::EnsureProcessTerminated(std::move(process.process)); }
diff --git a/content/browser/child_process_launcher_helper_win.cc b/content/browser/child_process_launcher_helper_win.cc index edb54c3..88854dcc 100644 --- a/content/browser/child_process_launcher_helper_win.cc +++ b/content/browser/child_process_launcher_helper_win.cc
@@ -18,7 +18,6 @@ #include "mojo/public/cpp/platform/platform_channel.h" #include "sandbox/policy/win/sandbox_win.h" #include "sandbox/win/src/sandbox_types.h" -#include "services/service_manager/embedder/result_codes.h" namespace content { namespace internal { @@ -107,7 +106,7 @@ DCHECK(CurrentlyOnProcessLauncherTaskRunner()); // Client has gone away, so just kill the process. Using exit code 0 means // that UMA won't treat this as a crash. - process.process.Terminate(service_manager::RESULT_CODE_NORMAL_EXIT, false); + process.process.Terminate(RESULT_CODE_NORMAL_EXIT, false); } void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread(
diff --git a/content/browser/font_access/font_enumeration_cache_fontconfig.cc b/content/browser/font_access/font_enumeration_cache_fontconfig.cc index bc2879b..4c638da 100644 --- a/content/browser/font_access/font_enumeration_cache_fontconfig.cc +++ b/content/browser/font_access/font_enumeration_cache_fontconfig.cc
@@ -7,7 +7,7 @@ #include <fontconfig/fontconfig.h> #include "base/feature_list.h" -#include "base/metrics/histogram_macros.h" +#include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" @@ -83,7 +83,7 @@ // Metrics. const base::ElapsedTimer start_timer; int incomplete_count = 0; - int dupe_count = 0; + int duplicate_count = 0; auto font_enumeration_table = std::make_unique<blink::FontEnumerationTable>(); @@ -94,7 +94,7 @@ std::unique_ptr<FcFontSet, decltype(&FcFontSetDestroy)> fontset( ListFonts(object_set.get()), FcFontSetDestroy); - UMA_HISTOGRAM_CUSTOM_COUNTS( + base::UmaHistogramCustomCounts( "Fonts.AccessAPI.EnumerationCache.Fontconfig.FontCount", fontset->nfont, 1, 5000, 50); @@ -120,7 +120,7 @@ } if (fonts_seen.count(postscript_name) != 0) { - ++dupe_count; + ++duplicate_count; // Skip duplicates. continue; } @@ -137,17 +137,16 @@ *added_font_meta = metadata; } - UMA_HISTOGRAM_COUNTS_100( + base::UmaHistogramCounts100( "Fonts.AccessAPI.EnumerationCache.Fontconfig.IncompleteFontCount", incomplete_count); - UMA_HISTOGRAM_COUNTS_100( - "Fonts.AccessAPI.EnumerationCache.Fontconfig.DuplicateFontCount", - dupe_count); + base::UmaHistogramCounts100( + "Fonts.AccessAPI.EnumerationCache.DuplicateFontCount", duplicate_count); BuildEnumerationCache(std::move(font_enumeration_table)); - UMA_HISTOGRAM_MEDIUM_TIMES("Fonts.AccessAPI.EnumerationTime", - start_timer.Elapsed()); + base::UmaHistogramMediumTimes("Fonts.AccessAPI.EnumerationTime", + start_timer.Elapsed()); // Respond to pending and future requests. StartCallbacksTaskQueue(); }
diff --git a/content/browser/font_access/font_enumeration_cache_mac.mm b/content/browser/font_access/font_enumeration_cache_mac.mm index e4f696b..0e3e4eb0 100644 --- a/content/browser/font_access/font_enumeration_cache_mac.mm +++ b/content/browser/font_access/font_enumeration_cache_mac.mm
@@ -9,7 +9,7 @@ #include "base/feature_list.h" #include "base/mac/foundation_util.h" -#include "base/metrics/histogram_macros.h" +#include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" #include "base/strings/sys_string_conversions.h" #include "base/task/task_traits.h" @@ -81,6 +81,10 @@ base::ScopedCFTypeRef<CFArrayRef> font_descs( CTFontCollectionCreateMatchingFontDescriptors(collection)); + // Used to filter duplicates. + std::set<std::string> fonts_seen; + int duplicate_count = 0; + for (CFIndex i = 0; i < CFArrayGetCount(font_descs); ++i) { CTFontDescriptorRef fd = base::mac::CFCast<CTFontDescriptorRef>( CFArrayGetValueAtIndex(font_descs, i)); @@ -91,9 +95,18 @@ base::ScopedCFTypeRef<CFStringRef> cf_family = GetLocalizedString(fd, kCTFontFamilyNameAttribute); + std::string postscript_name = + base::SysCFStringRefToUTF8(cf_postscript_name.get()); + + if (fonts_seen.count(postscript_name) != 0) { + ++duplicate_count; + // Skip duplicates. + continue; + } + fonts_seen.insert(postscript_name); + blink::FontEnumerationTable_FontMetadata metadata; - metadata.set_postscript_name( - base::SysCFStringRefToUTF8(cf_postscript_name.get()).c_str()); + metadata.set_postscript_name(postscript_name.c_str()); metadata.set_full_name( base::SysCFStringRefToUTF8(cf_full_name.get()).c_str()); metadata.set_family(base::SysCFStringRefToUTF8(cf_family.get()).c_str()); @@ -105,8 +118,10 @@ BuildEnumerationCache(std::move(font_enumeration_table)); - UMA_HISTOGRAM_MEDIUM_TIMES("Fonts.AccessAPI.EnumerationTime", - start_timer.Elapsed()); + base::UmaHistogramCounts100( + "Fonts.AccessAPI.EnumerationCache.DuplicateFontCount", duplicate_count); + base::UmaHistogramMediumTimes("Fonts.AccessAPI.EnumerationTime", + start_timer.Elapsed()); // Respond to pending and future requests. StartCallbacksTaskQueue(); }
diff --git a/content/browser/font_access/font_enumeration_cache_win.cc b/content/browser/font_access/font_enumeration_cache_win.cc index 95bcfb7..5f9a774f 100644 --- a/content/browser/font_access/font_enumeration_cache_win.cc +++ b/content/browser/font_access/font_enumeration_cache_win.cc
@@ -248,7 +248,7 @@ outstanding_family_results_ = collection_->GetFontFamilyCount(); - UMA_HISTOGRAM_CUSTOM_COUNTS( + base::UmaHistogramCustomCounts( "Fonts.AccessAPI.EnumerationCache.Dwrite.FamilyCount", outstanding_family_results_, 1, 5000, 50); } @@ -282,7 +282,20 @@ if (FAILED(family_data_result->exit_hresult)) enumeration_errors_[family_data_result->exit_hresult]++; + // Used to filter duplicates. + std::set<std::string> fonts_seen; + int duplicate_count = 0; + for (const auto& font_meta : family_data_result->fonts) { + const std::string& postscript_name = font_meta.postscript_name(); + + if (fonts_seen.count(postscript_name) != 0) { + ++duplicate_count; + // Skip duplicates. + continue; + } + fonts_seen.insert(postscript_name); + blink::FontEnumerationTable_FontMetadata* added_font_meta = font_enumeration_table_->add_fonts(); *added_font_meta = font_meta; @@ -291,6 +304,9 @@ if (!outstanding_family_results_) { FinalizeEnumerationCache(); } + + base::UmaHistogramCounts100( + "Fonts.AccessAPI.EnumerationCache.DuplicateFontCount", duplicate_count); } void FontEnumerationCacheWin::FinalizeEnumerationCache() { @@ -316,8 +332,8 @@ std::move(font_enumeration_table_)); BuildEnumerationCache(std::move(enumeration_table)); - UMA_HISTOGRAM_MEDIUM_TIMES("Fonts.AccessAPI.EnumerationTime", - enumeration_timer_->Elapsed()); + base::UmaHistogramMediumTimes("Fonts.AccessAPI.EnumerationTime", + enumeration_timer_->Elapsed()); enumeration_timer_.reset(); // Respond to pending and future requests.
diff --git a/content/browser/hid/hid_service.cc b/content/browser/hid/hid_service.cc index efccfa37..e82e310 100644 --- a/content/browser/hid/hid_service.cc +++ b/content/browser/hid/hid_service.cc
@@ -23,9 +23,13 @@ HidService::HidService(RenderFrameHost* render_frame_host, mojo::PendingReceiver<blink::mojom::HidService> receiver) - : FrameServiceBase(render_frame_host, std::move(receiver)) { - watchers_.set_disconnect_handler(base::BindRepeating( - &HidService::OnWatcherConnectionError, base::Unretained(this))); + : FrameServiceBase(render_frame_host, std::move(receiver)), + requesting_origin_(render_frame_host->GetLastCommittedOrigin()), + embedding_origin_( + render_frame_host->GetMainFrame()->GetLastCommittedOrigin()) { + watchers_.set_disconnect_handler( + base::BindRepeating(&HidService::OnWatcherRemoved, base::Unretained(this), + true /* cleanup_watcher_ids */)); HidDelegate* delegate = GetContentClient()->browser()->GetHidDelegate(); if (delegate) @@ -107,7 +111,10 @@ } mojo::PendingRemote<device::mojom::HidConnectionWatcher> watcher; - watchers_.Add(this, watcher.InitWithNewPipeAndPassReceiver()); + mojo::ReceiverId receiver_id = + watchers_.Add(this, watcher.InitWithNewPipeAndPassReceiver()); + watcher_ids_.insert({device_guid, receiver_id}); + GetContentClient() ->browser() ->GetHidDelegate() @@ -118,9 +125,16 @@ std::move(callback))); } -void HidService::OnWatcherConnectionError() { +void HidService::OnWatcherRemoved(bool cleanup_watcher_ids) { if (watchers_.empty()) DecrementActiveFrameCount(); + + if (cleanup_watcher_ids) { + // Clean up any associated |watchers_ids_| entries. + base::EraseIf(watcher_ids_, [&](const auto& watcher_entry) { + return watcher_entry.second == watchers_.current_receiver(); + }); + } } void HidService::DecrementActiveFrameCount() { @@ -165,8 +179,26 @@ return; } - // TODO(mattreynolds): Close connection between Blink and the device if the - // device lost permission. + HidDelegate* delegate = GetContentClient()->browser()->GetHidDelegate(); + WebContents* web_contents = + WebContents::FromRenderFrameHost(render_frame_host()); + + base::EraseIf(watcher_ids_, [&](const auto& watcher_entry) { + const auto* device_info = + delegate->GetDeviceInfo(web_contents, watcher_entry.first); + if (!device_info) + return true; + + if (delegate->HasDevicePermission(web_contents, origin(), *device_info)) { + return false; + } + + watchers_.Remove(watcher_entry.second); + return true; + }); + + // If needed decrement the active frame count. + OnWatcherRemoved(false /* cleanup_watcher_ids */); } void HidService::FinishGetDevices(
diff --git a/content/browser/hid/hid_service.h b/content/browser/hid/hid_service.h index ead8fe0..3eb495da 100644 --- a/content/browser/hid/hid_service.h +++ b/content/browser/hid/hid_service.h
@@ -60,7 +60,7 @@ HidService(RenderFrameHost*, mojo::PendingReceiver<blink::mojom::HidService>); ~HidService() override; - void OnWatcherConnectionError(); + void OnWatcherRemoved(bool cleanup_watcher_ids); void DecrementActiveFrameCount(); void FinishGetDevices(GetDevicesCallback callback, @@ -84,6 +84,10 @@ // the WebContentsImpl when an active connection indicator should be shown. mojo::ReceiverSet<device::mojom::HidConnectionWatcher> watchers_; + // Maps every receiver to a guid to allow closing particular connections when + // the user revokes a permission. + std::multimap<std::string, mojo::ReceiverId> watcher_ids_; + base::WeakPtrFactory<HidService> weak_factory_{this}; };
diff --git a/content/browser/hid/hid_service_unittest.cc b/content/browser/hid/hid_service_unittest.cc index 56b69351..13cc8876 100644 --- a/content/browser/hid/hid_service_unittest.cc +++ b/content/browser/hid/hid_service_unittest.cc
@@ -331,4 +331,56 @@ device_removed_loop.Run(); } +TEST_F(HidServiceTest, RevokeDevicePermission) { + NavigateAndCommit(GURL(kTestUrl)); + + mojo::Remote<blink::mojom::HidService> service; + contents()->GetMainFrame()->GetHidService( + service.BindNewPipeAndPassReceiver()); + + // For now the device has permission. + EXPECT_CALL(hid_delegate(), HasDevicePermission).WillOnce(Return(true)); + + // Create a new device. + auto device_info = device::mojom::HidDeviceInfo::New(); + device_info->guid = kTestGuid; + ConnectDevice(*device_info); + EXPECT_CALL(hid_delegate(), GetDeviceInfo) + .WillOnce(Return(device_info.get())); + + // Connect the device. + mojo::PendingRemote<device::mojom::HidConnectionClient> hid_connection_client; + connection_client()->Bind( + hid_connection_client.InitWithNewPipeAndPassReceiver()); + + EXPECT_FALSE(contents()->IsConnectedToHidDevice()); + + base::RunLoop run_loop; + mojo::Remote<device::mojom::HidConnection> connection; + service->Connect( + kTestGuid, std::move(hid_connection_client), + base::BindLambdaForTesting( + [&run_loop, + &connection](mojo::PendingRemote<device::mojom::HidConnection> c) { + connection.Bind(std::move(c)); + run_loop.Quit(); + })); + run_loop.Run(); + + EXPECT_TRUE(contents()->IsConnectedToHidDevice()); + EXPECT_TRUE(connection); + + // Simulate user revoking permission. + EXPECT_CALL(hid_delegate(), HasDevicePermission).WillOnce(Return(false)); + url::Origin origin = url::Origin::Create(GURL(kTestUrl)); + hid_delegate().OnPermissionRevoked(origin, origin); + + // TODO(mattreynolds): Use a disconnect handler with a run loop instead of the + // potentially flaky `RunUntilIdle`. This depends on fixing + // `FakeHidConnection` to monitor the watcher just as `HidConnectionImpl` + // does. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(contents()->IsConnectedToHidDevice()); +} + } // namespace content
diff --git a/content/browser/hid/hid_test_utils.cc b/content/browser/hid/hid_test_utils.cc index 38c01d5..6ce8ad6 100644 --- a/content/browser/hid/hid_test_utils.cc +++ b/content/browser/hid/hid_test_utils.cc
@@ -44,6 +44,12 @@ observer.OnDeviceRemoved(device); } +void MockHidDelegate::OnPermissionRevoked(const url::Origin& requesting_origin, + const url::Origin& embedding_origin) { + for (auto& observer : observer_list_) + observer.OnPermissionRevoked(requesting_origin, embedding_origin); +} + HidTestContentBrowserClient::HidTestContentBrowserClient() = default; HidTestContentBrowserClient::~HidTestContentBrowserClient() = default;
diff --git a/content/browser/hid/hid_test_utils.h b/content/browser/hid/hid_test_utils.h index bf800a6..bb124509 100644 --- a/content/browser/hid/hid_test_utils.h +++ b/content/browser/hid/hid_test_utils.h
@@ -14,6 +14,7 @@ #include "services/device/public/mojom/hid.mojom-forward.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/public/mojom/hid/hid.mojom-forward.h" +#include "url/origin.h" namespace content { @@ -41,6 +42,8 @@ // these methods to broadcast device connections to all delegate observers. void OnDeviceAdded(const device::mojom::HidDeviceInfo& device); void OnDeviceRemoved(const device::mojom::HidDeviceInfo& device); + void OnPermissionRevoked(const url::Origin& requesting_origin, + const url::Origin& embedding_origin); MOCK_METHOD0(RunChooserInternal, std::vector<device::mojom::HidDeviceInfoPtr>()); @@ -53,6 +56,10 @@ const device::mojom::HidDeviceInfo& device)); MOCK_METHOD1(GetHidManager, device::mojom::HidManager*(content::WebContents* web_contents)); + MOCK_METHOD2( + GetDeviceInfo, + const device::mojom::HidDeviceInfo*(content::WebContents* web_contents, + const std::string& guid)); private: base::ObserverList<Observer> observer_list_;
diff --git a/content/browser/net/cross_origin_opener_policy_reporter.cc b/content/browser/net/cross_origin_opener_policy_reporter.cc index c1080fdf..ac9cab4 100644 --- a/content/browser/net/cross_origin_opener_policy_reporter.cc +++ b/content/browser/net/cross_origin_opener_policy_reporter.cc
@@ -34,7 +34,7 @@ constexpr char kProperty[] = "property"; constexpr char kReferrer[] = "referrer"; constexpr char kSourceFile[] = "sourceFile"; -constexpr char kViolationType[] = "type"; +constexpr char kType[] = "type"; // Report attribute values: constexpr char kDispositionEnforce[] = "enforce"; @@ -55,23 +55,6 @@ } } -const char* ToString(network::mojom::CoopAccessReportType report_type) { - switch (report_type) { - case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOpener: - return "access-from-coop-page-to-opener"; - case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOpenee: - return "access-from-coop-page-to-openee"; - case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOther: - return "access-from-coop-page-to-other"; - case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOpener: - return "access-to-coop-page-from-opener"; - case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOpenee: - return "access-to-coop-page-from-openee"; - case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOther: - return "access-to-coop-page-from-other"; - } -} - base::Optional<base::UnguessableToken> GetFrameToken( FrameTreeNode* frame, SiteInstance* site_instance) { @@ -182,7 +165,7 @@ body.SetString(kPreviousURL, same_origin_with_previous ? SanitizedURL(previous_url) : ""); body.SetString(kReferrer, context_referrer_url_); - body.SetString(kViolationType, kTypeToResponse); + body.SetString(kType, kTypeToResponse); QueueNavigationReport(std::move(body), *endpoint, is_report_only); } @@ -202,7 +185,7 @@ sanitized_next_url = SanitizedURL(next_url); base::DictionaryValue body; body.SetString(kNextURL, sanitized_next_url); - body.SetString(kViolationType, kTypeFromResponse); + body.SetString(kType, kTypeFromResponse); QueueNavigationReport(std::move(body), *endpoint, is_report_only); } @@ -223,7 +206,7 @@ network::features::kCrossOriginOpenerPolicyAccessReporting)); base::DictionaryValue body; - body.SetStringPath(kViolationType, ToString(report_type)); + body.SetStringPath(kType, network::CoopAccessReportTypeToString(report_type)); body.SetStringPath(kDisposition, kDispositionReporting); body.SetStringPath(kEffectivePolicy, ToString(coop_.report_only_value));
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 474c064e..a4d7f7d 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -265,7 +265,6 @@ "//services/network/public/cpp", "//services/network/public/mojom", "//services/resource_coordinator/public/cpp/memory_instrumentation", - "//services/service_manager/embedder:embedder_result_codes", "//services/service_manager/public/mojom", "//services/video_capture/public/mojom", "//services/viz/public/mojom",
diff --git a/content/common/zygote/zygote_communication_linux.cc b/content/common/zygote/zygote_communication_linux.cc index a2497b46..bdc2b0a 100644 --- a/content/common/zygote/zygote_communication_linux.cc +++ b/content/common/zygote/zygote_communication_linux.cc
@@ -19,8 +19,8 @@ #include "base/stl_util.h" #include "content/common/zygote/zygote_commands_linux.h" #include "content/public/common/content_switches.h" +#include "content/public/common/result_codes.h" #include "sandbox/policy/switches.h" -#include "services/service_manager/embedder/result_codes.h" #include "third_party/icu/source/i18n/unicode/timezone.h" namespace content { @@ -279,7 +279,7 @@ // Set this now to handle the error cases. if (exit_code) - *exit_code = service_manager::RESULT_CODE_NORMAL_EXIT; + *exit_code = RESULT_CODE_NORMAL_EXIT; int status = base::TERMINATION_STATUS_NORMAL_TERMINATION; if (len == -1) {
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index 216ec97..bd83dfa 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -483,7 +483,6 @@ "//ppapi/c", "//services/device/public/cpp/geolocation", "//services/metrics/public/cpp:metrics_cpp", - "//services/service_manager/embedder:embedder_result_codes", "//ui/accessibility", "//ui/base", "//ui/base/clipboard",
diff --git a/content/public/browser/browser_main_parts.cc b/content/public/browser/browser_main_parts.cc index 7d75bc6f..8980628 100644 --- a/content/public/browser/browser_main_parts.cc +++ b/content/public/browser/browser_main_parts.cc
@@ -4,12 +4,12 @@ #include "content/public/browser/browser_main_parts.h" -#include "services/service_manager/embedder/result_codes.h" +#include "content/public/common/result_codes.h" namespace content { int BrowserMainParts::PreEarlyInitialization() { - return service_manager::RESULT_CODE_NORMAL_EXIT; + return RESULT_CODE_NORMAL_EXIT; } int BrowserMainParts::PreCreateThreads() {
diff --git a/content/public/browser/child_process_termination_info.h b/content/public/browser/child_process_termination_info.h index deb21d02..8195864 100644 --- a/content/public/browser/child_process_termination_info.h +++ b/content/public/browser/child_process_termination_info.h
@@ -27,7 +27,7 @@ // contain a platform specific launch failure error code. Otherwise, it will // contain the exit code for the process (e.g. status from waitpid if on // posix, from GetExitCodeProcess on Windows). - int exit_code = service_manager::RESULT_CODE_NORMAL_EXIT; + int exit_code = RESULT_CODE_NORMAL_EXIT; // Populated only for renderer process. True if there are any visible // clients at the time of process death.
diff --git a/content/public/browser/hid_delegate.h b/content/public/browser/hid_delegate.h index 758fdbf3..4d9c8b7 100644 --- a/content/public/browser/hid_delegate.h +++ b/content/public/browser/hid_delegate.h
@@ -76,6 +76,11 @@ // object. virtual void AddObserver(RenderFrameHost* frame, Observer* observer) = 0; virtual void RemoveObserver(RenderFrameHost* frame, Observer* observer) = 0; + + // Gets the device info for a particular device, identified by its guid. + virtual const device::mojom::HidDeviceInfo* GetDeviceInfo( + content::WebContents* web_contents, + const std::string& guid) = 0; }; } // namespace content
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index dc190f1..674af74db 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -32,8 +32,6 @@ # header-only dependency, without bringing in all of content. source_set("result_codes") { sources = [ "result_codes.h" ] - - deps = [ "//services/service_manager/embedder:embedder_result_codes" ] } # This target allows other targets to depend on content_descriptors.h which is @@ -226,7 +224,6 @@ "//ppapi/buildflags", "//ppapi/c", "//services/network/public/cpp", - "//services/service_manager/embedder:embedder_result_codes", "//services/service_manager/public/cpp", "//skia", "//storage/common",
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index 76cec14..0053ecf 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -140,6 +140,7 @@ IPC_STRUCT_TRAITS_MEMBER(caret_browsing_enabled) #if defined(OS_LINUX) || defined(OS_CHROMEOS) IPC_STRUCT_TRAITS_MEMBER(system_font_family_name) + IPC_STRUCT_TRAITS_MEMBER(selection_clipboard_buffer_available) #endif #if defined(OS_WIN) IPC_STRUCT_TRAITS_MEMBER(caption_font_family_name)
diff --git a/content/public/common/result_codes.h b/content/public/common/result_codes.h index a0b0b74..00ff24c 100644 --- a/content/public/common/result_codes.h +++ b/content/public/common/result_codes.h
@@ -5,8 +5,6 @@ #ifndef CONTENT_PUBLIC_COMMON_RESULT_CODES_H_ #define CONTENT_PUBLIC_COMMON_RESULT_CODES_H_ -#include "services/service_manager/embedder/result_codes.h" - namespace content { // This file consolidates all the return codes for the browser and renderer @@ -30,10 +28,10 @@ // TODO(wfh): Break the dependency so it is possible to add more values. enum ResultCode { - RESULT_CODE_CONTENT_START = service_manager::RESULT_CODE_LAST_CODE, + RESULT_CODE_NORMAL_EXIT, // Process was killed by user or system. - RESULT_CODE_KILLED = RESULT_CODE_CONTENT_START, + RESULT_CODE_KILLED, // Process hung. RESULT_CODE_HUNG,
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index 65a27d0..6b130b0f 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -934,9 +934,7 @@ ? blink::WebString::FromUTF8(head.cache_storage_cache_name) : blink::WebString()); - response->SetRemoteIPAddress(WebString::FromUTF8( - net::HostPortPair::FromIPEndPoint(head.remote_endpoint).HostForURL())); - response->SetRemotePort(head.remote_endpoint.port()); + response->SetRemoteIPEndpoint(head.remote_endpoint); // This computation can only be done once SetUrlListViaServiceWorker() has // been called on |response|, so that ResponseUrl() returns the correct
diff --git a/content/renderer/loader/web_url_loader_impl_unittest.cc b/content/renderer/loader/web_url_loader_impl_unittest.cc index 6faa82a5..7648df0c 100644 --- a/content/renderer/loader/web_url_loader_impl_unittest.cc +++ b/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -456,31 +456,34 @@ EXPECT_TRUE(dispatcher()->defers_loading()); } -TEST_F(WebURLLoaderImplTest, ResponseIPAddress) { +TEST_F(WebURLLoaderImplTest, ResponseIPEndpoint) { GURL url("http://example.test/"); struct TestCase { const char* ip; - const char* expected; + uint16_t port; } cases[] = { - {"127.0.0.1", "127.0.0.1"}, - {"123.123.123.123", "123.123.123.123"}, - {"::1", "[::1]"}, - {"2001:0db8:85a3:0000:0000:8a2e:0370:7334", - "[2001:db8:85a3::8a2e:370:7334]"}, - {"2001:db8:85a3:0:0:8a2e:370:7334", "[2001:db8:85a3::8a2e:370:7334]"}, - {"2001:db8:85a3::8a2e:370:7334", "[2001:db8:85a3::8a2e:370:7334]"}, - {"::ffff:192.0.2.128", "[::ffff:c000:280]"}}; + {"127.0.0.1", 443}, + {"123.123.123.123", 80}, + {"::1", 22}, + {"2001:0db8:85a3:0000:0000:8a2e:0370:7334", 1337}, + {"2001:db8:85a3:0:0:8a2e:370:7334", 12345}, + {"2001:db8:85a3::8a2e:370:7334", 8080}, + {"::ffff:192.0.2.128", 8443}, + }; for (const auto& test : cases) { SCOPED_TRACE(test.ip); - network::mojom::URLResponseHead head; + net::IPAddress address; ASSERT_TRUE(address.AssignFromIPLiteral(test.ip)); - head.remote_endpoint = net::IPEndPoint(address, 443); + + network::mojom::URLResponseHead head; + head.remote_endpoint = net::IPEndPoint(address, test.port); + blink::WebURLResponse response; WebURLLoaderImpl::PopulateURLResponse(url, head, &response, true, -1); - EXPECT_EQ(test.expected, response.RemoteIPAddress().Utf8()); + EXPECT_EQ(head.remote_endpoint, response.RemoteIPEndpoint()); }; }
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index c8015df..578e434 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -235,7 +235,6 @@ "//net:net_resources", "//ppapi/buildflags", "//services/network/public/cpp", - "//services/service_manager/embedder:embedder_result_codes", "//services/test/echo:lib", "//services/test/echo/public/mojom", "//third_party/blink/public:blink",
diff --git a/content/shell/DEPS b/content/shell/DEPS index cef6986e..265cdfa 100644 --- a/content/shell/DEPS +++ b/content/shell/DEPS
@@ -40,9 +40,6 @@ "+components/viz/common/switches.h", "+services/test/echo", - # Access to the process specific switches. - "+services/service_manager/embedder", - # Separating content shell and web test code. Only narrow parts of content # shell may access and inject web test code at runtime. "-content/web_test/browser",
diff --git a/content/shell/browser/shell_browser_main_parts.cc b/content/shell/browser/shell_browser_main_parts.cc index 86d7269..881bdd5 100644 --- a/content/shell/browser/shell_browser_main_parts.cc +++ b/content/shell/browser/shell_browser_main_parts.cc
@@ -23,6 +23,7 @@ #include "content/public/browser/storage_partition.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" +#include "content/public/common/result_codes.h" #include "content/public/common/url_constants.h" #include "content/shell/android/shell_descriptors.h" #include "content/shell/browser/shell.h" @@ -34,7 +35,6 @@ #include "net/base/filename_util.h" #include "net/base/net_module.h" #include "net/grit/net_resources.h" -#include "services/service_manager/embedder/result_codes.h" #include "ui/base/resource/resource_bundle.h" #include "url/gurl.h" @@ -148,7 +148,7 @@ net::NetworkChangeNotifier::SetFactory( new net::NetworkChangeNotifierFactoryAndroid()); #endif - return service_manager::RESULT_CODE_NORMAL_EXIT; + return RESULT_CODE_NORMAL_EXIT; } void ShellBrowserMainParts::InitializeBrowserContexts() {
diff --git a/content/zygote/BUILD.gn b/content/zygote/BUILD.gn index 9ef08ea..dcf5726 100644 --- a/content/zygote/BUILD.gn +++ b/content/zygote/BUILD.gn
@@ -21,7 +21,6 @@ "//ipc", "//sandbox", "//sandbox/policy", - "//services/service_manager/embedder:embedder_result_codes", "//third_party/icu", ]
diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc index 7a43c9b..95d5a82 100644 --- a/content/zygote/zygote_linux.cc +++ b/content/zygote/zygote_linux.cc
@@ -36,6 +36,7 @@ #include "content/common/zygote/zygote_commands_linux.h" #include "content/public/common/content_descriptors.h" #include "content/public/common/content_switches.h" +#include "content/public/common/result_codes.h" #include "content/public/common/zygote/send_zygote_child_ping_linux.h" #include "content/public/common/zygote/zygote_fork_delegate_linux.h" #include "ipc/ipc_channel.h" @@ -43,7 +44,6 @@ #include "sandbox/linux/services/namespace_sandbox.h" #include "sandbox/policy/linux/sandbox_linux.h" #include "sandbox/policy/sandbox.h" -#include "services/service_manager/embedder/result_codes.h" #include "third_party/icu/source/i18n/unicode/timezone.h" // See @@ -128,7 +128,7 @@ // right after the process starts and it may fail to send zygote magic // number to browser process. if (!r) - _exit(service_manager::RESULT_CODE_NORMAL_EXIT); + _exit(RESULT_CODE_NORMAL_EXIT); #else CHECK(r) << "Sending zygote magic failed"; #endif @@ -377,7 +377,7 @@ // it terminated normally. NOTREACHED(); status = base::TERMINATION_STATUS_NORMAL_TERMINATION; - exit_code = service_manager::RESULT_CODE_NORMAL_EXIT; + exit_code = RESULT_CODE_NORMAL_EXIT; } base::Pickle write_pickle;
diff --git a/device/fido/cable/v2_authenticator.cc b/device/fido/cable/v2_authenticator.cc index 8fb4435..8e4225f 100644 --- a/device/fido/cable/v2_authenticator.cc +++ b/device/fido/cable/v2_authenticator.cc
@@ -372,6 +372,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!msg) { + FIDO_LOG(DEBUG) << "WebSocket tunnel closed"; read_callback_.Run(base::nullopt); return; } @@ -482,6 +483,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!msg) { + FIDO_LOG(ERROR) << "Closing transaction due to transport EOF"; std::move(complete_callback_).Run(); return; }
diff --git a/device/fido/cable/websocket_adapter.cc b/device/fido/cable/websocket_adapter.cc index fd36f05..b522f58d 100644 --- a/device/fido/cable/websocket_adapter.cc +++ b/device/fido/cable/websocket_adapter.cc
@@ -93,6 +93,12 @@ write_pipe_ = std::move(writable); client_receiver_.Bind(std::move(client_receiver)); + // |handshake_receiver_| will disconnect soon. In order to catch network + // process crashes, we switch to watching |client_receiver_|. + handshake_receiver_.set_disconnect_handler(base::DoNothing()); + client_receiver_.set_disconnect_handler(base::BindOnce( + &WebSocketAdapter::OnMojoPipeDisconnect, base::Unretained(this))); + socket_remote_->StartReceiving(); std::move(on_tunnel_ready_).Run(true, routing_id);
diff --git a/extensions/browser/api/execute_code_function.cc b/extensions/browser/api/execute_code_function.cc index c0b1b1b..3d5e4ac1 100644 --- a/extensions/browser/api/execute_code_function.cc +++ b/extensions/browser/api/execute_code_function.cc
@@ -130,9 +130,13 @@ if (!extension() && !IsWebView()) return false; - ScriptExecutor::ScriptType script_type = ScriptExecutor::JAVASCRIPT; + DCHECK(!(ShouldInsertCSS() && ShouldRemoveCSS())); + + auto action_type = UserScript::ActionType::ADD_JAVASCRIPT; if (ShouldInsertCSS()) - script_type = ScriptExecutor::CSS; + action_type = UserScript::ActionType::ADD_CSS; + else if (ShouldRemoveCSS()) + action_type = UserScript::ActionType::REMOVE_CSS; ScriptExecutor::FrameScope frame_scope = details_->all_frames.get() && *details_->all_frames @@ -169,7 +173,7 @@ css_origin = CSS_ORIGIN_AUTHOR; executor->ExecuteScript( - host_id_, script_type, code_string, frame_scope, frame_id, + host_id_, action_type, code_string, frame_scope, frame_id, match_about_blank, run_at, IsWebView() ? ScriptExecutor::WEB_VIEW_PROCESS : ScriptExecutor::DEFAULT_PROCESS, @@ -193,7 +197,7 @@ return RespondNow(Error(kMoreThanOneValuesError)); if (details_->css_origin != api::extension_types::CSS_ORIGIN_NONE && - !ShouldInsertCSS()) { + !ShouldInsertCSS() && !ShouldRemoveCSS()) { return RespondNow(Error(kCSSOriginForNonCSSError)); } @@ -236,7 +240,8 @@ extension()); // TODO(lazyboy): |extension_id| should not be empty(), turn this into a // DCHECK. - bool might_require_localization = ShouldInsertCSS() && !extension_id.empty(); + bool might_require_localization = + (ShouldInsertCSS() || ShouldRemoveCSS()) && !extension_id.empty(); int resource_id = 0; const ComponentExtensionResourceManager* component_extension_resource_manager = @@ -285,9 +290,10 @@ return; } - // insertCSS doesn't have a result argument. - Respond(ShouldInsertCSS() ? NoArguments() - : OneArgument(result.CreateDeepCopy())); + // insertCSS and removeCSS don't have a result argument. + Respond(ShouldInsertCSS() || ShouldRemoveCSS() + ? NoArguments() + : OneArgument(result.CreateDeepCopy())); } } // namespace extensions
diff --git a/extensions/browser/api/execute_code_function.h b/extensions/browser/api/execute_code_function.h index 7588dbf..291c9e2 100644 --- a/extensions/browser/api/execute_code_function.h +++ b/extensions/browser/api/execute_code_function.h
@@ -46,6 +46,7 @@ // fatal (VALIDATION_FAILURE). virtual InitResult Init() = 0; virtual bool ShouldInsertCSS() const = 0; + virtual bool ShouldRemoveCSS() const = 0; virtual bool CanExecuteScriptOnPage(std::string* error) = 0; virtual ScriptExecutor* GetScriptExecutor(std::string* error) = 0; virtual bool IsWebView() const = 0; @@ -70,6 +71,9 @@ } // The injection details. + // Note that for tabs.removeCSS we still use |InjectDetails| rather than + // |DeleteInjectionDetails|, since the two types are compatible; the value + // of |run_at| defaults to |RUN_AT_NONE|. std::unique_ptr<api::extension_types::InjectDetails> details_; base::Optional<InitResult> init_result_; // Set iff |init_result_| == FAILURE, holds the error string.
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc index 75eb3aa..f7af229 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -430,6 +430,10 @@ return false; } +bool WebViewInternalExecuteCodeFunction::ShouldRemoveCSS() const { + return false; +} + bool WebViewInternalExecuteCodeFunction::CanExecuteScriptOnPage( std::string* error) { return true;
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h index 4babdabf..e9eefa0a 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h
@@ -90,6 +90,7 @@ // Initialize |details_| if it hasn't already been. InitResult Init() override; bool ShouldInsertCSS() const override; + bool ShouldRemoveCSS() const override; bool CanExecuteScriptOnPage(std::string* error) override; // Guarded by a process ID check. extensions::ScriptExecutor* GetScriptExecutor(std::string* error) final;
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index fe74a67..9cbd5bdd 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1572,6 +1572,7 @@ PASSWORDSPRIVATE_GETWEAKCREDENTIALS = 1509, ACCESSIBILITY_PRIVATE_MOVEMAGNIFIERTORECT = 1510, FILEMANAGERPRIVATE_SINGLEPARTITIONFORMAT = 1511, + TABS_REMOVECSS = 1512, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/extensions/browser/script_executor.cc b/extensions/browser/script_executor.cc index 199f27c..b8b144c 100644 --- a/extensions/browser/script_executor.cc +++ b/extensions/browser/script_executor.cc
@@ -241,7 +241,7 @@ ScriptExecutor::~ScriptExecutor() {} void ScriptExecutor::ExecuteScript(const HostID& host_id, - ScriptExecutor::ScriptType script_type, + UserScript::ActionType action_type, const std::string& code, ScriptExecutor::FrameScope frame_scope, int frame_id, @@ -268,7 +268,7 @@ ExtensionMsg_ExecuteCode_Params params; params.request_id = next_request_id_++; params.host_id = host_id; - params.is_javascript = (script_type == JAVASCRIPT); + params.action_type = action_type; params.code = code; params.match_about_blank = (about_blank == MATCH_ABOUT_BLANK); params.run_at = run_at; @@ -279,9 +279,11 @@ params.user_gesture = user_gesture; params.css_origin = css_origin; - // Generate an injection key if this is a CSS injection from an extension - // (i.e. tabs.insertCSS). - if (host_id.type() == HostID::EXTENSIONS && script_type == CSS) + // Generate the unique key that represents this CSS injection or removal + // from an extension (i.e. tabs.insertCSS or tabs.removeCSS). + if (host_id.type() == HostID::EXTENSIONS && + (action_type == UserScript::ADD_CSS || + action_type == UserScript::REMOVE_CSS)) params.injection_key = GenerateInjectionKey(host_id, script_url, code); // Handler handles IPCs and deletes itself on completion.
diff --git a/extensions/browser/script_executor.h b/extensions/browser/script_executor.h index c1a3bf32..97e68310 100644 --- a/extensions/browser/script_executor.h +++ b/extensions/browser/script_executor.h
@@ -46,12 +46,6 @@ explicit ScriptExecutor(content::WebContents* web_contents); ~ScriptExecutor(); - // The type of script being injected. - enum ScriptType { - JAVASCRIPT, - CSS, - }; - // The scope of the script injection across the frames. enum FrameScope { SINGLE_FRAME, @@ -93,7 +87,7 @@ // before a response is received (in this case the callback will be with a // failure and appropriate error message). void ExecuteScript(const HostID& host_id, - ScriptType script_type, + UserScript::ActionType action_type, const std::string& code, FrameScope frame_scope, int frame_id,
diff --git a/extensions/common/api/extension_types.json b/extensions/common/api/extension_types.json index e2ea16dc..e00040e 100644 --- a/extensions/common/api/extension_types.json +++ b/extensions/common/api/extension_types.json
@@ -74,6 +74,32 @@ "description": "The <a href=\"https://www.w3.org/TR/css3-cascade/#cascading-origins\">origin</a> of the CSS to inject. This may only be specified for CSS, not JavaScript. Defaults to <code>\"author\"</code>." } } + }, + { + "id": "DeleteInjectionDetails", + "type": "object", + "description": "Details of the CSS to remove. Either the code or the file property must be set, but both may not be set at the same time.", + "properties": { + "code": {"type": "string", "optional": true, "description": "CSS code to remove."}, + "file": {"type": "string", "optional": true, "description": "CSS file to remove."}, + "allFrames": { + "type": "boolean", + "optional": true, + "description": "If allFrames is <code>true</code>, implies that the CSS should be removed from all frames of current page. By default, it's <code>false</code> and is only removed from the top frame. If <code>true</code> and <code>frameId</code> is set, then the code is removed from the selected frame and all of its child frames." + }, + "frameId": { + "type": "integer", + "optional": true, + "minimum": 0, + "description": "The <a href='webNavigation#frame_ids'>frame</a> from where the CSS should be removed. Defaults to 0 (the top-level frame)." + }, + "matchAboutBlank": {"type": "boolean", "optional": true, "description": "If matchAboutBlank is true, then the code is also removed from about:blank and about:srcdoc frames if your extension has access to its parent document. By default it is <code>false</code>."}, + "cssOrigin": { + "$ref": "CSSOrigin", + "optional": true, + "description": "The <a href=\"https://www.w3.org/TR/css3-cascade/#cascading-origins\">origin</a> of the CSS to remove. Defaults to <code>\"author\"</code>." + } + } } ] }
diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index c125a43..81cae9b9 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h
@@ -59,6 +59,9 @@ IPC_ENUM_TRAITS_MAX_VALUE(extensions::UserScript::RunLocation, extensions::UserScript::RUN_LOCATION_LAST - 1) +IPC_ENUM_TRAITS_MAX_VALUE(extensions::UserScript::ActionType, + extensions::UserScript::ACTION_TYPE_LAST) + IPC_ENUM_TRAITS_MAX_VALUE(extensions::MessagingEndpoint::Type, extensions::MessagingEndpoint::Type::kLast) @@ -163,7 +166,7 @@ IPC_STRUCT_MEMBER(HostID, host_id) // Whether the code is JavaScript or CSS. - IPC_STRUCT_MEMBER(bool, is_javascript) + IPC_STRUCT_MEMBER(extensions::UserScript::ActionType, action_type) // String of code to execute. IPC_STRUCT_MEMBER(std::string, code)
diff --git a/extensions/common/user_script.h b/extensions/common/user_script.h index 2645e4c..009b07c 100644 --- a/extensions/common/user_script.h +++ b/extensions/common/user_script.h
@@ -54,6 +54,16 @@ // Update this if you add more injected script types! static const InjectionType INJECTION_TYPE_LAST = PROGRAMMATIC_SCRIPT; + // The type of the content being added or removed by the extension. + enum ActionType { + ADD_JAVASCRIPT, + ADD_CSS, + REMOVE_CSS, + }; + // The last type of action taken; used for enum verification in IPC. + // Update this if you add more injected script types! + static const ActionType ACTION_TYPE_LAST = REMOVE_CSS; + // Locations that user scripts can be run inside the document. // The three run locations must strictly follow each other in both load order // (i.e., start *always* comes before end) and numerically, as we use
diff --git a/extensions/renderer/programmatic_script_injector.cc b/extensions/renderer/programmatic_script_injector.cc index 6de5d30b..19b8026 100644 --- a/extensions/renderer/programmatic_script_injector.cc +++ b/extensions/renderer/programmatic_script_injector.cc
@@ -48,6 +48,14 @@ return params_->css_origin; } +bool ProgrammaticScriptInjector::IsRemovingCSS() const { + return params_->action_type == UserScript::ActionType::REMOVE_CSS; +} + +bool ProgrammaticScriptInjector::IsAddingCSS() const { + return params_->action_type == UserScript::ActionType::ADD_CSS; +} + const base::Optional<std::string> ProgrammaticScriptInjector::GetInjectionKey() const { return params_->injection_key; @@ -60,13 +68,16 @@ bool ProgrammaticScriptInjector::ShouldInjectJs( UserScript::RunLocation run_location, const std::set<std::string>& executing_scripts) const { - return params_->run_at == run_location && params_->is_javascript; + return params_->run_at == run_location && + params_->action_type == UserScript::ActionType::ADD_JAVASCRIPT; } -bool ProgrammaticScriptInjector::ShouldInjectCss( +bool ProgrammaticScriptInjector::ShouldInjectOrRemoveCss( UserScript::RunLocation run_location, const std::set<std::string>& injected_stylesheets) const { - return params_->run_at == run_location && !params_->is_javascript; + return params_->run_at == run_location && + (params_->action_type == UserScript::ActionType::ADD_CSS || + params_->action_type == UserScript::ActionType::REMOVE_CSS); } PermissionsData::PageAccess ProgrammaticScriptInjector::CanExecuteOnFrame( @@ -111,7 +122,7 @@ std::set<std::string>* executing_scripts, size_t* num_injected_js_scripts) const { DCHECK_EQ(params_->run_at, run_location); - DCHECK(params_->is_javascript); + DCHECK_EQ(params_->action_type, UserScript::ActionType::ADD_JAVASCRIPT); return std::vector<blink::WebScriptSource>( 1, blink::WebScriptSource(blink::WebString::FromUTF8(params_->code), @@ -123,7 +134,8 @@ std::set<std::string>* injected_stylesheets, size_t* num_injected_stylesheets) const { DCHECK_EQ(params_->run_at, run_location); - DCHECK(!params_->is_javascript); + DCHECK(params_->action_type == UserScript::ActionType::ADD_CSS || + params_->action_type == UserScript::ActionType::REMOVE_CSS); return std::vector<blink::WebString>( 1, blink::WebString::FromUTF8(params_->code));
diff --git a/extensions/renderer/programmatic_script_injector.h b/extensions/renderer/programmatic_script_injector.h index e29bba16..5e2e2913 100644 --- a/extensions/renderer/programmatic_script_injector.h +++ b/extensions/renderer/programmatic_script_injector.h
@@ -32,12 +32,14 @@ UserScript::InjectionType script_type() const override; bool IsUserGesture() const override; base::Optional<CSSOrigin> GetCssOrigin() const override; + bool IsRemovingCSS() const override; + bool IsAddingCSS() const override; const base::Optional<std::string> GetInjectionKey() const override; bool ExpectsResults() const override; bool ShouldInjectJs( UserScript::RunLocation run_location, const std::set<std::string>& executing_scripts) const override; - bool ShouldInjectCss( + bool ShouldInjectOrRemoveCss( UserScript::RunLocation run_location, const std::set<std::string>& injected_stylesheets) const override; PermissionsData::PageAccess CanExecuteOnFrame(
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc index a1d5b88..b13a81b7 100644 --- a/extensions/renderer/script_injection.cc +++ b/extensions/renderer/script_injection.cc
@@ -255,22 +255,22 @@ DCHECK(!complete_); bool should_inject_js = injector_->ShouldInjectJs( run_location_, scripts_run_info->executing_scripts[host_id().id()]); - bool should_inject_css = injector_->ShouldInjectCss( + bool should_inject_or_remove_css = injector_->ShouldInjectOrRemoveCss( run_location_, scripts_run_info->injected_stylesheets[host_id().id()]); // This can happen if the extension specified a script to // be run in multiple rules, and the script has already run. // See crbug.com/631247. - if (!should_inject_js && !should_inject_css) { + if (!should_inject_js && !should_inject_or_remove_css) { return INJECTION_FINISHED; } if (should_inject_js) InjectJs(&(scripts_run_info->executing_scripts[host_id().id()]), &(scripts_run_info->num_js)); - if (should_inject_css) - InjectCss(&(scripts_run_info->injected_stylesheets[host_id().id()]), - &(scripts_run_info->num_css)); + if (should_inject_or_remove_css) + InjectOrRemoveCss(&(scripts_run_info->injected_stylesheets[host_id().id()]), + &(scripts_run_info->num_css)); complete_ = did_inject_js_ || !should_inject_js; @@ -379,8 +379,9 @@ } } -void ScriptInjection::InjectCss(std::set<std::string>* injected_stylesheets, - size_t* num_injected_stylesheets) { +void ScriptInjection::InjectOrRemoveCss( + std::set<std::string>* injected_stylesheets, + size_t* num_injected_stylesheets) { std::vector<blink::WebString> css_sources = injector_->GetCssSources( run_location_, injected_stylesheets, num_injected_stylesheets); blink::WebLocalFrame* web_frame = render_frame_->GetWebFrame(); @@ -394,9 +395,28 @@ if (const base::Optional<std::string>& injection_key = injector_->GetInjectionKey()) style_sheet_key = blink::WebString::FromASCII(*injection_key); - for (const blink::WebString& css : css_sources) - web_frame->GetDocument().InsertStyleSheet(css, &style_sheet_key, - blink_css_origin); + // CSS deletion can be thought of as the inverse of CSS injection + // (i.e. x - y = x + -y and x | y = ~(~x & ~y)), so it is handled here in the + // injection function. + // + // TODO(https://crbug.com/1116061): Extend this API's capabilities to also + // remove CSS added by content scripts? + bool adding_css = injector_->IsAddingCSS(); + bool removing_css = injector_->IsRemovingCSS(); + DCHECK(!(adding_css && removing_css)) << "Operations are mutually exclusive."; + DCHECK(adding_css || removing_css) + << "At least one of the operations must happen for InjectOrRemoveCss() " + "to be called."; + + if (removing_css) { + web_frame->GetDocument().RemoveInsertedStyleSheet(style_sheet_key, + blink_css_origin); + } else { + DCHECK(adding_css); + for (const blink::WebString& css : css_sources) + web_frame->GetDocument().InsertStyleSheet(css, &style_sheet_key, + blink_css_origin); + } } } // namespace extensions
diff --git a/extensions/renderer/script_injection.h b/extensions/renderer/script_injection.h index 8c743fbd..7634ad3 100644 --- a/extensions/renderer/script_injection.h +++ b/extensions/renderer/script_injection.h
@@ -105,9 +105,9 @@ void InjectJs(std::set<std::string>* executing_scripts, size_t* num_injected_js_scripts); - // Inject any CSS source into the frame for the injection. - void InjectCss(std::set<std::string>* injected_stylesheets, - size_t* num_injected_stylesheets); + // Inject or remove any CSS source into the frame for the injection. + void InjectOrRemoveCss(std::set<std::string>* injected_stylesheets, + size_t* num_injected_stylesheets); // Notify that we will not inject, and mark it as acknowledged. void NotifyWillNotInject(ScriptInjector::InjectFailureReason reason);
diff --git a/extensions/renderer/script_injector.h b/extensions/renderer/script_injector.h index af2f8957..67452f04 100644 --- a/extensions/renderer/script_injector.h +++ b/extensions/renderer/script_injector.h
@@ -45,6 +45,14 @@ // Returns the CSS origin of this injection. virtual base::Optional<CSSOrigin> GetCssOrigin() const = 0; + // Returns true is CSS is being removed or added respectively. + // + // TODO(https://crrev.com/608854): Consider using a GetActionType()-like + // method that returns a bitmask or enum item with the operations being + // performed. + virtual bool IsRemovingCSS() const = 0; + virtual bool IsAddingCSS() const = 0; + // Returns the key for this injection, if it's a CSS injection. virtual const base::Optional<std::string> GetInjectionKey() const = 0; @@ -57,8 +65,9 @@ UserScript::RunLocation run_location, const std::set<std::string>& executing_scripts) const = 0; - // Returns true if the script should inject CSS at the given |run_location|. - virtual bool ShouldInjectCss( + // Returns true if the script should inject or remove CSS at the given + // |run_location|. + virtual bool ShouldInjectOrRemoveCss( UserScript::RunLocation run_location, const std::set<std::string>& injected_stylesheets) const = 0; @@ -76,7 +85,7 @@ size_t* num_injected_js_scripts) const = 0; // Returns the css to inject at the given |run_location|. - // Only called if ShouldInjectCss() is true. + // Only called if ShouldInjectOrRemoveCss() is true. virtual std::vector<blink::WebString> GetCssSources( UserScript::RunLocation run_location, std::set<std::string>* injected_stylesheets,
diff --git a/extensions/renderer/user_script_injector.cc b/extensions/renderer/user_script_injector.cc index 381ca41..bea979b 100644 --- a/extensions/renderer/user_script_injector.cc +++ b/extensions/renderer/user_script_injector.cc
@@ -144,6 +144,14 @@ return base::nullopt; } +bool UserScriptInjector::IsRemovingCSS() const { + return false; +} + +bool UserScriptInjector::IsAddingCSS() const { + return script_ && !script_->css_scripts().empty(); +} + const base::Optional<std::string> UserScriptInjector::GetInjectionKey() const { return base::nullopt; } @@ -156,7 +164,7 @@ ShouldInjectScripts(script_->js_scripts(), executing_scripts); } -bool UserScriptInjector::ShouldInjectCss( +bool UserScriptInjector::ShouldInjectOrRemoveCss( UserScript::RunLocation run_location, const std::set<std::string>& injected_stylesheets) const { return script_ && run_location == UserScript::DOCUMENT_START &&
diff --git a/extensions/renderer/user_script_injector.h b/extensions/renderer/user_script_injector.h index 5ff1dcf..aaf2f3b 100644 --- a/extensions/renderer/user_script_injector.h +++ b/extensions/renderer/user_script_injector.h
@@ -40,12 +40,14 @@ UserScript::InjectionType script_type() const override; bool IsUserGesture() const override; base::Optional<CSSOrigin> GetCssOrigin() const override; + bool IsRemovingCSS() const override; + bool IsAddingCSS() const override; const base::Optional<std::string> GetInjectionKey() const override; bool ExpectsResults() const override; bool ShouldInjectJs( UserScript::RunLocation run_location, const std::set<std::string>& executing_scripts) const override; - bool ShouldInjectCss( + bool ShouldInjectOrRemoveCss( UserScript::RunLocation run_location, const std::set<std::string>& injected_stylesheets) const override; PermissionsData::PageAccess CanExecuteOnFrame(
diff --git a/extensions/shell/app/DEPS b/extensions/shell/app/DEPS index 7b4a9a1f..5e684bcb 100644 --- a/extensions/shell/app/DEPS +++ b/extensions/shell/app/DEPS
@@ -8,7 +8,6 @@ "+content/public/browser", "+content/public/utility", "+sandbox", - "+services/service_manager/embedder", # Pieces of content_shell reused in app_shell. # TODO(jamescook): Eliminate these. http://crbug.com/438283
diff --git a/extensions/shell/browser/shell_browser_main_parts.cc b/extensions/shell/browser/shell_browser_main_parts.cc index e036f11a..0ebc55a 100644 --- a/extensions/shell/browser/shell_browser_main_parts.cc +++ b/extensions/shell/browser/shell_browser_main_parts.cc
@@ -159,7 +159,7 @@ } int ShellBrowserMainParts::PreEarlyInitialization() { - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } int ShellBrowserMainParts::PreCreateThreads() { @@ -260,7 +260,7 @@ if (!run_message_loop_) return true; desktop_controller_->Run(); - *result_code = service_manager::RESULT_CODE_NORMAL_EXIT; + *result_code = content::RESULT_CODE_NORMAL_EXIT; return true; }
diff --git a/extensions/shell/test/DEPS b/extensions/shell/test/DEPS index 695820a..9e38412 100644 --- a/extensions/shell/test/DEPS +++ b/extensions/shell/test/DEPS
@@ -3,7 +3,6 @@ "+content/shell/common", "+content/shell/browser/shell_application_mac.h", "+content/public/utility", - "+services/service_manager/embedder", # Testing utilities can access anything in extensions/shell. "+extensions/shell",
diff --git a/headless/DEPS b/headless/DEPS index 221cb10..5df623a 100644 --- a/headless/DEPS +++ b/headless/DEPS
@@ -26,7 +26,6 @@ "+sandbox/policy", "+sandbox/win/src", "+services/network/public", - "+services/service_manager/embedder", "+services/service_manager/public", "+third_party/blink/public/common/web_preferences", ]
diff --git a/ios/chrome/browser/main/browser_util.mm b/ios/chrome/browser/main/browser_util.mm index 2b1c0b1..9588ad0e 100644 --- a/ios/chrome/browser/main/browser_util.mm +++ b/ios/chrome/browser/main/browser_util.mm
@@ -108,7 +108,11 @@ MoveSnapshot(tab_id, source_browser, destination_browser); std::unique_ptr<web::WebState> web_state = source_browser->GetWebStateList()->DetachWebStateAt(source_tab_index); + int insertion_flags = WebStateList::INSERT_FORCE_INDEX; + if (destination_browser->GetWebStateList()->empty()) { + insertion_flags = WebStateList::INSERT_ACTIVATE; + } destination_browser->GetWebStateList()->InsertWebState( - destination_tab_index, std::move(web_state), - WebStateList::INSERT_FORCE_INDEX, WebStateOpener()); + destination_tab_index, std::move(web_state), insertion_flags, + WebStateOpener()); }
diff --git a/ios/chrome/browser/omaha/omaha_service.h b/ios/chrome/browser/omaha/omaha_service.h index fd27a73..e9d3557 100644 --- a/ios/chrome/browser/omaha/omaha_service.h +++ b/ios/chrome/browser/omaha/omaha_service.h
@@ -68,6 +68,8 @@ FRIEND_TEST_ALL_PREFIXES(OmahaServiceTest, InstallEventMessageTest); FRIEND_TEST_ALL_PREFIXES(OmahaServiceTest, SendPingFailure); FRIEND_TEST_ALL_PREFIXES(OmahaServiceTest, SendPingSuccess); + FRIEND_TEST_ALL_PREFIXES(OmahaServiceTest, + CallbackForScheduledNotUsedOnErrorResponse); FRIEND_TEST_ALL_PREFIXES(OmahaServiceTest, OneOffSuccess); FRIEND_TEST_ALL_PREFIXES(OmahaServiceTest, OngoingPingOneOffCallbackUsed); FRIEND_TEST_ALL_PREFIXES(OmahaServiceTest, OneOffCallbackUsedOnlyOnce);
diff --git a/ios/chrome/browser/omaha/omaha_service.mm b/ios/chrome/browser/omaha/omaha_service.mm index 783c809..7e7a95f 100644 --- a/ios/chrome/browser/omaha/omaha_service.mm +++ b/ios/chrome/browser/omaha/omaha_service.mm
@@ -251,6 +251,7 @@ } else if ([status isEqualToString:@"ok"]) { _updateInformation->is_up_to_date = false; } else { + _updateInformation = nullptr; _hasError = YES; } } else if ([elementName isEqualToString:@"event"]) { @@ -753,7 +754,7 @@ // it canceled a scheduled ping. need_to_schedule_ping = scheduled_ping_canceled_; scheduled_ping_canceled_ = false; - } else { + } else if (!details->is_up_to_date) { base::PostTask(FROM_HERE, {web::WebThread::UI}, base::BindOnce(upgrade_recommended_callback_, *details)); }
diff --git a/ios/chrome/browser/omaha/omaha_service_unittest.mm b/ios/chrome/browser/omaha/omaha_service_unittest.mm index 3ffe6ec..ca725e3 100644 --- a/ios/chrome/browser/omaha/omaha_service_unittest.mm +++ b/ios/chrome/browser/omaha/omaha_service_unittest.mm
@@ -60,6 +60,7 @@ void OnNeedUpdate(const UpgradeRecommendedDetails& details) { was_one_off_ = false; + scheduled_callback_used_ = true; need_update_ = !details.is_up_to_date; } @@ -68,7 +69,13 @@ need_update_ = !details.is_up_to_date; } - bool WasOneOff() { return was_one_off_; } + bool WasOneOff() { + bool was_one_off = was_one_off_; + was_one_off_ = false; + return was_one_off; + } + + bool ScheduledCallbackUsed() { return scheduled_callback_used_; } bool NeedUpdate() { DCHECK_CURRENTLY_ON(web::WebThread::UI); @@ -115,6 +122,7 @@ private: bool need_update_ = false; bool was_one_off_ = false; + bool scheduled_callback_used_ = false; IOSChromeScopedTestingChromeBrowserStateManager scoped_browser_state_manager_; web::WebTaskEnvironment task_environment_; @@ -257,6 +265,40 @@ EXPECT_GT(service.last_sent_time_, now); EXPECT_EQ(4088, service.last_server_date_); EXPECT_FALSE(NeedUpdate()); + EXPECT_FALSE(ScheduledCallbackUsed()); +} + +TEST_F(OmahaServiceTest, CallbackForScheduledNotUsedOnErrorResponse) { + base::Time now = base::Time::Now(); + OmahaService service(false); + service.StartInternal(); + + service.set_upgrade_recommended_callback( + base::Bind(&OmahaServiceTest::OnNeedUpdate, base::Unretained(this))); + service.InitializeURLLoaderFactory(test_shared_url_loader_factory_); + CleanService(&service, version_info::GetVersionNumber()); + + service.SendPing(); + + EXPECT_EQ(1, service.number_of_tries_); + EXPECT_TRUE(service.current_ping_time_.is_null()); + EXPECT_GE(service.next_tries_time_, now + base::TimeDelta::FromMinutes(54)); + EXPECT_LE(service.next_tries_time_, now + base::TimeDelta::FromHours(7)); + + std::string response = + std::string( + "<?xml version=\"1.0\"?><response protocol=\"3.0\" server=\"prod\">" + "<daystart elapsed_days=\"4088\"/><app appid=\"") + + test_application_id() + + "\" status=\"ok\">" + "<updatecheck status=\"error\"/><ping status=\"ok\"/>" + "</app></response>"; + auto* pending_request = test_url_loader_factory_.GetPendingRequest(0); + test_url_loader_factory_.SimulateResponseForPendingRequest( + pending_request->request.url.spec(), response); + + EXPECT_FALSE(NeedUpdate()); + EXPECT_FALSE(ScheduledCallbackUsed()); } TEST_F(OmahaServiceTest, OneOffSuccess) {
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm index 1c6a5ed..05aec75 100644 --- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm +++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm
@@ -16,6 +16,7 @@ #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "services/network/public/cpp/shared_url_loader_factory.h" +#include "ui/base/page_transition_types.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -59,6 +60,8 @@ // Boolean order important, feature flag last. Otherwise it messes // with usage statistics of control and experimental group (UMA). if (request_info.target_frame_is_main && + ui::PageTransitionCoreTypeIs(request_info.transition_type, + ui::PAGE_TRANSITION_TYPED) && web_state_->GetLastCommittedURL().is_empty() && // empty tab history IsWellKnownChangePasswordUrl(request_url) && base::FeatureList::IsEnabled(
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm b/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm index 5930ea4..17f7e83db 100644 --- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm +++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm
@@ -53,6 +53,18 @@ constexpr char kMockChangePasswordPath[] = "/change-password-override"; +// Re-implementation of web::LoadUrl() that allows specifying a custom page +// transition. +void LoadUrlWithTransition(web::WebState* web_state, + const GURL& url, + ui::PageTransition transition) { + web::NavigationManager* navigation_manager = + web_state->GetNavigationManager(); + web::NavigationManager::WebLoadParams params(url); + params.transition_type = transition; + navigation_manager->LoadURLWithParams(params); +} + } // namespace class TestChangePasswordUrlService @@ -271,3 +283,17 @@ EXPECT_EQ(GetNavigatedUrl().path(), kMockChangePasswordPath); ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOverrideUrl); } + +TEST_F(WellKnownChangePasswordTabHelperTest, + NoSupportForChangePasswordForLinks) { + path_response_map_[kWellKnownChangePasswordPath] = {net::HTTP_OK, {}}; + LoadUrlWithTransition(web_state(), + test_server_->GetURL(kWellKnownChangePasswordPath), + ui::PAGE_TRANSITION_LINK); + ASSERT_TRUE(WaitUntilLoaded()); + EXPECT_EQ(GetNavigatedUrl().path(), kWellKnownChangePasswordPath); + + // In the case of PAGE_TRANSITION_LINK the tab helper should not be active and + // no metrics should be recorded. + EXPECT_TRUE(test_recorder_->GetEntriesByName(UkmBuilder::kEntryName).empty()); +}
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index ff8944e..30a9be9 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -610,7 +610,21 @@ [self createInitialUI:(startInIncognito ? ApplicationMode::INCOGNITO : ApplicationMode::NORMAL)]; - if (!self.startupParameters) { + // A pending tab move should not display the restore infobar since restoration + // will replace the moved tab. + BOOL pendingTabMove = NO; + if (IsSceneStartupSupported()) { + if (@available(iOS 13, *)) { + for (NSUserActivity* activity in self.sceneState.connectionOptions + .userActivities) { + if (ActivityIsTabMove(activity)) { + pendingTabMove = YES; + } + } + } + } + + if (!self.startupParameters && !pendingTabMove) { // The startup parameters may create new tabs or navigations. If the restore // infobar is displayed now, it may be dismissed immediately and the user // will never be able to restore the session. @@ -1593,7 +1607,7 @@ if (@available(iOS 13, *)) { for (NSUserActivity* activity in self.sceneState.connectionOptions .userActivities) { - if (ActivityIsURLLoad(activity)) { + if (ActivityIsURLLoad(activity) || ActivityIsTabMove(activity)) { return NO; } }
diff --git a/ios/chrome/browser/ui/open_in/open_in_toolbar.mm b/ios/chrome/browser/ui/open_in/open_in_toolbar.mm index 6e7e87b7..66bdca6 100644 --- a/ios/chrome/browser/ui/open_in/open_in_toolbar.mm +++ b/ios/chrome/browser/ui/open_in/open_in_toolbar.mm
@@ -48,8 +48,9 @@ // https://crbug.com/857371. @property(nonatomic, strong) UIView* bottomMargin; -// Constraint to have the open in toolbar be displayed above the bottom toolbar. -@property(nonatomic, strong) NSLayoutConstraint* bottomMarginConstraint; +// Constraint to have the open in toolbar be displayed above the bottom +// toolbar. +@property(nonatomic, strong) NSLayoutConstraint* bottomMarginTopConstraint; // Relayout the frame of the Open In toolbar, based on its superview and the // bottom margin. @@ -85,7 +86,8 @@ @implementation OpenInToolbar @synthesize bottomMargin = _bottomMargin; -@synthesize bottomMarginConstraint = _bottomMarginConstraint; +@synthesize bottomMarginTopConstraint = _bottomMarginTopConstraint; + @synthesize openButton = _openButton; @synthesize topBorder = _topBorder; @@ -130,6 +132,7 @@ bottom.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:bottom]; self.bottomMargin = bottom; + [self.bottomMargin.heightAnchor constraintEqualToConstant:0].active = YES; } return self; } @@ -156,24 +159,32 @@ return _topBorder; } -- (void)setBottomMarginConstraint:(NSLayoutConstraint*)bottomMarginConstraint { - if (_bottomMarginConstraint == bottomMarginConstraint) +- (void)setBottomMarginTopConstraint: + (NSLayoutConstraint*)bottomMarginTopConstraint { + if (_bottomMarginTopConstraint == bottomMarginTopConstraint) return; - _bottomMarginConstraint.active = NO; - _bottomMarginConstraint = bottomMarginConstraint; - _bottomMarginConstraint.active = YES; + _bottomMarginTopConstraint.active = NO; + _bottomMarginTopConstraint = bottomMarginTopConstraint; + _bottomMarginTopConstraint.active = YES; } #pragma mark Public - (void)updateBottomMarginHeight { - NSLayoutDimension* marginHeightAnchor = self.bottomMargin.heightAnchor; + if (!self.superview) { + self.bottomMarginTopConstraint = nil; + return; + } + + NSLayoutAnchor* marginTopAnchor = self.bottomMargin.topAnchor; NamedGuide* guide = [NamedGuide guideWithName:kSecondaryToolbarGuide view:self]; - self.bottomMarginConstraint = - guide ? [marginHeightAnchor constraintEqualToAnchor:guide.heightAnchor] - : [marginHeightAnchor constraintEqualToConstant:0]; + self.bottomMarginTopConstraint = + guide ? [marginTopAnchor constraintEqualToAnchor:guide.topAnchor] + : [marginTopAnchor + constraintEqualToAnchor:self.superview.bottomAnchor]; + [self relayout]; } @@ -191,10 +202,16 @@ } - (void)relayout { - CGRect frame = self.superview.frame; + [self layoutIfNeeded]; + CGRect frame = self.superview.bounds; + CGRect frameFromSuperview = + [self.bottomMargin convertRect:self.bottomMargin.bounds + toView:self.superview]; + CGSize sizeThatFits = [self sizeThatFits:frame.size]; - CGFloat toolbarHeight = - sizeThatFits.height + self.bottomMargin.frame.size.height; + CGFloat toolbarHeight = sizeThatFits.height + frame.size.height - + CGRectGetMinY(frameFromSuperview); + frame.origin.y = frame.size.height - toolbarHeight; frame.size.height = toolbarHeight;
diff --git a/ios/chrome/browser/ui/passwords/BUILD.gn b/ios/chrome/browser/ui/passwords/BUILD.gn index 3a81be02..351a87d 100644 --- a/ios/chrome/browser/ui/passwords/BUILD.gn +++ b/ios/chrome/browser/ui/passwords/BUILD.gn
@@ -85,7 +85,9 @@ "//base", "//base/test:test_support", "//components/password_manager/core/common", + "//components/strings:components_strings_grit", "//ios/chrome/browser/ui/authentication:eg_test_support+eg2", + "//ios/chrome/browser/ui/settings/password:password_constants", "//ios/chrome/test:eg_test_support+eg2", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2", @@ -93,6 +95,7 @@ "//ios/web/public/test/http_server", "//net:test_support", "//testing/gtest", + "//ui/base:base", ] frameworks = [ "UIKit.framework",
diff --git a/ios/chrome/browser/ui/passwords/password_breach_app_interface.h b/ios/chrome/browser/ui/passwords/password_breach_app_interface.h index b26f37a7..c87b272a 100644 --- a/ios/chrome/browser/ui/passwords/password_breach_app_interface.h +++ b/ios/chrome/browser/ui/passwords/password_breach_app_interface.h
@@ -11,7 +11,9 @@ @interface PasswordBreachAppInterface : NSObject // Shows Password Breach with a default type of leak and URL. -+ (void)showPasswordBreach; +// |checkButtonPresent| indicates that password was reused and user has option +// to check all passwords. ++ (void)showPasswordBreachWithCheckButton:(BOOL)checkButtonPresent; @end
diff --git a/ios/chrome/browser/ui/passwords/password_breach_app_interface.mm b/ios/chrome/browser/ui/passwords/password_breach_app_interface.mm index 2b30c80e..d10dfbb 100644 --- a/ios/chrome/browser/ui/passwords/password_breach_app_interface.mm +++ b/ios/chrome/browser/ui/passwords/password_breach_app_interface.mm
@@ -13,10 +13,11 @@ @implementation PasswordBreachAppInterface -+ (void)showPasswordBreach { ++ (void)showPasswordBreachWithCheckButton:(BOOL)checkButtonPresent { auto handler = chrome_test_util::HandlerForActiveBrowser(); auto leakType = password_manager::CreateLeakType( - password_manager::IsSaved(true), password_manager::IsReused(false), + password_manager::IsSaved(true), + password_manager::IsReused(checkButtonPresent), password_manager::IsSyncing(true)); [(id<PasswordBreachCommands>)handler showPasswordBreachForLeakType:leakType
diff --git a/ios/chrome/browser/ui/passwords/password_breach_egtest.mm b/ios/chrome/browser/ui/passwords/password_breach_egtest.mm index c974a54..f760a5b 100644 --- a/ios/chrome/browser/ui/passwords/password_breach_egtest.mm +++ b/ios/chrome/browser/ui/passwords/password_breach_egtest.mm
@@ -2,13 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/strings/sys_string_conversions.h" +#include "base/test/scoped_feature_list.h" +#include "components/password_manager/core/common/password_manager_features.h" +#include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ui/passwords/password_breach_app_interface.h" #import "ios/chrome/browser/ui/passwords/password_breach_constants.h" +#import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/testing/earl_grey/app_launch_manager.h" #import "ios/testing/earl_grey/earl_grey_test.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -23,9 +30,23 @@ #pragma clang diagnostic pop namespace { + +using chrome_test_util::ButtonWithAccessibilityLabel; + id<GREYMatcher> PasswordBreachMatcher() { return grey_accessibilityID(kPasswordBreachViewAccessibilityIdentifier); } + +id<GREYMatcher> PasswordListMatcher() { + return grey_accessibilityID(kPasswordsTableViewId); +} + +id<GREYMatcher> CheckPasswordButton() { + return grey_allOf(ButtonWithAccessibilityLabel(base::SysUTF16ToNSString( + l10n_util::GetStringUTF16(IDS_LEAK_CHECK_CREDENTIALS))), + grey_interactable(), nullptr); +} + } // namespace @interface PasswordBreachTestCase : ChromeTestCase @@ -36,9 +57,27 @@ #pragma mark - Tests - (void)testPasswordBreachIsPresented { - [PasswordBreachAppInterface showPasswordBreach]; + [PasswordBreachAppInterface showPasswordBreachWithCheckButton:NO]; [[EarlGrey selectElementWithMatcher:PasswordBreachMatcher()] assertWithMatcher:grey_notNil()]; } +// Tests that Check password button redirects to the Passwords List. +- (void)testPasswordBreachRedirectToPasswords { + // TODO(crbug.com/1096986): Remove it once feature is enabled by default. + AppLaunchConfiguration config; + config.features_enabled.push_back(password_manager::features::kPasswordCheck); + [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config]; + + [PasswordBreachAppInterface showPasswordBreachWithCheckButton:YES]; + [[EarlGrey selectElementWithMatcher:PasswordBreachMatcher()] + assertWithMatcher:grey_notNil()]; + + [[EarlGrey selectElementWithMatcher:CheckPasswordButton()] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:PasswordListMatcher()] + assertWithMatcher:grey_notNil()]; +} + @end
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm index 79aa4dc..e02689e2 100644 --- a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm +++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm
@@ -799,34 +799,34 @@ return; } - const GURL& upgradeUrl = details.upgrade_url; - - if (!upgradeUrl.is_valid()) { - self.updateCheckRowState = UpdateCheckRowStateOmahaError; - [self reconfigureUpdateCheckItem]; - return; - } - - if (!details.next_version.size() || - !base::Version(details.next_version).IsValid()) { - self.updateCheckRowState = UpdateCheckRowStateOmahaError; - [self reconfigureUpdateCheckItem]; - return; - } - - // Valid results, update NSUserDefaults. - NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - - [defaults setValue:base::SysUTF8ToNSString(upgradeUrl.spec()) - forKey:kIOSChromeUpgradeURLKey]; - [defaults setValue:base::SysUTF8ToNSString(details.next_version) - forKey:kIOSChromeNextVersionKey]; - [defaults setBool:details.is_up_to_date forKey:kIOSChromeUpToDateKey]; - if (details.is_up_to_date) { self.updateCheckRowState = UpdateCheckRowStateUpToDate; } else { + // upgradeURL and next_version are only set if not up to date. + const GURL& upgradeUrl = details.upgrade_url; + + if (!upgradeUrl.is_valid()) { + self.updateCheckRowState = UpdateCheckRowStateOmahaError; + [self reconfigureUpdateCheckItem]; + return; + } + + if (!details.next_version.size() || + !base::Version(details.next_version).IsValid()) { + self.updateCheckRowState = UpdateCheckRowStateOmahaError; + [self reconfigureUpdateCheckItem]; + return; + } + self.updateCheckRowState = UpdateCheckRowStateOutOfDate; + // Valid results, update NSUserDefaults. + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + + [defaults setValue:base::SysUTF8ToNSString(upgradeUrl.spec()) + forKey:kIOSChromeUpgradeURLKey]; + [defaults setValue:base::SysUTF8ToNSString(details.next_version) + forKey:kIOSChromeNextVersionKey]; + [defaults setBool:details.is_up_to_date forKey:kIOSChromeUpToDateKey]; // Treat the safety check finding the device out of date as if the update // infobar was just shown to not overshow the infobar to the user. [defaults setObject:[NSDate date] forKey:kLastInfobarDisplayTimeKey];
diff --git a/media/audio/win/audio_low_latency_input_win.cc b/media/audio/win/audio_low_latency_input_win.cc index 8df4203..94fd5b4 100644 --- a/media/audio/win/audio_low_latency_input_win.cc +++ b/media/audio/win/audio_low_latency_input_win.cc
@@ -5,10 +5,12 @@ #include "media/audio/win/audio_low_latency_input_win.h" #include <objbase.h> +#include <propkey.h> #include <algorithm> #include <cmath> #include <memory> +#include <utility> #include "base/logging.h" #include "base/metrics/histogram_functions.h" @@ -16,6 +18,8 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" +#include "base/win/scoped_propvariant.h" +#include "base/win/scoped_variant.h" #include "media/audio/audio_device_description.h" #include "media/audio/audio_features.h" #include "media/audio/win/avrt_wrapper_win.h" @@ -25,6 +29,7 @@ #include "media/base/audio_timestamp_helper.h" #include "media/base/channel_layout.h" #include "media/base/limits.h" +#include "media/base/media_switches.h" using base::win::ScopedCOMInitializer; @@ -130,6 +135,17 @@ return "UNKNOWN"; } +bool VariantBoolToBool(VARIANT_BOOL var_bool) { + switch (var_bool) { + case VARIANT_TRUE: + return true; + case VARIANT_FALSE: + return false; + } + LOG(ERROR) << "Invalid VARIANT_BOOL type"; + return false; +} + std::string GetOpenLogString(WASAPIAudioInputStream::StreamOpenResult result, HRESULT hr, WAVEFORMATEXTENSIBLE input_format, @@ -250,6 +266,9 @@ return false; } + // Check if raw audio processing is supported for the selected capture device. + raw_processing_supported_ = RawProcessingSupported(); + // Obtain an IAudioClient interface which enables us to create and initialize // an audio stream between an audio application and the audio engine. hr = endpoint_device_->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, @@ -267,8 +286,17 @@ hr = GetAudioEngineStreamFormat(); #endif + // Attempt to enable communications category and raw capture mode on the audio + // stream. Ignoring return value since the method logs its own error messages + // and it should be OK to continue opening the stream even after a failure. + if (base::FeatureList::IsEnabled(media::kWasapiRawAudioCapture) && + raw_processing_supported_ && + !AudioDeviceDescription::IsLoopbackDevice(device_id_)) { + SetCommunicationsCategoryAndRawCaptureMode(); + } + // Verify that the selected audio endpoint supports the specified format - // set during construction. + // set during construction and using the specified client properties. hr = S_OK; if (!DesiredFormatIsSupported(&hr)) { open_result_ = OPEN_RESULT_FORMAT_NOT_SUPPORTED; @@ -415,6 +443,15 @@ // It is also valid to call Close() after Start() has been called. Stop(); + // Only upload UMA histogram for the case when AGC is enabled, i.e., for + // WebRTC based audio input streams. + if (GetAutomaticGainControl()) { + // Upload UMA histogram to track if the capture device supported raw audio + // capture or not. See https://crbug.com/1133643. + base::UmaHistogramBoolean("Media.Audio.RawProcessingSupportedWin", + raw_processing_supported_); + } + if (converter_) converter_->RemoveInput(this); @@ -809,6 +846,68 @@ return hr; } +bool WASAPIAudioInputStream::RawProcessingSupported() { + DCHECK(endpoint_device_.Get()); + // Check if System.Devices.AudioDevice.RawProcessingSupported can be found + // and queried in the Windows Property System. It corresponds to raw + // processing mode support for the specified audio device. If its value is + // VARIANT_TRUE the device supports raw processing mode. + bool raw_processing_supported = false; + Microsoft::WRL::ComPtr<IPropertyStore> properties; + base::win::ScopedPropVariant raw_processing; + if (FAILED(endpoint_device_->OpenPropertyStore(STGM_READ, &properties)) || + FAILED( + properties->GetValue(PKEY_Devices_AudioDevice_RawProcessingSupported, + raw_processing.Receive())) || + raw_processing.get().vt != VT_BOOL) { + SendLogMessage( + "%s => (WARNING: failed to access " + "System.Devices.AudioDevice.RawProcessingSupported)", + __func__); + } else { + raw_processing_supported = VariantBoolToBool(raw_processing.get().boolVal); + SendLogMessage( + "%s => (System.Devices.AudioDevice.RawProcessingSupported=%s)", + __func__, raw_processing_supported ? "true" : "false"); + } + return raw_processing_supported; +} + +HRESULT WASAPIAudioInputStream::SetCommunicationsCategoryAndRawCaptureMode() { + DCHECK(audio_client_.Get()); + DCHECK(!AudioDeviceDescription::IsLoopbackDevice(device_id_)); + DCHECK(raw_processing_supported_); + SendLogMessage("%s()", __func__); + + Microsoft::WRL::ComPtr<IAudioClient2> audio_client2; + HRESULT hr = audio_client_.As(&audio_client2); + if (FAILED(hr)) { + SendLogMessage("%s => (ERROR: IAudioClient2 is not supported)", __func__); + return hr; + } + // Use IAudioClient2::SetClientProperties() to set communications category + // and to enable raw stream capture if it is supported. + if (audio_client2.Get()) { + AudioClientProperties audio_props = {0}; + audio_props.cbSize = sizeof(AudioClientProperties); + audio_props.bIsOffload = false; + // AudioCategory_Communications opts us in to communications policy and + // communications processing. AUDCLNT_STREAMOPTIONS_RAW turns off the + // processing, but not the policy. + audio_props.eCategory = AudioCategory_Communications; + // The audio stream is a 'raw' stream that bypasses all signal processing + // except for endpoint specific, always-on processing in the Audio + // Processing Object (APO), driver, and hardware. + audio_props.Options = AUDCLNT_STREAMOPTIONS_RAW; + hr = audio_client2->SetClientProperties(&audio_props); + if (FAILED(hr)) { + SendLogMessage("%s => (ERROR: IAudioClient2::SetClientProperties=[%s])", + __func__, ErrorToString(hr).c_str()); + } + } + return hr; +} + bool WASAPIAudioInputStream::DesiredFormatIsSupported(HRESULT* hr) { SendLogMessage("%s()", __func__); // An application that uses WASAPI to manage shared-mode streams can rely @@ -1014,7 +1113,7 @@ // // http://msdn.microsoft.com/en-us/library/windows/desktop/dd316551(v=vs.85).aspx if (AudioDeviceDescription::IsLoopbackDevice(device_id_)) { - SendLogMessage("%s => (WARNING: loopback mode is selected", __func__); + SendLogMessage("%s => (WARNING: loopback mode is selected)", __func__); hr = endpoint_device_->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr, &audio_render_client_for_loopback_); if (FAILED(hr)) {
diff --git a/media/audio/win/audio_low_latency_input_win.h b/media/audio/win/audio_low_latency_input_win.h index 417c22f..c2d87b1 100644 --- a/media/audio/win/audio_low_latency_input_win.h +++ b/media/audio/win/audio_low_latency_input_win.h
@@ -154,6 +154,10 @@ // The Open() method is divided into these sub methods. HRESULT SetCaptureDevice(); + // Returns whether raw audio processing is supported or not for the selected + // capture device. + bool RawProcessingSupported(); + HRESULT SetCommunicationsCategoryAndRawCaptureMode(); HRESULT GetAudioEngineStreamFormat(); // Returns whether the desired format is supported or not and writes the // result of a failing system call to |*hr|, or S_OK if successful. If this @@ -298,6 +302,10 @@ // session starts. Utilized in UMA histogram. bool audio_session_starts_at_zero_volume_ = false; + // Set to true if the selected audio device supports raw audio capture. + // Also added to a UMS histogram. + bool raw_processing_supported_ = false; + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(WASAPIAudioInputStream);
diff --git a/media/audio/win/audio_low_latency_input_win_unittest.cc b/media/audio/win/audio_low_latency_input_win_unittest.cc index 81cf90ab..8d29d01 100644 --- a/media/audio/win/audio_low_latency_input_win_unittest.cc +++ b/media/audio/win/audio_low_latency_input_win_unittest.cc
@@ -19,6 +19,7 @@ #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/test/test_timeouts.h" #include "base/win/scoped_com_initializer.h" @@ -29,6 +30,7 @@ #include "media/audio/audio_unittest_util.h" #include "media/audio/test_audio_thread.h" #include "media/audio/win/core_audio_util_win.h" +#include "media/base/media_switches.h" #include "media/base/seekable_buffer.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -258,7 +260,8 @@ DISALLOW_COPY_AND_ASSIGN(ScopedAudioInputStream); }; -class WinAudioInputTest : public ::testing::Test { +class WinAudioInputTest : public ::testing::Test, + public ::testing::WithParamInterface<bool> { public: WinAudioInputTest() { audio_manager_ = @@ -350,8 +353,13 @@ } // Test Open(), Start(), Stop(), Close() calling sequence. -TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) { +TEST_P(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) { ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); + base::test::ScopedFeatureList feature_list; + const bool use_raw_audio = GetParam(); + use_raw_audio + ? feature_list.InitAndEnableFeature(media::kWasapiRawAudioCapture) + : feature_list.InitAndDisableFeature(media::kWasapiRawAudioCapture); ScopedAudioInputStream ais( CreateDefaultAudioInputStream(audio_manager_.get())); EXPECT_TRUE(ais->Open()); @@ -526,6 +534,33 @@ ais.Close(); } +// As above, intended for manual testing only but this time using the raw +// capture mode. +TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFileRAW) { + ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); + + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(media::kWasapiRawAudioCapture); + + // Name of the output PCM file containing captured data. The output file + // will be stored in the directory containing 'media_unittests.exe'. + // Example of full name: \src\build\Debug\out_stereo_10sec_raw.pcm. + const char* file_name = "out_10sec_raw.pcm"; + + AudioInputStreamWrapper aisw(audio_manager_.get()); + ScopedAudioInputStream ais(aisw.Create()); + ASSERT_TRUE(ais->Open()); + + VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; + WriteToFileAudioSink file_sink(file_name); + VLOG(0) << ">> Speak into the default microphone while recording."; + ais->Start(&file_sink); + base::PlatformThread::Sleep(TestTimeouts::action_timeout()); + ais->Stop(); + VLOG(0) << ">> Recording has stopped."; + ais.Close(); +} + TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamResampleToFile) { ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); @@ -577,11 +612,14 @@ VLOG(0) << ">> Speak into the default microphone while recording."; ais->Start(&file_sink); base::PlatformThread::Sleep(TestTimeouts::action_timeout()); - // base::PlatformThread::Sleep(base::TimeDelta::FromMinutes(10)); ais->Stop(); VLOG(0) << ">> Recording has stopped."; ais.Close(); } } +INSTANTIATE_TEST_SUITE_P(WinAudioInputTests, + WinAudioInputTest, + testing::Bool()); + } // namespace media
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 6444cb9..104d51d 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -655,6 +655,15 @@ const base::Feature MEDIA_EXPORT kMediaFoundationVP8Decoding{ "MediaFoundationVP8Decoding", base::FEATURE_DISABLED_BY_DEFAULT}; +// Use the AUDCLNT_STREAMOPTIONS_RAW option on WASAPI input audio streams in +// combination with the IAudioClient2::SetClientProperties() API. +// The audio stream is a 'raw' stream that bypasses all signal processing except +// for endpoint specific, always-on processing in the Audio Processing Object +// (APO), driver, and hardware. +// https://docs.microsoft.com/en-us/windows/win32/api/audioclient/ne-audioclient-audclnt_streamoptions +const base::Feature MEDIA_EXPORT kWasapiRawAudioCapture{ + "WASAPIRawAudioCapture", base::FEATURE_DISABLED_BY_DEFAULT}; + #endif // defined(OS_WIN) #if defined(OS_MAC)
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 14c59bef..0f47b38 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -221,6 +221,7 @@ MEDIA_EXPORT extern const base::Feature kMediaFoundationAV1Decoding; MEDIA_EXPORT extern const base::Feature kMediaFoundationVideoCapture; MEDIA_EXPORT extern const base::Feature kMediaFoundationVP8Decoding; +MEDIA_EXPORT extern const base::Feature kWasapiRawAudioCapture; #endif // defined(OS_WIN) #if defined(OS_MAC)
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 64ef89d..e889678 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc
@@ -1299,6 +1299,12 @@ std::move(mailbox_holders_release_cb_).Run(release_sync_token); } + // Someone might be monitoring original wrapped frame for feedback. + // Ensure all accumulated feedback is propagated to the original frame. + if (wrapped_frame_) { + wrapped_frame_->feedback()->Combine(feedback_); + } + for (auto& callback : done_callbacks_) std::move(callback).Run(); }
diff --git a/native_client_sdk/src/doc/faq.rst b/native_client_sdk/src/doc/faq.rst index f1a3ab15..581c6b3 100644 --- a/native_client_sdk/src/doc/faq.rst +++ b/native_client_sdk/src/doc/faq.rst
@@ -599,7 +599,7 @@ .. _native-client-discuss: https://groups.google.com/group/native-client-discuss .. _deprecated in Chrome: http://blog.chromium.org/2013/09/saying-goodbye-to-our-old-friend-npapi.html .. _OpenGL ES 2.0: https://www.khronos.org/opengles/ -.. _GLES2 file: https://code.google.com/p/chromium/codesearch#chromium/src/ppapi/lib/gl/gles2/gles2.c +.. _GLES2 file: https://source.chromium.org/chromium/chromium/src/+/HEAD:ppapi/lib/gl/gles2/gles2.c .. _Google Chrome privacy policy: https://www.google.com/chrome/intl/en/privacy.html .. _Google Chrome Terms of Service: https://www.google.com/chrome/intl/en/eula_text.html .. _webports: https://chromium.googlesource.com/webports
diff --git a/remoting/ios/persistence/remoting_preferences.h b/remoting/ios/persistence/remoting_preferences.h index 178417e..de6fd95 100644 --- a/remoting/ios/persistence/remoting_preferences.h +++ b/remoting/ios/persistence/remoting_preferences.h
@@ -15,7 +15,7 @@ extern RemotingFlag const RemotingFlagNotificationUiState; // |RemotingPreferences| is the centralized place to ask for information about -// defaults and prefrences. +// defaults and preferences. @interface RemotingPreferences : NSObject - (HostSettings*)settingsForHost:(NSString*)hostId;
diff --git a/sandbox/linux/syscall_broker/remote_syscall_arg_handler.cc b/sandbox/linux/syscall_broker/remote_syscall_arg_handler.cc index 642427b..f73113c7 100644 --- a/sandbox/linux/syscall_broker/remote_syscall_arg_handler.cc +++ b/sandbox/linux/syscall_broker/remote_syscall_arg_handler.cc
@@ -4,6 +4,7 @@ #include "sandbox/linux/syscall_broker/remote_syscall_arg_handler.h" +#include <string.h> #include <sys/ioctl.h> #include <sys/syscall.h> #include <sys/types.h>
diff --git a/services/network/public/cpp/cross_origin_opener_policy.cc b/services/network/public/cpp/cross_origin_opener_policy.cc index 880dd98..bc45fe5 100644 --- a/services/network/public/cpp/cross_origin_opener_policy.cc +++ b/services/network/public/cpp/cross_origin_opener_policy.cc
@@ -38,4 +38,21 @@ } } +const char* CoopAccessReportTypeToString(mojom::CoopAccessReportType type) { + switch (type) { + case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOpener: + return "access-from-coop-page-to-opener"; + case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOpenee: + return "access-from-coop-page-to-openee"; + case network::mojom::CoopAccessReportType::kAccessFromCoopPageToOther: + return "access-from-coop-page-to-other"; + case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOpener: + return "access-to-coop-page-from-opener"; + case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOpenee: + return "access-to-coop-page-from-openee"; + case network::mojom::CoopAccessReportType::kAccessToCoopPageFromOther: + return "access-to-coop-page-from-other"; + } +} + } // namespace network
diff --git a/services/network/public/cpp/cross_origin_opener_policy.h b/services/network/public/cpp/cross_origin_opener_policy.h index 5e4e16a..0a75a94 100644 --- a/services/network/public/cpp/cross_origin_opener_policy.h +++ b/services/network/public/cpp/cross_origin_opener_policy.h
@@ -34,6 +34,9 @@ COMPONENT_EXPORT(NETWORK_CPP_BASE) bool IsAccessFromCoopPage(mojom::CoopAccessReportType); +COMPONENT_EXPORT(NETWORK_CPP_BASE) +const char* CoopAccessReportTypeToString(mojom::CoopAccessReportType type); + } // namespace network #endif // SERVICES_NETWORK_PUBLIC_CPP_CROSS_ORIGIN_OPENER_POLICY_H_
diff --git a/services/service_manager/embedder/BUILD.gn b/services/service_manager/embedder/BUILD.gn deleted file mode 100644 index e3af755..0000000 --- a/services/service_manager/embedder/BUILD.gn +++ /dev/null
@@ -1,9 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//testing/test.gni") - -source_set("embedder_result_codes") { - sources = [ "result_codes.h" ] -}
diff --git a/services/service_manager/embedder/DEPS b/services/service_manager/embedder/DEPS deleted file mode 100644 index 74636dad..0000000 --- a/services/service_manager/embedder/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+components/tracing/common", - "+ui/base", -]
diff --git a/services/service_manager/embedder/README.md b/services/service_manager/embedder/README.md deleted file mode 100644 index 7b9004d..0000000 --- a/services/service_manager/embedder/README.md +++ /dev/null
@@ -1,17 +0,0 @@ -# Service Manager Embedder API - -The Service Manager is a library for opaquely managing service process launch, -sandboxing, and lifetime; and for brokering Mojo interface connections among -services. - -The Service Manager must be configured with a static set of declarative service -definitions. The embedder API provides a means of embedding core Service Manager -functionality into a standalone executable, delegating configuration and -assorted implementation details to the embedder. - -As one example, the Content layer of Chromium embeds the Service Manager via -this API, and there it's used [WIP] to drive all process management and IPC -setup across the system. - -This API is a work in progress, and more details will be documented here as the -API is stabilized.
diff --git a/services/service_manager/embedder/result_codes.h b/services/service_manager/embedder/result_codes.h deleted file mode 100644 index c153a496..0000000 --- a/services/service_manager/embedder/result_codes.h +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_SERVICE_MANAGER_EMBEDDER_RESULT_CODES_H_ -#define SERVICES_SERVICE_MANAGER_EMBEDDER_RESULT_CODES_H_ - -namespace service_manager { - -// The return code returned by the main method. -// Extended by embedders. - -enum ResultCode { - // Process terminated normally. - RESULT_CODE_NORMAL_EXIT, - - // Last return code (keep this last). - RESULT_CODE_LAST_CODE -}; - -// Embedders may rely on these result codes not changing. -static_assert(RESULT_CODE_LAST_CODE == 1, "This enum is frozen."); - -} // namespace service_manager - -#endif // SERVICES_SERVICE_MANAGER_EMBEDDER_RESULT_CODES_H_
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index d363395..8a47f998 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -245,8 +245,12 @@ "type": "console_test_launcher", }, "blink_python_tests": { + "args": [ + "../../third_party/blink/tools/run_blinkpy_tests.py", + ], "label": "//:blink_python_tests", - "type": "generated_script", + "script": "//testing/scripts/run_isolated_script_test.py", + "type": "script", }, "blink_tests": { "label": "//:blink_tests", @@ -257,12 +261,23 @@ "type": "console_test_launcher", }, "blink_web_tests": { - "label": "//:blink_web_tests", - "type": "generated_script", "args": [ + "../../third_party/blink/tools/run_web_tests.py", + "--seed", + "4", + "--no-show-results", + "--zero-tests-executed-ok", + "--clobber-old-results", + "--exit-after-n-failures", + "5000", + "--exit-after-n-crashes-or-timeouts", + "100", "--results-directory", "${ISOLATED_OUTDIR}", ], + "label": "//:blink_web_tests", + "script": "//testing/scripts/run_isolated_script_test.py", + "type": "script", }, "boundary_interface_example_apk": { "label": "//android_webview/support_library/boundary_interfaces:boundary_interface_example_apk",
diff --git a/testing/test.gni b/testing/test.gni index 91a2ce768..0187b24f 100644 --- a/testing/test.gni +++ b/testing/test.gni
@@ -24,7 +24,6 @@ if (is_chromeos) { import("//build/config/chromeos/rules.gni") - import("//build/util/generate_wrapper.gni") } if (is_ios) { @@ -556,66 +555,6 @@ } } -# Defines a type of test that invokes a script to run, rather than -# invoking an executable. -# -# The script must implement the -# [test executable API](//docs/testing/test_executable_api.md). -# -# The template must be passed the `script` parameter, which specifies -# the path to the script to run. It may optionally be passed a -# `script_args` parameter, which can be used to include a list of -# args to be specified by default. The template will produce -# a `$root_build_dir/run_$target_name` wrapper and write the runtime_deps -# for the target to $root_build_dir/${target_name}.runtime_deps, as per -# the conventions listed in the -# [test wrapper API](//docs/testing/test_wrapper_api.md). -template("script_test") { - generate_wrapper(target_name) { - testonly = true - wrapper_script = "${root_build_dir}/bin/run_${target_name}" - - executable = "//testing/test_env.py" - - executable_args = - [ "@WrappedPath(" + rebase_path(invoker.script, root_build_dir) + ")" ] - if (defined(invoker.args)) { - executable_args += invoker.args - } - - data = [ - "//.vpython", - "//testing/test_env.py", - - # These aren't needed by *every* test, but they're likely needed often - # enough to just make it easier to declare them here. - "//testing/xvfb.py", - "//testing/scripts/common.py", - - invoker.script, - ] - if (defined(invoker.data)) { - data += invoker.data - } - data_deps = [] - if (defined(invoker.data_deps)) { - data_deps += invoker.data_deps - } - - forward_variables_from(invoker, - [ "*" ], - [ - "data", - "data_deps", - "script", - "script_args", - "testonly", - ]) - - write_runtime_deps = "${root_build_dir}/${target_name}.runtime_deps" - } -} - # Test defaults. set_defaults("test") { if (is_android) {
diff --git a/third_party/blink/common/input/web_coalesced_input_event.cc b/third_party/blink/common/input/web_coalesced_input_event.cc index f5af6a1..dffae01c 100644 --- a/third_party/blink/common/input/web_coalesced_input_event.cc +++ b/third_party/blink/common/input/web_coalesced_input_event.cc
@@ -35,7 +35,7 @@ return *coalesced_events_[index].get(); } -const std::vector<WebCoalescedInputEvent::WebScopedInputEvent>& +const std::vector<std::unique_ptr<WebInputEvent>>& WebCoalescedInputEvent::GetCoalescedEventsPointers() const { return coalesced_events_; } @@ -54,7 +54,7 @@ return *predicted_events_[index].get(); } -const std::vector<WebCoalescedInputEvent::WebScopedInputEvent>& +const std::vector<std::unique_ptr<WebInputEvent>>& WebCoalescedInputEvent::GetPredictedEventsPointers() const { return predicted_events_; } @@ -98,7 +98,8 @@ return event_->CanCoalesce(*other.event_); } -void WebCoalescedInputEvent::CoalesceWith(WebCoalescedInputEvent& newer_event) { +void WebCoalescedInputEvent::CoalesceWith( + const WebCoalescedInputEvent& newer_event) { TRACE_EVENT2("input", "WebCoalescedInputEvent::CoalesceWith", "traceId", latency_.trace_id(), "coalescedTraceId", newer_event.latency_.trace_id()); @@ -113,14 +114,10 @@ event_->SetTimeStamp(time_stamp); AddCoalescedEvent(*newer_event.event_); - // When coalescing two input events, we keep the oldest LatencyInfo - // since it will represent the longest latency. If it's a GestureScrollUpdate - // event, update the old event's last timestamp and scroll delta using the - // newer event's latency info. + // If this is a GestureScrollUpdate event, update the old event's last + // timestamp and scroll delta using the newer event's latency info. if (event_->GetType() == WebInputEvent::Type::kGestureScrollUpdate) latency_.CoalesceScrollUpdateWith(newer_event.latency_); - newer_event.latency_ = latency_; - newer_event.latency_.set_coalesced(); } } // namespace blink
diff --git a/third_party/blink/public/common/input/web_coalesced_input_event.h b/third_party/blink/public/common/input/web_coalesced_input_event.h index a33bef6..f169511 100644 --- a/third_party/blink/public/common/input/web_coalesced_input_event.h +++ b/third_party/blink/public/common/input/web_coalesced_input_event.h
@@ -51,18 +51,14 @@ bool CanCoalesceWith(const WebCoalescedInputEvent& other) const WARN_UNUSED_RESULT; - // Coalesce with the |newer_event|. This object will be updated to - // take into account |newer_event|'s fields, and |newer_event|'s latency - // info will become the trace id of the older event (and be marked as - // coalesced). - void CoalesceWith(WebCoalescedInputEvent& newer_event); + // Coalesce with the |newer_event|. This object will be updated to take into + // account |newer_event|'s fields. + void CoalesceWith(const WebCoalescedInputEvent& newer_event); private: - using WebScopedInputEvent = std::unique_ptr<WebInputEvent>; - - WebScopedInputEvent event_; - std::vector<WebScopedInputEvent> coalesced_events_; - std::vector<WebScopedInputEvent> predicted_events_; + std::unique_ptr<WebInputEvent> event_; + std::vector<std::unique_ptr<WebInputEvent>> coalesced_events_; + std::vector<std::unique_ptr<WebInputEvent>> predicted_events_; ui::LatencyInfo latency_; };
diff --git a/third_party/blink/public/platform/DEPS b/third_party/blink/public/platform/DEPS index bd56937..7f8021bd 100644 --- a/third_party/blink/public/platform/DEPS +++ b/third_party/blink/public/platform/DEPS
@@ -31,6 +31,7 @@ "+media/base/video_frame_metadata.h", "+media/base/video_transformation.h", "+mojo/public", + "+net/base/ip_endpoint.h", "+net/cert", "+net/dns/public", "+net/http",
diff --git a/third_party/blink/public/platform/web_url_response.h b/third_party/blink/public/platform/web_url_response.h index c2598f9e..4126241 100644 --- a/third_party/blink/public/platform/web_url_response.h +++ b/third_party/blink/public/platform/web_url_response.h
@@ -35,6 +35,7 @@ #include "base/optional.h" #include "base/time/time.h" +#include "net/base/ip_endpoint.h" #include "net/cert/ct_policy_status.h" #include "net/http/http_response_info.h" #include "third_party/blink/public/common/security/security_style.h" @@ -286,13 +287,9 @@ // See network::ResourceResponseInfo::did_navigation_preload for details. BLINK_PLATFORM_EXPORT void SetDidServiceWorkerNavigationPreload(bool); - // Remote IP address of the socket which fetched this resource. - BLINK_PLATFORM_EXPORT WebString RemoteIPAddress() const; - BLINK_PLATFORM_EXPORT void SetRemoteIPAddress(const WebString&); - - // Remote port number of the socket which fetched this resource. - BLINK_PLATFORM_EXPORT uint16_t RemotePort() const; - BLINK_PLATFORM_EXPORT void SetRemotePort(uint16_t); + // Remote IP endpoint of the socket which fetched this resource. + BLINK_PLATFORM_EXPORT net::IPEndPoint RemoteIPEndpoint() const; + BLINK_PLATFORM_EXPORT void SetRemoteIPEndpoint(const net::IPEndPoint&); // Address space from which this resource was fetched. BLINK_PLATFORM_EXPORT network::mojom::IPAddressSpace AddressSpace() const;
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc index b73b912..708d398b 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -38,6 +38,7 @@ #include "base/bind_helpers.h" #include "third_party/blink/public/mojom/v8_cache_options.mojom-blink.h" #include "third_party/blink/public/web/web_settings.h" +#include "third_party/blink/renderer/bindings/core/v8/script_evaluation_result.h" #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" @@ -83,40 +84,29 @@ window_proxy_manager_->UpdateSecurityOrigin(security_origin); } +// TODO(crbug/1129743): Use ScriptEvaluationResult instead of +// v8::Local<v8::Value> as the return type. v8::Local<v8::Value> ScriptController::ExecuteScriptAndReturnValue( v8::Local<v8::Context> context, const ScriptSourceCode& source, const KURL& base_url, SanitizeScriptErrors sanitize_script_errors, const ScriptFetchOptions& fetch_options) { - TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data", - inspector_evaluate_script_event::Data(window_->GetFrame(), - source.Url().GetString(), - source.StartPosition())); - v8::Local<v8::Value> result; - { mojom::blink::V8CacheOptions v8_cache_options = mojom::blink::V8CacheOptions::kDefault; if (const Settings* settings = window_->GetFrame()->GetSettings()) v8_cache_options = settings->GetV8CacheOptions(); - // Isolate exceptions that occur when compiling and executing - // the code. These exceptions should not interfere with - // javascript code we might evaluate from C++ when returning - // from here. - v8::TryCatch try_catch(GetIsolate()); - try_catch.SetVerbose(true); + ScriptEvaluationResult result = V8ScriptRunner::CompileAndRunScript( + GetIsolate(), ScriptState::From(context), window_.Get(), source, + base_url, sanitize_script_errors, fetch_options, + std::move(v8_cache_options), + V8ScriptRunner::RethrowErrorsOption::DoNotRethrow()); - if (!V8ScriptRunner::CompileAndRunScript( - GetIsolate(), ScriptState::From(context), window_.Get(), source, - base_url, sanitize_script_errors, fetch_options, - std::move(v8_cache_options)) - .ToLocal(&result)) { - return result; - } - } + if (result.GetResultType() == ScriptEvaluationResult::ResultType::kSuccess) + return result.GetSuccessValue(); - return result; + return v8::Local<v8::Value>(); } TextPosition ScriptController::EventHandlerPosition() const {
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc index 223c8e0..ec7bcf34 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -31,11 +31,13 @@ #include "third_party/blink/public/mojom/v8_cache_options.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/binding_security.h" #include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h" +#include "third_party/blink/renderer/bindings/core/v8/script_evaluation_result.h" #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" #include "third_party/blink/renderer/bindings/core/v8/script_streamer.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h" #include "third_party/blink/renderer/bindings/core/v8/v8_initializer.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/core/execution_context/agent.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" @@ -364,7 +366,7 @@ return result; } -v8::MaybeLocal<v8::Value> V8ScriptRunner::CompileAndRunScript( +ScriptEvaluationResult V8ScriptRunner::CompileAndRunScript( v8::Isolate* isolate, ScriptState* script_state, ExecutionContext* execution_context, @@ -372,55 +374,131 @@ const KURL& base_url, SanitizeScriptErrors sanitize_script_errors, const ScriptFetchOptions& fetch_options, - mojom::blink::V8CacheOptions v8_cache_options) { + mojom::blink::V8CacheOptions v8_cache_options, + RethrowErrorsOption rethrow_errors) { DCHECK_EQ(isolate, script_state->GetIsolate()); - // Omit storing base URL if it is same as source URL. - // Note: This improves chance of getting into a fast path in - // ReferrerScriptInfo::ToV8HostDefinedOptions. - KURL stored_base_url = (base_url == source.Url()) ? KURL() : base_url; + LocalDOMWindow* window = DynamicTo<LocalDOMWindow>(execution_context); + LocalFrame* frame = window ? window->GetFrame() : nullptr; + TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data", + inspector_evaluate_script_event::Data( + frame, source.Url().GetString(), source.StartPosition())); - // TODO(hiroshige): Remove this code and related use counters once the - // measurement is done. - ReferrerScriptInfo::BaseUrlSource base_url_source = - ReferrerScriptInfo::BaseUrlSource::kOther; - if (source.SourceLocationType() == ScriptSourceLocationType::kExternalFile && - !base_url.IsNull()) { - switch (sanitize_script_errors) { - case SanitizeScriptErrors::kDoNotSanitize: - base_url_source = - ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSSameOrigin; - break; - case SanitizeScriptErrors::kSanitize: - base_url_source = - ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin; - break; + // Scope for |v8::TryCatch|. + { + v8::TryCatch try_catch(isolate); + // Step 8.3. Otherwise, rethrow errors is false. Perform the following + // steps: [spec text] + // Step 8.3.1. Report the exception given by evaluationStatus.[[Value]] + // for script. [spec text] + // + // This will be done inside V8 by setting TryCatch::SetVerbose(true) here. + if (!rethrow_errors.ShouldRethrow()) { + try_catch.SetVerbose(true); + } + + // Omit storing base URL if it is same as source URL. + // Note: This improves chance of getting into a fast path in + // ReferrerScriptInfo::ToV8HostDefinedOptions. + KURL stored_base_url = (base_url == source.Url()) ? KURL() : base_url; + + // TODO(hiroshige): Remove this code and related use counters once the + // measurement is done. + ReferrerScriptInfo::BaseUrlSource base_url_source = + ReferrerScriptInfo::BaseUrlSource::kOther; + if (source.SourceLocationType() == + ScriptSourceLocationType::kExternalFile && + !base_url.IsNull()) { + switch (sanitize_script_errors) { + case SanitizeScriptErrors::kDoNotSanitize: + base_url_source = + ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSSameOrigin; + break; + case SanitizeScriptErrors::kSanitize: + base_url_source = + ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin; + break; + } + } + const ReferrerScriptInfo referrer_info(stored_base_url, fetch_options, + base_url_source); + + v8::Local<v8::Script> script; + + v8::ScriptCompiler::CompileOptions compile_options; + V8CodeCache::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8CodeCache::GetCompileOptions(v8_cache_options, source); + + v8::MaybeLocal<v8::Value> maybe_result; + if (V8ScriptRunner::CompileScript(script_state, source, + sanitize_script_errors, compile_options, + no_cache_reason, referrer_info) + .ToLocal(&script)) { + maybe_result = + V8ScriptRunner::RunCompiledScript(isolate, script, execution_context); + probe::ProduceCompilationCache(probe::ToCoreProbeSink(execution_context), + source, script); + V8CodeCache::ProduceCache(isolate, script, source, produce_cache_options); + } + + // TODO(crbug/1114601): Investigate whether to check CanContinue() in other + // script evaluation code paths. + if (!try_catch.CanContinue()) { + return ScriptEvaluationResult::FromClassicAborted(); + } + + if (!try_catch.HasCaught()) { + // Step 10. If evaluationStatus is a normal completion, then return + // evaluationStatus. [spec text] + v8::Local<v8::Value> result; + bool success = maybe_result.ToLocal(&result); + DCHECK(success); + return ScriptEvaluationResult::FromClassicSuccess(result); + } + + DCHECK(maybe_result.IsEmpty()); + + if (rethrow_errors.ShouldRethrow() && + sanitize_script_errors == SanitizeScriptErrors::kDoNotSanitize) { + // Step 8.1. If rethrow errors is true and script's muted errors is + // false, then: [spec text] + // + // Step 8.1.2. Rethrow evaluationStatus.[[Value]]. [spec text] + // + // We rethrow exceptions reported from importScripts() here. The + // original filename/lineno/colno information (which points inside of + // imported scripts) is kept through ReThrow(), and will be eventually + // reported to WorkerGlobalScope.onerror via `TryCatch::SetVerbose(true)` + // called at top-level worker script evaluation. + try_catch.ReThrow(); + return ScriptEvaluationResult::FromClassicException(); } } - const ReferrerScriptInfo referrer_info(stored_base_url, fetch_options, - base_url_source); + // |v8::TryCatch| is (and should be) exited, before ThrowException() below. - v8::Local<v8::Script> script; + if (rethrow_errors.ShouldRethrow()) { + // kDoNotSanitize case is processed and early-exited above. + DCHECK_EQ(sanitize_script_errors, SanitizeScriptErrors::kSanitize); - v8::ScriptCompiler::CompileOptions compile_options; - V8CodeCache::ProduceCacheOptions produce_cache_options; - v8::ScriptCompiler::NoCacheReason no_cache_reason; - std::tie(compile_options, produce_cache_options, no_cache_reason) = - V8CodeCache::GetCompileOptions(v8_cache_options, source); + // Step 8.2. If rethrow errors is true and script's muted errors is + // true, then: [spec text] + // + // Step 8.2.2. Throw a "NetworkError" DOMException. [spec text] + // + // We don't supply any message here to avoid leaking details of muted + // errors. + V8ThrowException::ThrowException( + isolate, V8ThrowDOMException::CreateOrEmpty( + isolate, DOMExceptionCode::kNetworkError, + rethrow_errors.Message())); + return ScriptEvaluationResult::FromClassicException(); + } - if (!V8ScriptRunner::CompileScript(script_state, source, - sanitize_script_errors, compile_options, - no_cache_reason, referrer_info) - .ToLocal(&script)) - return v8::MaybeLocal<v8::Value>(); - - v8::MaybeLocal<v8::Value> maybe_result = - V8ScriptRunner::RunCompiledScript(isolate, script, execution_context); - probe::ProduceCompilationCache(probe::ToCoreProbeSink(execution_context), - source, script); - V8CodeCache::ProduceCache(isolate, script, source, produce_cache_options); - - return maybe_result; + // #report-the-error for rethrow errors == true is already handled via + // |TryCatch::SetVerbose(true)| above. + return ScriptEvaluationResult::FromClassicException(); } v8::MaybeLocal<v8::Value> V8ScriptRunner::CompileAndRunInternalScript(
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h index 46f480299..38ca4a3 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "v8/include/v8.h" namespace WTF { @@ -39,6 +40,7 @@ namespace blink { +class ScriptEvaluationResult; class ExecutionContext; class KURL; class ReferrerScriptInfo; @@ -51,6 +53,43 @@ STATIC_ONLY(V8ScriptRunner); public: + // Rethrow errors flag in + // https://html.spec.whatwg.org/C/#run-a-classic-script + class RethrowErrorsOption final { + STACK_ALLOCATED(); + + public: + RethrowErrorsOption(RethrowErrorsOption&&) = default; + RethrowErrorsOption& operator=(RethrowErrorsOption&&) = default; + + RethrowErrorsOption(const RethrowErrorsOption&) = delete; + RethrowErrorsOption& operator=(const RethrowErrorsOption&) = delete; + + // Rethrow errors flag is false. + static RethrowErrorsOption DoNotRethrow() { + return RethrowErrorsOption(base::nullopt); + } + + // Rethrow errors flag is true. When rethrowing, a NetworkError with + // `message` is thrown. This is used only for importScripts(), and + // `message` is used to throw NetworkErrors with the same message text, + // no matter whether the NetworkError is thrown inside or outside + // EvaluateAndReturnValue(). + static RethrowErrorsOption Rethrow(const String& message) { + return RethrowErrorsOption(message); + } + + bool ShouldRethrow() const { return static_cast<bool>(message_); } + String Message() const { return *message_; } + + private: + explicit RethrowErrorsOption(base::Optional<String> message) + : message_(std::move(message)) {} + + // `nullopt` <=> rethrow errors is false. + base::Optional<String> message_; + }; + // For the following methods, the caller sites have to hold // a HandleScope and a ContextScope. static v8::MaybeLocal<v8::Script> CompileScript( @@ -69,7 +108,7 @@ v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason, const ReferrerScriptInfo&); - static v8::MaybeLocal<v8::Value> CompileAndRunScript( + static ScriptEvaluationResult CompileAndRunScript( v8::Isolate*, ScriptState*, ExecutionContext*, @@ -77,7 +116,8 @@ const KURL&, SanitizeScriptErrors, const ScriptFetchOptions&, - mojom::blink::V8CacheOptions); + mojom::blink::V8CacheOptions, + RethrowErrorsOption); static v8::MaybeLocal<v8::Value> CompileAndRunInternalScript( v8::Isolate*, ScriptState*,
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc index dc9b7f4f..5103c28 100644 --- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -316,114 +316,41 @@ const ScriptSourceCode& source_code, SanitizeScriptErrors sanitize_script_errors, mojom::blink::V8CacheOptions v8_cache_options, - RethrowErrorsOption rethrow_errors) { - if (IsExecutionForbidden()) { + V8ScriptRunner::RethrowErrorsOption rethrow_errors) { + if (IsExecutionForbidden()) return ScriptEvaluationResult::FromClassicNotRun(); - } - // Scope for |TRACE_EVENT1| and |v8::TryCatch| below. - { - DCHECK(IsContextInitialized()); - DCHECK(is_ready_to_evaluate_); + DCHECK(IsContextInitialized()); + DCHECK(is_ready_to_evaluate_); - TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data", - inspector_evaluate_script_event::Data( - nullptr, source_code.Url(), source_code.StartPosition())); + // TODO(crbug/1114994): Plumb this from ClassicScript. + const KURL base_url = source_code.Url(); - v8::TryCatch block(isolate_); + // Use default ReferrerScriptInfo here, as + // - A work{er,let} script doesn't have a nonce, and + // - a work{er,let} script is always "not parser inserted". + // TODO(crbug/1114988): After crbug/1114988 is fixed, this can be the + // default ScriptFetchOptions(). Currently the default ScriptFetchOptions() + // is not used because it has CredentialsMode::kOmit. + // TODO(crbug/1114989): Plumb this from ClassicScript. + ScriptFetchOptions script_fetch_options( + String(), IntegrityMetadataSet(), String(), + ParserDisposition::kNotParserInserted, + network::mojom::CredentialsMode::kSameOrigin, + network::mojom::ReferrerPolicy::kDefault, + mojom::blink::FetchImportanceMode::kImportanceAuto); - // Step 8.3. Otherwise, rethrow errors is false. Perform the following - // steps: [spec text] - // Step 8.3.1. Report the exception given by evaluationStatus.[[Value]] - // for script. [spec text] - // - // This will be done inside V8 (inside V8ScriptRunner::CompileAndRunScript() - // below) by setting TryCatch::SetVerbose(true) here. - if (!rethrow_errors.ShouldRethrow()) { - block.SetVerbose(true); - } + ScriptEvaluationResult result = V8ScriptRunner::CompileAndRunScript( + isolate_, script_state_, global_scope_, source_code, base_url, + sanitize_script_errors, script_fetch_options, v8_cache_options, + std::move(rethrow_errors)); - // TODO(crbug/1114994): Plumb this from ClassicScript. - const KURL base_url = source_code.Url(); - - // Use default ReferrerScriptInfo here, as - // - A work{er,let} script doesn't have a nonce, and - // - a work{er,let} script is always "not parser inserted". - // TODO(crbug/1114988): After crbug/1114988 is fixed, this can be the - // default ScriptFetchOptions(). Currently the default ScriptFetchOptions() - // is not used because it has CredentialsMode::kOmit. - // TODO(crbug/1114989): Plumb this from ClassicScript. - ScriptFetchOptions script_fetch_options( - String(), IntegrityMetadataSet(), String(), - ParserDisposition::kNotParserInserted, - network::mojom::CredentialsMode::kSameOrigin, - network::mojom::ReferrerPolicy::kDefault, - mojom::blink::FetchImportanceMode::kImportanceAuto); - - v8::MaybeLocal<v8::Value> maybe_result = - V8ScriptRunner::CompileAndRunScript( - isolate_, script_state_, global_scope_, source_code, base_url, - sanitize_script_errors, script_fetch_options, v8_cache_options); - - // TODO(crbug/1114601): Investigate whether to check CanContinue() in other - // script evaluation code paths. - if (!block.CanContinue()) { - ForbidExecution(); - return ScriptEvaluationResult::FromClassicAborted(); - } - + if (result.GetResultType() == ScriptEvaluationResult::ResultType::kAborted) + ForbidExecution(); + else CHECK(!IsExecutionForbidden()); - if (!block.HasCaught()) { - // Step 10. If evaluationStatus is a normal completion, then return - // evaluationStatus. [spec text] - v8::Local<v8::Value> result; - bool success = maybe_result.ToLocal(&result); - DCHECK(success); - return ScriptEvaluationResult::FromClassicSuccess(result); - } - - DCHECK(maybe_result.IsEmpty()); - - if (rethrow_errors.ShouldRethrow() && - sanitize_script_errors == SanitizeScriptErrors::kDoNotSanitize) { - // Step 8.1. If rethrow errors is true and script's muted errors is - // false, then: [spec text] - // - // Step 8.1.2. Rethrow evaluationStatus.[[Value]]. [spec text] - // - // We rethrow exceptions reported from importScripts() here. The - // original filename/lineno/colno information (which points inside of - // imported scripts) is kept through ReThrow(), and will be eventually - // reported to WorkerGlobalScope.onerror via `TryCatch::SetVerbose(true)` - // called at top-level worker script evaluation. - block.ReThrow(); - return ScriptEvaluationResult::FromClassicException(); - } - } - // |v8::TryCatch| is (and should be) exited, before ThrowException() below. - - if (rethrow_errors.ShouldRethrow()) { - // kDoNotSanitize case is processed and early-exited above. - DCHECK_EQ(sanitize_script_errors, SanitizeScriptErrors::kSanitize); - - // Step 8.2. If rethrow errors is true and script's muted errors is - // true, then: [spec text] - // - // Step 8.2.2. Throw a "NetworkError" DOMException. [spec text] - // - // We don't supply any message here to avoid leaking details of muted - // errors. - V8ThrowException::ThrowException( - isolate_, V8ThrowDOMException::CreateOrEmpty( - isolate_, DOMExceptionCode::kNetworkError, - rethrow_errors.Message())); - return ScriptEvaluationResult::FromClassicException(); - } - - // #report-the-error for rethrow errors == true is already handled via - // |TryCatch::SetVerbose(true)| above. - return ScriptEvaluationResult::FromClassicException(); + return result; } void WorkerOrWorkletScriptController::ForbidExecution() {
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h index 5ab5e584..24286a79 100644 --- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h +++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
@@ -57,50 +57,14 @@ bool IsExecutionForbidden() const; - // Rethrow errors flag in - // https://html.spec.whatwg.org/C/#run-a-classic-script - class RethrowErrorsOption final { - STACK_ALLOCATED(); - - public: - RethrowErrorsOption(RethrowErrorsOption&&) = default; - RethrowErrorsOption& operator=(RethrowErrorsOption&&) = default; - - RethrowErrorsOption(const RethrowErrorsOption&) = delete; - RethrowErrorsOption& operator=(const RethrowErrorsOption&) = delete; - - // Rethrow errors flag is false. - static RethrowErrorsOption DoNotRethrow() { - return RethrowErrorsOption(base::nullopt); - } - - // Rethrow errors flag is true. When rethrowing, a NetworkError with - // `message` is thrown. This is used only for importScripts(), and - // `message` is used to throw NetworkErrors with the same message text, - // no matter whether the NetworkError is thrown inside or outside - // EvaluateAndReturnValue(). - static RethrowErrorsOption Rethrow(const String& message) { - return RethrowErrorsOption(message); - } - - bool ShouldRethrow() const { return static_cast<bool>(message_); } - String Message() const { return *message_; } - - private: - explicit RethrowErrorsOption(base::Optional<String> message) - : message_(std::move(message)) {} - - // `nullopt` <=> rethrow errors is false. - base::Optional<String> message_; - }; - // https://html.spec.whatwg.org/C/#run-a-classic-script // Callers should enter ScriptState::Scope before calling this. ScriptEvaluationResult EvaluateAndReturnValue( const ScriptSourceCode&, SanitizeScriptErrors sanitize_script_errors, mojom::blink::V8CacheOptions = mojom::blink::V8CacheOptions::kDefault, - RethrowErrorsOption = RethrowErrorsOption::DoNotRethrow()); + V8ScriptRunner::RethrowErrorsOption = + V8ScriptRunner::RethrowErrorsOption::DoNotRethrow()); // Prevents future JavaScript execution. void ForbidExecution();
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 09469c6..6cf406ae 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -1565,18 +1565,12 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gyroscope.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_collection_info.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_collection_info.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_connection_event.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_connection_event.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_device.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_device.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_input_report_event.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_input_report_event.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_info.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_info.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_item.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_item.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_canvas_element.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_canvas_element.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_element.cc",
diff --git a/third_party/blink/renderer/core/css/rule_feature_set.cc b/third_party/blink/renderer/core/css/rule_feature_set.cc index c5b144f..698615e 100644 --- a/third_party/blink/renderer/core/css/rule_feature_set.cc +++ b/third_party/blink/renderer/core/css/rule_feature_set.cc
@@ -511,6 +511,9 @@ void RuleFeatureSet::ExtractInvalidationSetFeaturesFromSimpleSelector( const CSSSelector& selector, InvalidationSetFeatures& features) { + features.has_features_for_rule_set_invalidation |= + selector.IsIdClassOrAttributeSelector(); + if (selector.Match() == CSSSelector::kTag && selector.TagQName().LocalName() != CSSSelector::UniversalSelectorAtom()) { features.NarrowToTag(selector.TagQName().LocalName()); @@ -729,6 +732,7 @@ const CSSSelector* sub_selector = selector_list->First(); bool all_sub_selectors_have_features = true; + bool all_sub_selectors_have_features_for_ruleset_invalidation = true; InvalidationSetFeatures any_features; for (; sub_selector; sub_selector = CSSSelectorList::Next(*sub_selector)) { @@ -739,6 +743,8 @@ features.invalidation_flags.SetWholeSubtreeInvalid(true); return kRequiresSubtreeInvalidation; } + all_sub_selectors_have_features_for_ruleset_invalidation &= + complex_features.has_features_for_rule_set_invalidation; if (complex_features.has_nth_pseudo) features.has_nth_pseudo = true; if (!all_sub_selectors_have_features) @@ -752,6 +758,8 @@ // any invalidation set features. E.g. :-webkit-any(*, span). if (all_sub_selectors_have_features) features.NarrowToFeatures(any_features); + features.has_features_for_rule_set_invalidation |= + all_sub_selectors_have_features_for_ruleset_invalidation; return kNormalInvalidation; } @@ -810,8 +818,6 @@ if (!simple_selector->TagHistory() || simple_selector->Relation() != CSSSelector::kSubSelector) { - features.has_features_for_rule_set_invalidation = - features.HasIdClassOrAttribute(); return simple_selector; } } @@ -849,6 +855,8 @@ invalidation_set.AddId(id); for (const auto& tag_name : features.tag_names) invalidation_set.AddTagName(tag_name); + for (const auto& emitted_tag_name : features.emitted_tag_names) + invalidation_set.AddTagName(emitted_tag_name); for (const auto& class_name : features.classes) invalidation_set.AddClass(class_name); for (const auto& attribute : features.attributes) @@ -876,6 +884,11 @@ simple_selector.SelectorList()->First(); sub_selector; sub_selector = CSSSelectorList::Next(*sub_selector)) { AutoRestoreMaxDirectAdjacentSelectors restore_max(sibling_features); + AutoRestoreTreeBoundaryCrossingFlag restore_tree_boundary( + descendant_features); + + if (simple_selector.IsHostPseudoClass()) + descendant_features.invalidation_flags.SetTreeBoundaryCrossing(true); descendant_features.has_features_for_rule_set_invalidation = false; @@ -934,8 +947,6 @@ return; } - if (simple_selector.IsHostPseudoClass()) - descendant_features.invalidation_flags.SetTreeBoundaryCrossing(true); if (simple_selector.IsV0InsertionPointCrossing()) descendant_features.invalidation_flags.SetInsertionPointCrossing(true); if (simple_selector.GetPseudoType() == CSSSelector::kPseudoPart) @@ -1384,7 +1395,22 @@ classes.AppendVector(other.classes); attributes.AppendVector(other.attributes); ids.AppendVector(other.ids); - tag_names.AppendVector(other.tag_names); + // Tag names that have been added to an invalidation set for an ID, a class, + // or an attribute are called "emitted" tag names. Emitted tag names need to + // go in a separate vector in order to correctly track which tag names to + // add to the type rule invalidation set. + // + // Example: :is(.a, div) :is(span, .b, ol, .c li) + // + // For the above selector, we need span and ol in the type invalidation set, + // but not li, since that tag name was added to the invalidation set for .c. + // Hence, when processing the rightmost :is(), we end up with li in the + // emitted_tag_names vector, and span and ol in the regular tag_names vector. + if (other.has_features_for_rule_set_invalidation) + emitted_tag_names.AppendVector(other.tag_names); + else + tag_names.AppendVector(other.tag_names); + emitted_tag_names.AppendVector(other.emitted_tag_names); max_direct_adjacent_selectors = std::max(max_direct_adjacent_selectors, other.max_direct_adjacent_selectors); invalidation_flags.Merge(other.invalidation_flags); @@ -1404,7 +1430,8 @@ bool RuleFeatureSet::InvalidationSetFeatures::HasFeatures() const { return !classes.IsEmpty() || !attributes.IsEmpty() || !ids.IsEmpty() || - !tag_names.IsEmpty() || invalidation_flags.InvalidateCustomPseudo() || + !tag_names.IsEmpty() || !emitted_tag_names.IsEmpty() || + invalidation_flags.InvalidateCustomPseudo() || invalidation_flags.InvalidatesParts(); }
diff --git a/third_party/blink/renderer/core/css/rule_feature_set.h b/third_party/blink/renderer/core/css/rule_feature_set.h index 0a3f22f..ffbe4ad 100644 --- a/third_party/blink/renderer/core/css/rule_feature_set.h +++ b/third_party/blink/renderer/core/css/rule_feature_set.h
@@ -273,15 +273,18 @@ attributes.clear(); ids.clear(); tag_names.clear(); + emitted_tag_names.clear(); } unsigned Size() const { - return classes.size() + attributes.size() + ids.size() + tag_names.size(); + return classes.size() + attributes.size() + ids.size() + + tag_names.size() + emitted_tag_names.size(); } Vector<AtomicString> classes; Vector<AtomicString> attributes; Vector<AtomicString> ids; Vector<AtomicString> tag_names; + Vector<AtomicString> emitted_tag_names; unsigned max_direct_adjacent_selectors = 0; InvalidationFlags invalidation_flags; bool content_pseudo_crossing = false; @@ -321,6 +324,25 @@ unsigned original_value_ = 0; }; + // For :is(:host(.a), .b) .c, the invalidation set for .a should be marked + // as tree-crossing, but the invalidation set for .b should not. + class AutoRestoreTreeBoundaryCrossingFlag { + STACK_ALLOCATED(); + + public: + explicit AutoRestoreTreeBoundaryCrossingFlag( + InvalidationSetFeatures& features) + : features_(features), + original_value_(features.invalidation_flags.TreeBoundaryCrossing()) {} + ~AutoRestoreTreeBoundaryCrossingFlag() { + features_.invalidation_flags.SetTreeBoundaryCrossing(original_value_); + } + + private: + InvalidationSetFeatures& features_; + bool original_value_; + }; + static void ExtractInvalidationSetFeature(const CSSSelector&, InvalidationSetFeatures&);
diff --git a/third_party/blink/renderer/core/css/rule_feature_set_test.cc b/third_party/blink/renderer/core/css/rule_feature_set_test.cc index 550681c..461b18f 100644 --- a/third_party/blink/renderer/core/css/rule_feature_set_test.cc +++ b/third_party/blink/renderer/core/css/rule_feature_set_test.cc
@@ -1512,6 +1512,28 @@ {":is(.a + .b, .c + .d) + :is(.e + .f, .g + .h)", ".a + .b + .f, .a + .b + .h, .c + .d + .f, .c + .d + .h," ".e + .f, .g + .h"}, + {":is(div)", "div"}, + {":is(div, span)", "div, span"}, + {":is(.a, div)", ".a, div"}, + {":is(.a, :is(div, span))", ".a, div, span"}, + {":is(.a, span) :is(div, .b)", ".a div, .a .b, span div, span .b"}, + {":is(.a, span) + :is(div, .b)", + ".a + div, .a + .b, span + div, span + .b"}, + {":is(.a, .b)::slotted(.c)", ".a::slotted(.c), .b::slotted(.c)"}, + {".a :is(.b, .c)::slotted(.d)", ".a .b::slotted(.d), .a .c::slotted(.d)"}, + {".a + :is(.b, .c)::slotted(.d)", + ".a + .b::slotted(.d), .a + .c::slotted(.d)"}, + {":is(.a, .b)::cue(i)", ".a::cue(i), .b::cue(i)"}, + {".a :is(.b, .c)::cue(i)", ".a .b::cue(i), .a .c::cue(i)"}, + {".a + :is(.b, .c)::cue(i)", ".a + .b::cue(i), .a + .c::cue(i)"}, + {":is(.a, :host + .b, .c) .d", ".a .d, :host + .b .d, .c .d"}, + {":is(.a, :host(.b) .c, .d) div", ".a div, :host(.b) .c div, .d div"}, + {".a :is(.b, .c)::part(foo)", ".a .b::part(foo), .a .c::part(foo)"}, + {":is(.a, .b)::part(foo)", ".a::part(foo), .b::part(foo)"}, + {":is(.a, .b) :is(.c, .d)::part(foo)", + ".a .c::part(foo), .a .d ::part(foo)," + ".b .c::part(foo), .b .d ::part(foo)"}, + // clang-format on };
diff --git a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc index 185e152..6ee6f91 100644 --- a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc +++ b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
@@ -189,7 +189,8 @@ // register an event handler. && !(shadow_ancestor_element && shadow_ancestor_element->GetLayoutObject() && - shadow_ancestor_element->GetLayoutObject()->IsTextControl()) && + shadow_ancestor_element->GetLayoutObject() + ->IsTextControlIncludingNG()) && HasRichlyEditableStyle(*editable_root)) { RemoveInterchangeNodes(fragment_); return;
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc index 75eab85..a7d566b 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
@@ -357,7 +357,7 @@ // Enter user-agent shadow root, if necessary. if (iteration_progress_ < kHandledUserAgentShadowRoot) { if (std::is_same<Strategy, EditingStrategy>::value && - EntersTextControls() && layout_object->IsTextControl()) { + EntersTextControls() && layout_object->IsTextControlIncludingNG()) { ShadowRoot* user_agent_shadow_root = To<Element>(node_)->UserAgentShadowRoot(); DCHECK(user_agent_shadow_root->IsUserAgent()); @@ -554,7 +554,7 @@ } } - if (EntersTextControls() && layout_object->IsTextControl()) { + if (EntersTextControls() && layout_object->IsTextControlIncludingNG()) { // The shadow tree should be already visited. return; }
diff --git a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc index f96f3db..e6f569d7 100644 --- a/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc +++ b/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc
@@ -556,7 +556,7 @@ return nullptr; if (layout_object->IsText()) return node; - if (layout_object->IsTextControl()) { + if (layout_object->IsTextControlIncludingNG()) { node = To<TextControlElement>(node) ->VisiblePositionForIndex(1) .DeepEquivalent()
diff --git a/third_party/blink/renderer/core/frame/DEPS b/third_party/blink/renderer/core/frame/DEPS index e89497f..bce2d2b 100644 --- a/third_party/blink/renderer/core/frame/DEPS +++ b/third_party/blink/renderer/core/frame/DEPS
@@ -2,6 +2,9 @@ "ad_tracker_test.cc": [ "+base/run_loop.h", ], + "coop_access_violation_report_body.cc": [ + "+services/network/public/cpp/cross_origin_opener_policy.h" + ], "frame_view.cc": [ "+ui/gfx/transform.h" ],
diff --git a/third_party/blink/renderer/core/frame/coop_access_violation_report_body.cc b/third_party/blink/renderer/core/frame/coop_access_violation_report_body.cc index c730a35..acf50cd 100644 --- a/third_party/blink/renderer/core/frame/coop_access_violation_report_body.cc +++ b/third_party/blink/renderer/core/frame/coop_access_violation_report_body.cc
@@ -3,17 +3,26 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/frame/coop_access_violation_report_body.h" +#include "services/network/public/cpp/cross_origin_opener_policy.h" namespace blink { CoopAccessViolationReportBody::CoopAccessViolationReportBody( std::unique_ptr<SourceLocation> source_location, + network::mojom::blink::CoopAccessReportType type, const String& property) - : LocationReportBody(std::move(source_location)), property_(property) {} + : LocationReportBody(std::move(source_location)), + type_(type), + property_(property) {} + +String CoopAccessViolationReportBody::type() const { + return network::CoopAccessReportTypeToString(type_); +} void CoopAccessViolationReportBody::BuildJSONValue( V8ObjectBuilder& builder) const { LocationReportBody::BuildJSONValue(builder); + builder.AddString("type", type()); builder.AddString("property", property()); }
diff --git a/third_party/blink/renderer/core/frame/coop_access_violation_report_body.h b/third_party/blink/renderer/core/frame/coop_access_violation_report_body.h index cb8c18b..701264a 100644 --- a/third_party/blink/renderer/core/frame/coop_access_violation_report_body.h +++ b/third_party/blink/renderer/core/frame/coop_access_violation_report_body.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_COOP_ACCESS_VIOLATION_REPORT_BODY_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_COOP_ACCESS_VIOLATION_REPORT_BODY_H_ +#include "services/network/public/mojom/cross_origin_opener_policy.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" #include "third_party/blink/renderer/core/frame/location_report_body.h" @@ -15,13 +16,17 @@ DEFINE_WRAPPERTYPEINFO(); public: - CoopAccessViolationReportBody(std::unique_ptr<SourceLocation> source_location, - const String& property); + CoopAccessViolationReportBody( + std::unique_ptr<SourceLocation> source_location, + network::mojom::blink::CoopAccessReportType type, + const String& property); ~CoopAccessViolationReportBody() final = default; + String type() const; const String& property() const { return property_; } void BuildJSONValue(V8ObjectBuilder& builder) const final; private: + network::mojom::blink::CoopAccessReportType type_; const String property_; };
diff --git a/third_party/blink/renderer/core/frame/coop_access_violation_report_body.idl b/third_party/blink/renderer/core/frame/coop_access_violation_report_body.idl index 06ad8b6..bdeb2f4 100644 --- a/third_party/blink/renderer/core/frame/coop_access_violation_report_body.idl +++ b/third_party/blink/renderer/core/frame/coop_access_violation_report_body.idl
@@ -10,6 +10,7 @@ readonly attribute DOMString? sourceFile; readonly attribute unsigned long? lineNumber; readonly attribute unsigned long? columnNumber; + readonly attribute DOMString type; readonly attribute DOMString property; [CallWith=ScriptState] object toJSON(); };
diff --git a/third_party/blink/renderer/core/frame/dom_window.cc b/third_party/blink/renderer/core/frame/dom_window.cc index 4a909ad4..94ed6fd 100644 --- a/third_party/blink/renderer/core/frame/dom_window.cc +++ b/third_party/blink/renderer/core/frame/dom_window.cc
@@ -547,7 +547,8 @@ ReportType::kCoopAccessViolation, accessing_main_frame.GetDocument()->Url().GetString(), MakeGarbageCollected<CoopAccessViolationReportBody>( - std::move(location), String(property_name)))); + std::move(location), it->report_type, + String(property_name)))); } }
diff --git a/third_party/blink/renderer/core/html/canvas/text_metrics.idl b/third_party/blink/renderer/core/html/canvas/text_metrics.idl index a3b8513..9c58a6e 100644 --- a/third_party/blink/renderer/core/html/canvas/text_metrics.idl +++ b/third_party/blink/renderer/core/html/canvas/text_metrics.idl
@@ -34,8 +34,8 @@ readonly attribute double actualBoundingBoxRight; // y-direction - [RuntimeEnabled=ExtendedTextMetrics] readonly attribute double fontBoundingBoxAscent; - [RuntimeEnabled=ExtendedTextMetrics] readonly attribute double fontBoundingBoxDescent; + readonly attribute double fontBoundingBoxAscent; + readonly attribute double fontBoundingBoxDescent; readonly attribute double actualBoundingBoxAscent; readonly attribute double actualBoundingBoxDescent; [RuntimeEnabled=ExtendedTextMetrics] readonly attribute double emHeightAscent;
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc index 526b5463..9219e785 100644 --- a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
@@ -47,7 +47,8 @@ #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" #include "third_party/blink/renderer/core/html_names.h" -#include "third_party/blink/renderer/core/layout/layout_text_control_multi_line.h" +#include "third_party/blink/renderer/core/layout/layout_object.h" +#include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -213,10 +214,11 @@ } } -LayoutObject* HTMLTextAreaElement::CreateLayoutObject(const ComputedStyle&, - LegacyLayout) { +LayoutObject* HTMLTextAreaElement::CreateLayoutObject( + const ComputedStyle& style, + LegacyLayout legacy) { UseCounter::Count(GetDocument(), WebFeature::kLegacyLayoutByTextControl); - return new LayoutTextControlMultiLine(this); + return LayoutObjectFactory::CreateTextControlMultiLine(*this, style, legacy); } void HTMLTextAreaElement::AppendToFormData(FormData& form_data) {
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc index 9d505d400..45d928cd 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_element.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -107,7 +107,7 @@ void TextControlElement::DefaultEventHandler(Event& event) { if (event.type() == event_type_names::kWebkitEditableContentChanged && - GetLayoutObject() && GetLayoutObject()->IsTextControl()) { + GetLayoutObject() && GetLayoutObject()->IsTextControlIncludingNG()) { last_change_was_user_edit_ = !GetDocument().IsRunningExecCommand(); user_has_edited_the_field_ |= last_change_was_user_edit_;
diff --git a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc index 87518582a..28e87ca 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
@@ -35,7 +35,7 @@ #include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" #include "third_party/blink/renderer/core/html_names.h" -#include "third_party/blink/renderer/core/layout/layout_text_control_single_line.h" +#include "third_party/blink/renderer/core/layout/layout_object_factory.h" namespace blink { @@ -119,9 +119,10 @@ } LayoutObject* TextControlInnerEditorElement::CreateLayoutObject( - const ComputedStyle&, - LegacyLayout) { - return new LayoutTextControlInnerEditor(this); + const ComputedStyle& style, + LegacyLayout legacy) { + return LayoutObjectFactory::CreateTextControlInnerEditor(*this, style, + legacy); } scoped_refptr<ComputedStyle>
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc index b7938ca..39bd23d7 100644 --- a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -46,8 +46,7 @@ #include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/layout_details_marker.h" -#include "third_party/blink/renderer/core/layout/layout_text_control_single_line.h" -#include "third_party/blink/renderer/core/layout/layout_theme.h" +#include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" @@ -281,11 +280,13 @@ return true; } -LayoutObject* TextFieldInputType::CreateLayoutObject(const ComputedStyle&, - LegacyLayout) const { +LayoutObject* TextFieldInputType::CreateLayoutObject( + const ComputedStyle& style, + LegacyLayout legacy) const { UseCounter::Count(GetElement().GetDocument(), WebFeature::kLegacyLayoutByTextControl); - return new LayoutTextControlSingleLine(&GetElement()); + return LayoutObjectFactory::CreateTextControlSingleLine(GetElement(), style, + legacy); } void TextFieldInputType::CreateShadowSubtree() {
diff --git a/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc b/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc index c794037..b0ee1b05 100644 --- a/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc +++ b/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
@@ -46,6 +46,7 @@ #include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/text/character_visitor.h" #include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -425,10 +426,20 @@ Vector<ImageCandidate>& image_candidates, Document* document = nullptr) { const float kDefaultDensityValue = 1.0; + // The srcset image source selection mechanism is user-agent specific: + // https://html.spec.whatwg.org/multipage/images.html#selecting-an-image-source + // + // Setting max density value based on https://github.com/whatwg/html/pull/5901 + const float kMaxDensity = 2.2; bool ignore_src = false; if (image_candidates.IsEmpty()) return ImageCandidate(); + if (RuntimeEnabledFeatures::SrcsetMaxDensityEnabled() && + device_scale_factor > kMaxDensity) { + device_scale_factor = kMaxDensity; + } + // http://picture.responsiveimages.org/#normalize-source-densities for (ImageCandidate& image : image_candidates) { if (image.GetResourceWidth() > 0) {
diff --git a/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc b/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc index 9b8791a..856ec9c 100644 --- a/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc
@@ -10,6 +10,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/web_network_state_notifier.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { @@ -323,4 +324,25 @@ } } +TEST(HTMLSrcsetParserTest, MaxDensityEnabled) { + RuntimeEnabledFeatures::SetSrcsetMaxDensityEnabled(true); + SrcsetParserTestCase test_cases[] = { + {10.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1}, + {2.5, -1, "src.gif", "1.5x.gif 1.5x, 3x.gif 3x", "3x.gif", 3.0, -1}, + {4.0, 400, "", "400.gif 400w, 1000.gif 1000w", "1000.gif", 2.5, 1000}, + {0, 0, nullptr, nullptr, nullptr, + 0} // Do not remove the terminator line. + }; + + for (unsigned i = 0; test_cases[i].src_input; ++i) { + SrcsetParserTestCase test = test_cases[i]; + ImageCandidate candidate = BestFitSourceForImageAttributes( + test.device_scale_factor, test.effective_size, test.src_input, + test.srcset_input); + ASSERT_EQ(test.output_density, candidate.Density()); + ASSERT_EQ(test.output_resource_width, candidate.GetResourceWidth()); + ASSERT_EQ(test.output_url, candidate.ToString().Ascii()); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/DEPS b/third_party/blink/renderer/core/inspector/DEPS index 57411687..5b4c20a 100644 --- a/third_party/blink/renderer/core/inspector/DEPS +++ b/third_party/blink/renderer/core/inspector/DEPS
@@ -9,6 +9,8 @@ "+base/process/process_handle.h", "+base/process/process_metrics.h", "+cc/trees/transform_node.h", + "+net/base/ip_address.h", + "+net/base/ip_endpoint.h", "+third_party/inspector_protocol/crdtp", "+third_party/icu/source/common/unicode/locid.h", "+net/http/http_status_code.h",
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.cc b/third_party/blink/renderer/core/inspector/inspect_tools.cc index ad6e6d1..93d4851 100644 --- a/third_party/blink/renderer/core/inspector/inspect_tools.cc +++ b/third_party/blink/renderer/core/inspector/inspect_tools.cc
@@ -102,10 +102,14 @@ // SearchingForNodeTool -------------------------------------------------------- -SearchingForNodeTool::SearchingForNodeTool(InspectorDOMAgent* dom_agent, +SearchingForNodeTool::SearchingForNodeTool(InspectorOverlayAgent* overlay, + OverlayFrontend* frontend, + InspectorDOMAgent* dom_agent, bool ua_shadow, const std::vector<uint8_t>& config) - : dom_agent_(dom_agent), ua_shadow_(ua_shadow) { + : InspectTool(overlay, frontend), + dom_agent_(dom_agent), + ua_shadow_(ua_shadow) { auto parsed_config = protocol::Overlay::HighlightConfig::FromBinary( config.data(), config.size()); if (parsed_config) { @@ -131,7 +135,6 @@ !omit_tooltip_ && highlight_config_->show_info && node->GetLayoutObject() && node->GetDocument().GetFrame(); - DCHECK(overlay_); overlay_->EnsureAXContext(node); InspectorHighlight highlight(node, *highlight_config_, contrast_info_, append_element_info, false, is_locked_ancestor_); @@ -262,10 +265,15 @@ // QuadHighlightTool ----------------------------------------------------------- -QuadHighlightTool::QuadHighlightTool(std::unique_ptr<FloatQuad> quad, +QuadHighlightTool::QuadHighlightTool(InspectorOverlayAgent* overlay, + OverlayFrontend* frontend, + std::unique_ptr<FloatQuad> quad, Color color, Color outline_color) - : quad_(std::move(quad)), color_(color), outline_color_(outline_color) {} + : InspectTool(overlay, frontend), + quad_(std::move(quad)), + color_(color), + outline_color_(outline_color) {} bool QuadHighlightTool::ForwardEventsToOverlay() { return false; @@ -284,10 +292,13 @@ // NodeHighlightTool ----------------------------------------------------------- NodeHighlightTool::NodeHighlightTool( + InspectorOverlayAgent* overlay, + OverlayFrontend* frontend, Member<Node> node, String selector_list, std::unique_ptr<InspectorHighlightConfig> highlight_config) - : selector_list_(selector_list), + : InspectTool(overlay, frontend), + selector_list_(selector_list), highlight_config_(std::move(highlight_config)) { if (Node* locked_ancestor = DisplayLockUtilities::HighestLockedExclusiveAncestor(*node)) { @@ -339,7 +350,6 @@ if (!query_base) query_base = node_->ownerDocument(); - DCHECK(overlay_); overlay_->EnsureAXContext(query_base); StaticElementList* elements = query_base->QuerySelectorAll( @@ -369,7 +379,6 @@ NodeHighlightTool::GetNodeInspectorHighlightAsJson( bool append_element_info, bool append_distance_info) const { - DCHECK(overlay_); overlay_->EnsureAXContext(node_.Get()); InspectorHighlight highlight(node_.Get(), *highlight_config_, contrast_info_, append_element_info, append_distance_info, @@ -434,9 +443,12 @@ // SourceOrderTool ----------------------------------------------------------- SourceOrderTool::SourceOrderTool( + InspectorOverlayAgent* overlay, + OverlayFrontend* frontend, Node* node, std::unique_ptr<InspectorSourceOrderConfig> source_order_config) - : source_order_config_(std::move(source_order_config)) { + : InspectTool(overlay, frontend), + source_order_config_(std::move(source_order_config)) { if (Node* locked_ancestor = DisplayLockUtilities::HighestLockedExclusiveAncestor(*node)) { node_ = locked_ancestor; @@ -559,7 +571,6 @@ Node* node = hovered_node_.Get(); if (!node) return; - DCHECK(overlay_); overlay_->EnsureAXContext(node); InspectorHighlight highlight( node, InspectorHighlight::DefaultConfig(), @@ -589,7 +600,9 @@ // ScreenshotTool -------------------------------------------------------------- -void ScreenshotTool::DoInit() { +ScreenshotTool::ScreenshotTool(InspectorOverlayAgent* overlay, + OverlayFrontend* frontend) + : InspectTool(overlay, frontend) { auto& client = overlay_->GetFrame()->GetPage()->GetChromeClient(); client.SetCursorOverridden(false); client.SetCursor(CrossCursor(), overlay_->GetFrame());
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.h b/third_party/blink/renderer/core/inspector/inspect_tools.h index cdfc690..0cff030 100644 --- a/third_party/blink/renderer/core/inspector/inspect_tools.h +++ b/third_party/blink/renderer/core/inspector/inspect_tools.h
@@ -19,7 +19,9 @@ class SearchingForNodeTool : public InspectTool { public: - SearchingForNodeTool(InspectorDOMAgent* dom_agent, + SearchingForNodeTool(InspectorOverlayAgent* overlay, + OverlayFrontend* frontend, + InspectorDOMAgent* dom_agent, bool ua_shadow, const std::vector<uint8_t>& highlight_config); @@ -52,7 +54,9 @@ class QuadHighlightTool : public InspectTool { public: - QuadHighlightTool(std::unique_ptr<FloatQuad> quad, + QuadHighlightTool(InspectorOverlayAgent* overlay, + OverlayFrontend* frontend, + std::unique_ptr<FloatQuad> quad, Color color, Color outline_color); @@ -70,7 +74,9 @@ class NodeHighlightTool : public InspectTool { public: - NodeHighlightTool(Member<Node> node, + NodeHighlightTool(InspectorOverlayAgent* overlay, + OverlayFrontend* frontend, + Member<Node> node, String selector_list, std::unique_ptr<InspectorHighlightConfig> highlight_config); @@ -101,6 +107,8 @@ class SourceOrderTool : public InspectTool { public: SourceOrderTool( + InspectorOverlayAgent* overlay, + OverlayFrontend* frontend, Node* node, std::unique_ptr<InspectorSourceOrderConfig> source_order_config); std::unique_ptr<protocol::DictionaryValue> @@ -123,8 +131,9 @@ // ----------------------------------------------------------------------------- class GridHighlightTool : public InspectTool { + using InspectTool::InspectTool; + public: - GridHighlightTool() = default; void Draw(float scale) override; void AddGridConfig( Node* node, @@ -147,8 +156,7 @@ // ----------------------------------------------------------------------------- class NearbyDistanceTool : public InspectTool { - public: - NearbyDistanceTool() = default; + using InspectTool::InspectTool; private: int GetDataResourceId() override; @@ -166,8 +174,7 @@ // ----------------------------------------------------------------------------- class ShowViewSizeTool : public InspectTool { - public: - ShowViewSizeTool() = default; + using InspectTool::InspectTool; private: bool ForwardEventsToOverlay() override; @@ -180,11 +187,10 @@ class ScreenshotTool : public InspectTool { public: - ScreenshotTool() = default; + ScreenshotTool(InspectorOverlayAgent* overlay, OverlayFrontend* frontend); private: int GetDataResourceId() override; - void DoInit() override; void Dispatch(const String& message) override; DISALLOW_COPY_AND_ASSIGN(ScreenshotTool); @@ -194,9 +200,13 @@ class PausedInDebuggerTool : public InspectTool { public: - PausedInDebuggerTool(v8_inspector::V8InspectorSession* v8_session, + PausedInDebuggerTool(InspectorOverlayAgent* overlay, + OverlayFrontend* frontend, + v8_inspector::V8InspectorSession* v8_session, const String& message) - : v8_session_(v8_session), message_(message) {} + : InspectTool(overlay, frontend), + v8_session_(v8_session), + message_(message) {} private: int GetDataResourceId() override;
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc index 9e41b60..0a3a21b8 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -37,6 +37,8 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "build/build_config.h" +#include "net/base/ip_address.h" +#include "net/base/ip_endpoint.h" #include "net/http/http_status_code.h" #include "services/network/public/mojom/referrer_policy.mojom-blink.h" #include "services/network/public/mojom/websocket.mojom-blink.h" @@ -490,6 +492,15 @@ } } +String IPAddressToString(const net::IPAddress& address) { + String unbracketed = String::FromUTF8(address.ToString()); + if (!address.IsIPv6()) { + return unbracketed; + } + + return "[" + unbracketed + "]"; +} + } // namespace void InspectorNetworkAgent::Restore() { @@ -698,10 +709,11 @@ } } - String remote_ip_address = response.RemoteIPAddress(); - if (!remote_ip_address.IsEmpty()) { - response_object->setRemoteIPAddress(remote_ip_address); - response_object->setRemotePort(response.RemotePort()); + const net::IPEndPoint& remote_ip_endpoint = response.RemoteIPEndpoint(); + if (remote_ip_endpoint.address().IsValid()) { + response_object->setRemoteIPAddress( + IPAddressToString(remote_ip_endpoint.address())); + response_object->setRemotePort(remote_ip_endpoint.port()); } String protocol = response.AlpnNegotiatedProtocol();
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc index e1727d5..29402d2 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -111,13 +111,6 @@ // InspectTool ----------------------------------------------------------------- -void InspectTool::Init(InspectorOverlayAgent* overlay, - OverlayFrontend* frontend) { - overlay_ = overlay; - frontend_ = frontend; - DoInit(); -} - int InspectTool::GetDataResourceId() { return IDR_INSPECT_TOOL_HIGHLIGHT_JS; } @@ -624,7 +617,8 @@ std::unique_ptr<FloatQuad> quad = std::make_unique<FloatQuad>(FloatRect(x, y, width, height)); SetInspectTool(MakeGarbageCollected<QuadHighlightTool>( - std::move(quad), InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr)), + this, GetFrontend(), std::move(quad), + InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr)), InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr)))); return Response::Success(); } @@ -637,7 +631,8 @@ if (!ParseQuad(std::move(quad_array), quad.get())) return Response::ServerError("Invalid Quad format"); SetInspectTool(MakeGarbageCollected<QuadHighlightTool>( - std::move(quad), InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr)), + this, GetFrontend(), std::move(quad), + InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr)), InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr)))); return Response::Success(); } @@ -704,7 +699,8 @@ return response; SetInspectTool(MakeGarbageCollected<NodeHighlightTool>( - node, selector_list.fromMaybe(String()), std::move(highlight_config))); + this, GetFrontend(), node, selector_list.fromMaybe(String()), + std::move(highlight_config))); return Response::Success(); } @@ -714,7 +710,8 @@ persistent_tool_ = nullptr; if (grid_node_highlight_configs->size()) { - GridHighlightTool* grid_tool = MakeGarbageCollected<GridHighlightTool>(); + GridHighlightTool* grid_tool = + MakeGarbageCollected<GridHighlightTool>(this, GetFrontend()); for (std::unique_ptr<protocol::Overlay::GridNodeHighlightConfig>& config : *grid_node_highlight_configs) { Node* node = nullptr; @@ -725,7 +722,6 @@ InspectorOverlayAgent::ToGridHighlightConfig( config->getGridHighlightConfig())); } - grid_tool->Init(this, GetFrontend()); persistent_tool_ = grid_tool; } @@ -752,7 +748,7 @@ std::make_unique<InspectorSourceOrderConfig>(config); SetInspectTool(MakeGarbageCollected<SourceOrderTool>( - node, std::move(source_order_config))); + this, GetFrontend(), node, std::move(source_order_config))); return Response::Success(); } @@ -775,7 +771,8 @@ InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr)); SetInspectTool(MakeGarbageCollected<NodeHighlightTool>( - frame->DeprecatedLocalOwner(), String(), std::move(highlight_config))); + this, GetFrontend(), frame->DeprecatedLocalOwner(), String(), + std::move(highlight_config))); } else { PickTheRightTool(); } @@ -815,8 +812,8 @@ config->color_format = ColorFormat::HEX; } - NodeHighlightTool tool(node, "" /* selector_list */, std::move(config)); - tool.Init(this, GetFrontend()); + NodeHighlightTool tool(this, GetFrontend(), node, "" /* selector_list */, + std::move(config)); *result = tool.GetNodeInspectorHighlightAsJson( true /* append_element_info */, include_distance.fromMaybe(false)); return Response::Success(); @@ -825,8 +822,7 @@ Response InspectorOverlayAgent::getGridHighlightObjectsForTest( std::unique_ptr<protocol::Array<int>> node_ids, std::unique_ptr<protocol::DictionaryValue>* highlights) { - GridHighlightTool grid_highlight_tool; - grid_highlight_tool.Init(this, GetFrontend()); + GridHighlightTool grid_highlight_tool(this, GetFrontend()); for (const int node_id : *node_ids) { Node* node = nullptr; Response response = dom_agent_->AssertNode(node_id, node); @@ -851,8 +847,7 @@ auto config = std::make_unique<InspectorSourceOrderConfig>( InspectorSourceOrderHighlight::DefaultConfig()); - SourceOrderTool tool(node, std::move(config)); - tool.Init(this, GetFrontend()); + SourceOrderTool tool(this, GetFrontend(), node, std::move(config)); *result = tool.GetNodeInspectorSourceOrderHighlightAsJson(); return Response::Success(); } @@ -1230,7 +1225,7 @@ } // Show the resize tool. - SetInspectTool(MakeGarbageCollected<ShowViewSizeTool>()); + SetInspectTool(MakeGarbageCollected<ShowViewSizeTool>(this, GetFrontend())); resize_timer_active_ = true; resize_timer_.Stop(); resize_timer_.StartOneShot(base::TimeDelta::FromSeconds(1), FROM_HERE); @@ -1322,19 +1317,20 @@ inspect_mode == protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM) { inspect_tool = MakeGarbageCollected<SearchingForNodeTool>( - dom_agent_, + this, GetFrontend(), dom_agent_, inspect_mode == protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM, inspect_mode_protocol_config_.Get()); } else if (inspect_mode == protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot) { - inspect_tool = MakeGarbageCollected<ScreenshotTool>(); + inspect_tool = MakeGarbageCollected<ScreenshotTool>(this, GetFrontend()); } else if (inspect_mode == protocol::Overlay::InspectModeEnum::ShowDistances) { - inspect_tool = MakeGarbageCollected<NearbyDistanceTool>(); + inspect_tool = + MakeGarbageCollected<NearbyDistanceTool>(this, GetFrontend()); } else if (!paused_in_debugger_message_.Get().IsNull()) { inspect_tool = MakeGarbageCollected<PausedInDebuggerTool>( - v8_session_, paused_in_debugger_message_.Get()); + this, GetFrontend(), v8_session_, paused_in_debugger_message_.Get()); } else if (persistent_tool_) { inspect_tool = persistent_tool_; } @@ -1375,7 +1371,6 @@ // tool will be included into the JS resource. LoadFrameForTool(inspect_tool->GetDataResourceId()); EnsureEnableFrameOverlay(); - inspect_tool->Init(this, GetFrontend()); } else { inspect_tool_ = nullptr; if (!hinge_)
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h index dae922a1..2954a87 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
@@ -78,9 +78,10 @@ class CORE_EXPORT InspectTool : public GarbageCollected<InspectTool> { public: + InspectTool(InspectorOverlayAgent* overlay, OverlayFrontend* frontend) + : overlay_(overlay), frontend_(frontend) {} virtual ~InspectTool() = default; - void Init(InspectorOverlayAgent* overlay, OverlayFrontend* frontend); virtual int GetDataResourceId(); virtual bool HandleInputEvent(LocalFrameView* frame_view, const WebInputEvent& input_event, @@ -103,8 +104,6 @@ virtual bool HideOnMouseMove(); protected: - InspectTool() = default; - virtual void DoInit() {} Member<InspectorOverlayAgent> overlay_; OverlayFrontend* frontend_ = nullptr; };
diff --git a/third_party/blink/renderer/core/layout/generated_children.h b/third_party/blink/renderer/core/layout/generated_children.h index 82a8613..cf6f455 100644 --- a/third_party/blink/renderer/core/layout/generated_children.h +++ b/third_party/blink/renderer/core/layout/generated_children.h
@@ -17,7 +17,7 @@ static bool CanHaveGeneratedChildren(const LayoutObject& layout_object) { // FIXME: LayoutMedia::layout makes assumptions about what children are // allowed so we can't support generated content. - if (layout_object.IsMedia() || layout_object.IsTextControl() || + if (layout_object.IsMedia() || layout_object.IsTextControlIncludingNG() || IsMenuList(&layout_object)) return false;
diff --git a/third_party/blink/renderer/core/layout/geometry/logical_rect.cc b/third_party/blink/renderer/core/layout/geometry/logical_rect.cc index ddf8ebc..c83a7056 100644 --- a/third_party/blink/renderer/core/layout/geometry/logical_rect.cc +++ b/third_party/blink/renderer/core/layout/geometry/logical_rect.cc
@@ -33,6 +33,10 @@ return; } + UniteEvenIfEmpty(other); +} + +void LogicalRect::UniteEvenIfEmpty(const LogicalRect& other) { LogicalOffset new_end_offset(Max(EndOffset(), other.EndOffset())); LogicalOffset new_start_offset(Min(offset, other.offset)); size = new_end_offset - new_start_offset;
diff --git a/third_party/blink/renderer/core/layout/geometry/logical_rect.h b/third_party/blink/renderer/core/layout/geometry/logical_rect.h index b6196671..514ebe0 100644 --- a/third_party/blink/renderer/core/layout/geometry/logical_rect.h +++ b/third_party/blink/renderer/core/layout/geometry/logical_rect.h
@@ -65,6 +65,7 @@ } void Unite(const LogicalRect&); + void UniteEvenIfEmpty(const LogicalRect&); String ToString() const; };
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 26b8bc4..a9c4684 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -2646,7 +2646,7 @@ if (UNLIKELY(input)) { // As for LayoutButton, ControlClip is to for not BUTTONs but INPUT // buttons for IE/Firefox compatibility. - if (IsTextField() || IsButtonIncludingNG()) { + if (IsTextFieldIncludingNG() || IsButtonIncludingNG()) { DCHECK(HasControlClip()); PhysicalRect control_clip = PhysicalPaddingBoxRect(); control_clip.Move(location); @@ -2666,7 +2666,8 @@ bool LayoutBox::HasControlClip() const { NOT_DESTROYED(); - return UNLIKELY(IsTextField() || IsFileUploadControl() || IsMenuList(this) || + return UNLIKELY(IsTextFieldIncludingNG() || IsFileUploadControl() || + IsMenuList(this) || (IsButtonIncludingNG() && IsA<HTMLInputElement>(GetNode()))); } @@ -3835,9 +3836,10 @@ bool LayoutBox::ShouldComputeLogicalWidthFromAspectRatio( LayoutUnit* out_logical_height) const { NOT_DESTROYED(); - if (StyleRef().AspectRatio().IsAuto() || - (!StyleRef().LogicalHeight().IsFixed() && - !StyleRef().LogicalHeight().IsPercentOrCalc())) { + if (!ShouldComputeLogicalWidthFromAspectRatioAndInsets() && + (StyleRef().AspectRatio().IsAuto() || + (!StyleRef().LogicalHeight().IsFixed() && + !StyleRef().LogicalHeight().IsPercentOrCalc()))) { return false; }
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index 7f1a8807..0adaf5dc 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -560,12 +560,25 @@ LayoutUnit* logical_height = nullptr) const; bool ShouldComputeLogicalHeightFromAspectRatio() const { NOT_DESTROYED(); + if (ShouldComputeLogicalWidthFromAspectRatioAndInsets()) + return false; Length h = StyleRef().LogicalHeight(); return !StyleRef().AspectRatio().IsAuto() && (h.IsAuto() || (!IsOutOfFlowPositioned() && h.IsPercentOrCalc() && ComputePercentageLogicalHeight(h) == kIndefiniteSize)); } + bool ShouldComputeLogicalWidthFromAspectRatioAndInsets() const { + NOT_DESTROYED(); + const ComputedStyle& style = StyleRef(); + if (style.AspectRatio().IsAuto() || !IsOutOfFlowPositioned()) + return false; + if (style.Width().IsAuto() && style.Height().IsAuto() && + !style.LogicalTop().IsAuto() && !style.LogicalBottom().IsAuto() && + (style.LogicalLeft().IsAuto() || style.LogicalRight().IsAuto())) + return true; + return false; + } bool ComputeLogicalWidthFromAspectRatio(LayoutUnit* logical_width) const; MinMaxSizes ComputeMinMaxLogicalWidthFromAspectRatio() const;
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 7a98750..21c8a2e 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1045,7 +1045,7 @@ if (!style->Width().IsFixed() || !style->Height().IsFixed()) return false; - if (object->IsTextControl()) + if (object->IsTextControlIncludingNG()) return true; if (!object->HasNonVisibleOverflow()) @@ -1456,7 +1456,8 @@ // select elements inside that are created by user agent shadow DOM, and we // have (C++) code that assumes that the elements are indeed contained by the // text control. So just make sure this is the case. - if (IsA<LayoutView>(this) || IsSVGForeignObject() || IsTextControl()) + if (IsA<LayoutView>(this) || IsSVGForeignObject() || + IsTextControlIncludingNG()) return true; // https://www.w3.org/TR/css-transforms-1/#containing-block-for-all-descendants
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 46419ff..af644aa6 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -965,17 +965,21 @@ NOT_DESTROYED(); return IsOfType(kLayoutObjectTableSection); } - bool IsTextArea() const { + bool IsTextAreaIncludingNG() const { NOT_DESTROYED(); - return IsOfType(kLayoutObjectTextArea); + return IsOfType(kLayoutObjectTextArea) || + IsOfType(kLayoutObjectNGTextControlMultiLine); } - bool IsTextControl() const { + bool IsTextControlIncludingNG() const { NOT_DESTROYED(); - return IsOfType(kLayoutObjectTextControl); + return IsOfType(kLayoutObjectTextControl) || + IsOfType(kLayoutObjectNGTextControlMultiLine) || + IsOfType(kLayoutObjectNGTextControlSingleLine); } - bool IsTextField() const { + bool IsTextFieldIncludingNG() const { NOT_DESTROYED(); - return IsOfType(kLayoutObjectTextField); + return IsOfType(kLayoutObjectTextField) || + IsOfType(kLayoutObjectNGTextControlSingleLine); } bool IsVideo() const { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.cc b/third_party/blink/renderer/core/layout/layout_object_factory.cc index 07c6b61..1d189570 100644 --- a/third_party/blink/renderer/core/layout/layout_object_factory.cc +++ b/third_party/blink/renderer/core/layout/layout_object_factory.cc
@@ -25,6 +25,8 @@ #include "third_party/blink/renderer/core/layout/layout_table_row.h" #include "third_party/blink/renderer/core/layout/layout_table_section.h" #include "third_party/blink/renderer/core/layout/layout_text.h" +#include "third_party/blink/renderer/core/layout/layout_text_control_multi_line.h" +#include "third_party/blink/renderer/core/layout/layout_text_control_single_line.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h" @@ -36,6 +38,9 @@ #include "third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h" #include "third_party/blink/renderer/core/layout/ng/layout_ng_progress.h" #include "third_party/blink/renderer/core/layout/ng/layout_ng_ruby_as_block.h" +#include "third_party/blink/renderer/core/layout/ng/layout_ng_text_control_inner_editor.h" +#include "third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.h" +#include "third_party/blink/renderer/core/layout/ng/layout_ng_text_control_single_line.h" #include "third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h" #include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h" #include "third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h" @@ -266,6 +271,30 @@ node, style, legacy); } +LayoutObject* LayoutObjectFactory::CreateTextControlInnerEditor( + Node& node, + const ComputedStyle& style, + LegacyLayout legacy) { + return CreateObject<LayoutBlockFlow, LayoutNGTextControlInnerEditor, + LayoutTextControlInnerEditor>(node, style, legacy); +} + +LayoutObject* LayoutObjectFactory::CreateTextControlMultiLine( + Node& node, + const ComputedStyle& style, + LegacyLayout legacy) { + return CreateObject<LayoutBlockFlow, LayoutNGTextControlMultiLine, + LayoutTextControlMultiLine>(node, style, legacy); +} + +LayoutObject* LayoutObjectFactory::CreateTextControlSingleLine( + Node& node, + const ComputedStyle& style, + LegacyLayout legacy) { + return CreateObject<LayoutBlockFlow, LayoutNGTextControlSingleLine, + LayoutTextControlSingleLine>(node, style, legacy); +} + LayoutText* LayoutObjectFactory::CreateText(Node* node, scoped_refptr<StringImpl> str, LegacyLayout legacy) {
diff --git a/third_party/blink/renderer/core/layout/layout_object_factory.h b/third_party/blink/renderer/core/layout/layout_object_factory.h index 0ac03eda..5877295 100644 --- a/third_party/blink/renderer/core/layout/layout_object_factory.h +++ b/third_party/blink/renderer/core/layout/layout_object_factory.h
@@ -76,6 +76,15 @@ static LayoutObject* CreateSliderTrack(Node& node, const ComputedStyle& style, LegacyLayout legacy); + static LayoutObject* CreateTextControlInnerEditor(Node& node, + const ComputedStyle& style, + LegacyLayout legacy); + static LayoutObject* CreateTextControlMultiLine(Node& node, + const ComputedStyle& style, + LegacyLayout legacy); + static LayoutObject* CreateTextControlSingleLine(Node& node, + const ComputedStyle& style, + LegacyLayout legacy); static LayoutText* CreateText(Node*, scoped_refptr<StringImpl>, LegacyLayout); static LayoutTextFragment* CreateTextFragment(Node*,
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc index bd5c51b..df4d10d 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc +++ b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc
@@ -28,10 +28,9 @@ namespace blink { -LayoutTextControlMultiLine::LayoutTextControlMultiLine( - HTMLTextAreaElement* element) - : LayoutTextControl(element) { - DCHECK(element); +LayoutTextControlMultiLine::LayoutTextControlMultiLine(Element* element) + : LayoutTextControl(To<TextControlElement>(element)) { + DCHECK(IsA<HTMLTextAreaElement>(element)); } LayoutTextControlMultiLine::~LayoutTextControlMultiLine() = default;
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h index c684dd44..5828d9c 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h +++ b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h
@@ -27,11 +27,9 @@ namespace blink { -class HTMLTextAreaElement; - class LayoutTextControlMultiLine final : public LayoutTextControl { public: - LayoutTextControlMultiLine(HTMLTextAreaElement*); + explicit LayoutTextControlMultiLine(Element*); ~LayoutTextControlMultiLine() override; private:
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc index 7be1af4..a5376344 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc +++ b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" +#include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_analyzer.h" @@ -35,9 +36,10 @@ namespace blink { -LayoutTextControlSingleLine::LayoutTextControlSingleLine( - HTMLInputElement* element) - : LayoutTextControl(element) {} +LayoutTextControlSingleLine::LayoutTextControlSingleLine(Element* element) + : LayoutTextControl(To<TextControlElement>(element)) { + DCHECK(IsA<HTMLInputElement>(element)); +} LayoutTextControlSingleLine::~LayoutTextControlSingleLine() = default;
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_single_line.h b/third_party/blink/renderer/core/layout/layout_text_control_single_line.h index 87e32e9..e03d33b 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_single_line.h +++ b/third_party/blink/renderer/core/layout/layout_text_control_single_line.h
@@ -24,13 +24,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_TEXT_CONTROL_SINGLE_LINE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_TEXT_CONTROL_SINGLE_LINE_H_ -#include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/layout/layout_text_control.h" namespace blink { -class HTMLInputElement; - // LayoutObject for text-field <input>s. // // This class inherits from LayoutTextControl and LayoutBlockFlow. If we'd like @@ -39,7 +36,7 @@ // base class. class LayoutTextControlSingleLine : public LayoutTextControl { public: - LayoutTextControlSingleLine(HTMLInputElement*); + explicit LayoutTextControlSingleLine(Element*); ~LayoutTextControlSingleLine() override; protected:
diff --git a/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h b/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h index 92dfba2..f4795b5 100644 --- a/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h +++ b/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h
@@ -47,6 +47,13 @@ bool IsEmpty() const { return *this == NGBoxStrut(); } + void ClampNegativeToZero() { + inline_start = inline_start.ClampNegativeToZero(); + inline_end = inline_end.ClampNegativeToZero(); + block_start = block_start.ClampNegativeToZero(); + block_end = block_end.ClampNegativeToZero(); + } + inline NGPhysicalBoxStrut ConvertToPhysical(WritingMode, TextDirection) const; // The following two operators exist primarily to have an easy way to access
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc index 218e5761..4a06769e 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
@@ -607,7 +607,9 @@ // require layout, only ink overflow, but they currently do. {"#parent.after { text-decoration-line: underline; }", StyleChangeData::kNone, true, true}, - {"#parent.after { outline: auto; }", StyleChangeData::kNone, true}, + {"#parent { background: orange; }" // Make sure it's not culled. + "#parent.after { outline: auto; }", + StyleChangeData::kNone, true}, // Changing fonts should re-run |CollectInlines()|. {"#parent.after { font-size: 200%; }", StyleChangeData::kAll, true}, // Changing from/to out-of-flow should re-rerun |CollectInlines()|.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc index 778a3a1d7..a19b8bf 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
@@ -194,36 +194,87 @@ // maybe OOF objects. Investigate how to handle them. } } - AddChild(fragment, offset); + + NGMarginStrut end_margin_strut = child_layout_result.EndMarginStrut(); + // No margins should pierce outside formatting-context roots. + DCHECK(!fragment.IsFormattingContextRoot() || end_margin_strut.IsEmpty()); + + AddChild(fragment, offset, /* inline_container */ nullptr, &end_margin_strut); if (fragment.IsBox()) PropagateBreak(child_layout_result); } void NGBoxFragmentBuilder::AddChild(const NGPhysicalContainerFragment& child, const LogicalOffset& child_offset, - const LayoutInline* inline_container) { + const LayoutInline* inline_container, + const NGMarginStrut* margin_strut) { LogicalOffset adjusted_offset = child_offset; - if (child.IsCSSBox() && - box_type_ != NGPhysicalBoxFragment::NGBoxType::kInlineBox) { - // Apply the relative position offset. - const auto& box_child = To<NGPhysicalBoxFragment>(child); - if (box_child.Style().GetPosition() == EPosition::kRelative) { - adjusted_offset += ComputeRelativeOffsetForBoxFragment( - box_child, GetWritingDirection(), child_available_size_); + if (box_type_ != NGPhysicalBoxFragment::NGBoxType::kInlineBox) { + if (child.IsCSSBox()) { + // Apply the relative position offset. + const auto& box_child = To<NGPhysicalBoxFragment>(child); + if (box_child.Style().GetPosition() == EPosition::kRelative) { + adjusted_offset += ComputeRelativeOffsetForBoxFragment( + box_child, GetWritingDirection(), child_available_size_); + } + + // The |may_have_descendant_above_block_start_| flag is used to determine + // if a fragment can be re-used when preceding floats are present. This + // is relatively rare, and is true if: + // - An inflow child is positioned above our block-start edge. + // - Any inflow descendants (within the same formatting-context) which + // *may* have a child positioned above our block-start edge. + if ((child_offset.block_offset < LayoutUnit() && + !box_child.IsOutOfFlowPositioned()) || + (!box_child.IsFormattingContextRoot() && + box_child.MayHaveDescendantAboveBlockStart())) + may_have_descendant_above_block_start_ = true; } - // The |may_have_descendant_above_block_start_| flag is used to determine - // if a fragment can be re-used when preceding floats are present. This is - // relatively rare, and is true if: - // - An inflow child is positioned above our block-start edge. - // - Any inflow descendants (within the same formatting-context) which - // *may* have a child positioned above our block-start edge. - if ((child_offset.block_offset < LayoutUnit() && - !box_child.IsOutOfFlowPositioned()) || - (!box_child.IsFormattingContextRoot() && - box_child.MayHaveDescendantAboveBlockStart())) - may_have_descendant_above_block_start_ = true; + // If we are a scroll container, we need to track the maximum bounds of any + // inflow children (including line-boxes) to calculate the layout-overflow. + // + // This is used for determining the "padding-box" of the scroll container + // which is *sometimes* considered as part of the scrollable area. Inflow + // children contribute to this area, out-of-flow positioned children don't. + // + // Out-of-flow positioned children still contribute to the layout-overflow, + // but just don't influence where this padding is. + if (Node().IsScrollContainer() && !child.IsOutOfFlowPositioned()) { + NGBoxStrut margins; + if (child.IsCSSBox()) { + margins = + ComputeMarginsFor(child.Style(), child_available_size_.inline_size, + GetWritingMode(), Direction()); + } + + // If we are in block-flow layout we use the end *margin-strut* as the + // block-end "margin" (instead of just the block-end margin). + if (margin_strut) { + NGMarginStrut end_margin_strut = *margin_strut; + end_margin_strut.Append(margins.block_end, /* is_quirky */ false); + margins.block_end = end_margin_strut.Sum(); + } + + NGFragment fragment(GetWritingMode(), child); + + // Use the original offset (*without* relative-positioning applied), and + // clamp any negative margins to zero. + margins.ClampNegativeToZero(); + LogicalRect bounds = { + LogicalOffset(child_offset.inline_offset - margins.inline_start, + child_offset.block_offset - margins.block_start), + LogicalSize( + margins.inline_start + fragment.InlineSize() + margins.inline_end, + margins.block_start + fragment.BlockSize() + margins.block_end)}; + + // Even an empty (0x0) fragment contributes to the inflow-bounds. + if (!inflow_bounds_) + inflow_bounds_ = bounds; + else + inflow_bounds_->UniteEvenIfEmpty(bounds); + } } PropagateChildData(child, adjusted_offset, inline_container);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h index b29aa67..c2633bf7 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
@@ -207,7 +207,8 @@ void AddChild(const NGPhysicalContainerFragment&, const LogicalOffset&, - const LayoutInline* inline_container = nullptr); + const LayoutInline* inline_container = nullptr, + const NGMarginStrut* margin_strut = nullptr); // Manually add a break token to the builder. Note that we're assuming that // this break token is for content in the same flow as this parent. @@ -546,6 +547,7 @@ LogicalSize child_available_size_; LayoutUnit overflow_block_size_ = kIndefiniteSize; LayoutUnit intrinsic_block_size_; + base::Optional<LogicalRect> inflow_bounds_; NGFragmentItemsBuilder* items_builder_ = nullptr;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc index 7e89d08..9ea2c14b 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -923,6 +923,7 @@ do { NGBlockLayoutAlgorithm balancing_algorithm( {Node(), fragment_geometry, space, break_token.get()}); + balancing_algorithm.SetBoxType(NGPhysicalFragment::kColumnBox); scoped_refptr<const NGLayoutResult> result = balancing_algorithm.Layout(); // This algorithm should never abort.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc index 25d690ed..64cc0f6 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -255,9 +255,14 @@ LayoutUnit final_block_size = desired_block_size; - if (builder->FoundColumnSpanner()) + if (builder->FoundColumnSpanner()) { builder->SetDidBreakSelf(); + // A break before a spanner is a forced break, and is thus "perfect". It + // need not be weighed against other possible break points. + builder->SetBreakAppeal(kBreakAppealPerfect); + } + if (is_past_end) { final_block_size = intrinsic_block_size = LayoutUnit(); } else if (builder->FoundColumnSpanner()) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h index 407a2e9b..2aacbdf6 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
@@ -181,6 +181,10 @@ return box_->GetNGPaginationBreakability() == LayoutBox::kForbidBreaks; } + bool IsScrollContainer() const { + return IsBlock() && box_->IsScrollContainer(); + } + bool CreatesNewFormattingContext() const { return IsBlock() && box_->CreatesNewFormattingContext(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc index 4e74b147..b1f3d62 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -406,13 +406,18 @@ if (LIKELY(style.AspectRatio().IsAuto())) return kIndefiniteSize; - if (!style.LogicalHeight().IsAuto() && block_size == kIndefiniteSize) { - DCHECK(!style.HasOutOfFlowPosition()) << "OOF should pass in a block size"; - block_size = ComputeBlockSizeForFragment(space, style, border_padding, - kIndefiniteSize, base::nullopt); + if (block_size == kIndefiniteSize) { + if (space.IsFixedBlockSize()) { + block_size = space.AvailableSize().block_size; + } else if (!style.LogicalHeight().IsAuto()) { + DCHECK(!style.HasOutOfFlowPosition()) + << "OOF should pass in a block size"; + block_size = ComputeBlockSizeForFragment(space, style, border_padding, + kIndefiniteSize, base::nullopt); + } + if (block_size == kIndefiniteSize) + return kIndefiniteSize; } - if (block_size == kIndefiniteSize) - return kIndefiniteSize; // Check if we can get an inline size using the aspect ratio. return InlineSizeFromAspectRatio(border_padding, style.LogicalAspectRatio(), style.BoxSizing(), block_size);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc index 7ab636f..ab670081 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc
@@ -50,7 +50,15 @@ builder->initial_fragment_geometry_->padding.ConvertToPhysical( builder->GetWritingMode(), builder->Direction()); bool has_padding = !padding.IsZero(); + + const PhysicalSize physical_size = + ToPhysicalSize(builder->Size(), builder->GetWritingMode()); + WritingModeConverter converter(builder->GetWritingDirection(), physical_size); + base::Optional<PhysicalRect> inflow_bounds; + if (builder->inflow_bounds_) + inflow_bounds = converter.ToPhysical(*builder->inflow_bounds_); + const PhysicalRect layout_overflow; bool has_layout_overflow = false; bool has_rare_data =
diff --git a/third_party/blink/renderer/core/layout/text_autosizer.cc b/third_party/blink/renderer/core/layout/text_autosizer.cc index 24e0bc7..5ebb62b 100644 --- a/third_party/blink/renderer/core/layout/text_autosizer.cc +++ b/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -135,7 +135,7 @@ (containing_block && containing_block->IsHorizontalWritingMode() != layout_object->IsHorizontalWritingMode()) || layout_object->StyleRef().IsDisplayReplacedType() || - layout_object->IsTextArea() || + layout_object->IsTextAreaIncludingNG() || layout_object->StyleRef().UserModify() != EUserModify::kReadOnly; } @@ -777,8 +777,9 @@ // TextAreas and user-modifiable areas get a free pass to autosize regardless // of text content. - if (root->IsTextArea() || (root->Style() && root->StyleRef().UserModify() != - EUserModify::kReadOnly)) { + if (root->IsTextAreaIncludingNG() || + (root->Style() && + root->StyleRef().UserModify() != EUserModify::kReadOnly)) { cluster->has_enough_text_to_autosize_ = kHasEnoughText; return true; }
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc index 2c933a3..ac10854 100644 --- a/third_party/blink/renderer/core/page/focus_controller.cc +++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -1213,7 +1213,7 @@ return next_element; } LayoutObject* layout = next_element->GetLayoutObject(); - if (layout && layout->IsTextControl()) { + if (layout && layout->IsTextControlIncludingNG()) { // TODO(ajith.v) Extend it for select elements, radio buttons and check // boxes return next_element;
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc index 209fd32a..d735648 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -339,8 +339,7 @@ ScriptSourceCode::UsePostRedirectURL() ? response_url : complete_url), sanitize_script_errors, GetV8CacheOptions(), - WorkerOrWorkletScriptController::RethrowErrorsOption::Rethrow( - error_message)); + V8ScriptRunner::RethrowErrorsOption::Rethrow(error_message)); // Step 5.2: "If an exception was thrown or if the script was prematurely // aborted, then abort all these steps, letting the exception or aborting
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index 432dbe71..e4857d1 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -337,7 +337,7 @@ const auto* elem = DynamicTo<Element>(node); if (!elem) elem = FlatTreeTraversal::ParentElement(*node); - if (GetLayoutObject()->IsTextControl()) + if (GetLayoutObject()->IsTextControlIncludingNG()) return true; // Contrary to Firefox, we mark editable all auto-generated content, such as @@ -591,7 +591,8 @@ return false; LayoutObject* parent_layout_object = parent_object->GetLayoutObject(); - if (!parent_layout_object || !parent_layout_object->IsTextControl()) + if (!parent_layout_object || + !parent_layout_object->IsTextControlIncludingNG()) return false; const auto* text_control_element = @@ -716,7 +717,7 @@ // used to compute the character extent for index 0. This is the same as // what the caret's bounds would be if the editable area is focused. if (ParentObject() && ParentObject()->GetLayoutObject() && - ParentObject()->GetLayoutObject()->IsTextControl()) { + ParentObject()->GetLayoutObject()->IsTextControlIncludingNG()) { return false; } @@ -1895,14 +1896,14 @@ LayoutBoxModelObject* layout_object = ToLayoutBoxModelObject(layout_object_); auto* html_input_element = DynamicTo<HTMLInputElement>(*GetNode()); - if (html_input_element && layout_object->IsTextField()) { + if (html_input_element && layout_object->IsTextFieldIncludingNG()) { html_input_element->setValue( string, TextFieldEventBehavior::kDispatchInputAndChangeEvent); return true; } if (auto* text_area_element = DynamicTo<HTMLTextAreaElement>(*GetNode())) { - DCHECK(layout_object->IsTextArea()); + DCHECK(layout_object->IsTextAreaIncludingNG()); text_area_element->setValue( string, TextFieldEventBehavior::kDispatchInputAndChangeEvent); return true;
diff --git a/third_party/blink/renderer/modules/hid/BUILD.gn b/third_party/blink/renderer/modules/hid/BUILD.gn index 366ebb1..805fea0 100644 --- a/third_party/blink/renderer/modules/hid/BUILD.gn +++ b/third_party/blink/renderer/modules/hid/BUILD.gn
@@ -8,18 +8,12 @@ sources = [ "hid.cc", "hid.h", - "hid_collection_info.cc", - "hid_collection_info.h", "hid_connection_event.cc", "hid_connection_event.h", "hid_device.cc", "hid_device.h", "hid_input_report_event.cc", "hid_input_report_event.h", - "hid_report_info.cc", - "hid_report_info.h", - "hid_report_item.cc", - "hid_report_item.h", "navigator_hid.cc", "navigator_hid.h", ] @@ -27,7 +21,7 @@ source_set("unit_tests") { testonly = true - sources = [ "hid_report_item_test.cc" ] + sources = [ "hid_device_test.cc" ] configs += [ "//third_party/blink/renderer:config",
diff --git a/third_party/blink/renderer/modules/hid/hid_collection_info.cc b/third_party/blink/renderer/modules/hid/hid_collection_info.cc deleted file mode 100644 index f8851a5..0000000 --- a/third_party/blink/renderer/modules/hid/hid_collection_info.cc +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/modules/hid/hid_collection_info.h" - -#include "services/device/public/mojom/hid.mojom-blink.h" -#include "third_party/blink/renderer/modules/hid/hid_report_info.h" - -namespace blink { - -HIDCollectionInfo::HIDCollectionInfo( - const device::mojom::blink::HidCollectionInfo& info) - : usage_page_(info.usage->usage_page), - usage_(info.usage->usage), - collection_type_(info.collection_type) { - for (const auto& child : info.children) - children_.push_back(MakeGarbageCollected<HIDCollectionInfo>(*child)); - for (const auto& report : info.input_reports) - input_reports_.push_back(MakeGarbageCollected<HIDReportInfo>(*report)); - for (const auto& report : info.output_reports) - output_reports_.push_back(MakeGarbageCollected<HIDReportInfo>(*report)); - for (const auto& report : info.feature_reports) - feature_reports_.push_back(MakeGarbageCollected<HIDReportInfo>(*report)); -} - -HIDCollectionInfo::~HIDCollectionInfo() = default; - -uint16_t HIDCollectionInfo::usagePage() const { - return usage_page_; -} - -uint16_t HIDCollectionInfo::usage() const { - return usage_; -} - -const HeapVector<Member<HIDCollectionInfo>>& HIDCollectionInfo::children() - const { - return children_; -} - -const HeapVector<Member<HIDReportInfo>>& HIDCollectionInfo::inputReports() - const { - return input_reports_; -} - -const HeapVector<Member<HIDReportInfo>>& HIDCollectionInfo::outputReports() - const { - return output_reports_; -} - -const HeapVector<Member<HIDReportInfo>>& HIDCollectionInfo::featureReports() - const { - return feature_reports_; -} - -uint32_t HIDCollectionInfo::collectionType() const { - return collection_type_; -} - -void HIDCollectionInfo::Trace(Visitor* visitor) const { - visitor->Trace(children_); - visitor->Trace(input_reports_); - visitor->Trace(output_reports_); - visitor->Trace(feature_reports_); - ScriptWrappable::Trace(visitor); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_collection_info.h b/third_party/blink/renderer/modules/hid/hid_collection_info.h deleted file mode 100644 index 094fecf2..0000000 --- a/third_party/blink/renderer/modules/hid/hid_collection_info.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_COLLECTION_INFO_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_COLLECTION_INFO_H_ - -#include "services/device/public/mojom/hid.mojom-blink-forward.h" -#include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class HIDReportInfo; - -class MODULES_EXPORT HIDCollectionInfo : public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); - - public: - explicit HIDCollectionInfo( - const device::mojom::blink::HidCollectionInfo& collection); - ~HIDCollectionInfo() override; - - uint16_t usagePage() const; - uint16_t usage() const; - const HeapVector<Member<HIDCollectionInfo>>& children() const; - const HeapVector<Member<HIDReportInfo>>& inputReports() const; - const HeapVector<Member<HIDReportInfo>>& outputReports() const; - const HeapVector<Member<HIDReportInfo>>& featureReports() const; - uint32_t collectionType() const; - - void Trace(Visitor* visitor) const override; - - private: - uint16_t usage_page_; - uint16_t usage_; - uint32_t collection_type_; - HeapVector<Member<HIDCollectionInfo>> children_; - HeapVector<Member<HIDReportInfo>> input_reports_; - HeapVector<Member<HIDReportInfo>> output_reports_; - HeapVector<Member<HIDReportInfo>> feature_reports_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_COLLECTION_INFO_H_
diff --git a/third_party/blink/renderer/modules/hid/hid_collection_info.idl b/third_party/blink/renderer/modules/hid/hid_collection_info.idl index 23fcf24..787d63e 100644 --- a/third_party/blink/renderer/modules/hid/hid_collection_info.idl +++ b/third_party/blink/renderer/modules/hid/hid_collection_info.idl
@@ -5,24 +5,21 @@ // Information about a HID collection, including its reports and subcollections. // https://wicg.github.io/webhid/index.html#report-descriptor -[ - Exposed(Window WebHID), - SecureContext -] interface HIDCollectionInfo { +dictionary HIDCollectionInfo { // The 16-bit usage page associated with this collection. Zero if not set. - readonly attribute unsigned short usagePage; + unsigned short usagePage; // The 16-bit usage value associated with this collection. Zero if not set. - readonly attribute unsigned short usage; + unsigned short usage; // The subcollections of this collection, in the order they were encountered // in the report descriptor. - readonly attribute FrozenArray<HIDCollectionInfo> children; + sequence<HIDCollectionInfo> children; // Input, output, and feature reports described in this collection, sorted // by report ID. If this is a subcollection, only the portion of the report // described within this collection is included. - readonly attribute FrozenArray<HIDReportInfo> inputReports; - readonly attribute FrozenArray<HIDReportInfo> outputReports; - readonly attribute FrozenArray<HIDReportInfo> featureReports; + sequence<HIDReportInfo> inputReports; + sequence<HIDReportInfo> outputReports; + sequence<HIDReportInfo> featureReports; };
diff --git a/third_party/blink/renderer/modules/hid/hid_device.cc b/third_party/blink/renderer/modules/hid/hid_device.cc index 01dbcc39..51191c7 100644 --- a/third_party/blink/renderer/modules/hid/hid_device.cc +++ b/third_party/blink/renderer/modules/hid/hid_device.cc
@@ -6,13 +6,14 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_hid_collection_info.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_hid_report_info.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" #include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h" #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/hid/hid.h" -#include "third_party/blink/renderer/modules/hid/hid_collection_info.h" #include "third_party/blink/renderer/modules/hid/hid_input_report_event.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -85,6 +86,129 @@ return false; } +// The HID specification defines four canonical unit systems. Each unit system +// corresponds to a set of units for length, mass, time, temperature, current, +// and luminous intensity. The vendor-defined unit system can be used for +// devices which produce measurements that cannot be adequately described by +// these unit systems. +// +// See the Units table in section 6.2.2.7 of the Device Class Definition for +// HID v1.11. +// https://www.usb.org/document-library/device-class-definition-hid-111 +enum HidUnitSystem { + // none: No unit system + kUnitSystemNone = 0x00, + // si-linear: Centimeter, Gram, Seconds, Kelvin, Ampere, Candela + kUnitSystemSILinear = 0x01, + // si-rotation: Radians, Gram, Seconds, Kelvin, Ampere, Candela + kUnitSystemSIRotation = 0x02, + // english-linear: Inch, Slug, Seconds, Fahrenheit, Ampere, Candela + kUnitSystemEnglishLinear = 0x03, + // english-linear: Degrees, Slug, Seconds, Fahrenheit, Ampere, Candela + kUnitSystemEnglishRotation = 0x04, + // vendor-defined unit system + kUnitSystemVendorDefined = 0x0f, +}; + +uint32_t ConvertHidUsageAndPageToUint32( + const device::mojom::blink::HidUsageAndPage& usage) { + return (usage.usage_page) << 16 | usage.usage; +} + +String UnitSystemToString(uint8_t unit) { + DCHECK_LE(unit, 0x0f); + switch (unit) { + case kUnitSystemNone: + return "none"; + case kUnitSystemSILinear: + return "si-linear"; + case kUnitSystemSIRotation: + return "si-rotation"; + case kUnitSystemEnglishLinear: + return "english-linear"; + case kUnitSystemEnglishRotation: + return "english-rotation"; + case kUnitSystemVendorDefined: + return "vendor-defined"; + default: + break; + } + // Values other than those defined in HidUnitSystem are reserved by the spec. + return "reserved"; +} + +// Convert |unit_factor_exponent| from its coded representation to a signed +// integer type. +int8_t UnitFactorExponentToInt(uint8_t unit_factor_exponent) { + DCHECK_LE(unit_factor_exponent, 0x0f); + // Values from 0x08 to 0x0f encode negative exponents. + if (unit_factor_exponent > 0x08) + return int8_t{unit_factor_exponent} - 16; + return unit_factor_exponent; +} + +// Unpack the 32-bit unit definition value |unit| into each of its components. +// The unit definition value includes the unit system as well as unit factor +// exponents for each of the 6 units defined by the unit system. +void UnpackUnitValues(uint32_t unit, + String& unit_system, + int8_t& length_exponent, + int8_t& mass_exponent, + int8_t& time_exponent, + int8_t& temperature_exponent, + int8_t& current_exponent, + int8_t& luminous_intensity_exponent) { + unit_system = UnitSystemToString(unit & 0x0f); + length_exponent = UnitFactorExponentToInt((unit >> 4) & 0x0f); + mass_exponent = UnitFactorExponentToInt((unit >> 8) & 0x0f); + time_exponent = UnitFactorExponentToInt((unit >> 12) & 0x0f); + temperature_exponent = UnitFactorExponentToInt((unit >> 16) & 0x0f); + current_exponent = UnitFactorExponentToInt((unit >> 20) & 0x0f); + luminous_intensity_exponent = UnitFactorExponentToInt((unit >> 24) & 0x0f); +} + +HIDReportInfo* ToHIDReportInfo( + const device::mojom::blink::HidReportDescription& report_info) { + HIDReportInfo* result = HIDReportInfo::Create(); + result->setReportId(report_info.report_id); + + HeapVector<Member<HIDReportItem>> items; + for (const auto& item : report_info.items) + items.push_back(HIDDevice::ToHIDReportItem(*item)); + result->setItems(items); + + return result; +} + +HIDCollectionInfo* ToHIDCollectionInfo( + const device::mojom::blink::HidCollectionInfo& collection) { + HIDCollectionInfo* result = HIDCollectionInfo::Create(); + result->setUsage(collection.usage->usage); + result->setUsagePage(collection.usage->usage_page); + + HeapVector<Member<HIDReportInfo>> input_reports; + for (const auto& report : collection.input_reports) + input_reports.push_back(ToHIDReportInfo(*report)); + result->setInputReports(input_reports); + + HeapVector<Member<HIDReportInfo>> output_reports; + for (const auto& report : collection.output_reports) + output_reports.push_back(ToHIDReportInfo(*report)); + result->setOutputReports(output_reports); + + HeapVector<Member<HIDReportInfo>> feature_reports; + for (const auto& report : collection.feature_reports) + feature_reports.push_back(ToHIDReportInfo(*report)); + result->setFeatureReports(feature_reports); + + HeapVector<Member<HIDCollectionInfo>> children; + for (const auto& child : collection.children) + children.push_back(ToHIDCollectionInfo(*child)); + result->setChildren(children); + + return result; +} + } // namespace HIDDevice::HIDDevice(HID* parent, @@ -98,10 +222,8 @@ DCHECK(device_info_); for (const auto& collection : device_info_->collections) { // Omit information about top-level collections with protected usages. - if (!IsProtected(*collection->usage)) { - collections_.push_back( - MakeGarbageCollected<HIDCollectionInfo>(*collection)); - } + if (!IsProtected(*collection->usage)) + collections_.push_back(ToHIDCollectionInfo(*collection)); } } @@ -373,4 +495,57 @@ device_requests_.erase(find_result); } +// static +HIDReportItem* HIDDevice::ToHIDReportItem( + const device::mojom::blink::HidReportItem& report_item) { + HIDReportItem* result = HIDReportItem::Create(); + result->setIsAbsolute(!report_item.is_relative); + result->setIsArray(!report_item.is_variable); + result->setIsRange(report_item.is_range); + result->setHasNull(report_item.has_null_position); + result->setReportSize(report_item.report_size); + result->setReportCount(report_item.report_count); + result->setUnitExponent( + UnitFactorExponentToInt(report_item.unit_exponent & 0x0f)); + result->setLogicalMinimum(report_item.logical_minimum); + result->setLogicalMaximum(report_item.logical_maximum); + result->setPhysicalMinimum(report_item.physical_minimum); + result->setPhysicalMaximum(report_item.physical_maximum); + + Vector<uint32_t> usages; + for (const auto& usage : report_item.usages) + usages.push_back(ConvertHidUsageAndPageToUint32(*usage)); + result->setUsages(usages); + + result->setUsageMinimum( + ConvertHidUsageAndPageToUint32(*report_item.usage_minimum)); + result->setUsageMaximum( + ConvertHidUsageAndPageToUint32(*report_item.usage_maximum)); + + String unit_system; + int8_t unit_factor_length_exponent; + int8_t unit_factor_mass_exponent; + int8_t unit_factor_time_exponent; + int8_t unit_factor_temperature_exponent; + int8_t unit_factor_current_exponent; + int8_t unit_factor_luminous_intensity_exponent; + UnpackUnitValues(report_item.unit, unit_system, unit_factor_length_exponent, + unit_factor_mass_exponent, unit_factor_time_exponent, + unit_factor_temperature_exponent, + unit_factor_current_exponent, + unit_factor_luminous_intensity_exponent); + result->setUnitSystem(unit_system); + result->setUnitFactorLengthExponent(unit_factor_length_exponent); + result->setUnitFactorMassExponent(unit_factor_mass_exponent); + result->setUnitFactorTimeExponent(unit_factor_time_exponent); + result->setUnitFactorTemperatureExponent(unit_factor_temperature_exponent); + result->setUnitFactorCurrentExponent(unit_factor_current_exponent); + result->setUnitFactorLuminousIntensityExponent( + unit_factor_luminous_intensity_exponent); + + // TODO(mattreynolds): Set |strings_|. + + return result; +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_device.h b/third_party/blink/renderer/modules/hid/hid_device.h index 5a7bab92..24b338e 100644 --- a/third_party/blink/renderer/modules/hid/hid_device.h +++ b/third_party/blink/renderer/modules/hid/hid_device.h
@@ -10,6 +10,7 @@ #include "third_party/blink/public/mojom/hid/hid.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_hid_report_item.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -70,6 +71,9 @@ // ExecutionContextLifecycleObserver: void ContextDestroyed() override; + static HIDReportItem* ToHIDReportItem( + const device::mojom::blink::HidReportItem& report_item); + void Trace(Visitor*) const override; private:
diff --git a/third_party/blink/renderer/modules/hid/hid_device_test.cc b/third_party/blink/renderer/modules/hid/hid_device_test.cc new file mode 100644 index 0000000..ae9d383 --- /dev/null +++ b/third_party/blink/renderer/modules/hid/hid_device_test.cc
@@ -0,0 +1,162 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/hid/hid_device.h" + +#include "services/device/public/mojom/hid.mojom-blink.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +namespace { + +// Construct and return a sample HID report item. +device::mojom::blink::HidReportItemPtr MakeReportItem() { + auto item = device::mojom::blink::HidReportItem::New(); + item->is_range = false; // Usages for this item are defined by |usages|. + + // Configure the report item with reasonable values for a button-like input. + item->is_constant = false; // Data. + item->is_variable = true; // Variable. + item->is_relative = false; // Absolute. + item->wrap = false; // No wrap. + item->is_non_linear = false; // Linear. + item->no_preferred_state = false; // Preferred State. + item->has_null_position = false; // No Null position. + item->is_volatile = false; // Non Volatile. + item->is_buffered_bytes = false; // Bit Field. + + // Assign the primary button usage to this item. + item->usages.push_back(device::mojom::blink::HidUsageAndPage::New( + 0x01, device::mojom::blink::kPageButton)); + // |usage_minimum| and |usage_maximum| are unused. + item->usage_minimum = device::mojom::blink::HidUsageAndPage::New(0, 0); + item->usage_maximum = device::mojom::blink::HidUsageAndPage::New(0, 0); + + // Set the designator index and string index extents to zero. This indicates + // that no physical designators or strings are associated with this item. + item->designator_minimum = 0; + item->designator_minimum = 0; + item->string_minimum = 0; + item->string_maximum = 0; + + // The report field described by this item can only hold the logical values 0 + // and 1. + item->logical_minimum = 0; + item->logical_maximum = 1; + item->physical_minimum = 0; + item->physical_maximum = 1; + + // Values reported in this field are unitless. + item->unit_exponent = 0; + item->unit = 0; + + // This item defines a single report field, 8 bits wide. + item->report_size = 8; // 1 byte. + item->report_count = 1; + + return item; +} + +} // namespace + +TEST(HIDDeviceTest, singleUsageItem) { + device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); + HIDReportItem* item = HIDDevice::ToHIDReportItem(*mojo_item); + + // Check that all item properties are correctly converted for the sample + // report item. + EXPECT_TRUE(item->isAbsolute()); + EXPECT_FALSE(item->isArray()); + EXPECT_FALSE(item->isRange()); + EXPECT_FALSE(item->hasNull()); + EXPECT_EQ(1U, item->usages().size()); + EXPECT_EQ(0x00090001U, item->usages()[0]); + EXPECT_EQ(0U, item->usageMinimum()); + EXPECT_EQ(0U, item->usageMaximum()); + EXPECT_FALSE(item->hasStrings()); + EXPECT_EQ(8U, item->reportSize()); + EXPECT_EQ(1U, item->reportCount()); + EXPECT_EQ(0, item->unitExponent()); + EXPECT_EQ("none", item->unitSystem()); + EXPECT_EQ(0, item->unitFactorLengthExponent()); + EXPECT_EQ(0, item->unitFactorMassExponent()); + EXPECT_EQ(0, item->unitFactorTimeExponent()); + EXPECT_EQ(0, item->unitFactorTemperatureExponent()); + EXPECT_EQ(0, item->unitFactorCurrentExponent()); + EXPECT_EQ(0, item->unitFactorLuminousIntensityExponent()); + EXPECT_EQ(0, item->logicalMinimum()); + EXPECT_EQ(1, item->logicalMaximum()); + EXPECT_EQ(0, item->physicalMinimum()); + EXPECT_EQ(1, item->physicalMaximum()); +} + +TEST(HIDDeviceTest, multiUsageItem) { + device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); + + // Configure the item to use 8 non-consecutive usages. + mojo_item->usages.clear(); + for (int i = 1; i < 9; ++i) { + mojo_item->usages.push_back(device::mojom::blink::HidUsageAndPage::New( + 2 * i, device::mojom::blink::kPageButton)); + } + mojo_item->report_size = 1; // 1 bit. + mojo_item->report_count = 8; + HIDReportItem* item = HIDDevice::ToHIDReportItem(*mojo_item); + + EXPECT_EQ(8U, item->usages().size()); + EXPECT_EQ(0x00090002U, item->usages()[0]); + EXPECT_EQ(0x00090004U, item->usages()[1]); + EXPECT_EQ(0x00090006U, item->usages()[2]); + EXPECT_EQ(0x00090008U, item->usages()[3]); + EXPECT_EQ(0x0009000aU, item->usages()[4]); + EXPECT_EQ(0x0009000cU, item->usages()[5]); + EXPECT_EQ(0x0009000eU, item->usages()[6]); + EXPECT_EQ(0x00090010U, item->usages()[7]); + EXPECT_EQ(1U, item->reportSize()); + EXPECT_EQ(8U, item->reportCount()); +} + +TEST(HIDDeviceTest, usageRangeItem) { + device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); + + // Configure the item to use a usage range. The item defines eight fields, + // each 1-bit wide, with consecutive usages from the Button usage page. + mojo_item->is_range = true; + mojo_item->usages.clear(); + mojo_item->usage_minimum->usage_page = device::mojom::blink::kPageButton; + mojo_item->usage_minimum->usage = 0x01; // 1st button usage (primary). + mojo_item->usage_maximum->usage_page = device::mojom::blink::kPageButton; + mojo_item->usage_maximum->usage = 0x08; // 8th button usage. + mojo_item->report_size = 1; // 1 bit. + mojo_item->report_count = 8; + HIDReportItem* item = HIDDevice::ToHIDReportItem(*mojo_item); + + EXPECT_FALSE(item->hasStrings()); + EXPECT_EQ(0x00090001U, item->usageMinimum()); + EXPECT_EQ(0x00090008U, item->usageMaximum()); + EXPECT_EQ(1U, item->reportSize()); + EXPECT_EQ(8U, item->reportCount()); +} + +TEST(HIDDeviceTest, unitDefinition) { + device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); + + // Add a unit definition and check that the unit properties are correctly + // converted. + mojo_item->unit_exponent = 0x0C; // 10^-4 + mojo_item->unit = 0x0000E111; // g*cm/s^2 + HIDReportItem* item = HIDDevice::ToHIDReportItem(*mojo_item); + + EXPECT_EQ("si-linear", item->unitSystem()); + EXPECT_EQ(-4, item->unitExponent()); + EXPECT_EQ(1, item->unitFactorLengthExponent()); + EXPECT_EQ(1, item->unitFactorMassExponent()); + EXPECT_EQ(-2, item->unitFactorTimeExponent()); + EXPECT_EQ(0, item->unitFactorTemperatureExponent()); + EXPECT_EQ(0, item->unitFactorCurrentExponent()); + EXPECT_EQ(0, item->unitFactorLuminousIntensityExponent()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_report_info.cc b/third_party/blink/renderer/modules/hid/hid_report_info.cc deleted file mode 100644 index 0e39ccb9b..0000000 --- a/third_party/blink/renderer/modules/hid/hid_report_info.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/modules/hid/hid_report_info.h" - -#include "services/device/public/mojom/hid.mojom-blink.h" -#include "third_party/blink/renderer/modules/hid/hid_report_item.h" - -namespace blink { - -HIDReportInfo::HIDReportInfo( - const device::mojom::blink::HidReportDescription& report) - : report_id_(report.report_id) { - for (const auto& item : report.items) - items_.push_back(MakeGarbageCollected<HIDReportItem>(*item)); -} - -HIDReportInfo::~HIDReportInfo() {} - -uint8_t HIDReportInfo::reportId() const { - return report_id_; -} - -const HeapVector<Member<HIDReportItem>>& HIDReportInfo::items() const { - return items_; -} - -void HIDReportInfo::Trace(Visitor* visitor) const { - visitor->Trace(items_); - ScriptWrappable::Trace(visitor); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_report_info.h b/third_party/blink/renderer/modules/hid/hid_report_info.h deleted file mode 100644 index dbdfb69b..0000000 --- a/third_party/blink/renderer/modules/hid/hid_report_info.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_INFO_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_INFO_H_ - -#include "services/device/public/mojom/hid.mojom-blink-forward.h" -#include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class HIDReportItem; - -class MODULES_EXPORT HIDReportInfo : public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); - - public: - explicit HIDReportInfo( - const device::mojom::blink::HidReportDescription& report); - ~HIDReportInfo() override; - - uint8_t reportId() const; - const HeapVector<Member<HIDReportItem>>& items() const; - - void Trace(Visitor* visitor) const override; - - private: - uint8_t report_id_; - HeapVector<Member<HIDReportItem>> items_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_INFO_H_
diff --git a/third_party/blink/renderer/modules/hid/hid_report_info.idl b/third_party/blink/renderer/modules/hid/hid_report_info.idl index 0270175a..c6fe2c61 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_info.idl +++ b/third_party/blink/renderer/modules/hid/hid_report_info.idl
@@ -8,13 +8,10 @@ // only the portion of the report contained by the collection. // https://wicg.github.io/webhid/index.html#report-descriptor -[ - Exposed(Window WebHID), - SecureContext -] interface HIDReportInfo { +dictionary HIDReportInfo { // The 8-bit report ID associated with this report. - readonly attribute octet reportId; + octet reportId; // An ordered array that describes the fields within this report. - readonly attribute FrozenArray<HIDReportItem> items; + sequence<HIDReportItem> items; };
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.cc b/third_party/blink/renderer/modules/hid/hid_report_item.cc deleted file mode 100644 index 514b4c2f..0000000 --- a/third_party/blink/renderer/modules/hid/hid_report_item.cc +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/modules/hid/hid_report_item.h" - -#include "services/device/public/mojom/hid.mojom-blink.h" - -namespace blink { - -namespace { - -// The HID specification defines four canonical unit systems. Each unit system -// corresponds to a set of units for length, mass, time, temperature, current, -// and luminous intensity. The vendor-defined unit system can be used for -// devices which produce measurements that cannot be adequately described by -// these unit systems. -// -// See the Units table in section 6.2.2.7 of the Device Class Definition for -// HID v1.11. -// https://www.usb.org/document-library/device-class-definition-hid-111 -enum HidUnitSystem { - // none: No unit system - kUnitSystemNone = 0x00, - // si-linear: Centimeter, Gram, Seconds, Kelvin, Ampere, Candela - kUnitSystemSILinear = 0x01, - // si-rotation: Radians, Gram, Seconds, Kelvin, Ampere, Candela - kUnitSystemSIRotation = 0x02, - // english-linear: Inch, Slug, Seconds, Fahrenheit, Ampere, Candela - kUnitSystemEnglishLinear = 0x03, - // english-linear: Degrees, Slug, Seconds, Fahrenheit, Ampere, Candela - kUnitSystemEnglishRotation = 0x04, - // vendor-defined unit system - kUnitSystemVendorDefined = 0x0f, -}; - -uint32_t ConvertHidUsageAndPageToUint32( - const device::mojom::blink::HidUsageAndPage& usage) { - return (usage.usage_page) << 16 | usage.usage; -} - -String UnitSystemToString(uint8_t unit) { - DCHECK_LE(unit, 0x0f); - switch (unit) { - case kUnitSystemNone: - return "none"; - case kUnitSystemSILinear: - return "si-linear"; - case kUnitSystemSIRotation: - return "si-rotation"; - case kUnitSystemEnglishLinear: - return "english-linear"; - case kUnitSystemEnglishRotation: - return "english-rotation"; - case kUnitSystemVendorDefined: - return "vendor-defined"; - default: - break; - } - // Values other than those defined in HidUnitSystem are reserved by the spec. - return "reserved"; -} - -// Convert |unit_factor_exponent| from its coded representation to a signed -// integer type. -int8_t UnitFactorExponentToInt(uint8_t unit_factor_exponent) { - DCHECK_LE(unit_factor_exponent, 0x0f); - // Values from 0x08 to 0x0f encode negative exponents. - if (unit_factor_exponent > 0x08) - return int8_t{unit_factor_exponent} - 16; - return unit_factor_exponent; -} - -// Unpack the 32-bit unit definition value |unit| into each of its components. -// The unit definition value includes the unit system as well as unit factor -// exponents for each of the 6 units defined by the unit system. -void UnpackUnitValues(uint32_t unit, - String& unit_system, - int8_t& length_exponent, - int8_t& mass_exponent, - int8_t& time_exponent, - int8_t& temperature_exponent, - int8_t& current_exponent, - int8_t& luminous_intensity_exponent) { - unit_system = UnitSystemToString(unit & 0x0f); - length_exponent = UnitFactorExponentToInt((unit >> 4) & 0x0f); - mass_exponent = UnitFactorExponentToInt((unit >> 8) & 0x0f); - time_exponent = UnitFactorExponentToInt((unit >> 12) & 0x0f); - temperature_exponent = UnitFactorExponentToInt((unit >> 16) & 0x0f); - current_exponent = UnitFactorExponentToInt((unit >> 20) & 0x0f); - luminous_intensity_exponent = UnitFactorExponentToInt((unit >> 24) & 0x0f); -} - -} // namespace - -HIDReportItem::HIDReportItem(const device::mojom::blink::HidReportItem& item) - : is_absolute_(!item.is_relative), - is_array_(!item.is_variable), - is_range_(item.is_range), - has_null_(item.has_null_position), - report_size_(item.report_size), - report_count_(item.report_count), - unit_exponent_(UnitFactorExponentToInt(item.unit_exponent & 0x0f)), - logical_minimum_(item.logical_minimum), - logical_maximum_(item.logical_maximum), - physical_minimum_(item.physical_minimum), - physical_maximum_(item.physical_maximum) { - for (const auto& usage : item.usages) - usages_.push_back(ConvertHidUsageAndPageToUint32(*usage)); - usage_minimum_ = ConvertHidUsageAndPageToUint32(*item.usage_minimum); - usage_maximum_ = ConvertHidUsageAndPageToUint32(*item.usage_maximum); - UnpackUnitValues(item.unit, unit_system_, unit_factor_length_exponent_, - unit_factor_mass_exponent_, unit_factor_time_exponent_, - unit_factor_temperature_exponent_, - unit_factor_current_exponent_, - unit_factor_luminous_intensity_exponent_); - - // TODO(mattreynolds): Set |strings_|. -} - -HIDReportItem::~HIDReportItem() = default; - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.h b/third_party/blink/renderer/modules/hid/hid_report_item.h deleted file mode 100644 index 223e351a..0000000 --- a/third_party/blink/renderer/modules/hid/hid_report_item.h +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_ITEM_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_ITEM_H_ - -#include "services/device/public/mojom/hid.mojom-blink-forward.h" -#include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/heap/heap_allocator.h" -#include "third_party/blink/renderer/platform/heap/member.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class MODULES_EXPORT HIDReportItem : public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); - - public: - explicit HIDReportItem(const device::mojom::blink::HidReportItem& item); - ~HIDReportItem() override; - - bool isAbsolute() const { return is_absolute_; } - bool isArray() const { return is_array_; } - bool isRange() const { return is_range_; } - bool hasNull() const { return has_null_; } - const Vector<uint32_t>& usages() const { return usages_; } - uint32_t usageMinimum() const { return usage_minimum_; } - uint32_t usageMaximum() const { return usage_maximum_; } - const Vector<String>& strings() const { return strings_; } - uint16_t reportSize() const { return report_size_; } - uint16_t reportCount() const { return report_count_; } - int8_t unitExponent() const { return unit_exponent_; } - String unitSystem() const { return unit_system_; } - int8_t unitFactorLengthExponent() const { - return unit_factor_length_exponent_; - } - int8_t unitFactorMassExponent() const { return unit_factor_mass_exponent_; } - int8_t unitFactorTimeExponent() const { return unit_factor_time_exponent_; } - int8_t unitFactorTemperatureExponent() const { - return unit_factor_temperature_exponent_; - } - int8_t unitFactorCurrentExponent() const { - return unit_factor_current_exponent_; - } - int8_t unitFactorLuminousIntensityExponent() const { - return unit_factor_luminous_intensity_exponent_; - } - int32_t logicalMinimum() const { return logical_minimum_; } - int32_t logicalMaximum() const { return logical_maximum_; } - int32_t physicalMinimum() const { return physical_minimum_; } - int32_t physicalMaximum() const { return physical_maximum_; } - - private: - bool is_absolute_; - bool is_array_; - bool is_range_; - bool has_null_; - Vector<uint32_t> usages_; - Vector<String> strings_; - uint32_t usage_minimum_; - uint32_t usage_maximum_; - uint16_t report_size_; - uint16_t report_count_; - int8_t unit_exponent_; - String unit_system_; - int8_t unit_factor_length_exponent_; - int8_t unit_factor_mass_exponent_; - int8_t unit_factor_time_exponent_; - int8_t unit_factor_temperature_exponent_; - int8_t unit_factor_current_exponent_; - int8_t unit_factor_luminous_intensity_exponent_; - int32_t logical_minimum_; - int32_t logical_maximum_; - int32_t physical_minimum_; - int32_t physical_maximum_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_ITEM_H_
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item.idl b/third_party/blink/renderer/modules/hid/hid_report_item.idl index eed37327..01ee6d8 100644 --- a/third_party/blink/renderer/modules/hid/hid_report_item.idl +++ b/third_party/blink/renderer/modules/hid/hid_report_item.idl
@@ -28,77 +28,74 @@ "reserved", }; -[ - Exposed(Window WebHID), - SecureContext -] interface HIDReportItem { +dictionary HIDReportItem { // True if the item represents an absolute measurement (e.g. joystick tilt) // or false if it represents a relative measurement (e.g. mouse movement). - readonly attribute boolean isAbsolute; + boolean isAbsolute; // True if the item is an Array or false if it is a Variable. Array items // are typically used when a device needs to represent a large number of // button-type inputs, but only a few inputs need to be active at once. // Variable items require space in the report for each input, but can report // all inputs simultaneously. - readonly attribute boolean isArray; + boolean isArray; // True if the usages for this item are defined by |usageMinimum| and // |usageMaximum| or false if the usages are defined by |usages|. - readonly attribute boolean isRange; + boolean isRange; // True if the item uses an out-of-bounds value when there is no input. - readonly attribute boolean hasNull; + boolean hasNull; // An ordered list of 32-bit usage values associated with this item. Unused // if |isRange| is true. If |reportCount| is two or more, usages are // assigned from the list until the list is exhausted. - readonly attribute FrozenArray<unsigned long> usages; + sequence<unsigned long> usages; // The minimum and maximum usage values associated with this item. Unused if // |isRange| is false. If |reportCount| is two or more, usages are assigned // starting from |usageMinimum| and increment by one. - readonly attribute unsigned long usageMinimum; - readonly attribute unsigned long usageMaximum; + unsigned long usageMinimum; + unsigned long usageMaximum; // The size of a single field described by this item, in bits. - readonly attribute unsigned short reportSize; + unsigned short reportSize; // The number of similar fields described by this item. The total size of // the item described by this report is |reportSize| * |reportCount| bits. - readonly attribute unsigned short reportCount; + unsigned short reportCount; // The base 10 exponent of the units for this report item. For instance, for // kilograms |unitExponent| would be 3 and for micrograms it would be -6. - readonly attribute byte unitExponent; + byte unitExponent; // The unit system determines which units are used for length, mass, time, // temperature, current, and luminous intensity. May be "none" if the values // for this report item are unitless. - readonly attribute HIDUnitSystem unitSystem; + HIDUnitSystem unitSystem; // The following members determine the exponents for each factor of the // unit definition. For instance, for acceleration all factors would have // an exponent of 0 except |unitFactorLengthExponent| which would be 1 and // |unitFactorTimeExponent| which would be -2. - readonly attribute byte unitFactorLengthExponent; - readonly attribute byte unitFactorMassExponent; - readonly attribute byte unitFactorTimeExponent; - readonly attribute byte unitFactorTemperatureExponent; - readonly attribute byte unitFactorCurrentExponent; - readonly attribute byte unitFactorLuminousIntensityExponent; + byte unitFactorLengthExponent; + byte unitFactorMassExponent; + byte unitFactorTimeExponent; + byte unitFactorTemperatureExponent; + byte unitFactorCurrentExponent; + byte unitFactorLuminousIntensityExponent; // The minimum and maximum values that may be represented by this input. A // device with |hasNull| may report a value outside this range to indicate // no input. - readonly attribute long logicalMinimum; - readonly attribute long logicalMaximum; + long logicalMinimum; + long logicalMaximum; // The minimum and maximum values, scaled to the units described by |unit| // and |unitExponent|. - readonly attribute long physicalMinimum; - readonly attribute long physicalMaximum; + long physicalMinimum; + long physicalMaximum; // The strings associated with this item. - readonly attribute FrozenArray<DOMString> strings; + sequence<DOMString> strings; };
diff --git a/third_party/blink/renderer/modules/hid/hid_report_item_test.cc b/third_party/blink/renderer/modules/hid/hid_report_item_test.cc deleted file mode 100644 index 6902ab2a..0000000 --- a/third_party/blink/renderer/modules/hid/hid_report_item_test.cc +++ /dev/null
@@ -1,162 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/modules/hid/hid_report_item.h" - -#include "services/device/public/mojom/hid.mojom-blink.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace blink { - -namespace { - -// Construct and return a sample HID report item. -device::mojom::blink::HidReportItemPtr MakeReportItem() { - auto item = device::mojom::blink::HidReportItem::New(); - item->is_range = false; // Usages for this item are defined by |usages|. - - // Configure the report item with reasonable values for a button-like input. - item->is_constant = false; // Data. - item->is_variable = true; // Variable. - item->is_relative = false; // Absolute. - item->wrap = false; // No wrap. - item->is_non_linear = false; // Linear. - item->no_preferred_state = false; // Preferred State. - item->has_null_position = false; // No Null position. - item->is_volatile = false; // Non Volatile. - item->is_buffered_bytes = false; // Bit Field. - - // Assign the primary button usage to this item. - item->usages.push_back(device::mojom::blink::HidUsageAndPage::New( - 0x01, device::mojom::blink::kPageButton)); - // |usage_minimum| and |usage_maximum| are unused. - item->usage_minimum = device::mojom::blink::HidUsageAndPage::New(0, 0); - item->usage_maximum = device::mojom::blink::HidUsageAndPage::New(0, 0); - - // Set the designator index and string index extents to zero. This indicates - // that no physical designators or strings are associated with this item. - item->designator_minimum = 0; - item->designator_minimum = 0; - item->string_minimum = 0; - item->string_maximum = 0; - - // The report field described by this item can only hold the logical values 0 - // and 1. - item->logical_minimum = 0; - item->logical_maximum = 1; - item->physical_minimum = 0; - item->physical_maximum = 1; - - // Values reported in this field are unitless. - item->unit_exponent = 0; - item->unit = 0; - - // This item defines a single report field, 8 bits wide. - item->report_size = 8; // 1 byte. - item->report_count = 1; - - return item; -} - -} // namespace - -TEST(HIDReportItemTest, singleUsageItem) { - device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); - HIDReportItem item(*mojo_item); - - // Check that all item properties are correctly converted for the sample - // report item. - EXPECT_TRUE(item.isAbsolute()); - EXPECT_FALSE(item.isArray()); - EXPECT_FALSE(item.isRange()); - EXPECT_FALSE(item.hasNull()); - EXPECT_EQ(1U, item.usages().size()); - EXPECT_EQ(0x00090001U, item.usages()[0]); - EXPECT_EQ(0U, item.usageMinimum()); - EXPECT_EQ(0U, item.usageMaximum()); - EXPECT_TRUE(item.strings().IsEmpty()); - EXPECT_EQ(8U, item.reportSize()); - EXPECT_EQ(1U, item.reportCount()); - EXPECT_EQ(0, item.unitExponent()); - EXPECT_EQ("none", item.unitSystem()); - EXPECT_EQ(0, item.unitFactorLengthExponent()); - EXPECT_EQ(0, item.unitFactorMassExponent()); - EXPECT_EQ(0, item.unitFactorTimeExponent()); - EXPECT_EQ(0, item.unitFactorTemperatureExponent()); - EXPECT_EQ(0, item.unitFactorCurrentExponent()); - EXPECT_EQ(0, item.unitFactorLuminousIntensityExponent()); - EXPECT_EQ(0, item.logicalMinimum()); - EXPECT_EQ(1, item.logicalMaximum()); - EXPECT_EQ(0, item.physicalMinimum()); - EXPECT_EQ(1, item.physicalMaximum()); -} - -TEST(HIDReportItemTest, multiUsageItem) { - device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); - - // Configure the item to use 8 non-consecutive usages. - mojo_item->usages.clear(); - for (int i = 1; i < 9; ++i) { - mojo_item->usages.push_back(device::mojom::blink::HidUsageAndPage::New( - 2 * i, device::mojom::blink::kPageButton)); - } - mojo_item->report_size = 1; // 1 bit. - mojo_item->report_count = 8; - HIDReportItem item(*mojo_item); - - EXPECT_EQ(8U, item.usages().size()); - EXPECT_EQ(0x00090002U, item.usages()[0]); - EXPECT_EQ(0x00090004U, item.usages()[1]); - EXPECT_EQ(0x00090006U, item.usages()[2]); - EXPECT_EQ(0x00090008U, item.usages()[3]); - EXPECT_EQ(0x0009000aU, item.usages()[4]); - EXPECT_EQ(0x0009000cU, item.usages()[5]); - EXPECT_EQ(0x0009000eU, item.usages()[6]); - EXPECT_EQ(0x00090010U, item.usages()[7]); - EXPECT_EQ(1U, item.reportSize()); - EXPECT_EQ(8U, item.reportCount()); -} - -TEST(HIDReportItemTest, usageRangeItem) { - device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); - - // Configure the item to use a usage range. The item defines eight fields, - // each 1-bit wide, with consecutive usages from the Button usage page. - mojo_item->is_range = true; - mojo_item->usages.clear(); - mojo_item->usage_minimum->usage_page = device::mojom::blink::kPageButton; - mojo_item->usage_minimum->usage = 0x01; // 1st button usage (primary). - mojo_item->usage_maximum->usage_page = device::mojom::blink::kPageButton; - mojo_item->usage_maximum->usage = 0x08; // 8th button usage. - mojo_item->report_size = 1; // 1 bit. - mojo_item->report_count = 8; - HIDReportItem item(*mojo_item); - - EXPECT_TRUE(item.usages().IsEmpty()); - EXPECT_EQ(0x00090001U, item.usageMinimum()); - EXPECT_EQ(0x00090008U, item.usageMaximum()); - EXPECT_EQ(1U, item.reportSize()); - EXPECT_EQ(8U, item.reportCount()); -} - -TEST(HIDReportItemTest, unitDefinition) { - device::mojom::blink::HidReportItemPtr mojo_item = MakeReportItem(); - - // Add a unit definition and check that the unit properties are correctly - // converted. - mojo_item->unit_exponent = 0x0C; // 10^-4 - mojo_item->unit = 0x0000E111; // g*cm/s^2 - HIDReportItem item(*mojo_item); - - EXPECT_EQ("si-linear", item.unitSystem()); - EXPECT_EQ(-4, item.unitExponent()); - EXPECT_EQ(1, item.unitFactorLengthExponent()); - EXPECT_EQ(1, item.unitFactorMassExponent()); - EXPECT_EQ(-2, item.unitFactorTimeExponent()); - EXPECT_EQ(0, item.unitFactorTemperatureExponent()); - EXPECT_EQ(0, item.unitFactorCurrentExponent()); - EXPECT_EQ(0, item.unitFactorLuminousIntensityExponent()); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/hid/idls.gni b/third_party/blink/renderer/modules/hid/idls.gni index 2291d2ff..0ef4e76a 100644 --- a/third_party/blink/renderer/modules/hid/idls.gni +++ b/third_party/blink/renderer/modules/hid/idls.gni
@@ -4,18 +4,18 @@ modules_idl_files = [ "hid.idl", - "hid_collection_info.idl", "hid_connection_event.idl", "hid_device.idl", "hid_input_report_event.idl", - "hid_report_info.idl", - "hid_report_item.idl", ] modules_dictionary_idl_files = [ + "hid_collection_info.idl", "hid_connection_event_init.idl", "hid_device_filter.idl", "hid_device_request_options.idl", + "hid_report_info.idl", + "hid_report_item.idl", ] modules_dependency_idl_files = [ "navigator_hid.idl" ]
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc index 9a7248a..9f300df 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc
@@ -249,10 +249,6 @@ if (frame_rate_set.Max() && track_max_frame_rate > *frame_rate_set.Max()) track_max_frame_rate = *frame_rate_set.Max(); } - // Disable frame-rate adjustment if the requested rate is greater than the - // source rate. - if (track_max_frame_rate >= source_format.frame_rate) - track_max_frame_rate = 0.0; return VideoTrackAdapterSettings(target_resolution, track_min_aspect_ratio, track_max_aspect_ratio,
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_test.cc index 9bc18d30..419d681 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_test.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_test.cc
@@ -544,9 +544,7 @@ EXPECT_EQ(kSourceWidth, result.target_width()); EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio()); EXPECT_EQ(kMaxAspectRatio, result.max_aspect_ratio()); - // No frame-rate adjustment because the track will use the same frame rate - // as the source. - EXPECT_EQ(0.0, result.max_frame_rate()); + EXPECT_EQ(kSourceFrameRate, result.max_frame_rate()); } // High frame rate. @@ -563,9 +561,7 @@ EXPECT_EQ(kSourceWidth, result.target_width()); EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio()); EXPECT_EQ(kMaxAspectRatio, result.max_aspect_ratio()); - // No frame-rate adjustment because the track will use a frame rate that is - // greater than the source's. - EXPECT_EQ(0.0, result.max_frame_rate()); + EXPECT_EQ(kHighFrameRate, result.max_frame_rate()); } }
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc index 10935ee..8c25086 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc
@@ -40,24 +40,26 @@ EXPECT_EQ(std::string(), result.device_id()); } -void CheckTrackAdapterSettingsEqualsFormat(const VideoCaptureSettings& result) { +void CheckTrackAdapterSettingsEqualsFormat(const VideoCaptureSettings& result, + double frame_rate = 0.0) { // For content capture, resolution and frame rate should always be the same // for source and track. EXPECT_TRUE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(0.0, result.track_adapter_settings().max_frame_rate()); + EXPECT_EQ(frame_rate, result.track_adapter_settings().max_frame_rate()); } void CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio( - const VideoCaptureSettings& result) { + const VideoCaptureSettings& result, + double frame_rate = 0.0) { EXPECT_EQ( static_cast<double>(kMinScreenCastDimension) / kMaxScreenCastDimension, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ( static_cast<double>(kMaxScreenCastDimension) / kMinScreenCastDimension, result.track_adapter_settings().max_aspect_ratio()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsFormat(result, frame_rate); } } // namespace @@ -1296,7 +1298,7 @@ EXPECT_EQ(kFrameRate, result.min_frame_rate()); EXPECT_EQ(kFrameRate, result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, kFrameRate); } TEST_F(MediaStreamConstraintsUtilVideoContentTest, MandatoryMinFrameRate) { @@ -1375,7 +1377,8 @@ EXPECT_EQ(base::Optional<double>(), result.min_frame_rate()); EXPECT_EQ(kMaxFrameRate, result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kMaxFrameRate); } // kMaxFrameRate less than default @@ -1389,7 +1392,8 @@ EXPECT_EQ(base::Optional<double>(), result.min_frame_rate()); EXPECT_EQ(kMaxFrameRate, result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kMaxFrameRate); } // kMaxFrameRate greater than the maximum allowed @@ -1417,7 +1421,8 @@ EXPECT_EQ(base::Optional<double>(), result.min_frame_rate()); EXPECT_EQ(kMaxFrameRate, result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kMaxFrameRate); } } @@ -1435,7 +1440,8 @@ EXPECT_EQ(kMinFrameRate, result.min_frame_rate()); EXPECT_EQ(kMaxFrameRate, result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kMaxFrameRate); } { @@ -1450,7 +1456,8 @@ EXPECT_EQ(kMinFrameRate, result.min_frame_rate()); EXPECT_EQ(kMaxFrameRate, result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kMaxFrameRate); } { @@ -1465,7 +1472,8 @@ EXPECT_EQ(kMinFrameRate, result.min_frame_rate()); EXPECT_EQ(kMaxFrameRate, result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kMaxFrameRate); } } @@ -1481,7 +1489,8 @@ EXPECT_EQ(base::Optional<double>(), result.min_frame_rate()); EXPECT_EQ(base::Optional<double>(), result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kIdealFrameRate); } // Ideal greater than maximum. @@ -1497,7 +1506,8 @@ EXPECT_EQ(base::Optional<double>(), result.min_frame_rate()); EXPECT_EQ(kMaxFrameRate, result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kMaxFrameRate); } // Ideal less than minimum. @@ -1512,7 +1522,8 @@ EXPECT_EQ(kMinFrameRate, result.FrameRate()); EXPECT_EQ(base::Optional<double>(), result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kMinFrameRate); } // Ideal within range. @@ -1530,7 +1541,8 @@ EXPECT_EQ(kMinFrameRate, result.min_frame_rate()); EXPECT_EQ(kMaxFrameRate, result.max_frame_rate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, + kIdealFrameRate); } } @@ -1604,7 +1616,7 @@ EXPECT_EQ(std::string(), result.device_id()); EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().max_aspect_ratio()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsFormat(result, 10.0); MediaTrackConstraintSetPlatform& advanced4 = constraint_factory_.AddAdvanced(); @@ -1621,7 +1633,7 @@ EXPECT_EQ(std::string(), result.device_id()); EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().max_aspect_ratio()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsFormat(result, 10.0); constraint_factory_.basic().width.SetIdeal(100); constraint_factory_.basic().height.SetIdeal(100); @@ -1638,7 +1650,7 @@ EXPECT_EQ(std::string(), result.device_id()); EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().max_aspect_ratio()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsFormat(result, 10.0); constraint_factory_.basic().width.SetIdeal(2000); constraint_factory_.basic().height.SetIdeal(1500); @@ -1654,7 +1666,7 @@ EXPECT_EQ(std::string(), result.device_id()); EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().max_aspect_ratio()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsFormat(result, 10.0); } TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedExactResolution) { @@ -1744,7 +1756,7 @@ result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(1920.0 / 1080.0, result.track_adapter_settings().max_aspect_ratio()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsFormat(result, 60.0); } TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedNoiseReduction) { @@ -1933,7 +1945,7 @@ EXPECT_TRUE(result.HasValue()); EXPECT_EQ(40.0, result.FrameRate()); CheckNonFrameRateDefaults(result); - CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result); + CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result, 40.0); } TEST_F(MediaStreamConstraintsUtilVideoContentTest, @@ -1977,7 +1989,7 @@ result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(static_cast<double>(kMaxWidth) / kMinScreenCastDimension, result.track_adapter_settings().max_aspect_ratio()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsFormat(result, 90.0); } TEST_F(MediaStreamConstraintsUtilVideoContentTest, @@ -2005,7 +2017,7 @@ EXPECT_EQ( static_cast<double>(kMaxScreenCastDimension) / kMinScreenCastDimension, result.track_adapter_settings().max_aspect_ratio()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsFormat(result, 60.0); } TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedDeviceID) {
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc index f7c9e20..dcb574f 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc
@@ -299,9 +299,12 @@ static_cast<double>(track_settings_with_rescale.target_width()) / track_settings_with_rescale.target_height(); DCHECK(!std::isnan(target_aspect_ratio)); - double target_frame_rate = track_settings_with_rescale.max_frame_rate(); - if (target_frame_rate == 0.0) - target_frame_rate = NativeFrameRate(); + double best_supported_frame_rate = + track_settings_with_rescale.max_frame_rate(); + if (best_supported_frame_rate == 0.0 || + best_supported_frame_rate > NativeFrameRate()) { + best_supported_frame_rate = NativeFrameRate(); + } track_fitness_with_rescale = NumericValueFitness(basic_constraint_set.aspect_ratio, @@ -311,7 +314,7 @@ NumericValueFitness(basic_constraint_set.width, track_settings_with_rescale.target_width()) + NumericValueFitness(basic_constraint_set.frame_rate, - target_frame_rate); + best_supported_frame_rate); } double track_fitness_without_rescale = HUGE_VAL; @@ -326,17 +329,19 @@ basic_constraint_set, resolution_set(), constrained_frame_rate(), format(), false /* enable_rescale */); DCHECK(!track_settings_without_rescale.target_size().has_value()); - double target_frame_rate = + double best_supported_frame_rate = track_settings_without_rescale.max_frame_rate(); - if (target_frame_rate == 0.0) - target_frame_rate = NativeFrameRate(); + if (best_supported_frame_rate == 0.0 || + best_supported_frame_rate > NativeFrameRate()) { + best_supported_frame_rate = NativeFrameRate(); + } track_fitness_without_rescale = NumericValueFitness(basic_constraint_set.aspect_ratio, NativeAspectRatio()) + NumericValueFitness(basic_constraint_set.height, NativeHeight()) + NumericValueFitness(basic_constraint_set.width, NativeWidth()) + NumericValueFitness(basic_constraint_set.frame_rate, - target_frame_rate); + best_supported_frame_rate); } }
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc index f1bf96f..3eabce2 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc
@@ -50,8 +50,6 @@ void CheckTrackAdapterSettingsEqualsFrameRate( const VideoCaptureSettings& settings, double value = 0.0) { - if (value >= settings.FrameRate()) - value = 0.0; EXPECT_EQ(value, settings.track_adapter_settings().max_frame_rate()); } @@ -1184,7 +1182,8 @@ // format has a frame rate included in the requested range. EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(*default_closest_format_, result.Format()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsResolution(result); + CheckTrackAdapterSettingsEqualsFrameRate(result, kMaxFrameRate); } { @@ -1201,7 +1200,8 @@ // range. The default resolution should be preferred as secondary criterion. EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(*low_res_closest_format_, result.Format()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsResolution(result); + CheckTrackAdapterSettingsEqualsFrameRate(result, kMaxFrameRate); } { @@ -1220,7 +1220,8 @@ EXPECT_EQ(high_res_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(1280, result.Width()); EXPECT_EQ(720, result.Height()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsResolution(result); + CheckTrackAdapterSettingsEqualsFrameRate(result, kMaxFrameRate); } } @@ -1284,7 +1285,8 @@ EXPECT_EQ(1280, result.Width()); EXPECT_EQ(720, result.Height()); EXPECT_EQ(60, result.FrameRate()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsResolution(result); + CheckTrackAdapterSettingsEqualsFrameRate(result, kIdealFrameRate); } } @@ -2383,7 +2385,7 @@ // set. EXPECT_EQ(40.0, result.FrameRate()); CheckTrackAdapterSettingsEqualsResolution(result); - CheckTrackAdapterSettingsEqualsFrameRate(result); + CheckTrackAdapterSettingsEqualsFrameRate(result, 40.0); } TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, @@ -2425,7 +2427,8 @@ EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(30.0, result.FrameRate()); EXPECT_GE(1920, result.Width()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsResolution(result); + CheckTrackAdapterSettingsEqualsFrameRate(result, 30.0); } TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, @@ -2450,7 +2453,8 @@ EXPECT_EQ(high_res_device_->device_id.Utf8(), result.device_id()); EXPECT_EQ(60.0, result.FrameRate()); EXPECT_GE(1080, result.Height()); - CheckTrackAdapterSettingsEqualsFormat(result); + CheckTrackAdapterSettingsEqualsResolution(result); + CheckTrackAdapterSettingsEqualsFrameRate(result, 60.0); } TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedDeviceID) {
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc index d917c90..9866080 100644 --- a/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc
@@ -112,7 +112,13 @@ } // namespace -class WebRtcAudioRendererTest : public testing::Test { +// Flaky on TSAN. See https://crbug.com/1127211 +#if defined(THREAD_SANITIZER) +#define MAYBE_WebRtcAudioRendererTest DISABLED_WebRtcAudioRendererTest +#else +#define MAYBE_WebRtcAudioRendererTest WebRtcAudioRendererTest +#endif +class MAYBE_WebRtcAudioRendererTest : public testing::Test { public: MOCK_METHOD1(MockSwitchDeviceCallback, void(media::OutputDeviceStatus)); void SwitchDeviceCallback(base::RunLoop* loop, @@ -122,7 +128,7 @@ } protected: - WebRtcAudioRendererTest() + MAYBE_WebRtcAudioRendererTest() : source_(new MockAudioRendererSource()) // Tests crash on Android if these are defined. https://crbug.com/1119689 #if !defined(OS_ANDROID) @@ -216,7 +222,7 @@ }; // Verify that the renderer will be stopped if the only proxy is stopped. -TEST_F(WebRtcAudioRendererTest, StopRenderer) { +TEST_F(MAYBE_WebRtcAudioRendererTest, StopRenderer) { SetupRenderer(kDefaultOutputDeviceId); renderer_proxy_->Start(); @@ -229,7 +235,7 @@ // Verify that the renderer will not be stopped unless the last proxy is // stopped. -TEST_F(WebRtcAudioRendererTest, MultipleRenderers) { +TEST_F(MAYBE_WebRtcAudioRendererTest, MultipleRenderers) { SetupRenderer(kDefaultOutputDeviceId); renderer_proxy_->Start(); @@ -263,7 +269,7 @@ // Verify that the sink of the renderer is using the expected sample rate and // buffer size. -TEST_F(WebRtcAudioRendererTest, VerifySinkParameters) { +TEST_F(MAYBE_WebRtcAudioRendererTest, VerifySinkParameters) { SetupRenderer(kDefaultOutputDeviceId); renderer_proxy_->Start(); #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || \ @@ -285,7 +291,7 @@ renderer_proxy_->Stop(); } -TEST_F(WebRtcAudioRendererTest, NonDefaultDevice) { +TEST_F(MAYBE_WebRtcAudioRendererTest, NonDefaultDevice) { SetupRenderer(kDefaultOutputDeviceId); EXPECT_EQ(kDefaultOutputDeviceId, mock_sink()->GetOutputDeviceInfo().device_id()); @@ -305,7 +311,7 @@ renderer_proxy_->Stop(); } -TEST_F(WebRtcAudioRendererTest, SwitchOutputDevice) { +TEST_F(MAYBE_WebRtcAudioRendererTest, SwitchOutputDevice) { SetupRenderer(kDefaultOutputDeviceId); EXPECT_EQ(kDefaultOutputDeviceId, mock_sink()->GetOutputDeviceInfo().device_id()); @@ -325,7 +331,7 @@ base::RunLoop loop; renderer_proxy_->SwitchOutputDevice( kOtherOutputDeviceId, - base::BindOnce(&WebRtcAudioRendererTest::SwitchDeviceCallback, + base::BindOnce(&MAYBE_WebRtcAudioRendererTest::SwitchDeviceCallback, base::Unretained(this), &loop)); loop.Run(); EXPECT_EQ(kOtherOutputDeviceId, @@ -340,7 +346,7 @@ renderer_proxy_->Stop(); } -TEST_F(WebRtcAudioRendererTest, SwitchOutputDeviceInvalidDevice) { +TEST_F(MAYBE_WebRtcAudioRendererTest, SwitchOutputDeviceInvalidDevice) { SetupRenderer(kDefaultOutputDeviceId); EXPECT_EQ(kDefaultOutputDeviceId, mock_sink()->GetOutputDeviceInfo().device_id()); @@ -357,7 +363,7 @@ base::RunLoop loop; renderer_proxy_->SwitchOutputDevice( kInvalidOutputDeviceId, - base::BindOnce(&WebRtcAudioRendererTest::SwitchDeviceCallback, + base::BindOnce(&MAYBE_WebRtcAudioRendererTest::SwitchDeviceCallback, base::Unretained(this), &loop)); loop.Run(); EXPECT_EQ(kDefaultOutputDeviceId, @@ -372,7 +378,7 @@ renderer_proxy_->Stop(); } -TEST_F(WebRtcAudioRendererTest, InitializeWithInvalidDevice) { +TEST_F(MAYBE_WebRtcAudioRendererTest, InitializeWithInvalidDevice) { renderer_ = new blink::WebRtcAudioRenderer( scheduler::GetSingleThreadTaskRunnerForTesting(), stream_descriptor_, nullptr /*blink::WebLocalFrame*/, base::UnguessableToken::Create(), @@ -397,7 +403,7 @@ mock_sink()->GetOutputDeviceInfo().device_id()); } -TEST_F(WebRtcAudioRendererTest, SwitchOutputDeviceStoppedSource) { +TEST_F(MAYBE_WebRtcAudioRendererTest, SwitchOutputDeviceStoppedSource) { SetupRenderer(kDefaultOutputDeviceId); auto* original_sink = mock_sink(); renderer_proxy_->Start(); @@ -410,7 +416,7 @@ renderer_proxy_->Stop(); renderer_proxy_->SwitchOutputDevice( kInvalidOutputDeviceId, - base::BindOnce(&WebRtcAudioRendererTest::SwitchDeviceCallback, + base::BindOnce(&MAYBE_WebRtcAudioRendererTest::SwitchDeviceCallback, base::Unretained(this), &loop)); loop.Run(); }
diff --git a/third_party/blink/renderer/modules/webmidi/midi_access.cc b/third_party/blink/renderer/modules/webmidi/midi_access.cc index ac5f79d..84e0b38 100644 --- a/third_party/blink/renderer/modules/webmidi/midi_access.cc +++ b/third_party/blink/renderer/modules/webmidi/midi_access.cc
@@ -31,6 +31,10 @@ #include "third_party/blink/renderer/modules/webmidi/midi_access.h" #include <memory> +#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/loader/document_load_timing.h" #include "third_party/blink/renderer/core/loader/document_loader.h" @@ -42,6 +46,7 @@ #include "third_party/blink/renderer/modules/webmidi/midi_output_map.h" #include "third_party/blink/renderer/modules/webmidi/midi_port.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h" namespace blink { @@ -80,6 +85,22 @@ port.version, ToDeviceState(port.state))); } } + constexpr IdentifiableSurface surface = IdentifiableSurface::FromTypeAndToken( + IdentifiableSurface::Type::kWebFeature, + WebFeature::kRequestMIDIAccess_ObscuredByFootprinting); + if (IdentifiabilityStudySettings::Get()->IsSurfaceAllowed(surface)) { + IdentifiableTokenBuilder builder; + for (const auto& port : ports) { + builder.AddToken(IdentifiabilityBenignStringToken(port.id)); + builder.AddToken(IdentifiabilityBenignStringToken(port.name)); + builder.AddToken(IdentifiabilityBenignStringToken(port.manufacturer)); + builder.AddToken(IdentifiabilityBenignStringToken(port.version)); + builder.AddToken(port.type); + } + IdentifiabilityMetricBuilder(execution_context->UkmSourceID()) + .Set(surface, builder.GetToken()) + .Record(execution_context->UkmRecorder()); + } } MIDIAccess::~MIDIAccess() = default;
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc index c01f344..3f3efff7 100644 --- a/third_party/blink/renderer/platform/exported/web_url_response.cc +++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -413,20 +413,13 @@ resource_response_->SetDidServiceWorkerNavigationPreload(value); } -WebString WebURLResponse::RemoteIPAddress() const { - return resource_response_->RemoteIPAddress(); +net::IPEndPoint WebURLResponse::RemoteIPEndpoint() const { + return resource_response_->RemoteIPEndpoint(); } -void WebURLResponse::SetRemoteIPAddress(const WebString& remote_ip_address) { - resource_response_->SetRemoteIPAddress(remote_ip_address); -} - -uint16_t WebURLResponse::RemotePort() const { - return resource_response_->RemotePort(); -} - -void WebURLResponse::SetRemotePort(uint16_t remote_port) { - resource_response_->SetRemotePort(remote_port); +void WebURLResponse::SetRemoteIPEndpoint( + const net::IPEndPoint& remote_ip_endpoint) { + resource_response_->SetRemoteIPEndpoint(remote_ip_endpoint); } network::mojom::IPAddressSpace WebURLResponse::AddressSpace() const {
diff --git a/third_party/blink/renderer/platform/loader/BUILD.gn b/third_party/blink/renderer/platform/loader/BUILD.gn index a13b84a..1069a98 100644 --- a/third_party/blink/renderer/platform/loader/BUILD.gn +++ b/third_party/blink/renderer/platform/loader/BUILD.gn
@@ -142,6 +142,7 @@ ":make_platform_loader_generated_fetch_initiator_type_names", "//components/link_header_util", "//components/web_package", + "//net", "//services/metrics/public/cpp:ukm_builders", "//services/network/public/cpp", "//services/network/public/mojom:mojom_blink",
diff --git a/third_party/blink/renderer/platform/loader/fetch/DEPS b/third_party/blink/renderer/platform/loader/fetch/DEPS index 643d9d95..6b62d91 100644 --- a/third_party/blink/renderer/platform/loader/fetch/DEPS +++ b/third_party/blink/renderer/platform/loader/fetch/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+net/base/ip_endpoint.h", "+net/dns/public", "+services/network/public/cpp/fetch_api_utils.h", "+services/network/public/cpp/optional_trust_token_params.h",
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.h b/third_party/blink/renderer/platform/loader/fetch/resource_response.h index 3ce0d90..5fadb1c 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_response.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.h
@@ -33,6 +33,7 @@ #include "base/memory/scoped_refptr.h" #include "base/optional.h" #include "base/time/time.h" +#include "net/base/ip_endpoint.h" #include "services/network/public/mojom/cross_origin_embedder_policy.mojom-shared.h" #include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "services/network/public/mojom/ip_address_space.mojom-shared.h" @@ -391,13 +392,12 @@ response_time_ = response_time; } - const AtomicString& RemoteIPAddress() const { return remote_ip_address_; } - void SetRemoteIPAddress(const AtomicString& value) { - remote_ip_address_ = value; + const net::IPEndPoint& RemoteIPEndpoint() const { + return remote_ip_endpoint_; } - - uint16_t RemotePort() const { return remote_port_; } - void SetRemotePort(uint16_t value) { remote_port_ = value; } + void SetRemoteIPEndpoint(const net::IPEndPoint& value) { + remote_ip_endpoint_ = value; + } network::mojom::IPAddressSpace AddressSpace() const { return address_space_; } void SetAddressSpace(network::mojom::IPAddressSpace value) { @@ -510,11 +510,8 @@ AtomicString http_status_text_; HTTPHeaderMap http_header_fields_; - // Remote IP address of the socket which fetched this resource. - AtomicString remote_ip_address_; - - // Remote port number of the socket which fetched this resource. - uint16_t remote_port_ = 0; + // Remote IP endpoint of the socket which fetched this resource. + net::IPEndPoint remote_ip_endpoint_; // The address space from which this resource was fetched. network::mojom::IPAddressSpace address_space_ =
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index ebc165d..437ad78e 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1784,6 +1784,9 @@ name: "SmsReceiver", status: {"default": "experimental", "Android": "stable"}, }, + { + name: "SrcsetMaxDensity", + }, // Used as argument in attribute of stable-release functions/interfaces // where a runtime-enabled feature name is required for correct IDL syntax. // This is a global flag; do not change its status.
diff --git a/third_party/blink/renderer/platform/widget/input/main_thread_event_queue.cc b/third_party/blink/renderer/platform/widget/input/main_thread_event_queue.cc index e3e8850..48baeb3 100644 --- a/third_party/blink/renderer/platform/widget/input/main_thread_event_queue.cc +++ b/third_party/blink/renderer/platform/widget/input/main_thread_event_queue.cc
@@ -108,11 +108,6 @@ // If the other event was blocking store its callback to call later, but we // also save the trace_id to ensure the flow events correct show the // critical path. - // - // IMPORTANT: this if has to remain above CoalesceWith because that will - // overwrite other_event->latency_info() to be equal to |latency_| - // (including - // trace_id). if (other_event->callback_) { blocking_coalesced_callbacks_.push_back( std::make_pair(std::move(other_event->callback_),
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng index ef82c2a..bc893ba 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng +++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -118,11 +118,11 @@ crbug.com/591099 external/wpt/css/css-shapes/shape-outside/supported-shapes/polygon/shape-outside-polygon-017.html [ Failure ] ### external/wpt/css/css-sizing/ -crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/abspos-004.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/abspos-013.tentative.html [ Pass ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-024.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/block-aspect-ratio-028.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-009.tentative.html [ Failure ] +crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-014.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/percentage-resolution-002.tentative.html [ Failure ] crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/quirks-mode-001.tentative.html [ Failure ] crbug.com/591099 external/wpt/css/css-sizing/clone-nowrap-intrinsic-size-bidi.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 44f3caa..cae7ec8 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -273,7 +273,9 @@ crbug.com/1007229 external/wpt/intersection-observer/same-origin-grand-child-iframe.sub.html [ Pass Failure ] # Not supported yet -crbug.com/1045668 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-014.tentative.html [ Failure ] +crbug.com/1133835 external/wpt/css/css-sizing/aspect-ratio/replaced-element-023.tentative.html [ Failure ] +crbug.com/1133835 external/wpt/css/css-sizing/aspect-ratio/replaced-element-025.tentative.html [ Failure ] +crbug.com/1133835 external/wpt/css/css-sizing/aspect-ratio/replaced-element-027.tentative.html [ Failure ] crbug.com/936084 external/wpt/css/css-sizing/max-content-input-001.html [ Failure ] @@ -1112,7 +1114,6 @@ crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/out-of-flow/abspos-auto-position-on-line.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/out-of-flow/abspos-auto-position-on-line-rtl.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/out-of-flow/nested-multicol.html [ Failure ] -crbug.com/1066616 virtual/layout_ng_block_frag/fast/multicol/overflow-content.html [ Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/positioned-outside-of-columns.html [ Crash Failure ] crbug.com/1079031 virtual/layout_ng_block_frag/fast/multicol/positioned-split.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/shadow-breaking.html [ Failure ] @@ -2643,12 +2644,9 @@ crbug.com/958381 [ Mac ] external/wpt/css/CSS2/tables/table-anonymous-objects-206.xht [ Failure ] # ====== New tests from wpt-importer added here ====== -crbug.com/626703 external/wpt/css/css-sizing/aspect-ratio/replaced-element-027.tentative.html [ Failure ] crbug.com/626703 external/wpt/css/css-backgrounds/border-image-slice-007.htm [ Failure ] crbug.com/626703 external/wpt/css/css-backgrounds/border-image-slice-005.htm [ Failure ] crbug.com/626703 [ Mac11.0 ] external/wpt/scroll-to-text-fragment/redirects.html [ Timeout ] -crbug.com/626703 external/wpt/css/css-sizing/aspect-ratio/replaced-element-025.tentative.html [ Failure ] -crbug.com/626703 external/wpt/css/css-sizing/aspect-ratio/replaced-element-023.tentative.html [ Failure ] crbug.com/626703 [ Linux ] external/wpt/mathml/presentation-markup/operators/operator-dictionary-symmetric-005.html [ Failure Crash ] crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-non-collapsed-selection.tentative.html?Backspace [ Timeout ] crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-non-collapsed-selection.tentative.html?TypingA [ Timeout ] @@ -6606,10 +6604,6 @@ crbug.com/1094436 http/tests/devtools/sources/debugger-ui/snippet-edit-breakpoint.js [ Pass Timeout ] crbug.com/1094436 http/tests/devtools/sources/debugger/navigator-view.js [ Pass Failure Crash ] -# Temporarily disable tests to allow refactoring DevTools ad hoc fields in DOMNode -crbug.com/1133675 http/tests/devtools/elements/elements-child-node-count-mismatch.js [ Pass Failure ] -crbug.com/1133675 http/tests/devtools/elements/move-node.js [ Pass Failure Timeout ] - # Sheriff 2020-07-20 crbug.com/1107572 [ Mac ] http/tests/devtools/tracing/timeline-layout/timeline-layout-with-invalidations.js [ Pass Failure ] crbug.com/1107572 [ Mac ] http/tests/devtools/tracing/timeline-style/timeline-style-recalc-with-invalidations.js [ Pass Failure ] @@ -6653,9 +6647,6 @@ crbug.com/1092048 external/wpt/FileAPI/blob/Blob-stream.any.html [ Pass Timeout ] crbug.com/1092048 external/wpt/FileAPI/blob/Blob-stream.any.worker.html [ Pass Timeout ] -# Sheriff 2020-08-04: New wpt tests are failing -crbug.com/1112771 external/wpt/webhid/idlharness.https.window.html [ Failure ] - # Sheriff 2020-08-05 crbug.com/1113050 fast/borders/border-radius-mask-video-ratio.html [ Pass Failure ] crbug.com/1113127 fast/canvas/downsample-quality.html [ Pass Failure Crash ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-013.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-013.html new file mode 100644 index 0000000..38bd05f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-013.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/css-multicol-1/#spanning-columns"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="columns:2; column-gap:0; width:100px; background:red;"> + <div style="height:40px; background:green;"></div> + <div style="padding-top:20px; background:green;"> + <div style="column-span:all; height:70px; background:green;"></div> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollable-overflow-float.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollable-overflow-float.html new file mode 100644 index 0000000..f75c0a6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollable-overflow-float.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<meta name="assert" content="This ensures that floats block-end margin contributes to the scrollable overflow."> +<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" /> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<body onload="checkLayout('#target')"> + <div id="target" style="width: 100px; height: 100px; overflow: scroll;" data-expected-scroll-height="220"> + <div style="float: left; width: 50px; height: 200px; margin: 10px; background: lime;"></div> + </div> + <div id=log></div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid-expected.txt index c855080..034b6db 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid-expected.txt
@@ -12,6 +12,6 @@ PASS e.style['aspect-ratio'] = "16 / 0" should set the property value PASS e.style['aspect-ratio'] = "auto 16" should set the property value PASS e.style['aspect-ratio'] = "16 auto" should set the property value -FAIL e.style['aspect-ratio'] = "0 / 0" should set the property value assert_equals: serialization should be canonical expected "1 / 0" but got "0 / 0" +PASS e.style['aspect-ratio'] = "0 / 0" should set the property value Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid.html b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid.html index c7add59d..12f035d2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid.html
@@ -21,6 +21,5 @@ test_valid_value("aspect-ratio", "16 / 0"); test_valid_value("aspect-ratio", "auto 16"); test_valid_value("aspect-ratio", "16 auto", "auto 16"); -// https://github.com/w3c/csswg-drafts/issues/5084 -test_valid_value("aspect-ratio", "0 / 0", "1 / 0"); +test_valid_value("aspect-ratio", "0 / 0"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html index 435f6471..1d73b56 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/reporting-observer.html
@@ -63,6 +63,8 @@ assert_equals(report_access_from[0].type, "coop-access-violation"); assert_equals(report_access_from[0].url, opener_url.replace(/"/g, '%22')); assert_source_location_found(report_access_from[0]) + assert_equals(report_access_from[0].body.type, + "access-from-coop-page-to-openee"); // 5. The openee tries to access its opener. No reports for blocked access // to the COOP page should be dispatched. @@ -118,6 +120,8 @@ assert_equals(report_access_from[0].url, openee_url.replace(/"/g, '%22')); assert_true(report_access_from[0].body.sourceFile.includes("try-access.js")); assert_source_location_found(report_access_from[0]) + assert_equals(report_access_from[0].body.type, + "access-from-coop-page-to-opener"); // 4. The opener tries to access its openee. No reports for blocked access // to the COOP page should be dispatched. @@ -192,6 +196,8 @@ assert_equals(reports[0].url, opener_url.replace(/"/g, '%22')); assert_true(reports[0].body.sourceFile.includes("try-access.js")); assert_source_location_found(reports[0]); + assert_equals(reports[0].body.type, + "access-from-coop-page-to-openee"); }, "Access from same-origin iframe") promise_test(async t => {
diff --git a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-about-blank-expected.txt b/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-about-blank-expected.txt index a71d38d..66681371 100644 --- a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-about-blank-expected.txt +++ b/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-about-blank-expected.txt
@@ -1,6 +1,6 @@ This is a testharness.js-based test. PASS The fetch() API in an about:blank iframe with the 'client' referrer is fetched with no 'Referer' header -FAIL The fetch() API in an about:blank iframe with a custom URL referrer is fetched with a 'Referer` header that uses the outer document's URL along with its referrer policy assert_equals: expected "http://web-platform.test:8001" but got "http://web-platform.test:8001/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html/custom" +FAIL The fetch() API in an about:blank iframe with a custom URL referrer is fetched with a 'Referer` header that uses the outer document's URL along with its referrer policy assert_equals: expected "http://web-platform.test:8001/" but got "http://web-platform.test:8001/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html/custom" FAIL The value of document.referrer in an about:blank iframe is the outer document's full URL, regardless of referrer policy assert_equals: expected "http://web-platform.test:8001/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html" but got "http://web-platform.test:8001/" PASS A subresource fetched from an about:blank iframe is fetched with no 'Referer' header Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html b/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html index 2185ee29..60f91a5 100644 --- a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html +++ b/third_party/blink/web_tests/external/wpt/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html
@@ -42,7 +42,7 @@ // inherits its parent's referrer policy, the URL should be restricted to // its origin. testFetchURLReferrer.step_func_done(() => { - assert_equals(referrer, location.origin); + assert_equals(referrer, location.origin + '/'); })(); } else if (test_name === "testDocumentReferrer") { // The referrer of the initial document in an about:blank iframe is set to
diff --git a/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt index dd981326..0fe2410 100644 --- a/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 112 tests; 103 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 112 tests; 63 PASS, 49 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS Partial interface Navigator: original interface defined @@ -45,54 +45,54 @@ PASS HIDInputReportEvent interface: attribute device PASS HIDInputReportEvent interface: attribute reportId PASS HIDInputReportEvent interface: attribute data -PASS HIDReportItem interface: existence and properties of interface object -PASS HIDReportItem interface object length -PASS HIDReportItem interface object name -PASS HIDReportItem interface: existence and properties of interface prototype object -PASS HIDReportItem interface: existence and properties of interface prototype object's "constructor" property -PASS HIDReportItem interface: existence and properties of interface prototype object's @@unscopables property -PASS HIDReportItem interface: attribute isAbsolute -PASS HIDReportItem interface: attribute isArray -PASS HIDReportItem interface: attribute isRange -PASS HIDReportItem interface: attribute hasNull -PASS HIDReportItem interface: attribute usages -PASS HIDReportItem interface: attribute usageMinimum -PASS HIDReportItem interface: attribute usageMaximum -FAIL HIDReportItem interface: attribute designatorMinimum assert_true: The prototype object must have a property "designatorMinimum" expected true got false -FAIL HIDReportItem interface: attribute designatorMaximum assert_true: The prototype object must have a property "designatorMaximum" expected true got false -FAIL HIDReportItem interface: attribute stringMinimum assert_true: The prototype object must have a property "stringMinimum" expected true got false -FAIL HIDReportItem interface: attribute stringMaximum assert_true: The prototype object must have a property "stringMaximum" expected true got false -PASS HIDReportItem interface: attribute reportSize -PASS HIDReportItem interface: attribute reportCount -PASS HIDReportItem interface: attribute unitExponent -FAIL HIDReportItem interface: attribute unit assert_true: The prototype object must have a property "unit" expected true got false -PASS HIDReportItem interface: attribute logicalMinimum -PASS HIDReportItem interface: attribute logicalMaximum -PASS HIDReportItem interface: attribute physicalMinimum -PASS HIDReportItem interface: attribute physicalMaximum -PASS HIDReportInfo interface: existence and properties of interface object -PASS HIDReportInfo interface object length -PASS HIDReportInfo interface object name -PASS HIDReportInfo interface: existence and properties of interface prototype object -PASS HIDReportInfo interface: existence and properties of interface prototype object's "constructor" property -PASS HIDReportInfo interface: existence and properties of interface prototype object's @@unscopables property -PASS HIDReportInfo interface: attribute reportId -PASS HIDReportInfo interface: attribute items -PASS HIDCollectionInfo interface: existence and properties of interface object -PASS HIDCollectionInfo interface object length -PASS HIDCollectionInfo interface object name -PASS HIDCollectionInfo interface: existence and properties of interface prototype object -PASS HIDCollectionInfo interface: existence and properties of interface prototype object's "constructor" property -PASS HIDCollectionInfo interface: existence and properties of interface prototype object's @@unscopables property -PASS HIDCollectionInfo interface: attribute usagePage -PASS HIDCollectionInfo interface: attribute usage -PASS HIDCollectionInfo interface: attribute children -PASS HIDCollectionInfo interface: attribute inputReports -PASS HIDCollectionInfo interface: attribute outputReports -PASS HIDCollectionInfo interface: attribute featureReports -FAIL HIDCollectionInfo interface: attribute reportIds assert_true: The prototype object must have a property "reportIds" expected true got false -FAIL HIDCollectionInfo interface: operation getField(BufferSource, HIDFieldOptions) assert_own_property: interface prototype object missing non-static operation expected property "getField" missing -FAIL HIDCollectionInfo interface: operation setField(BufferSource, HIDFieldOptions, double) assert_own_property: interface prototype object missing non-static operation expected property "setField" missing +FAIL HIDReportItem interface: existence and properties of interface object assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface object length assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface object name assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: existence and properties of interface prototype object assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute isAbsolute assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute isArray assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute isRange assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute hasNull assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute usages assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute usageMinimum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute usageMaximum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute designatorMinimum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute designatorMaximum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute stringMinimum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute stringMaximum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute reportSize assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute reportCount assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute unitExponent assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute unit assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute logicalMinimum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute logicalMaximum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute physicalMinimum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportItem interface: attribute physicalMaximum assert_own_property: self does not have own property "HIDReportItem" expected property "HIDReportItem" missing +FAIL HIDReportInfo interface: existence and properties of interface object assert_own_property: self does not have own property "HIDReportInfo" expected property "HIDReportInfo" missing +FAIL HIDReportInfo interface object length assert_own_property: self does not have own property "HIDReportInfo" expected property "HIDReportInfo" missing +FAIL HIDReportInfo interface object name assert_own_property: self does not have own property "HIDReportInfo" expected property "HIDReportInfo" missing +FAIL HIDReportInfo interface: existence and properties of interface prototype object assert_own_property: self does not have own property "HIDReportInfo" expected property "HIDReportInfo" missing +FAIL HIDReportInfo interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "HIDReportInfo" expected property "HIDReportInfo" missing +FAIL HIDReportInfo interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "HIDReportInfo" expected property "HIDReportInfo" missing +FAIL HIDReportInfo interface: attribute reportId assert_own_property: self does not have own property "HIDReportInfo" expected property "HIDReportInfo" missing +FAIL HIDReportInfo interface: attribute items assert_own_property: self does not have own property "HIDReportInfo" expected property "HIDReportInfo" missing +FAIL HIDCollectionInfo interface: existence and properties of interface object assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface object length assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface object name assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: existence and properties of interface prototype object assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: attribute usagePage assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: attribute usage assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: attribute children assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: attribute inputReports assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: attribute outputReports assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: attribute featureReports assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: attribute reportIds assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: operation getField(BufferSource, HIDFieldOptions) assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing +FAIL HIDCollectionInfo interface: operation setField(BufferSource, HIDFieldOptions, double) assert_own_property: self does not have own property "HIDCollectionInfo" expected property "HIDCollectionInfo" missing PASS HIDDevice interface: existence and properties of interface object PASS HIDDevice interface object length PASS HIDDevice interface object name
diff --git a/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window.js index fa763e0..bdc8419b 100644 --- a/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window.js +++ b/third_party/blink/web_tests/external/wpt/webhid/idlharness.https.window.js
@@ -14,9 +14,6 @@ Navigator: ['navigator'], // TODO: HIDConnectionEvent // TODO: HIDInputReportEvent - // TODO: HIDReportItem - // TODO: HIDReportInfo - // TODO: HIDCollectionInfo // TODO: HIDDevice }); }
diff --git a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.js b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.js index 65f59a0..ea96197 100644 --- a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.js +++ b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.js
@@ -11,7 +11,6 @@ "Audio", "HTMLCanvasElement", "Path", - "TextMetrics", "CanvasProxy", "CanvasRenderingContext2D", "DrawingStyle",
diff --git a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.sharedworker-expected.txt index d834acc..7e4635f 100644 --- a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.sharedworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.sharedworker-expected.txt
@@ -8,7 +8,6 @@ PASS The Audio interface object should not be exposed PASS The HTMLCanvasElement interface object should not be exposed PASS The Path interface object should not be exposed -FAIL The TextMetrics interface object should not be exposed assert_false: expected false got true PASS The CanvasProxy interface object should not be exposed PASS The CanvasRenderingContext2D interface object should not be exposed PASS The DrawingStyle interface object should not be exposed
diff --git a/third_party/blink/web_tests/fast/events/wheel/wheel-scroll-latching-on-scrollbar.html b/third_party/blink/web_tests/fast/events/wheel/wheel-scroll-latching-on-scrollbar.html deleted file mode 100644 index cc0964c..0000000 --- a/third_party/blink/web_tests/fast/events/wheel/wheel-scroll-latching-on-scrollbar.html +++ /dev/null
@@ -1,84 +0,0 @@ -<!DOCTYPE HTML> -<script src='../../../resources/gesture-util.js'></script> -<script src="../../../resources/testharness.js"></script> -<script src="../../../resources/testharnessreport.js"></script> -<style> - - body { - margin: 0px; - height: 100px; - width: 100px; - } - #parentDiv { - background-color: #FF7F7F; - height: 100px; - width: 100px; - overflow: scroll; - } - #content1 { - height: 120px; - width: 120px; - } - #childDiv { - background-color: #84BE6A; - height: 80px; - width: 80px; - overflow: scroll; - } - #content2 { - height: 100px; - width: 100px; - } -</style> - -<div id="parentDiv"> - <div id="content1"> - <div id="childDiv"> - <div id="content2"> - </div> - </div> - </div> -</div> - -<script> -var childDiv = document.getElementById('childDiv'); -var parentDiv = document.getElementById('parentDiv'); -var rect = childDiv.getBoundingClientRect(); -const GESTURE_SOURCE_TYPE = GestureSourceType.MOUSE_INPUT; - -const MAX_RAF = 1000; -function waitForAnimationEnd() { - var last_child_scroll_offset = childDiv.scrollTop; - var last_parent_scroll_offset = parentDiv.scrollTop; - var last_changed_count = 0; - return new Promise((resolve, reject) => { - function tick(raf_count) { - // We requestAnimationFrame either for 1000 frames or until 20 frames with - // no change have been observed. - if (raf_count >= MAX_RAF || raf_count - last_changed_count > 20) { - resolve(); - } else { - if (childDiv.scrollTop != last_child_scroll_offset || - parentDiv.scrollTop != last_parent_scroll_offset) { - last_changed_count = raf_count; - last_child_scroll_offset = childDiv.scrollTop; - last_parent_scroll_offset = parentDiv.scrollTop; - } - requestAnimationFrame(tick.bind(this, raf_count + 1)); - } - } - tick(0); - }); -} - -promise_test(t => { - return smoothScroll(1000, rect.right - 5, rect.bottom - 5, GESTURE_SOURCE_TYPE, 'down', 4000) - .then(waitForAnimationEnd) - .then(() => { - assert_equals(childDiv.scrollTop, childDiv.scrollHeight - childDiv.clientHeight, - "childDiv must be fully scrolled"); - assert_equals(parentDiv.scrollTop, 0, "parentDiv shouldn't scroll at all"); - }); -}, "Scrolling on scrollbar of the child div doesn't propagate to the parent."); - -</script>
diff --git a/third_party/blink/web_tests/fast/scroll-snap/animate-fling-to-snap-points.html b/third_party/blink/web_tests/fast/scroll-snap/animate-fling-to-snap-points.html index 77d48847..b3e6812 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/animate-fling-to-snap-points.html +++ b/third_party/blink/web_tests/fast/scroll-snap/animate-fling-to-snap-points.html
@@ -44,7 +44,7 @@ promise_test (async () => { scroller.scrollTo(0, 0); await smoothScroll(100, 200, 200, GestureSourceType.TOUCH_INPUT, 'downright', SPEED_INSTANT); - await waitForAnimationEnd(scrollLeft, 700, 10); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 80, 1); assert_approx_equals(scroller.scrollTop, 80, 1); }, "Without fling enabled, the scroll ends at the closest snap point to the scroll destination."); @@ -52,7 +52,7 @@ promise_test (async () => { scroller.scrollTo(0, 0); await swipe(100, 200, 200, 'upleft', 900); - await waitForAnimationEnd(scrollLeft, 1000, 30); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 200, 1); assert_approx_equals(scroller.scrollTop, 200, 1); }, "Fling scroll ends at the closest snap point to the fling destination.") @@ -61,7 +61,7 @@ scroller.scrollTo(0, 0); // Scroll horizontally to (100, 0) with momentum. await swipe(100, 200, 200, 'left', 900); - await waitForAnimationEnd(scrollLeft, 1000, 30); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 200, 1); assert_approx_equals(scroller.scrollTop, 0, 1); }, "Fling scroll in one direction ends at closest snap point to the fling destination."); @@ -72,7 +72,7 @@ // expectation in this case is to snap as if user scrolled horizontally to (100, 0) with // momentun. await swipe(100, 200, 200, 'downleft', 900); - await waitForAnimationEnd(scrollLeft, 1000, 30); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 200, 1); // TODO(823998): Scroll top may land either at 0px or 80px which are both valid snap targets. // My expectation was that it would be at 0. Needs more investigation to deflake. @@ -92,7 +92,7 @@ return scroller.scrollLeft > 120; }); MakeUnscrollable(); - await waitForAnimationEnd(scrollLeft, 1000, 20); + await waitForAnimationEndTimeBased(scrollLeft); MakeScrollable(); }, "Should not crash if the scroller becomes unscrollable during fling."); @@ -103,7 +103,7 @@ return scroller.scrollLeft > 120; }); body.removeChild(scroller); - await waitForAnimationEnd(scrollLeft, 1000, 20); + await waitForAnimationEndTimeBased(scrollLeft); body.appendChild(scroller); }, "Should not crash if the scroller is removed during fling.");
diff --git a/third_party/blink/web_tests/fast/scroll-snap/root-scroller-snap-behaviour/arrow-key-scroll-snaps-visual-viewport.html b/third_party/blink/web_tests/fast/scroll-snap/root-scroller-snap-behaviour/arrow-key-scroll-snaps-visual-viewport.html index e18b85f..9ccb05c0 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/root-scroller-snap-behaviour/arrow-key-scroll-snaps-visual-viewport.html +++ b/third_party/blink/web_tests/fast/scroll-snap/root-scroller-snap-behaviour/arrow-key-scroll-snaps-visual-viewport.html
@@ -104,11 +104,9 @@ await arrowDown() - const max_frames = 500; - const max_unchanged_frames = 15; - await waitForAnimationEnd(() => { + await waitForAnimationEndTimeBased(() => { return root_scroller.scrollTop; - }, max_frames, max_unchanged_frames); + }); // The offset of the visual viewport and the layout viewport combined should // be at the snap point.
diff --git a/third_party/blink/web_tests/fast/scroll-snap/root-scroller-snap-behaviour/smooth-scroll-snaps-visual-viewport.html b/third_party/blink/web_tests/fast/scroll-snap/root-scroller-snap-behaviour/smooth-scroll-snaps-visual-viewport.html index eea38bc..362a0ad 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/root-scroller-snap-behaviour/smooth-scroll-snaps-visual-viewport.html +++ b/third_party/blink/web_tests/fast/scroll-snap/root-scroller-snap-behaviour/smooth-scroll-snaps-visual-viewport.html
@@ -113,11 +113,9 @@ 'down', SPEED_INSTANT); - const max_frames = 500; - const max_unchanged_frames = 15; - await waitForAnimationEnd(() => { + await waitForAnimationEndTimeBased(() => { return root_scroller.scrollTop; - }, max_frames, max_unchanged_frames); + }); // The offset of the visual viewport and the layout viewport combined should // be at the snap point.
diff --git a/third_party/blink/web_tests/fast/scroll-snap/snap-scrolls-visual-viewport.html b/third_party/blink/web_tests/fast/scroll-snap/snap-scrolls-visual-viewport.html index 9b66f8f..3beab223 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/snap-scrolls-visual-viewport.html +++ b/third_party/blink/web_tests/fast/scroll-snap/snap-scrolls-visual-viewport.html
@@ -62,11 +62,9 @@ scroll_direction, SPEED_INSTANT); - const max_frames = 500; - const max_unchanged_frames = 15; - await waitForAnimationEnd(() => { + await waitForAnimationEndTimeBased(() => { return window.scrollY + window.visualViewport.offsetTop; - }, max_frames, max_unchanged_frames); + }); assert_approx_equals(window.scrollY, layout_viewport_y, 1); assert_approx_equals(window.visualViewport.offsetTop, visual_viewport_y, 1);
diff --git a/third_party/blink/web_tests/fast/scroll-snap/snap-to-area-with-fractional-offset.html b/third_party/blink/web_tests/fast/scroll-snap/snap-to-area-with-fractional-offset.html index 9ab7594..e18d550 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/snap-to-area-with-fractional-offset.html +++ b/third_party/blink/web_tests/fast/scroll-snap/snap-to-area-with-fractional-offset.html
@@ -74,11 +74,11 @@ await mouseClickOn(10, 10); await keyPress('ArrowDown'); - await waitForAnimationEnd(() => { return scroller.scrollTop; }, 500, 15); + await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; }); assert_approx_equals(scroller.scrollTop, target_area.offsetTop, 1); await keyPress('ArrowUp'); - await waitForAnimationEnd(() => { return scroller.scrollTop; }, 500, 15); + await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; }); assert_approx_equals(scroller.scrollTop, initial_area.offsetTop, 1); }, "Keyboard scrolling should ignore the current snapped element even when its" + " offset is a fractional number."); @@ -88,11 +88,11 @@ assert_approx_equals(scroller.scrollTop, initial_area.offsetTop, 1); scroller.scrollBy(0, 10); - await waitForAnimationEnd(() => { return scroller.scrollTop; }, 500, 15); + await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; }); assert_approx_equals(scroller.scrollTop, target_area.offsetTop, 1); scroller.scrollBy(0, -10); - await waitForAnimationEnd(() => { return scroller.scrollTop; }, 500, 15); + await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; }); assert_approx_equals(scroller.scrollTop, initial_area.offsetTop, 1); }, "Programmatic directional scrolling should ignore the current snapped element" + " even when its offset is a fractional number.");
diff --git a/third_party/blink/web_tests/fast/scroll-snap/snap-to-target-on-layout-change.html b/third_party/blink/web_tests/fast/scroll-snap/snap-to-target-on-layout-change.html index 3818aec..ca972c3b 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/snap-to-target-on-layout-change.html +++ b/third_party/blink/web_tests/fast/scroll-snap/snap-to-target-on-layout-change.html
@@ -86,7 +86,7 @@ await mouseClickOn(10, 10); await wheelScroll(250 /* pixels to scroll */, 50, 50, 'down'); - await waitForAnimationEnd(() => { return scroller.scrollTop; }, 500, 15); + await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; }); assert_approx_equals(scroller.scrollTop, 400, 1); target_area.style.setProperty('top', '600px'); @@ -99,7 +99,7 @@ await mouseClickOn(10, 10); await keyPress('ArrowDown'); - await waitForAnimationEnd(() => { return scroller.scrollTop; }, 500, 15); + await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; }); assert_equals(scroller.scrollTop, 400); target_area.style.setProperty('top', '600px'); @@ -112,7 +112,7 @@ await mouseClickOn(10, 10); await touchScroll(250 /* delta */, 400, 400, 'down'); - await waitForAnimationEnd(() => { return scroller.scrollTop; }, 500, 15); + await waitForAnimationEndTimeBased(() => { return scroller.scrollTop; }); assert_equals(scroller.scrollTop, 400); target_area.style.setProperty('top', '600px');
diff --git a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-keyboard-scrolling-rtl.html b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-keyboard-scrolling-rtl.html index b2e0a3c..cca737e 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-keyboard-scrolling-rtl.html +++ b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-keyboard-scrolling-rtl.html
@@ -67,7 +67,7 @@ await mouseClickOn(510, 10); scroller.scrollTo(-615, 0); await keyPress("ArrowRight"); - await waitForAnimationEnd(scrollLeft, 500, 15); + await waitForAnimationEndTimeBased(scrollLeft); // The left border of #right is at -width. // The right border of #right is thus 200 - width. // When right-aligned, the scroll position should be 200 - width. @@ -78,7 +78,7 @@ await mouseClickOn(510, 10); scroller.scrollTo(-215, 0); await keyPress("ArrowLeft"); - await waitForAnimationEnd(scrollLeft, 500, 15); + await waitForAnimationEndTimeBased(scrollLeft); // The left border of #left is at -(400 + width). // The right border of #left is thus -(200 + width). // When right-aligned, the scroll position should be -(200 + width).
diff --git a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-keyboard-scrolling.html b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-keyboard-scrolling.html index 5890394..0068904ed 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-keyboard-scrolling.html +++ b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-keyboard-scrolling.html
@@ -41,7 +41,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 0); await keyPress("ArrowDown"); - await waitForAnimationEnd(scrollTop, 500, 15); + await waitForAnimationEndTimeBased(scrollTop); assert_equals(scroller.scrollTop, 400); }, "Snaps to bottom-left after pressing ArrowDown"); @@ -49,7 +49,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 400); await keyPress("ArrowUp"); - await waitForAnimationEnd(scrollTop, 500, 15); + await waitForAnimationEndTimeBased(scrollTop); assert_equals(scroller.scrollTop, 0); }, "Snaps to top-left after pressing ArrowUp"); @@ -57,7 +57,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 0); await keyPress("ArrowRight"); - await waitForAnimationEnd(scrollLeft, 500, 15); + await waitForAnimationEndTimeBased(scrollLeft); assert_equals(scroller.scrollLeft, 400); }, "Snaps to top-right after pressing ArrowRight"); @@ -65,7 +65,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(400, 0); await keyPress("ArrowLeft"); - await waitForAnimationEnd(scrollLeft, 500, 15); + await waitForAnimationEndTimeBased(scrollLeft); assert_equals(scroller.scrollLeft, 0); }, "Snaps to top-left after pressing ArrowLeft"); @@ -78,7 +78,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 0); await keyPress("ArrowRight"); - await waitForAnimationEnd(scrollLeft, 500, 15); + await waitForAnimationEndTimeBased(scrollLeft); assert_between_exclusive(scroller.scrollLeft, 0, 500); topLeft.style.width = ""; topRight.style.left = "400px"; @@ -94,7 +94,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 0); await keyPress("ArrowRight"); - await waitForAnimationEnd(scrollLeft, 500, 15); + await waitForAnimationEndTimeBased(scrollLeft); assert_equals(scroller.scrollLeft, 20); topLeft.style.width = ""; topRight.style.left = "400px"; @@ -106,7 +106,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(400, 0); await keyPress("ArrowRight"); - await waitForAnimationEnd(scrollLeft, 500, 15); + await waitForAnimationEndTimeBased(scrollLeft); assert_equals(scroller.scrollLeft, 400); }, "If there is no valid snap offset on the arrow key's direction other than " + "the current offset, and the scroll-snap-type is mandatory, stay at the " @@ -117,7 +117,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(400, 0); await keyPress("ArrowRight"); - await waitForAnimationEnd(scrollLeft, 500, 15); + await waitForAnimationEndTimeBased(scrollLeft); assert_greater_than(scroller.scrollLeft, 400); scroller.style.scrollSnapType = "both mandatory"; }, "If there is no valid snap offset on the arrow key's direction other than "
diff --git a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-scrollbar-scrolling.html b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-scrollbar-scrolling.html index 6788ce9..da3c367 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-scrollbar-scrolling.html +++ b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-scrollbar-scrolling.html
@@ -26,7 +26,7 @@ promise_test (async () => { scroller.scrollTo(0, 0); await mouseDragAndDrop(398, 20, 398, 120); - await waitForAnimationEnd(scrollTop, 500, 5); + await waitForAnimationEndTimeBased(scrollTop); await waitFor( () => { return scroller.scrollTop == 400; }); @@ -35,7 +35,7 @@ promise_test (async () => { scroller.scrollTo(0, 0); await mouseDragAndDrop(20, 398, 120, 398); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); await waitFor( () => { return scroller.scrollLeft == 400; }); @@ -44,7 +44,7 @@ promise_test (async () => { scroller.scrollTo(0, 0); await mousePressOn(398, 350, 1000); - await waitForAnimationEnd(scrollTop, 500, 5); + await waitForAnimationEndTimeBased(scrollTop); await waitFor( () => { return scroller.scrollTop == 400; }); @@ -53,7 +53,7 @@ promise_test (async () => { scroller.scrollTo(0, 0); await mousePressOn(350, 398, 1000); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); await waitFor( () => { return scroller.scrollLeft == 400; }); @@ -62,7 +62,7 @@ promise_test (async () => { scroller.scrollTo(0, 0); await touchTapOn(398, 350, 1000); - await waitForAnimationEnd(scrollTop, 500, 5); + await waitForAnimationEndTimeBased(scrollTop); await waitFor( () => { return scroller.scrollTop == 400; }); @@ -71,7 +71,7 @@ promise_test (async () => { scroller.scrollTo(0, 0); await touchTapOn(350, 398, 1000); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); await waitFor( () => { return scroller.scrollLeft == 400; });
diff --git a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-touchpad-scrolling.html b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-touchpad-scrolling.html index c3e8ea9..2d01723 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-touchpad-scrolling.html +++ b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-touchpad-scrolling.html
@@ -56,7 +56,7 @@ t.add_cleanup(cleanup); // scroll just 10px so the current snap point remains closest. await touchpadScroll(10 /* pixels to scroll */, 50, 50, 'right'); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 0, 1); }, "Touchpad scrolling (right) should prefer the closest snap area regardless" + " of scroll direction."); @@ -69,7 +69,7 @@ // Scroll passed the last snap point. await touchpadScroll(10 /* pixels to scroll */, 50, 50, 'left'); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 120, 1); }, "Touchpad scrolling (left) should prefer the closest snap area regardless of" + " scroll direction."); @@ -79,7 +79,7 @@ t.add_cleanup(cleanup); // Scroll so we pass the second snap point and a closest to third. await touchpadScroll(220 /* pixels to scroll */, 50, 50, 'right'); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 240, 1); }, "Touchpad scrolling should prefer the closest snap point in scroll to the" + " scroll end position.");
diff --git a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-wheel-scrolling.html b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-wheel-scrolling.html index 47b9f22..74c7a69 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/snaps-after-wheel-scrolling.html +++ b/third_party/blink/web_tests/fast/scroll-snap/snaps-after-wheel-scrolling.html
@@ -59,7 +59,7 @@ t.add_cleanup(cleanup); // scroll just 10px so the current snap point remains closest. await wheelScroll(10 /* pixels to scroll */, 50, 50, 'right'); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 120, 1); }, "Wheel scrolling (right) should prefer the next snap point in scroll" + " direction not the closest."); @@ -69,7 +69,7 @@ // Scroll just 1px so the current snap point remains closest. await wheelScroll(10 /* pixels to scroll */, 50, 50, 'left'); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 0, 1); }, "Wheel scrolling (left) should prefer the next snap point in scroll" + " direction not the closest."); @@ -78,7 +78,7 @@ t.add_cleanup(cleanup); // Scroll so we pass the second snap point. await wheelScroll(140 /* pixels to scroll */, 50, 50, 'right'); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 240, 1); }, "Wheel scrolling should prefer the next snap point in scroll" + " direction from scroll end position and not the scroll start position."); @@ -87,7 +87,7 @@ t.add_cleanup(cleanup); // Scroll passed the last snap point. await wheelScroll(200 /* pixels to scroll */, 50, 50, 'right'); - await waitForAnimationEnd(scrollLeft, 500, 5); + await waitForAnimationEndTimeBased(scrollLeft); assert_approx_equals(scroller.scrollLeft, 240, 1); }, "Wheel scrolling should prefer the closest scroll offset in the opposite" + " direction when there is no snap point in the scroll direction.");
diff --git a/third_party/blink/web_tests/fast/scroll-snap/snaps-for-different-key-granularity.html b/third_party/blink/web_tests/fast/scroll-snap/snaps-for-different-key-granularity.html index a3fb734..8983677 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/snaps-for-different-key-granularity.html +++ b/third_party/blink/web_tests/fast/scroll-snap/snaps-for-different-key-granularity.html
@@ -69,7 +69,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 0); await keyPress("ArrowDown"); - await waitForAnimationEnd(scrollTop, 500, 15); + await waitForAnimationEndTimeBased(scrollTop); assert_equals(scroller.scrollTop, 200); }, "Snaps to page1-line1 after pressing ArrowDown at page1."); @@ -77,7 +77,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 1200); await keyPress("ArrowUp"); - await waitForAnimationEnd(scrollTop, 500, 15); + await waitForAnimationEndTimeBased(scrollTop); assert_equals(scroller.scrollTop, 1000); }, "Snaps to page2-line2 after pressing ArrowUp at page3."); @@ -85,7 +85,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 0); await keyPress("PageDown"); - await waitForAnimationEnd(scrollTop, 500, 15); + await waitForAnimationEndTimeBased(scrollTop); assert_equals(scroller.scrollTop, 600); }, "Snaps to page2 after pressing PageDown at page1."); @@ -93,7 +93,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 1200); await keyPress("PageUp"); - await waitForAnimationEnd(scrollTop, 500, 15); + await waitForAnimationEndTimeBased(scrollTop); assert_equals(scroller.scrollTop, 600); }, "Snaps to page2 after pressing PageUp at page3."); @@ -101,7 +101,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 0); await keyPress("End"); - await waitForAnimationEnd(scrollTop, 500, 15); + await waitForAnimationEndTimeBased(scrollTop); assert_equals(scroller.scrollTop, 1200); }, "Snaps to page3 after pressing End at page1."); @@ -109,7 +109,7 @@ await mouseClickOn(10, 10); scroller.scrollTo(0, 1200); await keyPress("Home"); - await waitForAnimationEnd(scrollTop, 500, 15); + await waitForAnimationEndTimeBased(scrollTop); assert_equals(scroller.scrollTop, 0); }, "Snaps to page1 after pressing Home at page3."); </script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/fast/scrolling/wheel-scroll-latching-on-scrollbar.html b/third_party/blink/web_tests/fast/scrolling/wheel-scroll-latching-on-scrollbar.html new file mode 100644 index 0000000..d5e6c4a --- /dev/null +++ b/third_party/blink/web_tests/fast/scrolling/wheel-scroll-latching-on-scrollbar.html
@@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<script src='../../resources/gesture-util.js'></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<style> + + body { + margin: 0px; + height: 100px; + width: 100px; + } + #parentDiv { + background-color: #FF7F7F; + height: 100px; + width: 100px; + overflow: scroll; + } + #content1 { + height: 120px; + width: 120px; + } + #childDiv { + background-color: #84BE6A; + height: 80px; + width: 80px; + overflow: scroll; + } + #content2 { + height: 100px; + width: 100px; + } +</style> + +<div id="parentDiv"> + <div id="content1"> + <div id="childDiv"> + <div id="content2"> + </div> + </div> + </div> +</div> + +<script> +var childDiv = document.getElementById('childDiv'); +var parentDiv = document.getElementById('parentDiv'); +var rect = childDiv.getBoundingClientRect(); +const GESTURE_SOURCE_TYPE = GestureSourceType.MOUSE_INPUT; + +promise_test(async t => { + await smoothScroll(1000, rect.right - 5, rect.bottom - 25, GESTURE_SOURCE_TYPE, 'down', 4000); + await waitForAnimationEndTimeBased( () => { return childDiv.scrollTop; } ); + await waitForAnimationEndTimeBased( () => { return parentDiv.scrollTop; } ); + + assert_equals(childDiv.scrollTop, childDiv.scrollHeight - childDiv.clientHeight, + "childDiv must be fully scrolled"); + assert_equals(parentDiv.scrollTop, 0, "parentDiv shouldn't scroll at all"); +}, "Scrolling on scrollbar of the child div doesn't propagate to the parent."); + +</script>
diff --git a/third_party/blink/web_tests/hid/hidDevice_deviceInfo.html b/third_party/blink/web_tests/hid/hidDevice_deviceInfo.html index 7f18408..66c515b 100644 --- a/third_party/blink/web_tests/hid/hidDevice_deviceInfo.html +++ b/third_party/blink/web_tests/hid/hidDevice_deviceInfo.html
@@ -106,8 +106,6 @@ assert_equals(d.collections.length, 1, 'device.collections.length'); const c = d.collections[0]; - assert_true(c instanceof HIDCollectionInfo, - 'collection instanceof HIDCollectionInfo'); assert_equals(c.usagePage, device.mojom.PAGE_GENERIC_DESKTOP, 'collection.usagePage'); assert_equals(c.usage, device.mojom.GENERIC_DESKTOP_GAME_PAD, @@ -118,13 +116,10 @@ assert_equals(c.featureReports.length, 0, 'collection.featureReports.length'); const r = c.inputReports[0]; - assert_true(r instanceof HIDReportInfo, 'report instanceof HIDReportInfo'); assert_equals(r.reportId, kTestReportId, 'report.reportId'); assert_equals(r.items.length, 1, 'report.items.length'); const i = r.items[0]; - assert_true(i instanceof HIDReportItem, - 'reportItem instanceof HIDReportItem'); assert_true(i.isAbsolute, 'reportItem.isAbsolute'); assert_false(i.isArray, 'reportItem.isArray'); assert_false(i.isRange, 'reportItem.isRange'); @@ -153,7 +148,7 @@ assert_equals(i.logicalMaximum, 1, 'reportItem.logicalMaximum'); assert_equals(i.physicalMinimum, 0, 'reportItem.physicalMinimum'); assert_equals(i.physicalMaximum, 1, 'reportItem.physicalMaximum'); - assert_equals(i.strings.length, 0, 'reportItem.strings.length'); + // TODO(mattreynolds): Check i.strings.length. }, 'HIDDevice preserves device info'); hid_test(async (t, fake) => { @@ -180,17 +175,12 @@ assert_equals(d.collections.length, 1, 'device.collections.length'); const c = d.collections[0]; - assert_true(c instanceof HIDCollectionInfo, - 'collection instanceof HIDCollectionInfo'); assert_equals(c.inputReports.length, 1, 'collection.inputReports.length'); const r = c.inputReports[0]; - assert_true(r instanceof HIDReportInfo, 'report instanceof HIDReportInfo'); assert_equals(r.items.length, 1, 'report.items.length'); const i = r.items[0]; - assert_true(i instanceof HIDReportItem, - 'reportItem instanceof HIDReportItem'); assert_equals(i.unitExponent, -4, 'reportItem.unitExponent'); assert_equals(i.unitSystem, 'si-linear', 'reportItem.unitSystem'); assert_equals(i.unitFactorLengthExponent, 1,
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/elements-child-node-count-mismatch.js b/third_party/blink/web_tests/http/tests/devtools/elements/elements-child-node-count-mismatch.js index 6432df8..489d054b 100644 --- a/third_party/blink/web_tests/http/tests/devtools/elements/elements-child-node-count-mismatch.js +++ b/third_party/blink/web_tests/http/tests/devtools/elements/elements-child-node-count-mismatch.js
@@ -32,7 +32,7 @@ function afterExpand() { ElementsTestRunner.selectNodeWithId('body', node => { - const treeElement = node[treeOutline.treeElementSymbol()]; + const treeElement = treeOutline.treeElementByNode.get(node); TestRunner.addResult(`AFTER EXPAND: TreeElement childCount: ${treeElement.childCount()}`); var selectedElement = treeOutline.selectedTreeElement;
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/move-node.js b/third_party/blink/web_tests/http/tests/devtools/elements/move-node.js index 5a81e0f..3e16ef34a 100644 --- a/third_party/blink/web_tests/http/tests/devtools/elements/move-node.js +++ b/third_party/blink/web_tests/http/tests/devtools/elements/move-node.js
@@ -43,8 +43,8 @@ var child2 = ElementsTestRunner.expandedNodeWithId('child2'); var child4 = ElementsTestRunner.expandedNodeWithId('child4'); - treeOutline._treeElementBeingDragged = child2[treeOutline._treeElementSymbol]; - var treeElementToDropOn = child4[treeOutline._treeElementSymbol]; + treeOutline._treeElementBeingDragged = treeOutline.treeElementByNode.get(child2); + var treeElementToDropOn = treeOutline.treeElementByNode.get(child4); treeOutline._doMove(treeElementToDropOn); } ]);
diff --git a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 024498d1..590316cd 100644 --- a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1284,6 +1284,8 @@ getter actualBoundingBoxDescent getter actualBoundingBoxLeft getter actualBoundingBoxRight + getter fontBoundingBoxAscent + getter fontBoundingBoxDescent getter width method constructor interface TransformStream
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt index 9e63fad3..f3bec20 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -1172,6 +1172,8 @@ [Worker] getter actualBoundingBoxDescent [Worker] getter actualBoundingBoxLeft [Worker] getter actualBoundingBoxRight +[Worker] getter fontBoundingBoxAscent +[Worker] getter fontBoundingBoxDescent [Worker] getter width [Worker] method constructor [Worker] interface TransformStream
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index a586eda..4eb748b5 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -7281,6 +7281,8 @@ getter actualBoundingBoxDescent getter actualBoundingBoxLeft getter actualBoundingBoxRight + getter fontBoundingBoxAscent + getter fontBoundingBoxDescent getter width method constructor interface TextTrack : EventTarget
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt index e02bd7a..6b2a8588 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -1172,6 +1172,8 @@ [Worker] getter actualBoundingBoxDescent [Worker] getter actualBoundingBoxLeft [Worker] getter actualBoundingBoxRight +[Worker] getter fontBoundingBoxAscent +[Worker] getter fontBoundingBoxDescent [Worker] getter width [Worker] method constructor [Worker] interface TransformStream
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index d7e794fa..1345127e 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -2630,15 +2630,6 @@ method requestDevice setter onconnect setter ondisconnect -interface HIDCollectionInfo - attribute @@toStringTag - getter children - getter featureReports - getter inputReports - getter outputReports - getter usage - getter usagePage - method constructor interface HIDConnectionEvent : Event attribute @@toStringTag getter device @@ -2664,36 +2655,6 @@ getter device getter reportId method constructor -interface HIDReportInfo - attribute @@toStringTag - getter items - getter reportId - method constructor -interface HIDReportItem - attribute @@toStringTag - getter hasNull - getter isAbsolute - getter isArray - getter isRange - getter logicalMaximum - getter logicalMinimum - getter physicalMaximum - getter physicalMinimum - getter reportCount - getter reportSize - getter strings - getter unitExponent - getter unitFactorCurrentExponent - getter unitFactorLengthExponent - getter unitFactorLuminousIntensityExponent - getter unitFactorMassExponent - getter unitFactorTemperatureExponent - getter unitFactorTimeExponent - getter unitSystem - getter usageMaximum - getter usageMinimum - getter usages - method constructor interface HTMLAllCollection attribute @@toStringTag getter length
diff --git a/tools/ipc_fuzzer/message_replay/DEPS b/tools/ipc_fuzzer/message_replay/DEPS index 9af6d1d..339661b 100644 --- a/tools/ipc_fuzzer/message_replay/DEPS +++ b/tools/ipc_fuzzer/message_replay/DEPS
@@ -4,5 +4,4 @@ "+content/public/common", "+mojo/core/embedder", "+mojo/public", - "+services/service_manager/embedder", ]
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 011a3e5..57004a75 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -24670,6 +24670,7 @@ <int value="1509" label="PASSWORDSPRIVATE_GETWEAKCREDENTIALS"/> <int value="1510" label="ACCESSIBILITY_PRIVATE_MOVEMAGNIFIERTORECT"/> <int value="1511" label="FILEMANAGERPRIVATE_SINGLEPARTITIONFORMAT"/> + <int value="1512" label="TABS_REMOVECSS"/> </enum> <enum name="ExtensionIconState"> @@ -61674,8 +61675,9 @@ <enum name="RelaunchNotificationShowResult"> <int value="0" label="Shown"/> - <int value="1" label="Not shown for unknown reason"/> - <int value="2" label="Not shown due to background mode with no windows"/> + <int value="1" label="Not shown for unknown reason (deprecated)"/> + <int value="2" + label="Not shown due to background mode with no windows (deprecated)"/> </enum> <enum name="RemoteBookmarkUpdateError"> @@ -76623,7 +76625,7 @@ <int value="-529697949" label="EH_EXCEPTION_NUMBER"/> <int value="-36863" label="0xFFFF7001 - Crashpad kCrashExitCodeNoDump."/> <int value="-36862" label="0xFFFF7002 - Crashpad kFailedTerminationCode."/> - <int value="0" label="service_manager::RESULT_CODE_NORMAL_EXIT"/> + <int value="0" label="content::RESULT_CODE_NORMAL_EXIT"/> <int value="1" label="content::RESULT_CODE_KILLED"/> <int value="2" label="content::RESULT_CODE_HUNG"/> <int value="3" label="content::RESULT_CODE_KILLED_BAD_MESSAGE"/>
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml index 0c1a03c..5357b45 100644 --- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -11132,6 +11132,7 @@ <suffix name="kaleidoscope" label="Module ID for Kaleidoscope"/> <suffix name="shopping_tasks" label="Module ID for Shopping Tasks"/> <affected-histogram name="NewTabPage.Modules.Impression"/> + <affected-histogram name="NewTabPage.Modules.Loaded"/> <affected-histogram name="NewTabPage.Modules.Usage"/> </histogram_suffixes>
diff --git a/tools/metrics/histograms/histograms_xml/media/histograms.xml b/tools/metrics/histograms/histograms_xml/media/histograms.xml index 791b26a..16e352d26 100644 --- a/tools/metrics/histograms/histograms_xml/media/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/media/histograms.xml
@@ -497,6 +497,18 @@ </summary> </histogram> +<histogram name="Media.Audio.RawProcessingSupportedWin" enum="BooleanSupported" + expires_after="2021-09-30"> + <owner>henrika@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Whether the capture device supports raw audio capture or not. Emitted when + the audio input stream is closed but only on Windows platforms. Only + uploaded for the case when analog AGC is enabled, i.e., for WebRTC-based + audio input streams. + </summary> +</histogram> + <histogram name="Media.Audio.Render.FramesRequested" units="frames" expires_after="2021-04-05"> <owner>guidou@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml b/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml index 9ae7377..36fe214 100644 --- a/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml
@@ -761,6 +761,17 @@ </summary> </histogram> +<histogram name="NewTabPage.Modules.Loaded" units="ms" + expires_after="2021-01-01"> + <owner>tiborg@chromium.org</owner> + <owner>yyushkina@chromium.org</owner> + <owner>chrome-desktop-ntp@google.com</owner> + <summary> + Histogram of the time, in milliseconds since navigation start, it took until + an NTP module loaded. + </summary> +</histogram> + <histogram name="NewTabPage.Modules.ShownTime" units="ms" expires_after="2021-01-01"> <owner>tiborg@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index 6b1fd5e8..6227ad6 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -5133,6 +5133,17 @@ <summary>Time to retrieve the fallback fonts on the system.</summary> </histogram> +<histogram name="Fonts.AccessAPI.EnumerationCache.DuplicateFontCount" + units="count" expires_after="M90"> + <owner>oyiptong@chromium.org</owner> + <owner>storage-dev@chromium.org</owner> + <summary> + The number of duplicate fonts returned by system APIs. This is recorded when + fonts are enumerated to be returned to script as a result of a call to the + Font Access API. + </summary> +</histogram> + <histogram name="Fonts.AccessAPI.EnumerationCache.Dwrite.FamilyCount" units="families" expires_after="M90"> <owner>oyiptong@chromium.org</owner> @@ -5171,6 +5182,10 @@ <histogram name="Fonts.AccessAPI.EnumerationCache.Fontconfig.DuplicateFontCount" units="count" expires_after="M90"> + <obsolete> + Removed in M86 in favor of + Fonts.AccessAPI.EnumerationCache.DuplicateFontCount. + </obsolete> <owner>oyiptong@chromium.org</owner> <owner>storage-dev@chromium.org</owner> <summary>The number of duplicate fonts returned by fontconfig.</summary> @@ -5493,6 +5508,30 @@ </summary> </histogram> +<histogram name="Graphics.Smoothness.Diagnostic.ReadSharedMemoryDuration" + units="microseconds" expires_after="2021-09-01"> + <owner>sadrul@chromium.org</owner> + <owner>behdadb@chromium.org</owner> + <summary> + Diagnostic metric to track how long it takes to read the smoothness data + from shared memory. + + Warning: This metric may include reports from clients with low-resolution + clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports + will cause this metric to have an abnormal distribution. + </summary> +</histogram> + +<histogram name="Graphics.Smoothness.Diagnostic.ReadSharedMemoryUKMSuccess" + units="boolean" expires_after="2021-09-01"> + <owner>sadrul@chromium.org</owner> + <owner>fangzhoug@chromium.org</owner> + <summary> + Diagnostic metric to track how often reading the smoothness data for UKM + from the shared memory (using atomic memcpy) fails (or succeeds). + </summary> +</histogram> + <histogram name="Graphics.Smoothness.FrameSequenceLength" units="count" expires_after="2021-02-07"> <owner>sadrul@chromium.org</owner> @@ -11185,7 +11224,8 @@ </histogram> <histogram base="true" name="RelaunchNotification.ShowResult" - enum="RelaunchNotificationShowResult" expires_after="M85"> + enum="RelaunchNotificationShowResult" expires_after="M90"> + <owner>ayaelattar@chromium.org</owner> <owner>grt@chromium.org</owner> <summary> The result of an attempt to show a relaunch notification dialog.
diff --git a/tools/metrics/histograms/histograms_xml/payment/histograms.xml b/tools/metrics/histograms/histograms_xml/payment/histograms.xml index 510fc01..3fb4d9d 100644 --- a/tools/metrics/histograms/histograms_xml/payment/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/payment/histograms.xml
@@ -22,7 +22,7 @@ <histograms> <histogram name="PaymentRequest.CheckoutFunnel" - enum="PaymentRequestCheckoutFunnelSteps" expires_after="2021-08-01"> + enum="PaymentRequestCheckoutFunnelSteps" expires_after="M90"> <owner>danyao@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> @@ -35,14 +35,14 @@ </histogram> <histogram name="PaymentRequest.CheckoutFunnel.Aborted" - enum="PaymentRequestAbortReason" expires_after="2021-08-01"> + enum="PaymentRequestAbortReason" expires_after="M85"> <owner>danyao@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary>The reason that lead to an abort of the Payment Request.</summary> </histogram> <histogram name="PaymentRequest.CheckoutFunnel.NoShow" - enum="PaymentRequestNoShowReason" expires_after="2021-08-01"> + enum="PaymentRequestNoShowReason" expires_after="2020-05-24"> <owner>danyao@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> @@ -51,7 +51,7 @@ </histogram> <histogram name="PaymentRequest.Events" units="bitfield value" - expires_after="2021-08-01"> + expires_after="2021-01-31"> <owner>danyao@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> @@ -61,8 +61,8 @@ </histogram> <histogram name="PaymentRequest.JourneyLoggerHasRecorded" enum="Boolean" - expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + expires_after="2021-01-31"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> Whether a journey logger has recorded an events bit field or not. @@ -70,8 +70,8 @@ </histogram> <histogram name="PaymentRequest.JourneyLoggerHasRecordedMultipleTimes" - enum="Boolean" expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + enum="Boolean" expires_after="M85"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> When a journey logger attempts to record multiple events bit fields. @@ -79,8 +79,8 @@ </histogram> <histogram name="PaymentRequest.MissingContactFields" - enum="PaymentRequestMissingContactFields" expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + enum="PaymentRequestMissingContactFields" expires_after="2021-03-01"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> A bitfield representing different missing fields of the contact section in @@ -92,8 +92,8 @@ </histogram> <histogram name="PaymentRequest.MissingPaymentFields" - enum="PaymentRequestMissingPaymentFields" expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + enum="PaymentRequestMissingPaymentFields" expires_after="2021-03-01"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> A bitfield representing different missing fields of the payment info section @@ -105,8 +105,8 @@ </histogram> <histogram name="PaymentRequest.MissingShippingFields" - enum="PaymentRequestMissingShippingFields" expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + enum="PaymentRequestMissingShippingFields" expires_after="2021-03-01"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> A bitfield representing different missing fields of the shipping section in @@ -118,7 +118,7 @@ </histogram> <histogram name="PaymentRequest.NumberOfSuggestionsShown" units="units" - expires_after="2021-08-01"> + expires_after="2021-01-24"> <owner>danyao@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> @@ -127,8 +127,8 @@ </histogram> <histogram name="PaymentRequest.RefetchIconForInstalledApp" enum="Boolean" - expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + expires_after="2021-06-24"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> True when chrome crawls to refetch the missing icon of an already installed @@ -138,7 +138,7 @@ <histogram name="PaymentRequest.SecurePaymentConfirmationCredentialIdSizeInBytes" - units="bytes" expires_after="2021-08-01"> + units="bytes" expires_after="M93"> <owner>danyao@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> @@ -148,15 +148,15 @@ </histogram> <histogram name="PaymentRequest.ServiceWorkerStatusCodeTimeout" enum="Boolean" - expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + expires_after="2021-05-24"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary>True when a service worker times out 5 mins after request.</summary> </histogram> <histogram name="PaymentRequest.TimeToCheckout.Completed" units="ms" - expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + expires_after="2021-01-31"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> Records the time between a payment request .show() and its completion. @@ -164,10 +164,10 @@ </histogram> <histogram name="PaymentRequest.TimeToCheckout.Completed.Shown" units="ms" - expires_after="2021-08-01"> + expires_after="2021-01-31"> <!-- Name completed by histogram_suffixes name="PaymentRequestCompletedInstrument" --> - <owner>danyao@chromium.org</owner> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> Records the time between a payment request .show() and its completion when @@ -176,10 +176,10 @@ </histogram> <histogram name="PaymentRequest.TimeToCheckout.Completed.SkippedShow" - units="ms" expires_after="2021-08-01"> + units="ms" expires_after="2021-01-31"> <!-- Name completed by histogram_suffixes name="PaymentRequestCompletedInstrument" --> - <owner>danyao@chromium.org</owner> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> Records the time between a payment request .show() and its completion when @@ -188,8 +188,8 @@ </histogram> <histogram name="PaymentRequest.TimeToCheckout.OtherAborted" units="ms" - expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + expires_after="2021-01-31"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> Records the time between a payment request .show() and its termination by @@ -198,10 +198,10 @@ </histogram> <histogram name="PaymentRequest.TimeToCheckout.UserAborted" units="ms" - expires_after="2021-08-01"> + expires_after="2021-01-31"> <!-- Name completed by histogram_suffixes name="PaymentRequestPaymentSheetShowStatus" --> - <owner>danyao@chromium.org</owner> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> Records the time between a payment request .show() and its termination by @@ -210,8 +210,8 @@ </histogram> <histogram name="PaymentRequest.TransactionAmount.Completed" - enum="PaymentRequestTransactionSize" expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + enum="PaymentRequestTransactionSize" expires_after="2021-01-24"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> Records the transaction amounts completed using payment request API after @@ -220,8 +220,8 @@ </histogram> <histogram name="PaymentRequest.TransactionAmount.Triggered" - enum="PaymentRequestTransactionSize" expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> + enum="PaymentRequestTransactionSize" expires_after="2021-01-31"> + <owner>sahel@chromium.org</owner> <owner>web-payments-team@google.com</owner> <summary> Records the transaction amounts triggered using payment request API after
diff --git a/tools/metrics/histograms/histograms_xml/service/histograms.xml b/tools/metrics/histograms/histograms_xml/service/histograms.xml index 799de5b..9fd509f0 100644 --- a/tools/metrics/histograms/histograms_xml/service/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/service/histograms.xml
@@ -22,9 +22,8 @@ <histograms> <histogram name="ServiceWorker.AbortPaymentEvent.Time" units="ms" - expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> - <owner>web-payments-team@google.com</owner> + expires_after="M85"> + <owner>nhiroki@chromium.org</owner> <owner>jinho.bang@samsung.com</owner> <summary> The time taken between dispatching an AbortPaymentEvent to a Service Worker @@ -170,9 +169,8 @@ </histogram> <histogram name="ServiceWorker.CanMakePaymentEvent.Time" units="ms" - expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> - <owner>web-payments-team@google.com</owner> + expires_after="2020-04-19"> + <owner>nhiroki@chromium.org</owner> <owner>jinho.bang@samsung.com</owner> <summary> The time taken between dispatching an CanMakePaymentEvent to a Service @@ -663,9 +661,8 @@ </histogram> <histogram name="ServiceWorker.PaymentRequestEvent.Time" units="ms" - expires_after="2021-08-01"> - <owner>danyao@chromium.org</owner> - <owner>web-payments-team@google.com</owner> + expires_after="M81"> + <owner>nhiroki@chromium.org</owner> <owner>jinho.bang@samsung.com</owner> <summary> The time taken between dispatching an PaymentRequestEvent to a Service
diff --git a/tools/metrics/histograms/histograms_xml/windows/histograms.xml b/tools/metrics/histograms/histograms_xml/windows/histograms.xml index 73b95f57..727b22f 100644 --- a/tools/metrics/histograms/histograms_xml/windows/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/windows/histograms.xml
@@ -292,6 +292,22 @@ </summary> </histogram> +<histogram name="Windows.TouchDrag.Success" units="BooleanSuccess" + expires_after="2021-03-01"> + <owner>davidbienvenu@chromium.org</owner> + <owner>dfried@chromium.org</owner> + <summary> + Recorded each time the user starts a Windows touch drag drop of web + contents. This is currently only used by the WebUI tab strip, where touch + drag drop is enabled, to count the number of touch drags attempted. + ::DoDragDrop occasionally blocks waiting for a right mouse button down + followed by a move, which is detected by ::DoDragDrop not calling + QueryContinueDrag for more than a second. This will be recorded as false. + This stat will be used to determine how much of a real world problem this + is. + </summary> +</histogram> + </histograms> </histogram-configuration>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index e46eb54..02fb90b 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -4687,6 +4687,78 @@ </metric> </event> +<event name="Graphics.Smoothness.NormalizedPercentDroppedFrames" + singular="True"> + <owner>animations-dev@chromium.org</owner> + <owner>sadrul@chromium.org</owner> + <summary> + Measures various normalizations for the smoothness metric. The metric is + measured by counting dropped frames, and various normalization strategies + are used. + + The metric is reported once per page-load, and when the page closes (e.g. + the user closes the tab, or navigates away to a different page). + </summary> + <metric name="AboveThreshold"> + <summary> + The number of fixed-duration sliding windows (as a percentage) where the + number of dropped frames are above a threshold. The specific threshold is + yet to be determined. + </summary> + <aggregation> + <history> + <index fields="profile.country"/> + <statistics> + <quantiles type="std-percentiles"/> + </statistics> + </history> + </aggregation> + </metric> + <metric name="Average"> + <summary> + This is trivially computable by counting the total number of dropped + frames and the total number of vsyncs the page has been visible for, + exposed as a percentage. + </summary> + <aggregation> + <history> + <index fields="profile.country"/> + <statistics> + <quantiles type="std-percentiles"/> + </statistics> + </history> + </aggregation> + </metric> + <metric name="Percentile95"> + <summary> + The 95-th percentile dropped frames within a fixed-duration sliding window + (as a percentage). + </summary> + <aggregation> + <history> + <index fields="profile.country"/> + <statistics> + <quantiles type="std-percentiles"/> + </statistics> + </history> + </aggregation> + </metric> + <metric name="WorstCase"> + <summary> + The maximum number of dropped frames (as a percentage) within a + fixed-duration sliding window. + </summary> + <aggregation> + <history> + <index fields="profile.country"/> + <statistics> + <quantiles type="std-percentiles"/> + </statistics> + </history> + </aggregation> + </metric> +</event> + <event name="Graphics.Smoothness.PercentDroppedFrames"> <owner>animations-dev@chromium.org</owner> <owner>sadrul@chromium.org</owner>
diff --git a/ui/base/dragdrop/drag_source_win.cc b/ui/base/dragdrop/drag_source_win.cc index c274091..e02b9374 100644 --- a/ui/base/dragdrop/drag_source_win.cc +++ b/ui/base/dragdrop/drag_source_win.cc
@@ -16,6 +16,7 @@ } HRESULT DragSourceWin::QueryContinueDrag(BOOL escape_pressed, DWORD key_state) { + num_query_continues_++; if (cancel_drag_) return DRAGDROP_S_CANCEL;
diff --git a/ui/base/dragdrop/drag_source_win.h b/ui/base/dragdrop/drag_source_win.h index 466ec96..dc37c8ea 100644 --- a/ui/base/dragdrop/drag_source_win.h +++ b/ui/base/dragdrop/drag_source_win.h
@@ -42,6 +42,10 @@ cancel_drag_ = true; } + // This is used to tell if the drag drop actually started, for generating + // a BooleanSuccess histogram. + int num_query_continues() const { return num_query_continues_; } + // IDropSource implementation: HRESULT __stdcall QueryContinueDrag(BOOL escape_pressed, DWORD key_state) override; @@ -63,6 +67,12 @@ const OSExchangeData* data_; + // The number of times for this drag that Windows asked if the drag should + // continue. This is used in DesktopDragDropClientWin::StartDragAndDrop to + // detect if touch drag drop started successfully. See comment there for much + // more info. + int num_query_continues_ = 0; + DISALLOW_COPY_AND_ASSIGN(DragSourceWin); };
diff --git a/ui/base/ime/chromeos/extension_ime_util.cc b/ui/base/ime/chromeos/extension_ime_util.cc index 98c5536..8cac3adc 100644 --- a/ui/base/ime/chromeos/extension_ime_util.cc +++ b/ui/base/ime/chromeos/extension_ime_util.cc
@@ -173,15 +173,5 @@ return false; } -bool IsLanguageForArcIME(const std::string& language) { - return language == kArcImeLanguage; -} - -std::string MaybeGetLegacyXkbId(const std::string& input_method_id) { - if (IsKeyboardLayoutExtension(input_method_id)) - return GetComponentIDByInputMethodID(input_method_id); - return input_method_id; -} - } // namespace extension_ime_util } // namespace chromeos
diff --git a/ui/base/ime/chromeos/extension_ime_util.h b/ui/base/ime/chromeos/extension_ime_util.h index 380cfa8..a81c488 100644 --- a/ui/base/ime/chromeos/extension_ime_util.h +++ b/ui/base/ime/chromeos/extension_ime_util.h
@@ -88,35 +88,18 @@ bool COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) IsArcIME(const std::string& input_method_id); -// Returns true if the |input_method| is a member of |extension_id| of extension -// IME, otherwise returns false. -bool COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) - IsMemberOfExtension(const std::string& input_method_id, - const std::string& extension_id); - // Returns true if the |input_method_id| is the extension based xkb keyboard, // otherwise returns false. bool COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) IsKeyboardLayoutExtension(const std::string& input_method_id); -// Returns true if |language| is the fake one for ARC IMEs. -bool COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) - IsLanguageForArcIME(const std::string& language); - // Returns input method component id from the extension-based InputMethodID // for component IME extensions. This function does not check that // |input_method_id| is installed. std::string COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) GetComponentIDByInputMethodID(const std::string& input_method_id); -// Gets legacy xkb id (e.g. xkb:us::eng) from the new extension based xkb id -// (e.g. _comp_ime_...xkb:us::eng). If the given id is not prefixed with -// 'xkb:', just return the same as the given id. -std::string COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) - MaybeGetLegacyXkbId(const std::string& input_method_id); - } // namespace extension_ime_util - } // namespace chromeos #endif // UI_BASE_IME_CHROMEOS_EXTENSION_IME_UTIL_H_
diff --git a/ui/base/ime/chromeos/extension_ime_util_unittest.cc b/ui/base/ime/chromeos/extension_ime_util_unittest.cc index 8832e4d..38ee414 100644 --- a/ui/base/ime/chromeos/extension_ime_util_unittest.cc +++ b/ui/base/ime/chromeos/extension_ime_util_unittest.cc
@@ -82,38 +82,4 @@ EXPECT_FALSE(extension_ime_util::IsArcIME("mozc")); } -TEST(ExtensionIMEUtilTest, IsMemberOfExtension) { - const char* extention1 = "abcdefg"; - const char* extention2 = "hijklmn"; - const char* extention3 = "opqrstu"; - const char* engine_id1 = "12345"; - const char* engine_id2 = "67890"; - const char* engine_id3 = "31415"; - - const std::string extention_1_engine_1 = - extension_ime_util::GetInputMethodID(extention1, engine_id1); - const std::string extention_1_engine_2 = - extension_ime_util::GetInputMethodID(extention1, engine_id2); - const std::string component_3_engine_3 = - extension_ime_util::GetComponentInputMethodID(extention3, engine_id3); - - EXPECT_TRUE(extension_ime_util::IsMemberOfExtension(extention_1_engine_1, - extention1)); - EXPECT_TRUE(extension_ime_util::IsMemberOfExtension(extention_1_engine_2, - extention1)); - EXPECT_FALSE(extension_ime_util::IsMemberOfExtension(extention_1_engine_1, - extention2)); - EXPECT_FALSE(extension_ime_util::IsMemberOfExtension(extention_1_engine_2, - extention2)); - EXPECT_FALSE(extension_ime_util::IsMemberOfExtension(component_3_engine_3, - extention3)); -} - -TEST(ExtensionIMEUtilTest, IsLanguageForArcIMETest) { - EXPECT_TRUE(extension_ime_util::IsLanguageForArcIME( - extension_ime_util::kArcImeLanguage)); - EXPECT_FALSE(extension_ime_util::IsLanguageForArcIME( - extension_ime_util::kArcImeLanguage + std::string(" "))); -} - } // namespace chromeos
diff --git a/ui/base/ime/chromeos/input_method_util.cc b/ui/base/ime/chromeos/input_method_util.cc index 7df9b2a..f1e2c1c 100644 --- a/ui/base/ime/chromeos/input_method_util.cc +++ b/ui/base/ime/chromeos/input_method_util.cc
@@ -427,13 +427,21 @@ return disp; } +// Gets legacy xkb id (e.g. xkb:us::eng) from the new extension based xkb id +// (e.g. _comp_ime_...xkb:us::eng). If the given id is not prefixed with +// 'xkb:', just return the same as the given id. +std::string MaybeGetLegacyXkbId(const std::string& input_method_id) { + if (extension_ime_util::IsKeyboardLayoutExtension(input_method_id)) + return extension_ime_util::GetComponentIDByInputMethodID(input_method_id); + return input_method_id; +} + bool InputMethodUtil::TranslateStringInternal( const std::string& english_string, base::string16 *out_string) const { DCHECK(out_string); // |english_string| could be an input method id. So legacy xkb id is required // to get the translated string. - std::string key_string = extension_ime_util::MaybeGetLegacyXkbId( - english_string); + std::string key_string = MaybeGetLegacyXkbId(english_string); auto iter = english_to_resource_id_.find(key_string); if (iter == english_to_resource_id_.end()) {
diff --git a/ui/events/ozone/evdev/event_device_info.cc b/ui/events/ozone/evdev/event_device_info.cc index 8b3a413..e0ffefc4 100644 --- a/ui/events/ozone/evdev/event_device_info.cc +++ b/ui/events/ozone/evdev/event_device_info.cc
@@ -42,7 +42,6 @@ {0x046d, 0xb016}, // Logitech M535 {0x046d, 0xb019}, // Logitech MX Master 2S (Bluetooth) {0x046d, 0xc093}, // Logitech M500s - {0x046d, 0xc534}, // Logitech M185/M187 {0x056e, 0x0134}, // Elecom Enelo IR LED Mouse 350 {0x056e, 0x0141}, // Elecom EPRIM Blue LED 5 button mouse 228 {0x056e, 0x0159}, // Elecom Blue LED Mouse 203
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc index 48a316d..92a9e033a 100644 --- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc +++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_win.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/metrics/histogram_macros.h" #include "base/threading/hang_watcher.h" #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/dragdrop/drag_source_win.h" @@ -72,12 +73,32 @@ // Disable hang watching until the end of the function since the user can take // unbounded time to complete the drag. (http://crbug.com/806174) base::HangWatchScopeDisabled disabler; + base::TimeTicks start_time = base::TimeTicks::Now(); HRESULT result = ::DoDragDrop( ui::OSExchangeDataProviderWin::GetIDataObject(*data.get()), drag_source_.Get(), ui::DragDropTypes::DragOperationToDropEffect(operation), &effect); if (alive && source == ui::mojom::DragEventSource::kTouch) { + // In a normal drag drop, ::DoDragDrop calls QueryContinueDrag every time + // it gets a mouse or keyboard event. The windows doc + // https://docs.microsoft.com/en-us/windows/win32/api/oleidl/nf-oleidl-idropsource-querycontinuedrag + // says "every time it detects a change in keyboard or mouse button state" + // but empirically, on a Yoga laptop with a touch screen running Windows 10, + // it's called when it gets a mouse move event as well. (::DoDragDrop + // doesn't support touch, so Chrome synthesizes mouse events from touch + // events during drag drop.) + // In the touch failure case, when ::DoDragDrop blocks waiting for a right + // mouse button down event to start the drag, it only calls + // QueryContinueDrag once, when it gets an event that terminates the blocked + // drag drop, e.g., a swipe gesture from outside the Chrome window. So, we + // detect the failure case when a drag drop lasts more than one second, and + // QueryContinueDrag was not called more than once. + // See crbug.com/1126230. + UMA_HISTOGRAM_BOOLEAN("Windows.TouchDrag.Success", + drag_source_->num_query_continues() > 1 || + (base::TimeTicks::Now() - start_time < + base::TimeDelta::FromSeconds(1))); desktop_host_->SetInTouchDrag(false); } drag_source_copy->set_data(nullptr);
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn index 641e9be..370eaff 100644 --- a/weblayer/BUILD.gn +++ b/weblayer/BUILD.gn
@@ -463,7 +463,6 @@ "//services/network/public/cpp", "//services/network/public/mojom", "//services/preferences/tracked", - "//services/service_manager/embedder:embedder_result_codes", "//skia", "//third_party/blink/public:blink_headers", "//third_party/blink/public/common",
diff --git a/weblayer/browser/browser_main_parts_impl.cc b/weblayer/browser/browser_main_parts_impl.cc index eb9b363..769fd795 100644 --- a/weblayer/browser/browser_main_parts_impl.cc +++ b/weblayer/browser/browser_main_parts_impl.cc
@@ -20,8 +20,8 @@ #include "content/public/browser/render_process_host.h" #include "content/public/common/main_function_params.h" #include "content/public/common/page_visibility_state.h" +#include "content/public/common/result_codes.h" #include "content/public/common/url_constants.h" -#include "services/service_manager/embedder/result_codes.h" #include "ui/base/resource/resource_bundle.h" #include "weblayer/browser/browser_process.h" #include "weblayer/browser/cookie_settings_factory.h" @@ -140,7 +140,7 @@ } #endif - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } void BrowserMainPartsImpl::PreMainMessageLoopStart() { @@ -171,7 +171,7 @@ BrowserProcess::GetInstance()->GetSharedURLLoaderFactory()); download_manager->set_application_locale(i18n::GetApplicationLocale()); - return service_manager::RESULT_CODE_NORMAL_EXIT; + return content::RESULT_CODE_NORMAL_EXIT; } void BrowserMainPartsImpl::PreMainMessageLoopRun() {
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java index 32f947fb..7a9a730 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java
@@ -28,6 +28,7 @@ private RedirectHandler mRedirectHandler; private InterceptNavigationDelegateImpl mInterceptNavigationDelegate; private long mLastNavigationWithUserGestureTime = RedirectHandler.INVALID_TIME; + private boolean mDestroyed; InterceptNavigationDelegateClientImpl(TabImpl tab) { mTab = tab; @@ -53,6 +54,7 @@ } public void destroy() { + mDestroyed = true; getWebContents().removeObserver(mWebContentsObserver); mInterceptNavigationDelegate.associateWithWebContents(null); } @@ -118,6 +120,11 @@ @Override public void closeTab() { + // When InterceptNavigationDelegate determines that a tab needs to be closed, it posts a + // task invoking this method. It is possible that in the interim the tab was closed for + // another reason. In that case there is nothing more to do here. + if (mDestroyed) return; + closeTab(mTab); }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java index acfbee1..0fb7ca8d 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
@@ -938,6 +938,7 @@ } mInterceptNavigationDelegateClient.destroy(); + mInterceptNavigationDelegateClient = null; mInterceptNavigationDelegate = null; mInfoBarContainer.destroy();