diff --git a/DEPS b/DEPS index b4d7ea51..b52e57d81 100644 --- a/DEPS +++ b/DEPS
@@ -175,7 +175,7 @@ # 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': '7c095dc67ce6145ca1e5a6503f56fc126d700a67', + 'skia_revision': 'c65d0069ec56aa972e1fd18c3d3915db5bad3498', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -187,11 +187,11 @@ # 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': 'fca5a005aa880a51672c091fcb82f084b620670a', + 'angle_revision': '9fac1817ede6b2f1dc61468e2625cbc30d35077c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '59465799210b3f4962af1a9dc44a4ffecb422c10', + 'swiftshader_revision': '10a900e5ffaffdffe2806b1507af43a74acdfe9e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -238,7 +238,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '6043069708e1e7a33d4eda61115ee12d1a808972', + 'catapult_revision': 'c9e75ab1ff4788c19a7b525fe3f35022b2f4a9b6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -246,7 +246,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': '139deb3609b0a58ef3c663c2c993a6b51df28474', + 'devtools_frontend_revision': 'c7539abc143c72521e494589f3784dbea891408c', # 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. @@ -538,7 +538,7 @@ }, 'src/ios/third_party/material_font_disk_loader_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-foundation/material-font-disk-loader-ios.git' + '@' + '93acc021e3034898716028822cb802a3a816be7e', + 'url': Var('chromium_git') + '/external/github.com/material-foundation/material-font-disk-loader-ios.git' + '@' + '8e30188777b016182658fbaa0a4a020a48183224', 'condition': 'checkout_ios', }, @@ -864,7 +864,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '5b94048566ab2a458316af49f35655586fe503b0', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '471dda709844bf3c646cdaefbd522550ad5030b2', 'condition': 'checkout_linux', }, @@ -1282,7 +1282,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f04938adfc40c1ae4425fdc6a70f9b14961146f5', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '7449dc8a7f22156ee7a2bc2157260480938850e1', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1483,7 +1483,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '53655df4cde60b121fc530842ba9a6d5dfec1ae1', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '8ac79125c05256f4b6ad29533b99c7733e5ac219', + Var('webrtc_git') + '/src.git' + '@' + '9d2c2dba28656b3c913797daaf99b8bf56ca6103', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1553,7 +1553,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a2520bfd110b8af07309f81764382cdae38ba213', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@576e75e99e18ccfc3d6ab087bf29d83c8bf697ff', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index e9c965c..3574496 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -102,7 +102,6 @@ #include "services/network/public/mojom/cookie_manager.mojom-forward.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_provider.h" -#include "storage/browser/quota/quota_settings.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle_android.h" @@ -497,15 +496,6 @@ return new AwQuotaPermissionContext; } -void AwContentBrowserClient::GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - storage::GetNominalDynamicSettings( - partition->GetPath(), context->IsOffTheRecord(), - storage::GetDefaultDeviceInfoHelper(), std::move(callback)); -} - content::GeneratedCodeCacheSettings AwContentBrowserClient::GetGeneratedCodeCacheSettings( content::BrowserContext* context) {
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index e329711f..4c8d6fc5 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -84,10 +84,6 @@ content::BrowserContext* context) override; scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) override; content::GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( content::BrowserContext* context) override; void AllowCertificateError(
diff --git a/ash/shell/content/client/shell_content_browser_client.cc b/ash/shell/content/client/shell_content_browser_client.cc index 7a648118..83e5587 100644 --- a/ash/shell/content/client/shell_content_browser_client.cc +++ b/ash/shell/content/client/shell_content_browser_client.cc
@@ -33,13 +33,5 @@ return std::make_unique<ShellBrowserMainParts>(parameters); } -void ShellContentBrowserClient::GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - // This should not be called in ash content environment. - CHECK(false); -} - } // namespace shell } // namespace ash
diff --git a/ash/shell/content/client/shell_content_browser_client.h b/ash/shell/content/client/shell_content_browser_client.h index 23878ab..c7c9fedd 100644 --- a/ash/shell/content/client/shell_content_browser_client.h +++ b/ash/shell/content/client/shell_content_browser_client.h
@@ -11,7 +11,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "content/public/browser/content_browser_client.h" -#include "storage/browser/quota/quota_settings.h" namespace ash { namespace shell { @@ -24,10 +23,6 @@ // Overridden from content::ContentBrowserClient: std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts( const content::MainFunctionParams& parameters) override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) override; private: DISALLOW_COPY_AND_ASSIGN(ShellContentBrowserClient);
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h index ef5a1e4..a5b410d 100644 --- a/ash/wm/overview/overview_grid.h +++ b/ash/wm/overview/overview_grid.h
@@ -94,9 +94,9 @@ // first position in the grid. |use_spawn_animation| has no effect if either // |animate| or |reposition| are false. // - // Note: This function should only be called by |OverviewSession::AddItem|. - // |overview_session_| keeps count of all overview items, but this function - // does not update the tally. + // Note: This function should only be called by |OverviewSession::AddItem| and + // |OverviewGrid::AppendItem|. |overview_session_| keeps count of all overview + // items, but this function does not update the tally. void AddItem(aura::Window* window, bool reposition, bool animate, @@ -105,20 +105,23 @@ bool use_spawn_animation = false); // Similar to the above function, but adds the window to the end of the grid. + // Note: This function should only be called by |OverviewSession::AppendItem|. + // |overview_session_| keeps count of all overview items, but this function + // does not update the tally. void AppendItem(aura::Window* window, bool reposition, bool animate, bool use_spawn_animation = false); // Removes |overview_item| from the grid. |overview_item| cannot already be - // absent from the grid. No items are repositioned. + // absent from the grid. If |item_destroying| is true, we may want to notify + // |overview_session_| that this grid has become empty. If |item_destroying| + // and |reposition| are both true, all items are repositioned with animation. + // |reposition| has no effect if |item_destroying| is false. // // Note: This function should only be called by |OverviewSession::RemoveItem| // and |OverviewGrid::Shutdown|. |overview_session_| keeps count of all - // overview items, but this function does not update the tally. If - // |item_destroying| is true, we may want to notify |overview_session_| that - // there are no longer any items. Calls |PositionWindows| to animate the items - // to their new locations if |reposition| is true. + // overview items, but this function does not update the tally. void RemoveItem(OverviewItem* overview_item, bool item_destroying = false, bool reposition = false);
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 11780f3..8f1e9093f 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8892888623443193504 \ No newline at end of file +8892617276415118848 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 5557aad..0e9ebd0a 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8892888622585646768 \ No newline at end of file +8892617275597794992 \ No newline at end of file
diff --git a/build_overrides/vulkan_headers.gni b/build_overrides/vulkan_headers.gni new file mode 100644 index 0000000..6782a1f --- /dev/null +++ b/build_overrides/vulkan_headers.gni
@@ -0,0 +1,7 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/ui.gni") + +vulkan_use_x11 = use_x11
diff --git a/cc/animation/animation_host.cc b/cc/animation/animation_host.cc index 10c6f2ec..ceffe592 100644 --- a/cc/animation/animation_host.cc +++ b/cc/animation/animation_host.cc
@@ -654,15 +654,13 @@ } bool AnimationHost::ImplOnlyScrollAnimationUpdateTarget( - ElementId element_id, const gfx::Vector2dF& scroll_delta, const gfx::ScrollOffset& max_scroll_offset, base::TimeTicks frame_monotonic_time, base::TimeDelta delayed_by) { DCHECK(scroll_offset_animations_impl_); return scroll_offset_animations_impl_->ScrollAnimationUpdateTarget( - element_id, scroll_delta, max_scroll_offset, frame_monotonic_time, - delayed_by); + scroll_delta, max_scroll_offset, frame_monotonic_time, delayed_by); } ScrollOffsetAnimations& AnimationHost::scroll_offset_animations() const {
diff --git a/cc/animation/animation_host.h b/cc/animation/animation_host.h index a313470..af99fca9 100644 --- a/cc/animation/animation_host.h +++ b/cc/animation/animation_host.h
@@ -179,7 +179,6 @@ base::TimeDelta delayed_by, base::TimeDelta animation_start_offset) override; bool ImplOnlyScrollAnimationUpdateTarget( - ElementId element_id, const gfx::Vector2dF& scroll_delta, const gfx::ScrollOffset& max_scroll_offset, base::TimeTicks frame_monotonic_time,
diff --git a/cc/animation/animation_host_unittest.cc b/cc/animation/animation_host_unittest.cc index 45fd8cc..9e24db2 100644 --- a/cc/animation/animation_host_unittest.cc +++ b/cc/animation/animation_host_unittest.cc
@@ -137,14 +137,14 @@ time += base::TimeDelta::FromSecondsD(0.1); EXPECT_TRUE(host_impl_->ImplOnlyScrollAnimationUpdateTarget( - element_id_, scroll_delta, max_scroll_offset, time, base::TimeDelta())); + scroll_delta, max_scroll_offset, time, base::TimeDelta())); // Detach all animations from layers and timelines. host_impl_->ClearMutators(); time += base::TimeDelta::FromSecondsD(0.1); EXPECT_FALSE(host_impl_->ImplOnlyScrollAnimationUpdateTarget( - element_id_, scroll_delta, max_scroll_offset, time, base::TimeDelta())); + scroll_delta, max_scroll_offset, time, base::TimeDelta())); } // Tests that verify interaction of AnimationHost with LayerTreeMutator.
diff --git a/cc/animation/scroll_offset_animations_impl.cc b/cc/animation/scroll_offset_animations_impl.cc index bd2df460..1a15151 100644 --- a/cc/animation/scroll_offset_animations_impl.cc +++ b/cc/animation/scroll_offset_animations_impl.cc
@@ -88,7 +88,6 @@ } bool ScrollOffsetAnimationsImpl::ScrollAnimationUpdateTarget( - ElementId element_id, const gfx::Vector2dF& scroll_delta, const gfx::ScrollOffset& max_scroll_offset, base::TimeTicks frame_monotonic_time, @@ -100,8 +99,6 @@ return false; } - DCHECK_EQ(element_id, scroll_offset_animation_->element_id()); - KeyframeModel* keyframe_model = scroll_offset_animation_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET); if (!keyframe_model) {
diff --git a/cc/animation/scroll_offset_animations_impl.h b/cc/animation/scroll_offset_animations_impl.h index 3f5b8b3..e9f192b6 100644 --- a/cc/animation/scroll_offset_animations_impl.h +++ b/cc/animation/scroll_offset_animations_impl.h
@@ -47,8 +47,7 @@ base::TimeDelta delayed_by, base::TimeDelta animation_start_offset); - bool ScrollAnimationUpdateTarget(ElementId element_id, - const gfx::Vector2dF& scroll_delta, + bool ScrollAnimationUpdateTarget(const gfx::Vector2dF& scroll_delta, const gfx::ScrollOffset& max_scroll_offset, base::TimeTicks frame_monotonic_time, base::TimeDelta delayed_by);
diff --git a/cc/input/README.md b/cc/input/README.md index a5337e9..900820c4 100644 --- a/cc/input/README.md +++ b/cc/input/README.md
@@ -104,3 +104,51 @@ Also called the "Layout Viewport" in web/Blink terminology. This is the main "content scroller" in a given page, typically the document (`<html>`) element. This is the scroller to which position: fixed elements remain fixed to. + +## Compositor threaded scrollbar scrolling +Contact: arakeri@microsoft.com + +### Introduction +Scrollbar scrolling using the mouse happens on the main thread in Chromium. If +the main thread is busy (due to reasons like long running JS, etc), scrolling +by clicking on the scrollbar will appear to be janky. To provide a better user +experience, we have enabled off-main-thread scrollbar interaction for composited +scrollers. This frees up the main thread to perform other tasks like processing +javascript, etc. The core principal here is that MouseEvent(s) are converted to +GestureEvent(s) and dispatched in a VSync aligned manner. Choosing this design +also helps with the grand scrolling unification. + +### High-level design: + + + +### Core Implementation Details: +This is the basic principle: +- A new class called "cc::ScrollbarController" manages the state and behavior + related to translating Mouse events into GestureScrolls. +- When a kMouseDown arrives at InputHandlerProxy::RouteToTypeSpecificHandler, + it gets passed to the ScrollbarController to determine if this event will cause + scrollbar manipulation. +- The ScrollbarController returns enough data to the InputHandlerProxy to inject + gesture events to the CompositorThreadEventQueue (CTEQ). For example, in the + case of a mouse down, a GestureScrollBegin(GSB) and a GestureScrollUpdate(GSU) + are added to the CTEQ. +- Depending on the action, there can be more synthetic GSUs that get added to + the CTEQ. (For eg: thumb drags). +- The WebInputEvent::kMouseUp is responsible for cleaning up the scroll state. +- GestureScrollBegin gets dispatched first. This sets up the scroll_node and + other state necessary to begin scrolling in LayerTreeHostImpl::ScrollBegin. + This is as usual for all gesture based scrolls. +- GestureScrollUpdate(s) get handled next. Scroll deltas get applied to the node + that was set up during GestureScrollBegin. Depending on the type of scroll, + this may lead to an animated scroll (eg: LayerTreeHostImpl::ScrollAnimated for + autoscroll/mouse clicks) or a regular scroll. (eg: LayerTreeHostImpl::ScrollBy + for thumb drags) +- Finally, the GestureScrollEnd is dispatched and it clears the scrolling state + (like the CurrentlyScrollingNode) and calls SetNeedsCommitOnImplThread(). + +### Miscellaneous resources. +- [Demo page](https://rahul8805.github.io/DemoPages/BouncyMoon.html) +- [Lightning talk](https://www.youtube.com/watch?v=FOCHCuGA_MA&t=1150s) +- [input-dev thread](https://groups.google.com/a/chromium.org/forum/#!topic/input-dev/6ACOSDoAik4) +- [Full design doc](https://docs.google.com/document/d/1JqykSXnCkqwA1E3bUhhIi-IgEvM9HZdKtIu_S4Ncm6o/edit#heading=h.agf18oiankjh)
diff --git a/cc/input/scrollbar_controller.h b/cc/input/scrollbar_controller.h index 80a49f3f..01f933b 100644 --- a/cc/input/scrollbar_controller.h +++ b/cc/input/scrollbar_controller.h
@@ -11,6 +11,106 @@ #include "cc/layers/layer_impl.h" #include "cc/layers/painted_scrollbar_layer_impl.h" +// High level documentation: +// https://source.chromium.org/chromium/chromium/src/+/master:cc/input/README.md + +// Click scrolling. +// - A click is considered as a kMouseDown and a kMouseUp in quick succession. +// Every click on a composited non-custom arrow leads to 3 GestureEvents in +// total. +// - GSB and GSU on get queued in the CTEQ on mousedown and a GSE on mouseup. +// - The delta scrolled is constant at 40px (scaled by the device_scale_factor) +// for scrollbar arrows and a function of the viewport length in the case of +// track autoscroll. + +// Thumb dragging. +// - The sequence of events in the CTEQ would be something like GSB, GSU, GSU, +// GSU..., GSE +// - On every pointermove, the scroll delta is determined is as current pointer +// position - the point at which we got the initial mousedown. +// - The delta is then scaled by the scroller to scrollbar ratio so that +// dragging the thumb moves the scroller proportionately. +// - This ratio is calculated as: +// (scroll_layer_length - viewport_length) / +// (scrollbar_track_length - scrollbar_thumb_length) +// - On pointerup, the GSE clears state as mentioned above. + +// VSync aligned autoscroll. +// - Autoscroll is implemented as a "scroll animation" which has a linear timing +// function (see cc::LinearTimingFunction) and a curve with a constant velocity. +// - The main thread does autoscrolling by pumping events at 50ms interval. To +// have a similar kind of behaviour on the compositor thread, the autoscroll +// velocity is set to 800px per second for scrollbar arrows. +// - For track autoscrolling however, the velocity is a function of the viewport +// length. +// - Based on this velocity, an autoscroll curve is created. +// - An autoscroll animation is set up. (via +// LayerTreeHostImpl::ScrollAnimationCreateInternal) on the the known +// scroll_node and the scroller starts animation when the pointer is held. + +// Nuances: +// Thumb snapping. +// - During a thumb drag, if a pointer moves too far away from the scrollbar +// track, the thumb is supposed to snap back to it original place (i.e to the +// point before the thumb drag started). +// - This is done by having an imaginary no_snap_rect around the scrollbar +// track. This extends about 8 times the width of the track on either side. When +// a manipulation is in progress, the mouse is expected to stay within the +// bounds of this rect. Assuming a standard scrollbar, 17px wide, this is how +// it'd look like. +// https://github.com/rahul8805/CompositorThreadedScrollbarDocs/blob/master/snap.PNG?raw=true + +// - When a pointerdown is received, record the original offset of the thumb. +// - On every pointermove, check if the pointer is within the bounds of the +// no_snap_rect. If false, snap to the initial_scroll_offset and stop processing +// pointermove(s) until the pointer reenters the bounds of the rect. +// - The moment the mouse re-enters the bounds of the no_snap_rect, we snap to +// the initial_scroll_offset + event.PositionInWidget. + +// Thumb anchoring. +// - During a thumb drag, if the pointer runs off the track, there should be no +// additional scrolling until the pointer reenters the track and crosses the +// original mousedown point. +// - This is done by sending "clamped" deltas. The amount of scrollable delta is +// computed using LayerTreeHostImpl::ComputeScrollDelta. +// - Since the deltas are clamped, overscroll doesn't occur if it can't be +// consumed by the CurrentlyScrollingNode. + +// Autoscroll play/pause. +// - When the pointer moves in and out of bounds of a scrollbar part that can +// initiate autoscrolls (like arrows or track), the autoscroll animation is +// expected to play or pause accordingly. +// - On every ScrollbarController::WillBeginMainFrame, the pointer location is +// constantly checked and if it is outside the bounds of the scrollbar part that +// initiated the autoscroll, the autoscroll is stopped. +// - Similarly, when the pointer reenters the bounds, autoscroll is restarted +// again. All the vital information during autoscrolling such the velocity, +// direction, scroll layer length etc is held in +// cc::ScrollbarController::AutoscrollState. + +// Shift + click. +// - Doing a shift click on any part of a scrollbar track is supposed to do an +// instant scroll to that location (such that the thumb is still centered on the +// pointer). +// - When the MouseEvent reaches the +// InputHandlerProxy::RouteToTypeSpecificHandler, if the event is found to have +// a "Shift" modifier, the ScrollbarController calculates the offset based on +// the pointers current location on the track. +// - Once the offset is determined, the InputHandlerProxy creates a GSU with +// state that tells the LayerTreeHostImpl to perform a non-animated scroll to +// the offset. + +// Continuous autoscrolling. +// - This builds on top of the autoscolling implementation. "Continuous" +// autoscrolling is when an autoscroll is in progress and the size of the +// content keeps increasing. For eg: When you keep the down arrow pressed on +// websites like Facebook, the autoscrolling is expected to keep on going until +// the mouse is released. +// - This is implemented by monitoring the length of the scroller layer at every +// frame and if the length increases (and if autoscroll in the forward direction +// is already in progress), the old animation is aborted and a new autoscroll +// animation with the new scroller length is kicked off. + namespace cc { // This class is responsible for hit testing composited scrollbars, event // handling and creating gesture scroll deltas.
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 524b1309..7e6ebca 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -4116,9 +4116,9 @@ // that ScrollBy uses for non-animated wheel scrolls. scroll_status = ScrollBegin(scroll_state, WHEEL); if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { - scroll_animating_latched_element_id_ = ElementId(); - scroll_animating_overscroll_target_element_id_ = ElementId(); - ScrollEndImpl(); + scroll_animating_latched_element_id_ = CurrentlyScrollingNode()->element_id; + scroll_animating_overscroll_target_element_id_ = + CurrentlyScrollingNode()->element_id; } return scroll_status; } @@ -4177,8 +4177,6 @@ return false; } - scroll_tree.set_currently_scrolling_node(scroll_node->id); - gfx::ScrollOffset current_offset = scroll_tree.current_scroll_offset(scroll_node->element_id); gfx::ScrollOffset target_offset = scroll_tree.ClampScrollOffsetToLimits( @@ -4224,7 +4222,7 @@ scroll_accumulated_this_frame_ += gfx::ScrollOffset(scroll_delta); - if (scroll_node) { + if (scroll_node && mutator_host_->IsImplOnlyScrollAnimating()) { // Flash the overlay scrollbar even if the scroll dalta is 0. if (settings_.scrollbar_flash_after_any_scroll_update) { FlashAllScrollbars(false); @@ -4261,9 +4259,26 @@ return scroll_status; } + // TODO(bokan): This method currently does both targeting/latching as well + // as updating. As such, it's a combination of a gesture Begin and Update. + // We'll soon transform it so that this method can assume a scroller is + // already latched. The only decision it needs to make is whether to create + // a new animation or update an existing one, however, the scroll_node should + // already be latched. However, to avoid changing too much at once, for now + // this re-targeting remains here but if we're already latched we'll force + // targeting the same node so we don't change the latch mid-stream. + // https://crbug.com/1016229. ScrollStateData scroll_state_data; scroll_state_data.position_x = viewport_point.x(); scroll_state_data.position_y = viewport_point.y(); + scroll_state_data.is_beginning = true; + scroll_state_data.delta_x_hint = scroll_delta.x(); + scroll_state_data.delta_y_hint = scroll_delta.y(); + if (scroll_node) { + scroll_state_data.set_current_native_scrolling_element( + scroll_node->element_id); + } + ScrollState scroll_state(scroll_state_data); // ScrollAnimated is used for animated wheel scrolls. We find the first layer @@ -4341,31 +4356,11 @@ break; } } - // Set overscroll event target since neither an ongoing scroll animation has - // been updated nor a new scroll animation has been created for the current - // GSU. - if (!scroll_animating_latched_element_id_) { - // When no scroll animation has been created during the current scroll - // sequence (i.e. scroll_animating_latched_element_id_ == ElementId()) we - // need to set last_scroller_element_id_ here since scrollEnd won't get - // called. - last_scroller_element_id_ = scroll_node->element_id; - // We will send the overscroll events to viewport or the last element in - // the cut chain when no scroll animation has been created during the - // current scroll sequence. - scroll_animating_overscroll_target_element_id_ = scroll_node->element_id; - } else { - // When a scroll animation has been created during the current scroll - // sequence, the overscroll events target should be the element that - // scrolling is latched to. - scroll_animating_overscroll_target_element_id_ = - scroll_animating_latched_element_id_; - } + overscroll_delta_for_main_thread_ += pending_delta; client_->SetNeedsCommitOnImplThread(); } - ScrollEndImpl(); if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) { // Update scroll_status.thread to SCROLL_IGNORED when there is no ongoing // scroll animation, we can scroll on impl thread and yet, we couldn't @@ -4657,6 +4652,8 @@ TRACE_EVENT_SCOPE_THREAD, "isNull", scroll_node ? false : true); active_tree_->SetCurrentlyScrollingNode(scroll_node); + last_scroller_element_id_ = + scroll_node ? scroll_node->element_id : ElementId(); } bool LayerTreeHostImpl::CanConsumeDelta(const ScrollNode& scroll_node, @@ -4974,22 +4971,6 @@ scroll_animating_snap_target_ids_ = TargetSnapAreaElementIds(); } -void LayerTreeHostImpl::ScrollEndImpl() { - // In smooth-scrolling path when the GSE arrives after scroll animation - // completion, CurrentlyScrollingNode() is already cleared due to - // ScrollEndImpl call inside ScrollOffsetAnimationFinished. In this case - // last_scroller_element_id_ is already set in the same ScrollEndImpl call and - // we should not reset it here. - if (!last_scroller_element_id_ && CurrentlyScrollingNode()) - last_scroller_element_id_ = CurrentlyScrollingNode()->element_id; - - browser_controls_offset_manager_->ScrollEnd(); - ClearCurrentlyScrollingNode(); - frame_trackers_.StopSequence(wheel_scrolling_ - ? FrameSequenceTrackerType::kWheelScroll - : FrameSequenceTrackerType::kTouchScroll); -} - void LayerTreeHostImpl::ScrollEnd(bool should_snap) { if ((should_snap && SnapAtScrollEnd()) || mutator_host_->IsImplOnlyScrollAnimating()) { @@ -4997,7 +4978,13 @@ deferred_scroll_end_ = true; return; } - ScrollEndImpl(); + + browser_controls_offset_manager_->ScrollEnd(); + ClearCurrentlyScrollingNode(); + frame_trackers_.StopSequence(wheel_scrolling_ + ? FrameSequenceTrackerType::kWheelScroll + : FrameSequenceTrackerType::kTouchScroll); + deferred_scroll_end_ = false; scroll_gesture_did_end_ = true; client_->SetNeedsCommitOnImplThread(); @@ -5935,7 +5922,7 @@ gfx::Vector2dF scaled_delta = gfx::ScaleVector2d(scroll_delta, 1.f / scale_factor); bool animation_updated = mutator_host_->ImplOnlyScrollAnimationUpdateTarget( - scroll_node->element_id, scaled_delta, + scaled_delta, active_tree_->property_trees()->scroll_tree.MaxScrollOffset( scroll_node->id), CurrentBeginFrameArgs().frame_time, delayed_by); @@ -6116,8 +6103,6 @@ ScrollEnd(/*should_snap=*/false); return; } - - ScrollEndImpl(); } void LayerTreeHostImpl::NotifyAnimationWorkletStateChange(
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 1af0122..9f7f8ae6 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -960,8 +960,6 @@ const gfx::Vector2dF& scroll_delta, base::TimeDelta delayed_by); - void ScrollEndImpl(); - // Creates an animation curve and returns true if we need to update the // scroll position to a snap point. Otherwise returns false. bool SnapAtScrollEnd(); @@ -1273,7 +1271,7 @@ // ended. bool scroll_gesture_did_end_; - // Set in ScrollEnd before clearing the currently scrolling node. This is + // Set in ScrollBegin and outlives the currently scrolling node so it can be // used to send the scrollend DOM event when scrolling has happened on CC. ElementId last_scroller_element_id_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 28777d6..21ce721 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -1660,6 +1660,7 @@ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(pointer_position, delta).thread); + host_impl_->ScrollEnd(); EXPECT_EQ(overflow->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -11032,6 +11033,7 @@ EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); + host_impl_->ScrollEnd(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); @@ -11099,7 +11101,9 @@ host_impl_->ScrollAnimated(gfx::Point(10, 10), gfx::Vector2d(0, 20)) .thread); - EXPECT_EQ(scrolling_layer->scroll_tree_index(), + // Scrolling the inner viewport happens through the Viewport class which + // uses the outer viewport to represent "latched to the viewport". + EXPECT_EQ(OuterViewportScrollLayer()->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); } @@ -11232,6 +11236,8 @@ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get()) .thread); + host_impl_->ScrollEnd(); + // The second ScrollAnimatedBegin should not get ignored. EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -11471,6 +11477,7 @@ EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); + host_impl_->ScrollEnd(); host_impl_->DidFinishImplFrame(); begin_frame_args.frame_time = @@ -11518,7 +11525,8 @@ host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor); // Scroll by a small amount, there should be no bubbling to the outer - // viewport. + // viewport (but scrolling the viewport always sets the outer as the + // currently scrolling node). base::TimeTicks start_time = base::TimeTicks() + base::TimeDelta::FromMilliseconds(250); viz::BeginFrameArgs begin_frame_args = @@ -11528,7 +11536,7 @@ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(10, 20)).thread); host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(inner_scroll_layer->scroll_tree_index(), + EXPECT_EQ(outer_scroll_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); begin_frame_args.frame_id.sequence_number++; @@ -11546,7 +11554,7 @@ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(100, 100)).thread); host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(inner_scroll_layer->scroll_tree_index(), + EXPECT_EQ(outer_scroll_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); begin_frame_args.frame_id.sequence_number++; @@ -11582,7 +11590,7 @@ .thread); host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(inner_scroll_layer->scroll_tree_index(), + EXPECT_EQ(outer_scroll_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); begin_frame_args.frame_id.sequence_number++; @@ -11621,7 +11629,9 @@ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(90, 90)).thread); host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(inner_scroll_layer->scroll_tree_index(), + // When either the inner or outer node is being scrolled, the outer node is + // the one that's "latched". + EXPECT_EQ(outer_scroll_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); begin_frame_args.frame_id.sequence_number++; @@ -11639,7 +11649,7 @@ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(50, 50)).thread); host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_EQ(inner_scroll_layer->scroll_tree_index(), + EXPECT_EQ(outer_scroll_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); // Verify that all the delta is applied to the inner viewport and nothing is @@ -11729,8 +11739,13 @@ EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100), scrolling_layer->CurrentScrollOffset()); - EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingNode()); + // The CurrentlyScrollingNode shouldn't be cleared until a GestureScrollEnd. + EXPECT_EQ(scrolling_layer->scroll_tree_index(), + host_impl_->CurrentlyScrollingNode()->id); host_impl_->DidFinishImplFrame(); + + host_impl_->ScrollEnd(); + EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingNode()); } // Test that smooth scrolls clamp correctly when bounds change mid-animation.
diff --git a/cc/trees/mutator_host.h b/cc/trees/mutator_host.h index a77f841..fa0fe4f 100644 --- a/cc/trees/mutator_host.h +++ b/cc/trees/mutator_host.h
@@ -145,7 +145,6 @@ base::TimeDelta delayed_by, base::TimeDelta animation_start_offset) = 0; virtual bool ImplOnlyScrollAnimationUpdateTarget( - ElementId element_id, const gfx::Vector2dF& scroll_delta, const gfx::ScrollOffset& max_scroll_offset, base::TimeTicks frame_monotonic_time,
diff --git a/chrome/android/java/res/layout/new_tab_page_offline_card.xml b/chrome/android/java/res/layout/new_tab_page_offline_card.xml index 58f691f..1129025c 100644 --- a/chrome/android/java/res/layout/new_tab_page_offline_card.xml +++ b/chrome/android/java/res/layout/new_tab_page_offline_card.xml
@@ -30,6 +30,8 @@ android:layout_toEndOf="@id/icon" android:layout_marginStart="16dp" android:text="@string/explore_offline_card_title" + android:focusable="true" + android:focusableInTouchMode="true" android:textAppearance="@style/TextAppearance.BlackTitle1" /> <TextView @@ -40,6 +42,8 @@ android:layout_alignStart="@id/title" android:layout_marginTop="6dp" android:text="@string/explore_offline_card_description" + android:focusable="true" + android:focusableInTouchMode="true" android:textAppearance="@style/TextAppearance.BlackHint2" /> <org.chromium.components.browser_ui.widget.DualControlLayout
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/AccountManagementFragment.java index 7318f31..5ed0bce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/sync/AccountManagementFragment.java
@@ -318,19 +318,17 @@ if (intent != null) { startActivity(intent); - return; + } else { + // AccountManagerFacade couldn't create intent, use SigninUtils to open settings + // instead. + SigninUtils.openSettingsForAllAccounts(getActivity()); } - // AccountManagerFacade couldn't create intent, use SigninUtils to open settings - // instead. - SigninUtils.openSettingsForAllAccounts(getActivity()); + // Return to the last opened tab if triggered from the content area. + if (mGaiaServiceType != GAIAServiceType.GAIA_SERVICE_TYPE_NONE) { + if (isAdded()) getActivity().finish(); + } }); - - // Return to the last opened tab if triggered from the content area. - if (mGaiaServiceType != GAIAServiceType.GAIA_SERVICE_TYPE_NONE) { - if (isAdded()) getActivity().finish(); - } - return true; }); addAccountPreference.setManagedPreferenceDelegate(preference -> !canAddAccounts());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java index 3a091cb..da972a8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -170,7 +170,9 @@ } @Override - public void notifyAllAnimationsFinished(Item frontInfoBar) {} + public void notifyAllAnimationsFinished(Item frontInfoBar) { + mDoneAnimating = true; + } } private MockAppDetailsDelegate mDetailsDelegate; @@ -594,14 +596,14 @@ String webBannerUrl = WebappTestPage.getServiceWorkerUrl(mTestServer); resetEngagementForUrl(webBannerUrl, 10); - Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab(); - new TabLoadObserver(tab).fullyLoadUrl(webBannerUrl); - waitUntilAmbientBadgeInfoBarAppears(mTabbedActivityTestRule); - InfoBarContainer container = mTabbedActivityTestRule.getInfoBarContainer(); final InfobarListener listener = new InfobarListener(); container.addAnimationListener(listener); + Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab(); + new TabLoadObserver(tab).fullyLoadUrl(webBannerUrl); + waitUntilAmbientBadgeInfoBarAppears(mTabbedActivityTestRule); + // Explicitly dismiss the ambient badge. CriteriaHelper.pollUiThread(() -> listener.mDoneAnimating);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 759fad14..7926632 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -611,8 +611,6 @@ namespace { -const storage::QuotaSettings* g_default_quota_settings; - #if BUILDFLAG(ENABLE_PLUGINS) // TODO(teravest): Add renderer-side API-specific checking for these APIs so // that blanket permission isn't granted to all dev channel APIs for these. @@ -2635,20 +2633,6 @@ return new ChromeQuotaPermissionContext(); } -void ChromeContentBrowserClient::GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - if (g_default_quota_settings) { - // For debugging tests harness can inject settings. - std::move(callback).Run(*g_default_quota_settings); - return; - } - storage::GetNominalDynamicSettings( - partition->GetPath(), context->IsOffTheRecord(), - storage::GetDefaultDeviceInfoHelper(), std::move(callback)); -} - content::GeneratedCodeCacheSettings ChromeContentBrowserClient::GetGeneratedCodeCacheSettings( content::BrowserContext* context) { @@ -4911,12 +4895,6 @@ return ui::NativeTheme::GetInstanceForWeb(); } -// static -void ChromeContentBrowserClient::SetDefaultQuotaSettingsForTesting( - const storage::QuotaSettings* settings) { - g_default_quota_settings = settings; -} - scoped_refptr<safe_browsing::UrlCheckerDelegate> ChromeContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate( content::ResourceContext* resource_context) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 2b1501f..2ff5032 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -31,7 +31,6 @@ #include "ppapi/buildflags/buildflags.h" #include "services/network/public/mojom/network_context.mojom-forward.h" #include "services/service_manager/public/cpp/binder_registry.h" -#include "storage/browser/quota/quota_settings.h" class ChromeContentBrowserClientParts; class PrefRegistrySimple; @@ -278,10 +277,6 @@ #endif scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) override; content::GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( content::BrowserContext* context) override; void AllowCertificateError( @@ -690,11 +685,6 @@ bool allow); #endif - // The value pointed to by |settings| should remain valid until the - // the function is called again with a new value or a nullptr. - static void SetDefaultQuotaSettingsForTesting( - const storage::QuotaSettings *settings); - scoped_refptr<safe_browsing::UrlCheckerDelegate> GetSafeBrowsingUrlCheckerDelegate(content::ResourceContext* resource_context);
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 1d743d7c..3d4de44 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -2376,6 +2376,7 @@ ] if (use_cups) { + configs += [ "//printing:cups" ] deps += [ "//chrome/services/cups_proxy", "//chrome/services/cups_proxy/public/mojom",
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index 6f41081..45ce2741 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -38,7 +38,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_tabstrip.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/common/extensions/api/downloads.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" @@ -4431,7 +4431,7 @@ base::Bind(&OnDangerPromptCreated); DownloadsAcceptDangerFunction::OnPromptCreatedForTesting( &callback); - BrowserActionTestUtil::Create(current_browser())->Press(0); + ExtensionActionTestHelper::Create(current_browser())->Press(0); observer->WaitForFinished(); }
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc index a0a030c..33f31b8 100644 --- a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
@@ -31,7 +31,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" @@ -112,9 +112,9 @@ } protected: - BrowserActionTestUtil* GetBrowserActionsBar() { + ExtensionActionTestHelper* GetBrowserActionsBar() { if (!browser_action_test_util_) - browser_action_test_util_ = BrowserActionTestUtil::Create(browser()); + browser_action_test_util_ = ExtensionActionTestHelper::Create(browser()); return browser_action_test_util_.get(); } @@ -146,7 +146,7 @@ } private: - std::unique_ptr<BrowserActionTestUtil> browser_action_test_util_; + std::unique_ptr<ExtensionActionTestHelper> browser_action_test_util_; DISALLOW_COPY_AND_ASSIGN(BrowserActionApiTest); }; @@ -523,7 +523,7 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, DISABLED_BrowserActionPopup) { ASSERT_TRUE( LoadExtension(test_data_dir_.AppendASCII("browser_action/popup"))); - BrowserActionTestUtil* actions_bar = GetBrowserActionsBar(); + ExtensionActionTestHelper* actions_bar = GetBrowserActionsBar(); const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; @@ -658,7 +658,7 @@ // default. Browser* incognito_browser = CreateIncognitoBrowser(browser()->profile()); - ASSERT_EQ(0, BrowserActionTestUtil::Create(incognito_browser) + ASSERT_EQ(0, ExtensionActionTestHelper::Create(incognito_browser) ->NumberOfBrowserActions()); ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); @@ -674,7 +674,7 @@ extension->id(), browser()->profile(), true); extension = registry_observer.WaitForExtensionLoaded(); - ASSERT_EQ(1, BrowserActionTestUtil::Create(incognito_browser) + ASSERT_EQ(1, ExtensionActionTestHelper::Create(incognito_browser) ->NumberOfBrowserActions()); ASSERT_TRUE(incognito_ready_listener.WaitUntilSatisfied()); @@ -704,7 +704,7 @@ // default. Browser* incognito_browser = CreateIncognitoBrowser(browser()->profile()); - ASSERT_EQ(0, BrowserActionTestUtil::Create(incognito_browser) + ASSERT_EQ(0, ExtensionActionTestHelper::Create(incognito_browser) ->NumberOfBrowserActions()); // Set up a listener so we can reply for the extension to do the update. @@ -719,7 +719,7 @@ extensions::util::SetIsIncognitoEnabled(extension->id(), browser()->profile(), true); extension = registry_observer.WaitForExtensionLoaded(); - ASSERT_EQ(1, BrowserActionTestUtil::Create(incognito_browser) + ASSERT_EQ(1, ExtensionActionTestHelper::Create(incognito_browser) ->NumberOfBrowserActions()); ASSERT_TRUE(incognito_ready_listener.WaitUntilSatisfied()); @@ -755,7 +755,7 @@ // Open an incognito browser. Browser* incognito_browser = CreateIncognitoBrowser(browser()->profile()); - ASSERT_EQ(1, BrowserActionTestUtil::Create(incognito_browser) + ASSERT_EQ(1, ExtensionActionTestHelper::Create(incognito_browser) ->NumberOfBrowserActions()); // A click in the regular profile should open a tab in the regular profile. @@ -944,7 +944,7 @@ ASSERT_TRUE(LoadExtension( test_data_dir_.AppendASCII("browser_action/popup_with_iframe"))); - BrowserActionTestUtil* actions_bar = GetBrowserActionsBar(); + ExtensionActionTestHelper* actions_bar = GetBrowserActionsBar(); const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_;
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc index fba1e17..cdc5e9f 100644 --- a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc +++ b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" #include "chrome/test/base/interactive_test_utils.h" @@ -129,7 +129,7 @@ } void EnsurePopupActive() { - auto test_util = BrowserActionTestUtil::Create(browser()); + auto test_util = ExtensionActionTestHelper::Create(browser()); EXPECT_TRUE(test_util->HasPopup()); EXPECT_TRUE(test_util->WaitForPopup()); EXPECT_TRUE(test_util->HasPopup()); @@ -162,17 +162,19 @@ content::WindowedNotificationObserver frame_observer( content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, content::NotificationService::AllSources()); - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); frame_observer.Wait(); EnsurePopupActive(); } // Close the popup window directly. - void ClosePopup() { BrowserActionTestUtil::Create(browser())->HidePopup(); } + void ClosePopup() { + ExtensionActionTestHelper::Create(browser())->HidePopup(); + } // Trigger a focus loss to close the popup. void ClosePopupViaFocusLoss() { - EXPECT_TRUE(BrowserActionTestUtil::Create(browser())->HasPopup()); + EXPECT_TRUE(ExtensionActionTestHelper::Create(browser())->HasPopup()); content::WindowedNotificationObserver observer( extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, content::NotificationService::AllSources()); @@ -191,7 +193,7 @@ #endif // The window disappears immediately. - EXPECT_FALSE(BrowserActionTestUtil::Create(browser())->HasPopup()); + EXPECT_FALSE(ExtensionActionTestHelper::Create(browser())->HasPopup()); // Wait for the notification to achieve a consistent state and verify that // the popup was properly torn down. @@ -212,7 +214,7 @@ if (!ShouldRunPopupTest()) return; - auto browserActionBar = BrowserActionTestUtil::Create(browser()); + auto browserActionBar = ExtensionActionTestHelper::Create(browser()); // Setup extension message listener to wait for javascript to finish running. ExtensionTestMessageListener listener("ready", true); { @@ -248,10 +250,10 @@ // Show second popup in new window. listener.Reply("show another"); frame_observer.Wait(); - EXPECT_TRUE(BrowserActionTestUtil::Create(new_browser)->HasPopup()); + EXPECT_TRUE(ExtensionActionTestHelper::Create(new_browser)->HasPopup()); } ASSERT_TRUE(catcher.GetNextResult()) << message_; - BrowserActionTestUtil::Create(new_browser)->HidePopup(); + ExtensionActionTestHelper::Create(new_browser)->HidePopup(); } // Tests opening a popup in an incognito window. @@ -271,10 +273,10 @@ // have popups if there is any popup open. #if !(defined(OS_LINUX) && !defined(USE_AURA)) // Starting window does not have a popup. - EXPECT_FALSE(BrowserActionTestUtil::Create(browser())->HasPopup()); + EXPECT_FALSE(ExtensionActionTestHelper::Create(browser())->HasPopup()); #endif // Incognito window should have a popup. - auto test_util = BrowserActionTestUtil::Create( + auto test_util = ExtensionActionTestHelper::Create( BrowserList::GetInstance()->GetLastActive()); EXPECT_TRUE(test_util->HasPopup()); test_util->HidePopup(); @@ -299,7 +301,7 @@ OpenURLOffTheRecord(profile(), GURL("chrome://newtab/")); EXPECT_TRUE(listener.WaitUntilSatisfied()); EXPECT_EQ(std::string("opened"), listener.message()); - auto test_util = BrowserActionTestUtil::Create(incognito_browser); + auto test_util = ExtensionActionTestHelper::Create(incognito_browser); EXPECT_TRUE(test_util->HasPopup()); test_util->HidePopup(); } @@ -394,7 +396,7 @@ 0, {TabStripModel::GestureType::kOther}); observer.Wait(); - EXPECT_FALSE(BrowserActionTestUtil::Create(browser())->HasPopup()); + EXPECT_FALSE(ExtensionActionTestHelper::Create(browser())->HasPopup()); } IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, @@ -404,7 +406,7 @@ // First, we open a popup. OpenPopupViaAPI(false); - auto browser_action_test_util = BrowserActionTestUtil::Create(browser()); + auto browser_action_test_util = ExtensionActionTestHelper::Create(browser()); EXPECT_TRUE(browser_action_test_util->HasPopup()); // Then, find the extension that created it. @@ -518,9 +520,9 @@ content::WindowedNotificationObserver frame_observer( content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, content::NotificationService::AllSources()); - BrowserActionTestUtil::Create(browser())->InspectPopup(0); + ExtensionActionTestHelper::Create(browser())->InspectPopup(0); frame_observer.Wait(); - EXPECT_TRUE(BrowserActionTestUtil::Create(browser())->HasPopup()); + EXPECT_TRUE(ExtensionActionTestHelper::Create(browser())->HasPopup()); // Close the browser window, this should not cause a crash. chrome::CloseWindow(browser()); @@ -533,7 +535,7 @@ return; OpenPopupViaAPI(false); - auto test_util = BrowserActionTestUtil::Create(browser()); + auto test_util = ExtensionActionTestHelper::Create(browser()); const gfx::NativeView popup_view = test_util->GetPopupNativeView(); EXPECT_NE(static_cast<gfx::NativeView>(nullptr), popup_view); const HWND popup_hwnd = views::HWNDForNativeView(popup_view);
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc index dc6716b..165069f 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc
@@ -19,7 +19,7 @@ #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/extensions/extension_test_util.h" #include "chrome/test/base/ui_test_utils.h" @@ -473,11 +473,11 @@ FILE_PATH_LITERAL("background.js"), base::StringPrintf(kBackgroundJsTemplate, GetAPIName(GetParam()))); - // Though this says "BrowserActionTestUtil", it's actually used for all + // Though this says "ExtensionActionTestHelper", it's actually used for all // toolbar actions. // TODO(devlin): Rename it to ToolbarActionTestUtil. - std::unique_ptr<BrowserActionTestUtil> toolbar_helper = - BrowserActionTestUtil::Create(browser()); + std::unique_ptr<ExtensionActionTestHelper> toolbar_helper = + ExtensionActionTestHelper::Create(browser()); EXPECT_EQ(0, toolbar_helper->NumberOfBrowserActions()); const Extension* extension = LoadExtension(test_dir.UnpackedPath()); ASSERT_TRUE(extension); @@ -526,8 +526,8 @@ const Extension* extension = LoadExtension(test_dir.UnpackedPath()); ASSERT_TRUE(extension); - std::unique_ptr<BrowserActionTestUtil> toolbar_helper = - BrowserActionTestUtil::Create(browser()); + std::unique_ptr<ExtensionActionTestHelper> toolbar_helper = + ExtensionActionTestHelper::Create(browser()); ExtensionAction* action = GetExtensionAction(*extension); ASSERT_TRUE(action); @@ -615,8 +615,8 @@ EXPECT_TRUE(ActionHasDefaultState(*action, tab_id)); EnsureActionIsEnabledOnActiveTab(action); - std::unique_ptr<BrowserActionTestUtil> toolbar_helper = - BrowserActionTestUtil::Create(browser()); + std::unique_ptr<ExtensionActionTestHelper> toolbar_helper = + ExtensionActionTestHelper::Create(browser()); ASSERT_EQ(1, toolbar_helper->NumberOfBrowserActions()); EXPECT_EQ(extension->id(), toolbar_helper->GetExtensionId(0));
diff --git a/chrome/browser/extensions/autoplay_browsertest.cc b/chrome/browser/extensions/autoplay_browsertest.cc index accbc33..14d5f92 100644 --- a/chrome/browser/extensions/autoplay_browsertest.cc +++ b/chrome/browser/extensions/autoplay_browsertest.cc
@@ -4,7 +4,7 @@ #include "base/strings/stringprintf.h" #include "chrome/browser/extensions/extension_apitest.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -35,8 +35,8 @@ LoadExtension(test_data_dir_.AppendASCII("autoplay_iframe")); ASSERT_TRUE(extension) << message_; - std::unique_ptr<BrowserActionTestUtil> browser_action_test_util = - BrowserActionTestUtil::Create(browser()); + std::unique_ptr<ExtensionActionTestHelper> browser_action_test_util = + ExtensionActionTestHelper::Create(browser()); extensions::ResultCatcher catcher; content::WindowedNotificationObserver popup_observer( content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc index 619822c..1fc80caa 100644 --- a/chrome/browser/extensions/crx_installer_browsertest.cc +++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -32,7 +32,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/web_application_info.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/extensions/extension_incognito_apitest.cc b/chrome/browser/extensions/extension_incognito_apitest.cc index 7d432e6..ce72ae9f6 100644 --- a/chrome/browser/extensions/extension_incognito_apitest.cc +++ b/chrome/browser/extensions/extension_incognito_apitest.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/url_constants.h" #include "chrome/test/base/ui_test_utils.h" @@ -185,7 +185,7 @@ embedded_test_server()->GetURL("/extensions/test_file.html")); // Simulate the incognito's browser action being clicked. - BrowserActionTestUtil::Create(incognito_browser)->Press(0); + ExtensionActionTestHelper::Create(incognito_browser)->Press(0); EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); }
diff --git a/chrome/browser/extensions/extension_keybinding_apitest.cc b/chrome/browser/extensions/extension_keybinding_apitest.cc index 697a0fa..40257ddb 100644 --- a/chrome/browser/extensions/extension_keybinding_apitest.cc +++ b/chrome/browser/extensions/extension_keybinding_apitest.cc
@@ -20,7 +20,7 @@ #include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" @@ -282,7 +282,7 @@ // immaterial to this test). ASSERT_TRUE(RunExtensionTest("keybinding/conflicting")) << message_; - auto browser_actions_bar = BrowserActionTestUtil::Create(browser()); + auto browser_actions_bar = ExtensionActionTestHelper::Create(browser()); // Test that there are two browser actions in the toolbar. ASSERT_EQ(2, browser_actions_bar->NumberOfBrowserActions()); @@ -373,8 +373,8 @@ ToolbarActionsModel::Get(profile()); toolbar_actions_model->SetVisibleIconCount(0); } - std::unique_ptr<BrowserActionTestUtil> test_helper = - BrowserActionTestUtil::Create(browser()); + std::unique_ptr<ExtensionActionTestHelper> test_helper = + ExtensionActionTestHelper::Create(browser()); EXPECT_EQ(0, test_helper->VisibleBrowserActions()); ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc index 9807ed3b..191173a 100644 --- a/chrome/browser/extensions/lazy_background_page_apitest.cc +++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -19,7 +19,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_features.h" @@ -152,7 +152,7 @@ // Observe background page being created and closed after // the browser action is clicked. LazyBackgroundObserver page_complete; - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); page_complete.Wait(); // Background page created a new tab before it closed. @@ -174,7 +174,7 @@ // Observe background page being created and closed after // the browser action is clicked. LazyBackgroundObserver page_complete; - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); page_complete.Wait(); // Background page is closed after creating a new tab. @@ -351,7 +351,7 @@ { ExtensionTestMessageListener nacl_module_loaded("nacl_module_loaded", false); - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); EXPECT_TRUE(nacl_module_loaded.WaitUntilSatisfied()); content::RunAllTasksUntilIdle(); EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id())); @@ -361,7 +361,7 @@ // down. { LazyBackgroundObserver page_complete; - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); page_complete.WaitUntilClosed(); } @@ -467,7 +467,7 @@ ExtensionTestMessageListener listener_incognito("waiting_incognito", false); LazyBackgroundObserver page_complete(browser()->profile()); - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); page_complete.Wait(); // Only the original event page received the message. @@ -543,7 +543,7 @@ EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id())); // The browser action has a new title. - auto browser_action = BrowserActionTestUtil::Create(browser()); + auto browser_action = ExtensionActionTestHelper::Create(browser()); ASSERT_EQ(1, browser_action->NumberOfBrowserActions()); EXPECT_EQ("Success", browser_action->GetTooltip(0)); } @@ -663,7 +663,7 @@ // Click on the browser action icon to load video. { ExtensionTestMessageListener video_loaded("video_loaded", false); - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); EXPECT_TRUE(video_loaded.WaitUntilSatisfied()); } @@ -677,7 +677,7 @@ testing::Not(testing::Contains(pip_activity))); ExtensionTestMessageListener entered_pip("entered_pip", false); - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); EXPECT_TRUE(entered_pip.WaitUntilSatisfied()); EXPECT_THAT(pm->GetLazyKeepaliveActivities(extension), testing::Contains(pip_activity)); @@ -687,7 +687,7 @@ // Background Page shuts down. { LazyBackgroundObserver page_complete; - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); page_complete.WaitUntilClosed(); EXPECT_FALSE(IsBackgroundPageAlive(extension->id())); }
diff --git a/chrome/browser/extensions/manifest_v3_browsertest.cc b/chrome/browser/extensions/manifest_v3_browsertest.cc index 6de51c8..eecfc83f 100644 --- a/chrome/browser/extensions/manifest_v3_browsertest.cc +++ b/chrome/browser/extensions/manifest_v3_browsertest.cc
@@ -6,7 +6,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/ui_test_utils.h" #include "components/version_info/channel.h" @@ -126,8 +126,8 @@ ASSERT_TRUE(extension); ASSERT_TRUE(listener.WaitUntilSatisfied()); - std::unique_ptr<BrowserActionTestUtil> action_test_util = - BrowserActionTestUtil::Create(browser()); + std::unique_ptr<ExtensionActionTestHelper> action_test_util = + ExtensionActionTestHelper::Create(browser()); ASSERT_EQ(1, action_test_util->NumberOfBrowserActions()); EXPECT_EQ(extension->id(), action_test_util->GetExtensionId(0));
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc index 8acfdb8..87a6a644 100644 --- a/chrome/browser/extensions/process_manager_browsertest.cc +++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -22,7 +22,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/permissions/permission_request_manager.h" #include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" @@ -415,7 +415,7 @@ EXPECT_FALSE(pm->IsBackgroundHostClosing(popup->id())); // Simulate clicking on the action to open a popup. - auto test_util = BrowserActionTestUtil::Create(browser()); + auto test_util = ExtensionActionTestHelper::Create(browser()); content::WindowedNotificationObserver frame_observer( content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, content::NotificationService::AllSources());
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index c05db95..2a70d38 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -34,7 +34,6 @@ #include "chrome/browser/push_messaging/push_messaging_app_identifier.h" #include "chrome/browser/push_messaging/push_messaging_service_factory.h" #include "chrome/browser/push_messaging/push_messaging_service_impl.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/api/web_navigation.h"
diff --git a/chrome/browser/extensions/user_script_listener.cc b/chrome/browser/extensions/user_script_listener.cc index 2a0dd5c..8668003 100644 --- a/chrome/browser/extensions/user_script_listener.cc +++ b/chrome/browser/extensions/user_script_listener.cc
@@ -228,9 +228,8 @@ URLPatterns new_patterns; CollectURLPatterns(extension, &new_patterns); - if (!new_patterns.empty()) { - AppendNewURLPatterns(browser_context, new_patterns); - } + DCHECK(!new_patterns.empty()); + AppendNewURLPatterns(browser_context, new_patterns); } void UserScriptListener::OnExtensionUnloaded(
diff --git a/chrome/browser/media/router/BUILD.gn b/chrome/browser/media/router/BUILD.gn index 295eb33..b2d7b40 100644 --- a/chrome/browser/media/router/BUILD.gn +++ b/chrome/browser/media/router/BUILD.gn
@@ -62,6 +62,8 @@ "presentation/presentation_service_delegate_observers.h", "presentation/receiver_presentation_service_delegate_impl.cc", "presentation/receiver_presentation_service_delegate_impl.h", + "presentation/web_contents_presentation_manager.cc", + "presentation/web_contents_presentation_manager.h", "route_message_observer.cc", "route_message_observer.h", "route_message_util.cc",
diff --git a/chrome/browser/media/router/presentation/presentation_service_delegate_impl.cc b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.cc index 12b75d3..d2e8d71c 100644 --- a/chrome/browser/media/router/presentation/presentation_service_delegate_impl.cc +++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.cc
@@ -444,8 +444,7 @@ DCHECK(!callback.is_null()); default_presentation_started_callback_ = std::move(callback); default_presentation_request_ = request; - for (auto& observer : default_presentation_request_observers_) - observer.OnDefaultPresentationChanged(*default_presentation_request_); + NotifyDefaultPresentationChanged(&request); } void PresentationServiceDelegateImpl::OnJoinRouteResponse( @@ -503,6 +502,8 @@ const MediaRoute& route) { auto* presentation_frame = GetOrAddPresentationFrame(render_frame_host_id); presentation_frame->AddPresentation(presentation_info, route); + // TODO(crbug.com/1031672): Notify WebContentsPresentationManager::Observer + // that the presentation routes have changed for the WebContents. } void PresentationServiceDelegateImpl::RemovePresentation( @@ -511,6 +512,8 @@ const auto it = presentation_frames_.find(render_frame_host_id); if (it != presentation_frames_.end()) it->second->RemovePresentation(presentation_id); + // TODO(crbug.com/1031672): Notify WebContentsPresentationManager::Observer + // that the presentation routes have changed for the WebContents. } void PresentationServiceDelegateImpl::StartPresentation( @@ -668,7 +671,27 @@ it->second->ListenForConnectionStateChange(connection, state_changed_cb); } -void PresentationServiceDelegateImpl::OnRouteResponse( +void PresentationServiceDelegateImpl::AddObserver( + WebContentsPresentationManager::Observer* observer) { + presentation_observers_.AddObserver(observer); +} + +void PresentationServiceDelegateImpl::RemoveObserver( + WebContentsPresentationManager::Observer* observer) { + presentation_observers_.RemoveObserver(observer); +} + +bool PresentationServiceDelegateImpl::HasDefaultPresentationRequest() const { + return default_presentation_request_.has_value(); +} + +const content::PresentationRequest& +PresentationServiceDelegateImpl::GetDefaultPresentationRequest() const { + DCHECK(HasDefaultPresentationRequest()); + return *default_presentation_request_; +} + +void PresentationServiceDelegateImpl::OnPresentationResponse( const content::PresentationRequest& presentation_request, mojom::RoutePresentationConnectionPtr connection, const RouteRequestResult& result) { @@ -695,26 +718,6 @@ } } -void PresentationServiceDelegateImpl::AddDefaultPresentationRequestObserver( - DefaultPresentationRequestObserver* observer) { - default_presentation_request_observers_.AddObserver(observer); -} - -void PresentationServiceDelegateImpl::RemoveDefaultPresentationRequestObserver( - DefaultPresentationRequestObserver* observer) { - default_presentation_request_observers_.RemoveObserver(observer); -} - -const content::PresentationRequest& -PresentationServiceDelegateImpl::GetDefaultPresentationRequest() const { - DCHECK(HasDefaultPresentationRequest()); - return *default_presentation_request_; -} - -bool PresentationServiceDelegateImpl::HasDefaultPresentationRequest() const { - return !!default_presentation_request_; -} - base::WeakPtr<PresentationServiceDelegateImpl> PresentationServiceDelegateImpl::GetWeakPtr() { return weak_factory_.GetWeakPtr(); @@ -737,8 +740,7 @@ return; default_presentation_request_.reset(); - for (auto& observer : default_presentation_request_observers_) - observer.OnDefaultPresentationRemoved(); + NotifyDefaultPresentationChanged(nullptr); } std::unique_ptr<media::FlingingController> @@ -798,6 +800,14 @@ } } +void PresentationServiceDelegateImpl::NotifyDefaultPresentationChanged( + const content::PresentationRequest* request) { + for (WebContentsPresentationManager::Observer& presentation_observer : + presentation_observers_) { + presentation_observer.OnDefaultPresentationChanged(request); + } +} + WEB_CONTENTS_USER_DATA_KEY_IMPL(PresentationServiceDelegateImpl) } // namespace media_router
diff --git a/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h index e9cd3a7d6..a183bb0 100644 --- a/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h +++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl.h
@@ -19,6 +19,7 @@ #include "build/build_config.h" #include "chrome/browser/media/router/media_router.h" #include "chrome/browser/media/router/presentation/presentation_service_delegate_observers.h" +#include "chrome/browser/media/router/presentation/web_contents_presentation_manager.h" #include "chrome/common/media_router/media_source.h" #include "chrome/common/media_router/mojom/media_router.mojom.h" #include "content/public/browser/presentation_request.h" @@ -87,27 +88,14 @@ // it also provides default presentation URL that is required for creating // browser-initiated presentations. It is scoped to the lifetime of a // WebContents, and is managed by the associated WebContents. +// It is accessed through the WebContentsPresentationManager interface by +// clients (e.g. the UI code) that is interested in the presentation status of +// the WebContents, but not in other aspects such as the render frame. class PresentationServiceDelegateImpl : public content::WebContentsUserData<PresentationServiceDelegateImpl>, - public content::ControllerPresentationServiceDelegate { + public content::ControllerPresentationServiceDelegate, + public WebContentsPresentationManager { public: - // Observer interface for listening to default presentation request - // changes for the WebContents. - class DefaultPresentationRequestObserver { - public: - virtual ~DefaultPresentationRequestObserver() = default; - - // Called when default presentation request for the corresponding - // WebContents is set or changed. - // |default_presentation_info|: New default presentation request. - virtual void OnDefaultPresentationChanged( - const content::PresentationRequest& default_presentation_request) = 0; - - // Called when default presentation request for the corresponding - // WebContents has been removed. - virtual void OnDefaultPresentationRemoved() = 0; - }; - // Retrieves the instance of PresentationServiceDelegateImpl that was attached // to the specified WebContents. If no instance was attached, creates one, // and attaches it to the specified WebContents. @@ -160,34 +148,22 @@ const content::PresentationConnectionStateChangedCallback& state_changed_cb) override; - // Callback invoked when a default PresentationRequest is started from a - // browser-initiated dialog. - void OnRouteResponse(const content::PresentationRequest& request, - mojom::RoutePresentationConnectionPtr connection, - const RouteRequestResult& result); + // WebContentsPresentationManager implementation. + void AddObserver(WebContentsPresentationManager::Observer* observer) override; + void RemoveObserver( + WebContentsPresentationManager::Observer* observer) override; + bool HasDefaultPresentationRequest() const override; + const content::PresentationRequest& GetDefaultPresentationRequest() + const override; + void OnPresentationResponse(const content::PresentationRequest& request, + mojom::RoutePresentationConnectionPtr connection, + const RouteRequestResult& result) override; - // Adds / removes an observer for listening to default PresentationRequest - // changes. This class does not own |observer|. When |observer| is about to - // be destroyed, |RemoveDefaultPresentationRequestObserver| must be called. - void AddDefaultPresentationRequestObserver( - DefaultPresentationRequestObserver* observer); - void RemoveDefaultPresentationRequestObserver( - DefaultPresentationRequestObserver* observer); - - // Gets the default presentation request for the owning WebContents. It - // is an error to call this method if the default presentation request does - // not exist. - const content::PresentationRequest& GetDefaultPresentationRequest() const; - - // Returns true if there is a default presentation request for the owning tab - // WebContents. - bool HasDefaultPresentationRequest() const; + base::WeakPtr<PresentationServiceDelegateImpl> GetWeakPtr(); // Returns the WebContents that owns this instance. content::WebContents* web_contents() const { return web_contents_; } - base::WeakPtr<PresentationServiceDelegateImpl> GetWeakPtr(); - bool HasScreenAvailabilityListenerForTest( int render_process_id, int render_frame_id, @@ -276,6 +252,9 @@ const blink::mojom::PresentationInfo& presentation_info, mojom::RoutePresentationConnectionPtr* connection); + void NotifyDefaultPresentationChanged( + const content::PresentationRequest* request); + // References to the WebContents that owns this instance, and associated // browser profile's MediaRouter instance. content::WebContents* const web_contents_; @@ -283,8 +262,8 @@ // References to the observers listening for changes to the default // presentation of the associated WebContents. - base::ObserverList<DefaultPresentationRequestObserver>::Unchecked - default_presentation_request_observers_; + base::ObserverList<WebContentsPresentationManager::Observer> + presentation_observers_; // Default presentation request for the owning WebContents. base::Optional<content::PresentationRequest> default_presentation_request_;
diff --git a/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc index e6464a3f49..b3cbe43 100644 --- a/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc +++ b/chrome/browser/media/router/presentation/presentation_service_delegate_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/media/router/media_router_factory.h" #include "chrome/browser/media/router/presentation/local_presentation_manager.h" #include "chrome/browser/media/router/presentation/local_presentation_manager_factory.h" +#include "chrome/browser/media/router/presentation/web_contents_presentation_manager.h" #include "chrome/browser/media/router/test/mock_media_router.h" #include "chrome/browser/media/router/test/mock_screen_availability_listener.h" #include "chrome/browser/media/router/test/test_helper.h" @@ -67,13 +68,27 @@ MOCK_METHOD1(OnDefaultPresentationStarted, void(const PresentationInfo&)); }; -class MockDefaultPresentationRequestObserver - : public PresentationServiceDelegateImpl:: - DefaultPresentationRequestObserver { +class MockWebContentsPresentationObserver + : public WebContentsPresentationManager::Observer { public: + explicit MockWebContentsPresentationObserver( + content::WebContents* web_contents) { + presentation_manager_ = WebContentsPresentationManager::Get(web_contents); + presentation_manager_->AddObserver(this); + } + + ~MockWebContentsPresentationObserver() override { + if (presentation_manager_) + presentation_manager_->RemoveObserver(this); + } + + MOCK_METHOD1(OnMediaRoutesChanged, + void(const std::vector<MediaRoute>& routes)); MOCK_METHOD1(OnDefaultPresentationChanged, - void(const content::PresentationRequest&)); - MOCK_METHOD0(OnDefaultPresentationRemoved, void()); + void(const content::PresentationRequest* presentation_request)); + + private: + base::WeakPtr<WebContentsPresentationManager> presentation_manager_; }; class MockCreatePresentationConnnectionCallbacks { @@ -178,8 +193,8 @@ // Should not trigger callback since route response is error. std::unique_ptr<RouteRequestResult> result = RouteRequestResult::FromError( "Error", RouteRequestResult::UNKNOWN_ERROR); - delegate_impl_->OnRouteResponse(request, /** connection */ nullptr, - *result); + delegate_impl_->OnPresentationResponse(request, /** connection */ nullptr, + *result); EXPECT_TRUE(Mock::VerifyAndClearExpectations(this)); // Should not trigger callback since request doesn't match. @@ -191,8 +206,8 @@ media_route.set_incognito(incognito); result = RouteRequestResult::FromSuccess(media_route, "differentPresentationId"); - delegate_impl_->OnRouteResponse(different_request, - /** connection */ nullptr, *result); + delegate_impl_->OnPresentationResponse(different_request, + /** connection */ nullptr, *result); EXPECT_TRUE(Mock::VerifyAndClearExpectations(this)); // Should trigger callback since request matches. @@ -200,8 +215,8 @@ MediaRoute media_route2("routeId", source1_, "mediaSinkId", "", true, true); media_route2.set_incognito(incognito); result = RouteRequestResult::FromSuccess(media_route2, "presentationId"); - delegate_impl_->OnRouteResponse(request, /** connection */ nullptr, - *result); + delegate_impl_->OnPresentationResponse(request, /** connection */ nullptr, + *result); } void SetMainFrame() { @@ -379,13 +394,12 @@ } TEST_F(PresentationServiceDelegateImplTest, - DefaultPresentationRequestObserver) { + NotifyWebContentsPresentationObservers) { auto callback = base::BindRepeating( &PresentationServiceDelegateImplTest::OnDefaultPresentationStarted, base::Unretained(this)); - StrictMock<MockDefaultPresentationRequestObserver> observer; - delegate_impl_->AddDefaultPresentationRequestObserver(&observer); + StrictMock<MockWebContentsPresentationObserver> observer(GetWebContents()); content::WebContentsTester::For(GetWebContents()) ->NavigateAndCommit(frame_url_); @@ -409,7 +423,7 @@ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer)); // Remove default presentation URL. - EXPECT_CALL(observer, OnDefaultPresentationRemoved()).Times(1); + EXPECT_CALL(observer, OnDefaultPresentationChanged(nullptr)).Times(1); content::PresentationRequest empty_request( {main_frame_process_id_, main_frame_routing_id_}, std::vector<GURL>(), frame_origin_);
diff --git a/chrome/browser/media/router/presentation/web_contents_presentation_manager.cc b/chrome/browser/media/router/presentation/web_contents_presentation_manager.cc new file mode 100644 index 0000000..17d69184 --- /dev/null +++ b/chrome/browser/media/router/presentation/web_contents_presentation_manager.cc
@@ -0,0 +1,21 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/media/router/presentation/web_contents_presentation_manager.h" + +#include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h" + +namespace media_router { + +// static +base::WeakPtr<WebContentsPresentationManager> +WebContentsPresentationManager::Get(content::WebContents* web_contents) { + return PresentationServiceDelegateImpl::GetOrCreateForWebContents( + web_contents) + ->GetWeakPtr(); +} + +WebContentsPresentationManager::~WebContentsPresentationManager() = default; + +} // namespace media_router
diff --git a/chrome/browser/media/router/presentation/web_contents_presentation_manager.h b/chrome/browser/media/router/presentation/web_contents_presentation_manager.h new file mode 100644 index 0000000..d3158a166 --- /dev/null +++ b/chrome/browser/media/router/presentation/web_contents_presentation_manager.h
@@ -0,0 +1,77 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_WEB_CONTENTS_PRESENTATION_MANAGER_H_ +#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_WEB_CONTENTS_PRESENTATION_MANAGER_H_ + +#include <vector> + +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "chrome/common/media_router/mojom/media_router.mojom.h" + +namespace content { +struct PresentationRequest; +class WebContents; +} // namespace content + +namespace media_router { + +class MediaRoute; +class RouteRequestResult; + +// Keeps track of the default PresentationRequest and presentation MediaRoutes +// associated with a WebContents. Its lifetime is tied to that of the +// WebContents. +class WebContentsPresentationManager { + public: + class Observer : public base::CheckedObserver { + public: + // Called whenever presentation MediaRoutes associated with the WebContents + // are added, removed, or have their attributes changed. + virtual void OnMediaRoutesChanged(const std::vector<MediaRoute>& routes) {} + + // |presentation_request| is a nullptr if the default PresentationRequest + // has been removed. + virtual void OnDefaultPresentationChanged( + const content::PresentationRequest* presentation_request) {} + + protected: + Observer() = default; + }; + + static base::WeakPtr<WebContentsPresentationManager> Get( + content::WebContents* web_contents); + + virtual ~WebContentsPresentationManager() = 0; + + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Returns true if there is a default presentation request for the + // WebContents. + virtual bool HasDefaultPresentationRequest() const = 0; + + // Gets the default presentation request for the WebContents. It is an error + // to call this method if the default presentation request does not exist. + virtual const content::PresentationRequest& GetDefaultPresentationRequest() + const = 0; + + // Invoked by Media Router when a PresentationRequest is started from a + // browser-initiated dialog. Updates the internal state and propagates the + // request result to the presentation controller. + virtual void OnPresentationResponse( + const content::PresentationRequest& presentation_request, + mojom::RoutePresentationConnectionPtr connection, + const RouteRequestResult& result) = 0; + + protected: + WebContentsPresentationManager() = default; +}; + +} // namespace media_router + +#endif // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_WEB_CONTENTS_PRESENTATION_MANAGER_H_
diff --git a/chrome/browser/net/dns_over_https_browsertest.cc b/chrome/browser/net/dns_over_https_browsertest.cc new file mode 100644 index 0000000..61ff5d3 --- /dev/null +++ b/chrome/browser/net/dns_over_https_browsertest.cc
@@ -0,0 +1,74 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/common/chrome_features.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/common/content_features.h" +#include "content/public/test/test_navigation_observer.h" +#include "net/dns/dns_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace { + +struct DohParameter { + std::string doh_provider; + std::string doh_template; + bool is_valid; +}; + +std::vector<DohParameter> GetDohServerTestCases() { + std::vector<DohParameter> doh_test_cases; + const auto& doh_server_templates = net::GetDohServerTemplatesListForTesting(); + for (const auto& server_template : doh_server_templates) { + doh_test_cases.push_back( + DohParameter({server_template.first, server_template.second, true})); + } + // Negative test-case + doh_test_cases.push_back(DohParameter( + {"NegativeTestExampleCom", "https://www.example.com", false})); + return doh_test_cases; +} + +} // namespace + +class DohBrowserTest : public InProcessBrowserTest, + public testing::WithParamInterface<DohParameter> { + public: + DohBrowserTest() : test_url_("https://www.google.com") { + // Allow test to use full host resolver code, instead of the test resolver + set_allow_network_access_to_host_resolutions(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + scoped_feature_list_.InitWithFeaturesAndParameters( + {// {features::kNetworkServiceInProcess, {}}, // Turn on for debugging + {features::kDnsOverHttps, + {{"Fallback", "false"}, {"Templates", GetParam().doh_template}}}}, + {}); + } + + protected: + base::test::ScopedFeatureList scoped_feature_list_; + const GURL test_url_; +}; + +IN_PROC_BROWSER_TEST_P(DohBrowserTest, MANUAL_ExternalDohServers) { + content::TestNavigationObserver nav_observer( + browser()->tab_strip_model()->GetActiveWebContents(), 1); + EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url_)); + nav_observer.WaitForNavigationFinished(); + EXPECT_EQ(GetParam().is_valid, nav_observer.last_navigation_succeeded()); +} + +INSTANTIATE_TEST_SUITE_P( + DohBrowserParameterizedTest, + DohBrowserTest, + ::testing::ValuesIn(GetDohServerTestCases()), + [](const testing::TestParamInfo<DohBrowserTest::ParamType>& info) { + return info.param.doh_provider; + });
diff --git a/chrome/browser/no_best_effort_tasks_browsertest.cc b/chrome/browser/no_best_effort_tasks_browsertest.cc index 029e8884..244d76b2 100644 --- a/chrome/browser/no_best_effort_tasks_browsertest.cc +++ b/chrome/browser/no_best_effort_tasks_browsertest.cc
@@ -253,9 +253,9 @@ // use BEST_EFFORT tasks. class NoBestEffortTasksTestWithQuota : public NoBestEffortTasksTest { protected: - std::unique_ptr<storage::QuotaSettings> CreateQuotaSettings() override { - // Return nullptr to use the real quota subsystem. - return nullptr; + bool UseProductionQuotaSettings() override { + // Return true to use the real quota subsystem. + return true; } };
diff --git a/chrome/browser/optimization_guide/optimization_guide_util.cc b/chrome/browser/optimization_guide/optimization_guide_util.cc index c977223..c3d4254 100644 --- a/chrome/browser/optimization_guide/optimization_guide_util.cc +++ b/chrome/browser/optimization_guide/optimization_guide_util.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/optimization_guide/optimization_guide_util.h" #include "base/logging.h" +#include "net/base/url_util.h" +#include "url/url_canon.h" std::string GetStringNameForOptimizationTarget( optimization_guide::proto::OptimizationTarget optimization_target) { @@ -17,3 +19,15 @@ NOTREACHED(); return std::string(); } + +bool IsHostValidToFetchFromRemoteOptimizationGuide(const std::string& host) { + if (net::HostStringIsLocalhost(host)) + return false; + url::CanonHostInfo host_info; + std::string canonicalized_host(net::CanonicalizeHost(host, &host_info)); + if (host_info.IsIPAddress() || + !net::IsCanonicalizedHostCompliant(canonicalized_host)) { + return false; + } + return true; +}
diff --git a/chrome/browser/optimization_guide/optimization_guide_util.h b/chrome/browser/optimization_guide/optimization_guide_util.h index f399abe..f596cb7 100644 --- a/chrome/browser/optimization_guide/optimization_guide_util.h +++ b/chrome/browser/optimization_guide/optimization_guide_util.h
@@ -16,4 +16,8 @@ std::string GetStringNameForOptimizationTarget( optimization_guide::proto::OptimizationTarget optimization_target); +// Returns false if the host is an IP address, localhosts, or an invalid +// host that is not supported by the remote optimization guide. +bool IsHostValidToFetchFromRemoteOptimizationGuide(const std::string& host); + #endif // CHROME_BROWSER_OPTIMIZATION_GUIDE_OPTIMIZATION_GUIDE_UTIL_H_
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager.cc b/chrome/browser/optimization_guide/prediction/prediction_manager.cc index d8e0f59..ff16540 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager.cc
@@ -186,7 +186,9 @@ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, PrefService* pref_service, Profile* profile) - : session_fcp_(), + : host_model_features_cache_( + std::max(features::MaxHostModelFeaturesCacheSize(), size_t(1))), + session_fcp_(), top_host_provider_(top_host_provider), model_and_features_store_(std::move(model_and_features_store)), url_loader_factory_(url_loader_factory), @@ -327,7 +329,7 @@ base::flat_map<std::string, float> PredictionManager::BuildFeatureMap( content::NavigationHandle* navigation_handle, - const base::flat_set<std::string>& model_features) const { + const base::flat_set<std::string>& model_features) { SEQUENCE_CHECKER(sequence_checker_); base::flat_map<std::string, float> feature_map; if (model_features.size() == 0) @@ -336,8 +338,8 @@ const base::flat_map<std::string, float>* host_model_features = nullptr; std::string host = navigation_handle->GetURL().host(); - auto it = host_model_features_map_.find(host); - if (it != host_model_features_map_.end()) + auto it = host_model_features_cache_.Get(host); + if (it != host_model_features_cache_.end()) host_model_features = &(it->second); UMA_HISTOGRAM_BOOLEAN( @@ -367,7 +369,7 @@ OptimizationTargetDecision PredictionManager::ShouldTargetNavigation( content::NavigationHandle* navigation_handle, - proto::OptimizationTarget optimization_target) const { + proto::OptimizationTarget optimization_target) { SEQUENCE_CHECKER(sequence_checker_); DCHECK(navigation_handle->GetURL().SchemeIsHTTPOrHTTPS()); @@ -457,9 +459,9 @@ return nullptr; } -base::flat_map<std::string, base::flat_map<std::string, float>> +const HostModelFeaturesMRUCache* PredictionManager::GetHostModelFeaturesForTesting() const { - return host_model_features_map_; + return &host_model_features_cache_; } void PredictionManager::SetPredictionModelFetcherForTesting( @@ -486,6 +488,19 @@ std::vector<std::string> top_hosts = top_host_provider_->GetTopHosts(); + // Remove hosts that are already available in the host model features cache. + // The request should still be made in case there is a new model or a model + // that does not rely on host model features to be fetched. + auto it = top_hosts.begin(); + while (it != top_hosts.end()) { + if (host_model_features_cache_.Peek(*it) != + host_model_features_cache_.end()) { + it = top_hosts.erase(it); + continue; + } + ++it; + } + if (!prediction_model_fetcher_) { prediction_model_fetcher_ = std::make_unique<PredictionModelFetcher>( url_loader_factory_, @@ -620,6 +635,9 @@ // Clear any data remaining in the stored get models response. get_models_response_data_to_store_.reset(); + // Purge any expired host model features from the store. + model_and_features_store_->PurgeExpiredHostModelFeatures(); + // TODO(crbug/1027596): Stopping the timer can be removed once the fetch // callback refactor is done. Otherwise, at the start of a fetch, a timer is // running to handle the cases that a fetch fails but the callback is not run. @@ -668,7 +686,7 @@ } UMA_HISTOGRAM_COUNTS_1000( "OptimizationGuide.PredictionManager.HostModelFeaturesMapSize", - host_model_features_map_.size()); + host_model_features_cache_.size()); // Load the prediction models for all the registered optimization targets now // that it is not blocked by loading the host model features. @@ -771,8 +789,8 @@ } if (model_features_for_host.size() == 0) return false; - host_model_features_map_[host_model_features.host()] = - model_features_for_host; + host_model_features_cache_.Put(host_model_features.host(), + model_features_for_host); return true; } @@ -831,9 +849,17 @@ } void PredictionManager::ClearHostModelFeatures() { - host_model_features_map_.clear(); + host_model_features_cache_.Clear(); if (model_and_features_store_) model_and_features_store_->ClearHostModelFeaturesFromDatabase(); } +base::Optional<base::flat_map<std::string, float>> +PredictionManager::GetHostModelFeaturesForHost(const std::string& host) const { + auto it = host_model_features_cache_.Peek(host); + if (it == host_model_features_cache_.end()) + return base::nullopt; + return it->second; +} + } // namespace optimization_guide
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager.h b/chrome/browser/optimization_guide/prediction/prediction_manager.h index 9d094df..9c0c30a 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager.h +++ b/chrome/browser/optimization_guide/prediction/prediction_manager.h
@@ -11,6 +11,7 @@ #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" +#include "base/containers/mru_cache.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" @@ -49,6 +50,9 @@ class PredictionModelFetcher; class TopHostProvider; +using HostModelFeaturesMRUCache = + base::HashingMRUCache<std::string, base::flat_map<std::string, float>>; + // A PredictionManager supported by the optimization guide that makes an // OptimizationTargetDecision by evaluating the corresponding prediction model // for an OptimizationTarget. @@ -87,7 +91,7 @@ // if model for the optimization target is not currently on the client. OptimizationTargetDecision ShouldTargetNavigation( content::NavigationHandle* navigation_handle, - proto::OptimizationTarget optimization_target) const; + proto::OptimizationTarget optimization_target); // Update |session_fcp_| and |previous_fcp_| with |fcp|. void UpdateFCPSessionStatistics(base::TimeDelta fcp); @@ -133,8 +137,11 @@ // Return the host model features for all hosts used by this // PredictionManager for testing. - base::flat_map<std::string, base::flat_map<std::string, float>> - GetHostModelFeaturesForTesting() const; + const HostModelFeaturesMRUCache* GetHostModelFeaturesForTesting() const; + + // Returns the host model features for a host if available. + base::Optional<base::flat_map<std::string, float>> + GetHostModelFeaturesForHost(const std::string& host) const; // Return the set of features that each host in |host_model_features_map_| // contains for testing. @@ -166,10 +173,11 @@ optimization_targets_at_intialization); // Construct and return a map containing the current feature values for the - // requested set of model features. + // requested set of model features. The host model features cache is updated + // based on if host model features were used. base::flat_map<std::string, float> BuildFeatureMap( content::NavigationHandle* navigation_handle, - const base::flat_set<std::string>& model_features) const; + const base::flat_set<std::string>& model_features); // Calculate and return the current value for the client feature specified // by |model_feature|. Return nullopt if the client does not support the @@ -273,12 +281,8 @@ // prediction manager. base::flat_set<proto::OptimizationTarget> registered_optimization_targets_; - // A map of host to host model features known to the prediction manager. - // - // TODO(crbug/1001194): When loading features for the map, the size should be - // restricted. - base::flat_map<std::string, base::flat_map<std::string, float>> - host_model_features_map_; + // A MRU cache of host to host model features known to the prediction manager. + HostModelFeaturesMRUCache host_model_features_cache_; // The current session's FCP statistics for HTTP/HTTPS navigations. OptimizationGuideSessionStatistic session_fcp_;
diff --git a/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc b/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc index f8ffc7ef..2d328d8a 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_manager_unittest.cc
@@ -185,6 +185,7 @@ return false; } + count_hosts_fetched_ = hosts.size(); switch (fetch_state_) { case PredictionModelFetcherEndState::kFetchFailed: std::move(models_fetched_callback).Run(base::nullopt); @@ -222,9 +223,11 @@ } bool models_fetched() { return models_fetched_; } + size_t hosts_fetched() { return count_hosts_fetched_; } private: bool models_fetched_ = false; + size_t count_hosts_fetched_ = 0; // The desired behavior of the TestPredictionModelFetcher. PredictionModelFetcherEndState fetch_state_; }; @@ -362,6 +365,7 @@ create_valid_prediction_model_ = create_valid_prediction_model; } + using PredictionManager::GetHostModelFeaturesForHost; using PredictionManager::GetHostModelFeaturesForTesting; using PredictionManager::GetPredictionModelForTesting; @@ -1163,19 +1167,17 @@ prediction_manager()->UpdateHostModelFeaturesForTesting( get_models_response.get()); - EXPECT_TRUE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "example2.com")); - base::flat_map<std::string, base::flat_map<std::string, float>> - host_model_features_map = - prediction_manager()->GetHostModelFeaturesForTesting(); - EXPECT_TRUE(host_model_features_map.contains("example1.com")); - EXPECT_TRUE(host_model_features_map.contains("example2.com")); - auto it = host_model_features_map.find("example1.com"); - EXPECT_TRUE(it->second.contains("host_feat1")); - EXPECT_EQ(2.0, it->second["host_feat1"]); - it = host_model_features_map.find("example2.com"); - EXPECT_TRUE(it->second.contains("host_feat1")); - EXPECT_EQ(2.0, it->second["host_feat1"]); + base::Optional<base::flat_map<std::string, float>> host_model_features_map = + prediction_manager()->GetHostModelFeaturesForHost("example1.com"); + EXPECT_TRUE(host_model_features_map); + EXPECT_TRUE(host_model_features_map->contains("host_feat1")); + EXPECT_EQ(2.0, (*host_model_features_map)["host_feat1"]); + + host_model_features_map = + prediction_manager()->GetHostModelFeaturesForHost("example2.com"); + EXPECT_TRUE(host_model_features_map); + EXPECT_TRUE(host_model_features_map->contains("host_feat1")); + EXPECT_EQ(2.0, (*host_model_features_map)["host_feat1"]); } TEST_F(PredictionManagerTest, NoHostModelFeaturesForHost) { @@ -1213,14 +1215,12 @@ false, 1); EXPECT_LT(test_prediction_model->last_evaluated_features()["host_feat1"], 0); - EXPECT_FALSE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "bar.com")); + EXPECT_FALSE(prediction_manager()->GetHostModelFeaturesForHost("bar.com")); // One item loaded from the store when initialized. - EXPECT_EQ(1u, prediction_manager()->GetHostModelFeaturesForTesting().size()); + EXPECT_EQ(1u, prediction_manager()->GetHostModelFeaturesForTesting()->size()); } TEST_F(PredictionManagerTest, UpdateHostModelFeaturesMissingHost) { - base::HistogramTester histogram_tester; CreatePredictionManager({}); prediction_manager()->SetPredictionModelFetcherForTesting( @@ -1239,14 +1239,13 @@ prediction_manager()->UpdateHostModelFeaturesForTesting( get_models_response.get()); - EXPECT_FALSE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "example1.com")); + EXPECT_FALSE( + prediction_manager()->GetHostModelFeaturesForHost("example1.com")); // One item loaded from the store when initialized. - EXPECT_EQ(1u, prediction_manager()->GetHostModelFeaturesForTesting().size()); + EXPECT_EQ(1u, prediction_manager()->GetHostModelFeaturesForTesting()->size()); } TEST_F(PredictionManagerTest, UpdateHostModelFeaturesNoFeature) { - base::HistogramTester histogram_tester; CreatePredictionManager({}); prediction_manager()->SetPredictionModelFetcherForTesting( @@ -1264,14 +1263,13 @@ prediction_manager()->UpdateHostModelFeaturesForTesting( get_models_response.get()); - EXPECT_FALSE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "example1.com")); + EXPECT_FALSE( + prediction_manager()->GetHostModelFeaturesForHost("example1.com")); // One item loaded from the store when initialized. - EXPECT_EQ(1u, prediction_manager()->GetHostModelFeaturesForTesting().size()); + EXPECT_EQ(1u, prediction_manager()->GetHostModelFeaturesForTesting()->size()); } TEST_F(PredictionManagerTest, UpdateHostModelFeaturesNoFeatureName) { - base::HistogramTester histogram_tester; CreatePredictionManager({}); prediction_manager()->SetPredictionModelFetcherForTesting( @@ -1292,15 +1290,13 @@ prediction_manager()->UpdateHostModelFeaturesForTesting( get_models_response.get()); - EXPECT_FALSE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "example1.com")); + EXPECT_FALSE( + prediction_manager()->GetHostModelFeaturesForHost("example1.com")); // One item loaded from the store when initialized. - EXPECT_EQ(1u, prediction_manager()->GetHostModelFeaturesForTesting().size()); + EXPECT_EQ(1u, prediction_manager()->GetHostModelFeaturesForTesting()->size()); } TEST_F(PredictionManagerTest, UpdateHostModelFeaturesDoubleValue) { - base::HistogramTester histogram_tester; - CreatePredictionManager({}); prediction_manager()->SetPredictionModelFetcherForTesting( BuildTestPredictionModelFetcher( @@ -1319,16 +1315,13 @@ prediction_manager()->UpdateHostModelFeaturesForTesting( get_models_response.get()); - EXPECT_TRUE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "example1.com")); - EXPECT_EQ( - 3.0, - prediction_manager() - ->GetHostModelFeaturesForTesting()["example1.com"]["host_feat1"]); + auto host_model_features = + prediction_manager()->GetHostModelFeaturesForHost("example1.com"); + EXPECT_TRUE(host_model_features); + EXPECT_EQ(3.0, (*host_model_features)["host_feat1"]); } TEST_F(PredictionManagerTest, UpdateHostModelFeaturesIntValue) { - base::HistogramTester histogram_tester; CreatePredictionManager({}); prediction_manager()->SetPredictionModelFetcherForTesting( @@ -1348,14 +1341,62 @@ prediction_manager()->UpdateHostModelFeaturesForTesting( get_models_response.get()); - EXPECT_TRUE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "example1.com")); + auto host_model_features = + prediction_manager()->GetHostModelFeaturesForHost("example1.com"); + EXPECT_TRUE(host_model_features); // We expect the value to be stored as a float but is created from an int64 // value. - EXPECT_EQ( - 4.0, - prediction_manager() - ->GetHostModelFeaturesForTesting()["example1.com"]["host_feat1"]); + EXPECT_EQ(4.0, (*host_model_features)["host_feat1"]); +} + +TEST_F(PredictionManagerTest, RestrictHostModelFeaturesCacheSize) { + CreatePredictionManager({}); + prediction_manager()->SetPredictionModelFetcherForTesting( + BuildTestPredictionModelFetcher( + PredictionModelFetcherEndState::kFetchFailed)); + + prediction_manager()->RegisterOptimizationTargets( + {proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD}); + + SetStoreInitialized(); + std::vector<std::string> hosts; + for (size_t i = 0; i <= features::MaxHostModelFeaturesCacheSize() + 1; i++) + hosts.push_back("host" + base::NumberToString(i) + ".com"); + std::unique_ptr<proto::GetModelsResponse> get_models_response = + BuildGetModelsResponse(hosts, {}); + + prediction_manager()->UpdateHostModelFeaturesForTesting( + get_models_response.get()); + + auto* host_model_features_cache = + prediction_manager()->GetHostModelFeaturesForTesting(); + EXPECT_EQ(features::MaxHostModelFeaturesCacheSize(), + host_model_features_cache->size()); +} + +TEST_F(PredictionManagerTest, FetchHostModelFeaturesNotInCache) { + base::HistogramTester histogram_tester; + + CreatePredictionManager({}); + prediction_manager()->SetPredictionModelFetcherForTesting( + BuildTestPredictionModelFetcher( + PredictionModelFetcherEndState:: + kFetchSuccessWithModelsAndHostsModelFeatures)); + + std::unique_ptr<proto::GetModelsResponse> get_models_response = + BuildGetModelsResponse({"example1.com", "bar.com"}, {}); + prediction_manager()->UpdateHostModelFeaturesForTesting( + get_models_response.get()); + + prediction_manager()->RegisterOptimizationTargets( + {proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD}); + + SetStoreInitialized(); + + EXPECT_TRUE(prediction_model_fetcher()->models_fetched()); + // Only 1 of the 2 top hosts should have features fetched for it as the other + // is already in the host model features cache. + EXPECT_EQ(prediction_model_fetcher()->hosts_fetched(), 1ul); } TEST_F(PredictionManagerTest, UpdateHostModelFeaturesUpdateDataInMap) { @@ -1379,14 +1420,12 @@ prediction_manager()->UpdateHostModelFeaturesForTesting( get_models_response.get()); - EXPECT_TRUE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "example1.com")); + auto host_model_features = + prediction_manager()->GetHostModelFeaturesForHost("example1.com"); + EXPECT_TRUE(host_model_features); // We expect the value to be stored as a float but is created from an int64 // value. - EXPECT_EQ( - 4.0, - prediction_manager() - ->GetHostModelFeaturesForTesting()["example1.com"]["host_feat1"]); + EXPECT_EQ(4.0, (*host_model_features)["host_feat1"]); get_models_response = BuildGetModelsResponse({"example1.com"}, {}); get_models_response->mutable_host_model_features(0) @@ -1400,20 +1439,15 @@ prediction_manager()->UpdateHostModelFeaturesForTesting( get_models_response.get()); - EXPECT_TRUE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "example1.com")); + host_model_features = + prediction_manager()->GetHostModelFeaturesForHost("example1.com"); + EXPECT_TRUE(host_model_features); + // We expect the value to be stored as a float but is created from an int64 // value. - EXPECT_EQ( - 5.0, - prediction_manager() - ->GetHostModelFeaturesForTesting()["example1.com"]["host_feat1"]); - EXPECT_TRUE(prediction_manager() - ->GetHostModelFeaturesForTesting()["example1.com"] - .contains("host_feat_added")); - EXPECT_EQ(6.0, prediction_manager() - ->GetHostModelFeaturesForTesting()["example1.com"] - ["host_feat_added"]); + EXPECT_EQ(5.0, (*host_model_features)["host_feat1"]); + EXPECT_TRUE((*host_model_features).contains("host_feat_added")); + EXPECT_EQ(6.0, (*host_model_features)["host_feat_added"]); } TEST_P(PredictionManagerTest, ClientFeature) { @@ -1534,14 +1568,12 @@ {optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD}); EXPECT_FALSE(models_and_features_store()->WasHostModelFeaturesLoaded()); EXPECT_FALSE(models_and_features_store()->WasModelLoaded()); - EXPECT_FALSE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "foo.com")); + EXPECT_FALSE(prediction_manager()->GetHostModelFeaturesForHost("foo.com")); SetStoreInitialized(); EXPECT_TRUE(models_and_features_store()->WasHostModelFeaturesLoaded()); EXPECT_TRUE(models_and_features_store()->WasModelLoaded()); - EXPECT_TRUE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "foo.com")); + EXPECT_TRUE(prediction_manager()->GetHostModelFeaturesForHost("foo.com")); EXPECT_FALSE(prediction_model_fetcher()->models_fetched()); } @@ -1557,16 +1589,14 @@ EXPECT_FALSE(models_and_features_store()->WasHostModelFeaturesLoaded()); EXPECT_FALSE(models_and_features_store()->WasModelLoaded()); - EXPECT_FALSE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "foo.com")); + EXPECT_FALSE(prediction_manager()->GetHostModelFeaturesForHost("foo.com")); prediction_manager()->RegisterOptimizationTargets( {optimization_guide::proto::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD}); RunUntilIdle(); EXPECT_TRUE(models_and_features_store()->WasHostModelFeaturesLoaded()); EXPECT_TRUE(models_and_features_store()->WasModelLoaded()); - EXPECT_TRUE(prediction_manager()->GetHostModelFeaturesForTesting().contains( - "foo.com")); + EXPECT_TRUE(prediction_manager()->GetHostModelFeaturesForHost("foo.com")); EXPECT_FALSE(prediction_model_fetcher()->models_fetched()); }
diff --git a/chrome/browser/optimization_guide/prediction/prediction_model_fetcher.cc b/chrome/browser/optimization_guide/prediction/prediction_model_fetcher.cc index d28aeed2..e91876b 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_model_fetcher.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_model_fetcher.cc
@@ -12,6 +12,7 @@ #include "base/feature_list.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "chrome/browser/optimization_guide/optimization_guide_util.h" #include "components/optimization_guide/optimization_guide_features.h" #include "components/optimization_guide/proto/models.pb.h" #include "content/public/browser/network_service_instance.h" @@ -70,8 +71,19 @@ pending_models_request_->set_request_context(request_context); - for (const auto& host : hosts) + // Limit the number of hosts to fetch features for, the list of hosts + // is assumed to be ordered from most to least important by the top + // host provider. + for (const auto& host : hosts) { + // Skip over localhosts, IP addresses, and invalid hosts. + if (!IsHostValidToFetchFromRemoteOptimizationGuide(host)) + continue; pending_models_request_->add_hosts(host); + if (static_cast<size_t>(pending_models_request_->hosts_size()) >= + features::MaxHostsForOptimizationGuideServiceModelsFetch()) { + break; + } + } for (const auto& model_request_info : models_request_info) *pending_models_request_->add_requested_models() = model_request_info; @@ -122,7 +134,7 @@ UMA_HISTOGRAM_COUNTS_100( "OptimizationGuide.PredictionModelFetcher." "GetModelsRequest.HostCount", - hosts.size()); + pending_models_request_->hosts_size()); // |url_loader_| should not retry on 5xx errors since the server may already // be overloaded. |url_loader_| should retry on network changes since the
diff --git a/chrome/browser/optimization_guide/prediction/prediction_model_fetcher_unittest.cc b/chrome/browser/optimization_guide/prediction/prediction_model_fetcher_unittest.cc index 1272eadf..2124fd2 100644 --- a/chrome/browser/optimization_guide/prediction/prediction_model_fetcher_unittest.cc +++ b/chrome/browser/optimization_guide/prediction/prediction_model_fetcher_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <memory> +#include <string> #include <vector> #include "base/callback.h" @@ -10,10 +11,12 @@ #include "base/memory/scoped_refptr.h" #include "base/optional.h" #include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "chrome/browser/optimization_guide/prediction/prediction_model_fetcher.h" +#include "components/optimization_guide/optimization_guide_features.h" #include "components/optimization_guide/proto/models.pb.h" #include "net/base/url_util.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -138,6 +141,59 @@ 0, 1); } +TEST_F(PredictionModelFetcherTest, + FetchOptimizationGuideServiceModelsLimitHosts) { + base::HistogramTester histogram_tester; + std::string response_content; + std::vector<std::string> hosts; + for (size_t i = 0; + i <= features::MaxHostsForOptimizationGuideServiceModelsFetch() + 1; i++) + hosts.push_back("host" + base::NumberToString(i) + ".com"); + std::vector<optimization_guide::proto::ModelInfo> models_request_info({}); + EXPECT_TRUE(FetchModels( + models_request_info, hosts, + optimization_guide::proto::RequestContext::CONTEXT_BATCH_UPDATE)); + VerifyHasPendingFetchRequests(); + + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.PredictionModelFetcher.GetModelsRequest.HostCount", + features::MaxHostsForOptimizationGuideServiceModelsFetch(), 1); + + EXPECT_TRUE(SimulateResponse(response_content, net::HTTP_OK)); + EXPECT_TRUE(models_fetched()); + + // No HostModelFeatures are returned. + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.PredictionModelFetcher.GetModelsResponse." + "HostModelFeatureCount", + 0, 1); +} + +TEST_F(PredictionModelFetcherTest, FetchFilterInvalidHosts) { + base::HistogramTester histogram_tester; + std::string response_content; + std::vector<std::string> hosts = {"192.168.1.1", "_abc", "localhost", + "foo.com"}; + std::vector<optimization_guide::proto::ModelInfo> models_request_info({}); + EXPECT_TRUE(FetchModels( + models_request_info, hosts, + optimization_guide::proto::RequestContext::CONTEXT_BATCH_UPDATE)); + VerifyHasPendingFetchRequests(); + + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.PredictionModelFetcher.GetModelsRequest.HostCount", 1, + 1); + + EXPECT_TRUE(SimulateResponse(response_content, net::HTTP_OK)); + EXPECT_TRUE(models_fetched()); + + // No HostModelFeatures are returned. + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.PredictionModelFetcher.GetModelsResponse." + "HostModelFeatureCount", + 0, 1); +} + // Tests 404 response from request. TEST_F(PredictionModelFetcherTest, FetchReturned404) { base::HistogramTester histogram_tester;
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 6d18f89e..ff9cfd9 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -242,7 +242,6 @@ // We'll crash the renderer after it's loaded. case FINAL_STATUS_RENDERER_CRASHED: case FINAL_STATUS_CANCELLED: - case FINAL_STATUS_PAGE_BEING_CAPTURED: case FINAL_STATUS_NAVIGATION_UNCOMMITTED: case FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE: return false; @@ -267,11 +266,9 @@ // been called, before checking its state. class ChannelDestructionWatcher { public: - ChannelDestructionWatcher() : channel_destroyed_(false) { - } + ChannelDestructionWatcher() : channel_destroyed_(false) {} - ~ChannelDestructionWatcher() { - } + ~ChannelDestructionWatcher() = default; void WatchChannel(content::RenderProcessHost* host) { host->AddFilter(new DestructionMessageFilter(this)); @@ -287,10 +284,8 @@ // Ignores all messages. class DestructionMessageFilter : public content::BrowserMessageFilter { public: - explicit DestructionMessageFilter(ChannelDestructionWatcher* watcher) - : BrowserMessageFilter(0), - watcher_(watcher) { - } + explicit DestructionMessageFilter(ChannelDestructionWatcher* watcher) + : BrowserMessageFilter(0), watcher_(watcher) {} private: ~DestructionMessageFilter() override { @@ -361,13 +356,9 @@ tab_strip_model_->RemoveObserver(this); } - void set_did_start_loading() { - did_start_loading_ = true; - } + void set_did_start_loading() { did_start_loading_ = true; } - void Wait() { - loop_.Run(); - } + void Wait() { loop_.Run(); } // WebContentsObserver implementation: void DidStartLoading() override { did_start_loading_ = true; } @@ -533,9 +524,8 @@ } // Opens the url in a new tab, with no opener. - void NavigateToDestURLWithDisposition( - WindowOpenDisposition disposition, - bool expect_swap_to_succeed) const { + void NavigateToDestURLWithDisposition(WindowOpenDisposition disposition, + bool expect_swap_to_succeed) const { NavigateToURLWithParams( content::OpenURLParams(dest_url_, Referrer(), disposition, ui::PAGE_TRANSITION_TYPED, false), @@ -568,9 +558,7 @@ NavigateToURLImpl(params, expect_swap_to_succeed); } - void OpenDestURLViaClick() const { - OpenURLViaClick(dest_url_); - } + void OpenDestURLViaClick() const { OpenURLViaClick(dest_url_); } void OpenURLViaClick(const GURL& url) const { OpenURLWithJSImpl("Click", url, GURL(), false); @@ -596,9 +584,7 @@ #endif } - void OpenDestURLViaWindowOpen() const { - OpenURLViaWindowOpen(dest_url_); - } + void OpenDestURLViaWindowOpen() const { OpenURLViaWindowOpen(dest_url_); } void OpenURLViaWindowOpen(const GURL& url) const { OpenURLWithJSImpl("WindowOpen", url, GURL(), true); @@ -638,15 +624,11 @@ EXPECT_TRUE(original_prerender_page); } - void DisableJavascriptCalls() { - call_javascript_ = false; - } + void DisableJavascriptCalls() { call_javascript_ = false; } void EnableJavascriptCalls() { call_javascript_ = true; } - void DisableLoadEventCheck() { - check_load_events_ = false; - } + void DisableLoadEventCheck() { check_load_events_ = false; } const PrerenderLinkManager* GetPrerenderLinkManager() const { PrerenderLinkManager* prerender_link_manager = @@ -659,10 +641,11 @@ int event_count; std::string expression = base::StringPrintf( "window.domAutomationController.send(" - " GetPrerenderEventCount(%d, '%s'))", index, type.c_str()); + " GetPrerenderEventCount(%d, '%s'))", + index, type.c_str()); - CHECK(content::ExecuteScriptAndExtractInt( - GetActiveWebContents(), expression, &event_count)); + CHECK(content::ExecuteScriptAndExtractInt(GetActiveWebContents(), + expression, &event_count)); return event_count; } @@ -692,8 +675,8 @@ " window.domAutomationController, 0))", index, type.c_str(), count); - CHECK(content::ExecuteScriptAndExtractInt( - GetActiveWebContents(), expression, &dummy)); + CHECK(content::ExecuteScriptAndExtractInt(GetActiveWebContents(), + expression, &dummy)); CHECK_EQ(0, dummy); } @@ -742,13 +725,9 @@ loader_host_override_ = host; } - void set_loader_path(const std::string& path) { - loader_path_ = path; - } + void set_loader_path(const std::string& path) { loader_path_ = path; } - void set_loader_query(const std::string& query) { - loader_query_ = query; - } + void set_loader_query(const std::string& query) { loader_query_ = query; } GURL GetCrossDomainTestUrl(const std::string& path) { static const std::string secondary_domain = "www.foo.com"; @@ -758,9 +737,7 @@ return GURL(url_str); } - const GURL& dest_url() const { - return dest_url_; - } + const GURL& dest_url() const { return dest_url_; } bool DidPrerenderPass(WebContents* web_contents) const { bool prerender_test_result = false; @@ -789,8 +766,8 @@ } void AddPrerender(const GURL& url, int index) { - std::string javascript = base::StringPrintf( - "AddPrerender('%s', %d)", url.spec().c_str(), index); + std::string javascript = + base::StringPrintf("AddPrerender('%s', %d)", url.spec().c_str(), index); RenderFrameHost* render_frame_host = GetActiveWebContents()->GetMainFrame(); render_frame_host->ExecuteJavaScriptForTests(base::ASCIIToUTF16(javascript), base::NullCallback()); @@ -935,9 +912,9 @@ WebContents* web_contents = GetActiveWebContents(); RenderFrameHost* render_frame_host = web_contents->GetMainFrame(); // Extra arguments in JS are ignored. - std::string javascript = base::StringPrintf( - "%s('%s', '%s')", javascript_function_name.c_str(), - url.spec().c_str(), ping_url.spec().c_str()); + std::string javascript = + base::StringPrintf("%s('%s', '%s')", javascript_function_name.c_str(), + url.spec().c_str(), ping_url.spec().c_str()); if (new_web_contents) { NewTabNavigationOrSwapObserver observer; @@ -968,8 +945,6 @@ std::unique_ptr<content::URLLoaderInterceptor> interceptor_; }; - - // Checks that the correct page load metrics observers are produced without a // prerender. IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PageLoadMetricsSimple) { @@ -1032,8 +1007,8 @@ EXPECT_TRUE(IsEmptyPrerenderLinkManager()); } -IN_PROC_BROWSER_TEST_F( - PrerenderBrowserTest, PrerenderPageRemovingLinkWithTwoLinks) { +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, + PrerenderPageRemovingLinkWithTwoLinks) { GetPrerenderManager()->mutable_config().max_link_concurrency = 2; GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; @@ -1060,8 +1035,8 @@ EXPECT_TRUE(IsEmptyPrerenderLinkManager()); } -IN_PROC_BROWSER_TEST_F( - PrerenderBrowserTest, PrerenderPageRemovingLinkWithTwoLinksOneLate) { +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, + PrerenderPageRemovingLinkWithTwoLinksOneLate) { GetPrerenderManager()->mutable_config().max_link_concurrency = 2; GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; @@ -1092,9 +1067,8 @@ EXPECT_TRUE(IsEmptyPrerenderLinkManager()); } -IN_PROC_BROWSER_TEST_F( - PrerenderBrowserTest, - PrerenderPageRemovingLinkWithTwoLinksRemovingOne) { +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, + PrerenderPageRemovingLinkWithTwoLinksRemovingOne) { GetPrerenderManager()->mutable_config().max_link_concurrency = 2; GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2; set_loader_query("links_to_insert=2"); @@ -1196,16 +1170,16 @@ #if defined(USE_AURA) && !defined(OS_WIN) // http://crbug.com/103496 #define MAYBE_PrerenderIframeDelayLoadPlugin \ - DISABLED_PrerenderIframeDelayLoadPlugin + DISABLED_PrerenderIframeDelayLoadPlugin #elif defined(OS_MACOSX) // http://crbug.com/100514 #define MAYBE_PrerenderIframeDelayLoadPlugin \ - DISABLED_PrerenderIframeDelayLoadPlugin + DISABLED_PrerenderIframeDelayLoadPlugin #elif defined(OS_WIN) // TODO(jschuh): Failing plugin tests. https://crbug.com/244653, // https://crbug.com/876872 #define MAYBE_PrerenderIframeDelayLoadPlugin \ - DISABLED_PrerenderIframeDelayLoadPlugin + DISABLED_PrerenderIframeDelayLoadPlugin #else #define MAYBE_PrerenderIframeDelayLoadPlugin PrerenderIframeDelayLoadPlugin #endif @@ -1435,18 +1409,14 @@ prerender->contents()->web_contents()); ASSERT_TRUE(prerender->contents()); ASSERT_TRUE(prerender->contents()->prerender_contents()); - prerender->contents()->prerender_contents()->GetController(). - LoadURL( - GURL(content::kChromeUICrashURL), - content::Referrer(), - ui::PAGE_TRANSITION_TYPED, - std::string()); + prerender->contents()->prerender_contents()->GetController().LoadURL( + GURL(content::kChromeUICrashURL), content::Referrer(), + ui::PAGE_TRANSITION_TYPED, std::string()); prerender->WaitForStop(); } #endif -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, - PrerenderPageWithFragment) { +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageWithFragment) { PrerenderTestURL("/prerender/prerender_page.html#fragment", FINAL_STATUS_USED, 1); @@ -1577,8 +1547,7 @@ // Checks that a top-level page which would normally request an SSL client // certificate will never be seen since it's an https top-level resource. -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, - PrerenderSSLClientCertTopLevel) { +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertTopLevel) { ProfileNetworkContextServiceFactory::GetForContext( current_browser()->profile()) ->set_client_cert_store_factory_for_testing(base::BindRepeating( @@ -1618,8 +1587,7 @@ std::string replacement_path = net::test_server::GetFilePathWithReplacements( "/prerender/prerender_with_image.html", replacement_text); PrerenderTestURL(replacement_path, - FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, - 0); + FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 0); } // Checks that an SSL Client Certificate request that originates from an @@ -1645,8 +1613,7 @@ std::string replacement_path = net::test_server::GetFilePathWithReplacements( "/prerender/prerender_with_iframe.html", replacement_text); PrerenderTestURL(replacement_path, - FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, - 0); + FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 0); } // Ensures that we do not prerender pages with a safe browsing @@ -1689,9 +1656,7 @@ std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); std::string replacement_path = net::test_server::GetFilePathWithReplacements( "/prerender/prerender_with_image.html", replacement_text); - PrerenderTestURL(replacement_path, - FINAL_STATUS_SAFE_BROWSING, - 0); + PrerenderTestURL(replacement_path, FINAL_STATUS_SAFE_BROWSING, 0); } // Ensures that we do not prerender pages which have a malware iframe. @@ -1705,9 +1670,7 @@ std::make_pair("REPLACE_WITH_URL", iframe_url.spec())); std::string replacement_path = net::test_server::GetFilePathWithReplacements( "/prerender/prerender_with_iframe.html", replacement_text); - PrerenderTestURL(replacement_path, - FINAL_STATUS_SAFE_BROWSING, - 0); + PrerenderTestURL(replacement_path, FINAL_STATUS_SAFE_BROWSING, 0); } // Checks that the favicon is properly loaded on prerender. @@ -1813,8 +1776,7 @@ } // Checks that the referrer policy is used when prerendering on HTTPS. -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, - PrerenderSSLReferrerPolicy) { +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLReferrerPolicy) { UseHttpsSrcServer(); set_loader_path("/prerender/prerender_loader_with_referrer_policy.html"); PrerenderTestURL("/prerender/prerender_referrer_policy.html", @@ -1977,13 +1939,6 @@ NavigateToURLWithParams(params, false); } -// Checks that the prerendering of a page is canceled correctly when the -// prerendered page tries to make a second navigation entry. -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNewNavigationEntry) { - PrerenderTestURL("/prerender/prerender_new_entry.html", - FINAL_STATUS_NEW_NAVIGATION_ENTRY, 1); -} - // Attempt a swap-in in a new tab. The session storage doesn't match, so it // should not swap. IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) { @@ -2066,8 +2021,8 @@ scoped_refptr<password_manager::TestPasswordStore> password_store = static_cast<password_manager::TestPasswordStore*>( PasswordStoreFactory::GetForProfile( - current_browser()->profile(), - ServiceAccessType::IMPLICIT_ACCESS).get()); + current_browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS) + .get()); autofill::PasswordForm signin_form; signin_form.signon_realm = embedded_test_server()->base_url().spec(); signin_form.password_value = base::ASCIIToUTF16("password"); @@ -2127,9 +2082,7 @@ return current_browser()->window()->GetLocationBar(); } - OmniboxView* GetOmniboxView() { - return GetLocationBar()->GetOmniboxView(); - } + OmniboxView* GetOmniboxView() { return GetLocationBar()->GetOmniboxView(); } predictors::AutocompleteActionPredictor* GetAutocompleteActionPredictor() { Profile* profile = current_browser()->profile(); @@ -2144,8 +2097,7 @@ ExpectPrerender(expected_final_status); WebContents* web_contents = GetActiveWebContents(); GetAutocompleteActionPredictor()->StartPrerendering( - url, - web_contents->GetController().GetDefaultSessionStorageNamespace(), + url, web_contents->GetController().GetDefaultSessionStorageNamespace(), gfx::Size(50, 50)); prerender->WaitForStart(); return prerender; @@ -2232,9 +2184,8 @@ WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); bool display_test_result = false; - ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents, - "DidDisplayReallyPass()", - &display_test_result)); + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + web_contents, "DidDisplayReallyPass()", &display_test_result)); ASSERT_TRUE(display_test_result); } #endif // BUILDFLAG(ENABLE_NACL)
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc index 89fe0a3c..02e437c 100644 --- a/chrome/browser/prerender/prerender_contents.cc +++ b/chrome/browser/prerender/prerender_contents.cc
@@ -579,19 +579,6 @@ return; } - // If the prerender made a second navigation entry, abort the prerender. This - // avoids having to correctly implement a complex history merging case (this - // interacts with location.replace) and correctly synchronize with the - // renderer. The final status may be monitored to see we need to revisit this - // decision. This does not affect client redirects as those do not push new - // history entries. (Calls to location.replace, navigations before onload, and - // <meta http-equiv=refresh> with timeouts under 1 second do not create - // entries in Blink.) - if (prerender_contents_->GetController().GetEntryCount() > 1) { - Destroy(FINAL_STATUS_NEW_NAVIGATION_ENTRY); - return; - } - // Add each redirect as an alias. |navigation_handle->GetURL()| is included in // |navigation_handle->GetRedirectChain()|. //
diff --git a/chrome/browser/prerender/prerender_final_status.h b/chrome/browser/prerender/prerender_final_status.h index e8206c1..ef00240f 100644 --- a/chrome/browser/prerender/prerender_final_status.h +++ b/chrome/browser/prerender/prerender_final_status.h
@@ -61,10 +61,10 @@ // Obsolete: FINAL_STATUS_WOULD_HAVE_BEEN_USED = 41, FINAL_STATUS_REGISTER_PROTOCOL_HANDLER = 42, FINAL_STATUS_CREATING_AUDIO_STREAM = 43, - FINAL_STATUS_PAGE_BEING_CAPTURED = 44, + // Obsolete: FINAL_STATUS_PAGE_BEING_CAPTURED = 44, FINAL_STATUS_BAD_DEFERRED_REDIRECT = 45, FINAL_STATUS_NAVIGATION_UNCOMMITTED = 46, - FINAL_STATUS_NEW_NAVIGATION_ENTRY = 47, + // Obsolete: FINAL_STATUS_NEW_NAVIGATION_ENTRY = 47, // Obsolete: FINAL_STATUS_COOKIE_STORE_NOT_LOADED = 48, // Obsolete: FINAL_STATUS_COOKIE_CONFLICT = 49, FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE = 50,
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc index f406a71..02e3312 100644 --- a/chrome/browser/prerender/prerender_manager.cc +++ b/chrome/browser/prerender/prerender_manager.cc
@@ -251,9 +251,8 @@ origin = ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN; } // TODO(ajwong): This does not correctly handle storage for isolated apps. - session_storage_namespace = - source_web_contents->GetController() - .GetDefaultSessionStorageNamespace(); + session_storage_namespace = source_web_contents->GetController() + .GetDefaultSessionStorageNamespace(); } return AddPrerenderWithPreconnectFallback(origin, url, referrer, initiator_origin, gfx::Rect(size), @@ -357,8 +356,7 @@ // namespace. // TODO(ajwong): This doesn't handle isolated apps correctly. PrerenderData* prerender_data = FindPrerenderData( - url, - web_contents->GetController().GetDefaultSessionStorageNamespace()); + url, web_contents->GetController().GetDefaultSessionStorageNamespace()); if (!prerender_data) return false; DCHECK(prerender_data->contents()); @@ -397,7 +395,7 @@ } if (WebContents* new_web_contents = - prerender_data->contents()->prerender_contents()) { + prerender_data->contents()->prerender_contents()) { if (web_contents == new_web_contents) return nullptr; // Do not swap in to ourself. @@ -416,8 +414,8 @@ // Do not swap if the target WebContents is not the only WebContents in its // current BrowsingInstance. if (web_contents->GetSiteInstance()->GetRelatedActiveContentsCount() != 1u) { - DCHECK_GT( - web_contents->GetSiteInstance()->GetRelatedActiveContentsCount(), 1u); + DCHECK_GT(web_contents->GetSiteInstance()->GetRelatedActiveContentsCount(), + 1u); prerender_data->contents()->Destroy( FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE); return nullptr; @@ -429,12 +427,6 @@ return nullptr; } - // Do not swap in the prerender if the current WebContents is being captured. - if (web_contents->IsBeingCaptured()) { - prerender_data->contents()->Destroy(FINAL_STATUS_PAGE_BEING_CAPTURED); - return nullptr; - } - DCHECK(prerender_data->contents()->prerendering_has_started()); // At this point, we've determined that we will use the prerender. @@ -542,8 +534,8 @@ bool PrerenderManager::HasPrerenderedUrl( GURL url, content::WebContents* web_contents) const { - content::SessionStorageNamespace* session_storage_namespace = web_contents-> - GetController().GetDefaultSessionStorageNamespace(); + content::SessionStorageNamespace* session_storage_namespace = + web_contents->GetController().GetDefaultSessionStorageNamespace(); for (const auto& prerender_data : active_prerenders_) { PrerenderContents* prerender_contents = prerender_data->contents(); @@ -647,8 +639,8 @@ auto dict_value = std::make_unique<base::DictionaryValue>(); dict_value->Set("history", prerender_history_->CopyEntriesAsValue()); dict_value->Set("active", GetActivePrerendersAsValue()); - dict_value->SetBoolean("enabled", - GetPredictionStatus() == NetworkPredictionStatus::ENABLED); + dict_value->SetBoolean( + "enabled", GetPredictionStatus() == NetworkPredictionStatus::ENABLED); std::string disabled_note; if (GetPredictionStatus() == NetworkPredictionStatus::DISABLED_ALWAYS) disabled_note = "Disabled by user setting"; @@ -848,8 +840,8 @@ // TODO(ppi): Check whether there are usually enough render processes // available on Android. If not, kill an existing renderers so that we can // create a new one. - if (content::RenderProcessHost::ShouldTryToUseExistingProcessHost( - profile_, url) && + if (content::RenderProcessHost::ShouldTryToUseExistingProcessHost(profile_, + url) && !content::RenderProcessHost::run_renderer_in_process()) { SkipPrerenderContentsAndMaybePreconnect(url, origin, FINAL_STATUS_TOO_MANY_PROCESSES); @@ -1093,7 +1085,7 @@ if (!config_.rate_limit_enabled) return true; return elapsed_time >= - base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); + base::TimeDelta::FromMilliseconds(kMinTimeBetweenPrerendersMs); } void PrerenderManager::DeleteOldWebContents() { @@ -1189,8 +1181,7 @@ void PrerenderManager::AddToHistory(PrerenderContents* contents) { PrerenderHistory::Entry entry(contents->prerender_url(), - contents->final_status(), - contents->origin(), + contents->final_status(), contents->origin(), base::Time::Now()); prerender_history_->AddEntry(entry); }
diff --git a/chrome/browser/resources/chromeos/camera/.eslintrc.js b/chrome/browser/resources/chromeos/camera/.eslintrc.js index 432de3b..568edb00 100644 --- a/chrome/browser/resources/chromeos/camera/.eslintrc.js +++ b/chrome/browser/resources/chromeos/camera/.eslintrc.js
@@ -395,8 +395,7 @@ 'indent': 'off', // TODO(shik): temporarily disable the rules we violate (b/117810572). - 'no-redeclare': 'off', // 3 errors - 'no-var': 'off', // 181 errors + 'no-var': 'off', // 64 errors 'prefer-const': 'off', // 27 errors }), };
diff --git a/chrome/browser/ssl/ssl_error_handler.cc b/chrome/browser/ssl/ssl_error_handler.cc index 4ee5efb..4c892401 100644 --- a/chrome/browser/ssl/ssl_error_handler.cc +++ b/chrome/browser/ssl/ssl_error_handler.cc
@@ -23,6 +23,7 @@ #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" +#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/interstitials/enterprise_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/bad_clock_blocking_page.h"
diff --git a/chrome/browser/ssl/ssl_error_handler.h b/chrome/browser/ssl/ssl_error_handler.h index 350f1d5e..3994a7fb 100644 --- a/chrome/browser/ssl/ssl_error_handler.h +++ b/chrome/browser/ssl/ssl_error_handler.h
@@ -12,8 +12,6 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/common_name_mismatch_handler.h" #include "chrome/browser/ssl/ssl_error_assistant.pb.h" #include "components/security_interstitials/content/security_interstitial_page.h"
diff --git a/chrome/browser/ssl/ssl_error_handler_unittest.cc b/chrome/browser/ssl/ssl_error_handler_unittest.cc index a3d08283..ee6f125 100644 --- a/chrome/browser/ssl/ssl_error_handler_unittest.cc +++ b/chrome/browser/ssl/ssl_error_handler_unittest.cc
@@ -19,6 +19,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/captive_portal/captive_portal_service.h" +#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/common_name_mismatch_handler.h" #include "chrome/browser/ssl/ssl_error_assistant.h"
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc index 5b3bf3f..ba3cafb 100644 --- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -138,9 +138,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterListInsertingBrowserTest, MainFrameActivation_SubresourceFilterList) { - content::ConsoleObserverDelegate console_observer(web_contents(), - kActivationConsoleMessage); - web_contents()->SetDelegate(&console_observer); + content::WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(kActivationConsoleMessage); GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); ConfigureAsSubresourceFilterOnlyURL(url); ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix( @@ -159,7 +158,7 @@ ui_test_utils::NavigateToURL(browser(), url); EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - EXPECT_EQ(kActivationConsoleMessage, console_observer.message()); + EXPECT_FALSE(console_observer.messages().empty()); // The main frame document should never be filtered. SetRulesetToDisallowURLsWithPathSuffix("frame_with_included_script.html"); @@ -232,9 +231,8 @@ } IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, MainFrameActivation) { - content::ConsoleObserverDelegate console_observer(web_contents(), - kActivationConsoleMessage); - web_contents()->SetDelegate(&console_observer); + content::WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(kActivationConsoleMessage); GURL url(GetTestUrl("subresource_filter/frame_with_included_script.html")); ConfigureAsPhishingURL(url); ASSERT_NO_FATAL_FAILURE(SetRulesetToDisallowURLsWithPathSuffix( @@ -247,7 +245,7 @@ ui_test_utils::NavigateToURL(browser(), url); EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); - EXPECT_EQ(console_observer.message(), kActivationConsoleMessage); + EXPECT_FALSE(console_observer.messages().empty()); // The main frame document should never be filtered. SetRulesetToDisallowURLsWithPathSuffix("frame_with_included_script.html"); @@ -279,9 +277,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, SubFrameActivation) { std::string message_filter = base::StringPrintf(kBlinkDisallowSubframeConsoleMessageFormat, "*"); - content::ConsoleObserverDelegate console_observer(web_contents(), - message_filter); - web_contents()->SetDelegate(&console_observer); + content::WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(message_filter); GURL url(GetTestUrl(kTestFrameSetPath)); ConfigureAsPhishingURL(url); @@ -299,8 +296,9 @@ SubresourceFilterAction::kUIShown, 1); // Console message for subframe blocking should be displayed. + EXPECT_FALSE(console_observer.messages().empty()); EXPECT_TRUE(base::MatchPattern( - console_observer.message(), + base::UTF16ToUTF8(console_observer.messages()[0].message), base::StringPrintf(kBlinkDisallowSubframeConsoleMessageFormat, "*included_script.js"))); } @@ -309,9 +307,8 @@ ActivationDisabled_NoConsoleMessage) { std::string message_filter = base::StringPrintf(kBlinkDisallowSubframeConsoleMessageFormat, "*"); - content::ConsoleObserverDelegate console_observer(web_contents(), - message_filter); - web_contents()->SetDelegate(&console_observer); + content::WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(message_filter); Configuration config( subresource_filter::mojom::ActivationLevel::kDisabled, @@ -327,16 +324,15 @@ // Console message for subframe blocking should not be displayed as filtering // is disabled. - EXPECT_TRUE(console_observer.message().empty()); + EXPECT_TRUE(console_observer.messages().empty()); } IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, ActivationDryRun_NoConsoleMessage) { std::string message_filter = base::StringPrintf(kBlinkDisallowSubframeConsoleMessageFormat, "*"); - content::ConsoleObserverDelegate console_observer(web_contents(), - message_filter); - web_contents()->SetDelegate(&console_observer); + content::WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(message_filter); Configuration config( subresource_filter::mojom::ActivationLevel::kDryRun, @@ -352,7 +348,7 @@ // Console message for subframe blocking should not be displayed as filtering // is enabled in dryrun mode. - EXPECT_TRUE(console_observer.message().empty()); + EXPECT_TRUE(console_observer.messages().empty()); } IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, @@ -419,9 +415,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, HistoryNavigationActivation) { - content::ConsoleObserverDelegate console_observer(web_contents(), - kActivationConsoleMessage); - web_contents()->SetDelegate(&console_observer); + content::WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(kActivationConsoleMessage); GURL url_with_activation(GetTestUrl(kTestFrameSetPath)); GURL url_without_activation( embedded_test_server()->GetURL("a.com", kTestFrameSetPath)); @@ -440,14 +435,14 @@ kSubframeNames, kExpectScriptInFrameToLoadWithoutActivation)); // No message should be displayed for navigating to URL without activation. - EXPECT_TRUE(console_observer.message().empty()); + EXPECT_TRUE(console_observer.messages().empty()); ui_test_utils::NavigateToURL(browser(), url_with_activation); ASSERT_NO_FATAL_FAILURE(ExpectParsedScriptElementLoadedStatusInFrames( kSubframeNames, kExpectScriptInFrameToLoadWithActivation)); // Console message should now be displayed. - EXPECT_EQ(console_observer.message(), kActivationConsoleMessage); + EXPECT_EQ(1u, console_observer.messages().size()); ASSERT_TRUE(web_contents()->GetController().CanGoBack()); content::WindowedNotificationObserver back_navigation_stop_observer( @@ -506,9 +501,8 @@ // dynamically inserting a subframe afterwards, and still expecting activation. IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, PageLevelActivationOutlivesSameDocumentNavigation) { - content::ConsoleObserverDelegate console_observer(web_contents(), - kActivationConsoleMessage); - web_contents()->SetDelegate(&console_observer); + content::WebContentsConsoleObserver console_observer(web_contents()); + console_observer.SetPattern(kActivationConsoleMessage); GURL url(GetTestUrl(kTestFrameSetPath)); ConfigureAsPhishingURL(url); ASSERT_NO_FATAL_FAILURE( @@ -526,7 +520,7 @@ ASSERT_TRUE(dynamic_frame); EXPECT_FALSE(WasParsedScriptElementLoaded(dynamic_frame)); - EXPECT_EQ(console_observer.message(), kActivationConsoleMessage); + EXPECT_EQ(1u, console_observer.messages().size()); } // If a navigation starts but aborts before commit, page level activation should
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index bf51004..63807dbd 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1399,6 +1399,7 @@ "//chrome/browser/resource_coordinator:tab_metrics_event_proto", "//chrome/browser/resource_coordinator/tab_ranker", "//chrome/browser/safe_browsing:advanced_protection", + "//chrome/browser/ui/color:color_headers", "//chrome/browser/ui/webui/app_management:mojo_bindings", "//chrome/common:buildflags", "//chrome/common:search_mojom", @@ -1452,10 +1453,7 @@ } if (use_color_pipeline) { - deps += [ - "//chrome/browser/ui/color:color", - "//chrome/browser/ui/color:mixers", - ] + deps += [ "//chrome/browser/ui/color:mixers" ] } } @@ -2889,6 +2887,8 @@ "views/frame/toolbar_button_provider.h", "views/frame/top_container_background.cc", "views/frame/top_container_background.h", + "views/frame/top_container_loading_bar.cc", + "views/frame/top_container_loading_bar.h", "views/frame/top_container_view.cc", "views/frame/top_container_view.h", "views/frame/top_controls_slide_controller.h", @@ -4193,19 +4193,20 @@ "//ui/views:test_support", ] sources += [ - "extensions/browser_action_test_util.h", + "extensions/extension_action_test_helper.h", "views/extensions/extensions_menu_test_util.cc", "views/extensions/extensions_menu_test_util.h", "views/find_bar_host_unittest_util_views.cc", "views/payments/test_chrome_payment_request_delegate.cc", "views/payments/test_chrome_payment_request_delegate.h", - "views/toolbar/browser_action_test_util_views.cc", - "views/toolbar/browser_action_test_util_views_mac.mm", + "views/toolbar/extension_action_test_helper_mac.mm", + "views/toolbar/extension_action_test_helper_views.cc", + "views/toolbar/extension_action_test_helper_views.h", "views/webauthn/authenticator_request_dialog_view_test_api.cc", "views/webauthn/authenticator_request_dialog_view_test_api.h", ] if (use_aura) { - sources += [ "views/toolbar/browser_action_test_util_views_aura.cc" ] + sources += [ "views/toolbar/extension_action_test_helper_aura.cc" ] deps += [ "//ui/aura", "//ui/wm",
diff --git a/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_crostini_tracker.cc b/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_crostini_tracker.cc index ce0b46b..ba050ef 100644 --- a/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_crostini_tracker.cc +++ b/chrome/browser/ui/ash/launcher/app_service/app_service_app_window_crostini_tracker.cc
@@ -98,6 +98,13 @@ chromeos::ProfileHelper::Get()->GetProfileByAccountId( primary_account_id)); + // Windows without an application id set will get filtered out here. + const std::string& crostini_shelf_app_id = + registry_service->GetCrostiniShelfAppId( + exo::GetShellApplicationId(window), exo::GetShellStartupId(window)); + if (crostini_shelf_app_id.empty()) + return; + // At this point, all remaining windows are Crostini windows. Firstly, we add // support for forcibly closing it. We use the registration to retrieve the // app's name, but this may be null in the case of apps with no associated
diff --git a/chrome/browser/ui/color/BUILD.gn b/chrome/browser/ui/color/BUILD.gn index af9c61b..9dfbdcd 100644 --- a/chrome/browser/ui/color/BUILD.gn +++ b/chrome/browser/ui/color/BUILD.gn
@@ -4,42 +4,47 @@ import("//ui/base/ui_features.gni") -assert(use_color_pipeline) - -source_set("color") { +source_set("color_headers") { sources = [ "chrome_color_id.h", ] public_deps = [ - "//ui/color:color", + "//ui/color:color_headers", ] + + if (!use_color_pipeline) { + public_deps += [ "//chrome/browser:theme_properties" ] + } } -executable("dump_colors") { - testonly = true +if (use_color_pipeline) { + executable("dump_colors") { + testonly = true - sources = [ - "tools/dump_colors.cc", - ] + sources = [ + "tools/dump_colors.cc", + ] - deps = [ - ":color", - ":mixers", - "//ui/color:mixers", - ] -} + deps = [ + ":color_headers", + ":mixers", + "//ui/color:mixers", + ] + } -source_set("mixers") { - sources = [ - "chrome_color_mixers.cc", - "chrome_color_mixers.h", - "omnibox_color_mixers.cc", - "omnibox_color_mixers.h", - ] + source_set("mixers") { + sources = [ + "chrome_color_mixers.cc", + "chrome_color_mixers.h", + "omnibox_color_mixers.cc", + "omnibox_color_mixers.h", + ] - deps = [ - ":color", - "//ui/color:mixers", - ] + deps = [ + ":color_headers", + "//ui/color:color", + "//ui/color:mixers", + ] + } }
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index 07c5ffc..129343f 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -5,56 +5,80 @@ #ifndef CHROME_BROWSER_UI_COLOR_CHROME_COLOR_ID_H_ #define CHROME_BROWSER_UI_COLOR_CHROME_COLOR_ID_H_ +#include "ui/color/color_buildflags.h" #include "ui/color/color_id.h" +#if !BUILDFLAG(USE_COLOR_PIPELINE) +#include "chrome/browser/themes/theme_properties.h" // nogncheck +#endif + // TODO(pkasting): Add the rest of the colors. // clang-format off #define CHROME_COLOR_IDS \ /* Omnibox output colors. */ \ - E(kColorOmniboxBackground, kChromeColorsStart), \ - E(kColorOmniboxBackgroundHovered), \ - E(kColorOmniboxBubbleOutline), \ - E(kColorOmniboxBubbleOutlineExperimentalKeywordMode), \ - E(kColorOmniboxResultsBackground), \ - E(kColorOmniboxResultsBackgroundHovered), \ - E(kColorOmniboxResultsBackgroundSelected), \ - E(kColorOmniboxResultsIcon), \ - E(kColorOmniboxResultsIconSelected), \ - E(kColorOmniboxResultsTextDimmed), \ - E(kColorOmniboxResultsTextDimmedSelected), \ - E(kColorOmniboxResultsTextSelected), \ - E(kColorOmniboxResultsUrl), \ - E(kColorOmniboxResultsUrlSelected), \ - E(kColorOmniboxSecurityChipDangerous), \ - E(kColorOmniboxSecurityChipDefault), \ - E(kColorOmniboxSecurityChipSecure), \ - E(kColorOmniboxSelectedKeyword), \ - E(kColorOmniboxText), \ - E(kColorOmniboxTextDimmed), \ + E(kColorOmniboxBackground, \ + ThemeProperties::COLOR_OMNIBOX_BACKGROUND, kChromeColorsStart) \ + E(kColorOmniboxBackgroundHovered, \ + ThemeProperties::COLOR_OMNIBOX_BACKGROUND_HOVERED) \ + E(kColorOmniboxBubbleOutline, \ + ThemeProperties::COLOR_OMNIBOX_BUBBLE_OUTLINE) \ + E(kColorOmniboxBubbleOutlineExperimentalKeywordMode, \ + ThemeProperties::COLOR_OMNIBOX_BUBBLE_OUTLINE_EXPERIMENTAL_KEYWORD_MODE) \ + E(kColorOmniboxResultsBackground, \ + ThemeProperties::COLOR_OMNIBOX_RESULTS_BG) \ + E(kColorOmniboxResultsBackgroundHovered, \ + ThemeProperties::COLOR_OMNIBOX_RESULTS_BG_HOVERED) \ + E(kColorOmniboxResultsBackgroundSelected, \ + ThemeProperties::COLOR_OMNIBOX_RESULTS_BG_SELECTED) \ + E(kColorOmniboxResultsIcon, ThemeProperties::COLOR_OMNIBOX_RESULTS_ICON) \ + E(kColorOmniboxResultsIconSelected, \ + ThemeProperties::COLOR_OMNIBOX_RESULTS_ICON_SELECTED) \ + E(kColorOmniboxResultsTextDimmed, \ + ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED) \ + E(kColorOmniboxResultsTextDimmedSelected, \ + ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_DIMMED_SELECTED) \ + E(kColorOmniboxResultsTextSelected, \ + ThemeProperties::COLOR_OMNIBOX_RESULTS_TEXT_SELECTED) \ + E(kColorOmniboxResultsUrl, ThemeProperties::COLOR_OMNIBOX_RESULTS_URL) \ + E(kColorOmniboxResultsUrlSelected, \ + ThemeProperties::COLOR_OMNIBOX_RESULTS_URL_SELECTED) \ + E(kColorOmniboxSecurityChipDangerous, \ + ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_DANGEROUS) \ + E(kColorOmniboxSecurityChipDefault, \ + ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_DEFAULT) \ + E(kColorOmniboxSecurityChipSecure, \ + ThemeProperties::COLOR_OMNIBOX_SECURITY_CHIP_SECURE) \ + E(kColorOmniboxSelectedKeyword, \ + ThemeProperties::COLOR_OMNIBOX_SELECTED_KEYWORD) \ + E(kColorOmniboxText, ThemeProperties::COLOR_OMNIBOX_TEXT) \ + E(kColorOmniboxTextDimmed, ThemeProperties::COLOR_OMNIBOX_TEXT_DIMMED) \ \ - E(kColorToolbar) -// clang-format on + E(kColorToolbar, ThemeProperties::COLOR_TOOLBAR) #include "ui/color/color_id_macros.inc" enum ChromeColorIds : ui::ColorId { kChromeColorsStart = ui::kUiColorsEnd, - CHROME_COLOR_IDS, + CHROME_COLOR_IDS kChromeColorsEnd, }; #include "ui/color/color_id_macros.inc" +// clang-format on + static_assert(ui::ColorId{kChromeColorsEnd} <= ui::ColorId{ui::kUiColorsLast}, "Embedder colors must not exceed allowed space"); +#if BUILDFLAG(USE_COLOR_PIPELINE) enum ChromeColorSetIds : ui::ColorSetId { kColorSetCustomTheme = ui::kUiColorSetsEnd, kChromeColorSetsEnd, }; +#endif // BUILDFLAG(USE_COLOR_PIPELINE) #endif // CHROME_BROWSER_UI_COLOR_CHROME_COLOR_ID_H_
diff --git a/chrome/browser/ui/color/tools/dump_colors.cc b/chrome/browser/ui/color/tools/dump_colors.cc index 34e664e5..288e81d 100644 --- a/chrome/browser/ui/color/tools/dump_colors.cc +++ b/chrome/browser/ui/color/tools/dump_colors.cc
@@ -19,10 +19,12 @@ #define STRINGIZE_COLOR_IDS #include "ui/color/color_id_macros.inc" +// clang-format off const char* enum_names[] = { - COLOR_IDS, - CHROME_COLOR_IDS, + COLOR_IDS + CHROME_COLOR_IDS }; +// clang-format on #include "ui/color/color_id_macros.inc"
diff --git a/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc b/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc index 9ba1e34..9da7fc4 100644 --- a/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc +++ b/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/extensions/scripting_permissions_modifier.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/test/test_browser_dialog.h" #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" @@ -93,7 +93,7 @@ ASSERT_EQ(1u, toolbar_actions_bar->GetActions().size()); EXPECT_TRUE(toolbar_actions_bar->GetActions()[0]->WantsToRun(tab)); - BrowserActionTestUtil::Create(browser())->Press(0); + ExtensionActionTestHelper::Create(browser())->Press(0); EXPECT_TRUE(toolbar_actions_bar->is_showing_bubble()); }
diff --git a/chrome/browser/ui/extensions/browser_action_test_util.h b/chrome/browser/ui/extensions/extension_action_test_helper.h similarity index 82% rename from chrome/browser/ui/extensions/browser_action_test_util.h rename to chrome/browser/ui/extensions/extension_action_test_helper.h index 2a5002402..a0b4609 100644 --- a/chrome/browser/ui/extensions/browser_action_test_util.h +++ b/chrome/browser/ui/extensions/extension_action_test_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_EXTENSIONS_BROWSER_ACTION_TEST_UTIL_H_ -#define CHROME_BROWSER_UI_EXTENSIONS_BROWSER_ACTION_TEST_UTIL_H_ +#ifndef CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_ACTION_TEST_HELPER_H_ +#define CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_ACTION_TEST_HELPER_H_ #include <stddef.h> @@ -22,16 +22,16 @@ class Size; } // namespace gfx -class BrowserActionTestUtil { +class ExtensionActionTestHelper { public: - // Constructs a BrowserActionTestUtil which, if |is_real_window| is false, + // Constructs a ExtensionActionTestHelper which, if |is_real_window| is false, // will create its own browser actions container. This is useful in unit // tests, when the |browser|'s window doesn't create platform-specific views. - static std::unique_ptr<BrowserActionTestUtil> Create( + static std::unique_ptr<ExtensionActionTestHelper> Create( Browser* browser, bool is_real_window = true); - virtual ~BrowserActionTestUtil() {} + virtual ~ExtensionActionTestHelper() {} // Returns the number of browser action buttons in the window toolbar. virtual int NumberOfBrowserActions() = 0; @@ -91,9 +91,9 @@ // Returns the associated ExtensionsContainer. virtual ExtensionsContainer* GetExtensionsContainer() = 0; - // Creates and returns a BrowserActionTestUtil with an "overflow" container, - // with this object's container as the main bar. - virtual std::unique_ptr<BrowserActionTestUtil> CreateOverflowBar( + // Creates and returns a ExtensionActionTestHelper with an "overflow" + // container, with this object's container as the main bar. + virtual std::unique_ptr<ExtensionActionTestHelper> CreateOverflowBar( Browser* browser) = 0; // Returns the minimum allowed size of an extension popup. @@ -109,10 +109,10 @@ virtual bool CanBeResized() = 0; protected: - BrowserActionTestUtil() {} + ExtensionActionTestHelper() {} private: - DISALLOW_COPY_AND_ASSIGN(BrowserActionTestUtil); + DISALLOW_COPY_AND_ASSIGN(ExtensionActionTestHelper); }; -#endif // CHROME_BROWSER_UI_EXTENSIONS_BROWSER_ACTION_TEST_UTIL_H_ +#endif // CHROME_BROWSER_UI_EXTENSIONS_EXTENSION_ACTION_TEST_HELPER_H_
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc b/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc index d6eae57..5efd0d41 100644 --- a/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc +++ b/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc
@@ -44,7 +44,7 @@ class LegacyToolbarTestHelper { public: explicit LegacyToolbarTestHelper(Browser* browser) - : test_util_(BrowserActionTestUtil::Create(browser, false)), + : test_util_(ExtensionActionTestHelper::Create(browser, false)), overflow_test_util_(test_util_->CreateOverflowBar(browser)), main_bar_(test_util_->GetToolbarActionsBar()), overflow_bar_(overflow_test_util_->GetToolbarActionsBar()) { @@ -61,8 +61,8 @@ ToolbarActionsBar* overflow_bar() { return overflow_bar_; } private: - std::unique_ptr<BrowserActionTestUtil> test_util_; - std::unique_ptr<BrowserActionTestUtil> overflow_test_util_; + std::unique_ptr<ExtensionActionTestHelper> test_util_; + std::unique_ptr<ExtensionActionTestHelper> overflow_test_util_; ToolbarActionsBar* main_bar_ = nullptr; ToolbarActionsBar* overflow_bar_ = nullptr; }; @@ -112,7 +112,7 @@ extension_service_ = extensions::ExtensionSystem::Get(profile())->extension_service(); - test_util_ = BrowserActionTestUtil::Create(browser(), false); + test_util_ = ExtensionActionTestHelper::Create(browser(), false); view_size_ = test_util_->GetToolbarActionSize(); } @@ -172,7 +172,7 @@ // ToolbarActionsModel associated with the main profile. ToolbarActionsModel* toolbar_model_ = nullptr; - std::unique_ptr<BrowserActionTestUtil> test_util_; + std::unique_ptr<ExtensionActionTestHelper> test_util_; // The standard size associated with a toolbar action view. gfx::Size view_size_;
diff --git a/chrome/browser/ui/search/local_ntp_js_browsertest.cc b/chrome/browser/ui/search/local_ntp_js_browsertest.cc index 6ac8c42..a868a53 100644 --- a/chrome/browser/ui/search/local_ntp_js_browsertest.cc +++ b/chrome/browser/ui/search/local_ntp_js_browsertest.cc
@@ -80,8 +80,9 @@ EXPECT_TRUE(success); } +// TODO(crbug.com/1038385): This test is flaky. // This runs a bunch of pure JS-side tests for the richer picker. -IN_PROC_BROWSER_TEST_F(LocalNTPJavascriptTest, CustomizeMenuTests) { +IN_PROC_BROWSER_TEST_F(LocalNTPJavascriptTest, DISABLED_CustomizeMenuTests) { content::WebContents* active_tab = local_ntp_test_utils::OpenNewTab( browser(), GURL(chrome::kChromeUINewTabURL)); ASSERT_TRUE(search::IsInstantNTP(active_tab));
diff --git a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc index 7dbbb287..e0faeeb0 100644 --- a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc +++ b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
@@ -22,7 +22,7 @@ #include "chrome/browser/extensions/scripting_permissions_modifier.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/extensions/extension_action_view_controller.h" #include "chrome/browser/ui/extensions/icon_with_badge_image_source.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -106,7 +106,7 @@ void BrowserActionsBarBrowserTest::SetUpOnMainThread() { extensions::ExtensionBrowserTest::SetUpOnMainThread(); - browser_actions_bar_ = BrowserActionTestUtil::Create(browser()); + browser_actions_bar_ = ExtensionActionTestHelper::Create(browser()); toolbar_model_ = ToolbarActionsModel::Get(profile()); } @@ -396,7 +396,7 @@ IN_PROC_BROWSER_TEST_F(BrowserActionsBarBrowserTest, OverflowedBrowserActionPopupTest) { - std::unique_ptr<BrowserActionTestUtil> overflow_bar = + std::unique_ptr<ExtensionActionTestHelper> overflow_bar = browser_actions_bar()->CreateOverflowBar(browser()); // Load up two extensions that have browser action popups. @@ -483,7 +483,7 @@ // Regression test for crbug.com/599467. IN_PROC_BROWSER_TEST_F(BrowserActionsBarBrowserTest, OverflowedBrowserActionPopupTestRemoval) { - std::unique_ptr<BrowserActionTestUtil> overflow_bar = + std::unique_ptr<ExtensionActionTestHelper> overflow_bar = browser_actions_bar()->CreateOverflowBar(browser()); // Install an extension and shrink the visible count to zero so the extension
diff --git a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.h b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.h index e2bcb4c5..bb3f0d22 100644 --- a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.h +++ b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.h
@@ -16,7 +16,7 @@ class Extension; } -class BrowserActionTestUtil; +class ExtensionActionTestHelper; class ToolbarActionsModel; // A platform-independent browser test class for the browser actions bar. @@ -29,7 +29,7 @@ void SetUpOnMainThread() override; void TearDownOnMainThread() override; - BrowserActionTestUtil* browser_actions_bar() { + ExtensionActionTestHelper* browser_actions_bar() { return browser_actions_bar_.get(); } ToolbarActionsModel* toolbar_model() { return toolbar_model_; } @@ -52,7 +52,7 @@ private: base::test::ScopedFeatureList feature_list_; - std::unique_ptr<BrowserActionTestUtil> browser_actions_bar_; + std::unique_ptr<ExtensionActionTestHelper> browser_actions_bar_; // The associated toolbar model, weak. ToolbarActionsModel* toolbar_model_;
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc index a20d6252..de9663c 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc
@@ -58,7 +58,7 @@ // order matches, the return value is empty; otherwise, it contains the error. std::string VerifyToolbarOrderForBar( const ToolbarActionsBar* actions_bar, - BrowserActionTestUtil* browser_action_test_util, + ExtensionActionTestHelper* browser_action_test_util, const char* expected_names[], size_t total_size, size_t visible_count) { @@ -172,7 +172,8 @@ profile()); ToolbarActionsBar::disable_animations_for_testing_ = true; - browser_action_test_util_ = BrowserActionTestUtil::Create(browser(), false); + browser_action_test_util_ = + ExtensionActionTestHelper::Create(browser(), false); overflow_browser_action_test_util_ = browser_action_test_util_->CreateOverflowBar(browser());
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.h b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.h index 78a0a0f..6385e6d 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.h +++ b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/test/scoped_feature_list.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "extensions/common/extension_builder.h" @@ -75,10 +75,10 @@ return overflow_browser_action_test_util_->GetToolbarActionsBar(); } ToolbarActionsModel* toolbar_model() { return toolbar_model_; } - BrowserActionTestUtil* browser_action_test_util() { + ExtensionActionTestHelper* browser_action_test_util() { return browser_action_test_util_.get(); } - BrowserActionTestUtil* overflow_browser_action_test_util() { + ExtensionActionTestHelper* overflow_browser_action_test_util() { return overflow_browser_action_test_util_.get(); } @@ -88,12 +88,12 @@ // The associated ToolbarActionsModel (owned by the keyed service setup). ToolbarActionsModel* toolbar_model_; - // A BrowserActionTestUtil object constructed with the associated + // A ExtensionActionTestHelper object constructed with the associated // ToolbarActionsBar. - std::unique_ptr<BrowserActionTestUtil> browser_action_test_util_; + std::unique_ptr<ExtensionActionTestHelper> browser_action_test_util_; - // The overflow container's BrowserActionTestUtil. - std::unique_ptr<BrowserActionTestUtil> overflow_browser_action_test_util_; + // The overflow container's ExtensionActionTestHelper. + std::unique_ptr<ExtensionActionTestHelper> overflow_browser_action_test_util_; std::unique_ptr<ui::test::MaterialDesignControllerTestAPI> material_design_state_;
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.cc index f0d6be4..aea9b9e 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.cc +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.cc
@@ -22,11 +22,12 @@ LocalCardMigrationIconView::LocalCardMigrationIconView( CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate) + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) : PageActionIconView(command_updater, IDC_MIGRATE_LOCAL_CREDIT_CARD_FOR_PAGE, - delegate) { - DCHECK(delegate); + icon_label_bubble_delegate, + page_action_icon_delegate) { SetID(VIEW_ID_MIGRATE_LOCAL_CREDIT_CARD_BUTTON); if (base::FeatureList::IsEnabled( features::kAutofillCreditCardUploadFeedback)) {
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h b/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h index a4c65ec..877e7d3 100644 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h +++ b/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h
@@ -18,8 +18,10 @@ // bubble. class LocalCardMigrationIconView : public PageActionIconView { public: - LocalCardMigrationIconView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate); + LocalCardMigrationIconView( + CommandUpdater* command_updater, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~LocalCardMigrationIconView() override; // PageActionIconView:
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_icon_view.cc b/chrome/browser/ui/views/autofill/payments/save_card_icon_view.cc index a6d0fb5..5dae0121 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_icon_view.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_icon_view.cc
@@ -19,12 +19,14 @@ namespace autofill { -SaveCardIconView::SaveCardIconView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate) +SaveCardIconView::SaveCardIconView( + CommandUpdater* command_updater, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) : PageActionIconView(command_updater, IDC_SAVE_CREDIT_CARD_FOR_PAGE, - delegate) { - DCHECK(delegate); + icon_label_bubble_delegate, + page_action_icon_delegate) { SetID(VIEW_ID_SAVE_CREDIT_CARD_BUTTON); if (base::FeatureList::IsEnabled(
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_icon_view.h b/chrome/browser/ui/views/autofill/payments/save_card_icon_view.h index 8306c762..601d1a7 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_icon_view.h +++ b/chrome/browser/ui/views/autofill/payments/save_card_icon_view.h
@@ -20,7 +20,8 @@ class SaveCardIconView : public PageActionIconView { public: SaveCardIconView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate); + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~SaveCardIconView() override; // PageActionIconView:
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 9c73dce..95a3385 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc
@@ -178,7 +178,7 @@ return extensions_container_; } -std::unique_ptr<BrowserActionTestUtil> +std::unique_ptr<ExtensionActionTestHelper> ExtensionsMenuTestUtil::CreateOverflowBar(Browser* browser) { // There is no overflow bar with the ExtensionsMenu implementation. NOTREACHED();
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_test_util.h b/chrome/browser/ui/views/extensions/extensions_menu_test_util.h index 1c7f391..b963740 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_test_util.h +++ b/chrome/browser/ui/views/extensions/extensions_menu_test_util.h
@@ -9,22 +9,22 @@ #include "base/auto_reset.h" #include "base/macros.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" class Browser; class ExtensionsMenuItemView; class ExtensionsMenuView; class ExtensionsToolbarContainer; -// An implementation of BrowserActionTestUtil that works with the ExtensionsMenu -// (i.e., when features::kExtensionsToolbarMenu is enabled). -class ExtensionsMenuTestUtil : public BrowserActionTestUtil { +// An implementation of ExtensionActionTestHelper that works with the +// ExtensionsMenu (i.e., when features::kExtensionsToolbarMenu is enabled). +class ExtensionsMenuTestUtil : public ExtensionActionTestHelper { public: ExtensionsMenuTestUtil(Browser* browser, bool is_real_window); ~ExtensionsMenuTestUtil() override; - // BrowserActionTestUtil: + // ExtensionActionTestHelper: int NumberOfBrowserActions() override; int VisibleBrowserActions() override; void InspectPopup(int index) override; @@ -41,10 +41,10 @@ void SetWidth(int width) override; ToolbarActionsBar* GetToolbarActionsBar() override; ExtensionsContainer* GetExtensionsContainer() override; - std::unique_ptr<BrowserActionTestUtil> CreateOverflowBar( + std::unique_ptr<ExtensionActionTestHelper> CreateOverflowBar( Browser* browser) override; // TODO(devlin): Some of these popup methods have a common implementation - // between this and BrowserActionTestUtilViews. It would make sense to + // between this and ExtensionActionTestHelperViews. It would make sense to // extract them (since they aren't dependent on the extension action UI // implementation). gfx::Size GetMinPopupSize() override;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index bbdd28e..4695525 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc
@@ -750,14 +750,14 @@ class WebAppNonClientFrameViewAshTest : public TopChromeMdParamTest<BrowserActionsBarBrowserTest> { public: - WebAppNonClientFrameViewAshTest() - : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} + WebAppNonClientFrameViewAshTest() = default; ~WebAppNonClientFrameViewAshTest() override = default; - GURL GetAppURL() { + GURL GetAppURL() const { return https_server_.GetURL("app.com", "/ssl/google.html"); } + static SkColor GetThemeColor() { return SK_ColorBLUE; } Browser* app_browser_ = nullptr; @@ -832,9 +832,11 @@ AppMenu* GetAppMenu() { return web_app_menu_button_->app_menu(); } - SkColor GetActiveColor() { return web_app_frame_toolbar_->active_color_; } + SkColor GetActiveColor() const { + return web_app_frame_toolbar_->active_color_; + } - bool GetPaintingAsActive() { + bool GetPaintingAsActive() const { return web_app_frame_toolbar_->paint_as_active_; } @@ -853,9 +855,9 @@ return *std::find_if( content_setting_views_->begin(), content_setting_views_->end(), - [](auto v) { - return ContentSettingImageModel::ImageType::GEOLOCATION == - v->GetTypeForTesting(); + [](const auto* view) { + return view->GetTypeForTesting() == + ContentSettingImageModel::ImageType::GEOLOCATION; }); } @@ -873,7 +875,7 @@ private: // For mocking a secure site. - net::EmbeddedTestServer https_server_; + net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS}; content::ContentMockCertVerifier cert_verifier_; DISALLOW_COPY_AND_ASSIGN(WebAppNonClientFrameViewAshTest);
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 5698f4d0..a0435f11 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -87,6 +87,7 @@ #include "chrome/browser/ui/views/frame/contents_layout_manager.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" #include "chrome/browser/ui/views/frame/tab_strip_region_view.h" +#include "chrome/browser/ui/views/frame/top_container_loading_bar.h" #include "chrome/browser/ui/views/frame/top_container_view.h" #include "chrome/browser/ui/views/frame/web_contents_close_handler.h" #include "chrome/browser/ui/views/frame/web_footer_experiment_view.h" @@ -898,6 +899,8 @@ // read out to screen readers, even if focus doesn't actually change. GetWidget()->GetFocusManager()->ClearFocus(); } + if (loading_bar_) + loading_bar_->SetWebContents(nullptr); contents_web_view_->SetWebContents(nullptr); devtools_web_view_->SetWebContents(nullptr); } @@ -939,6 +942,8 @@ } web_contents_close_handler_->ActiveTabChanged(); + if (loading_bar_) + loading_bar_->SetWebContents(new_contents); contents_web_view_->SetWebContents(new_contents); SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(new_contents); if (sad_tab_helper) @@ -968,6 +973,8 @@ // freed. This is because the focus manager performs some operations // on the selected WebContents when it is removed. web_contents_close_handler_->ActiveTabChanged(); + if (loading_bar_) + loading_bar_->SetWebContents(nullptr); contents_web_view_->SetWebContents(nullptr); infobar_container_->ChangeInfoBarManager(nullptr); app_banner_manager_observer_.RemoveAll(); @@ -1777,6 +1784,9 @@ if (selection.selection_changed()) toolbar_->InvalidateLayout(); + if (loading_bar_) + loading_bar_->SetWebContents(GetActiveWebContents()); + if (change.type() != TabStripModelChange::kInserted) return; @@ -2697,13 +2707,21 @@ webui_tab_strip_ = top_container_->AddChildView( std::make_unique<WebUITabStripContainerView>(browser_.get(), contents_container_)); + loading_bar_ = top_container_->AddChildView( + std::make_unique<TopContainerLoadingBar>()); + loading_bar_->SetWebContents(GetActiveWebContents()); } } else if (webui_tab_strip_) { top_container_->RemoveChildView(webui_tab_strip_); delete webui_tab_strip_; webui_tab_strip_ = nullptr; + + top_container_->RemoveChildView(loading_bar_); + delete loading_bar_; + loading_bar_ = nullptr; } GetBrowserViewLayout()->set_webui_tab_strip(webui_tab_strip_); + GetBrowserViewLayout()->set_loading_bar(loading_bar_); if (toolbar_) toolbar_->UpdateForWebUITabStrip(); #endif // BUILDFLAG(ENABLE_WEBUI_TAB_STRIP)
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 64c8886..4bf8b2c 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -68,6 +68,7 @@ class TabStripRegionView; class ToolbarButtonProvider; class ToolbarView; +class TopContainerLoadingBar; class TopContainerView; class TopControlsSlideControllerTest; class WebContentsCloseHandler; @@ -753,6 +754,9 @@ // Separator between top container and contents. views::View* contents_separator_ = nullptr; + // Loading bar (part of top container for / WebUI tab strip). + TopContainerLoadingBar* loading_bar_ = nullptr; + // The do-nothing view which controls the z-order of the find bar widget // relative to views which paint into layers and views with an associated // NativeView.
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc index 8cee9e7..d05dc2d 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.cc +++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -396,9 +396,18 @@ contents_separator_->SetBounds(vertical_layout_rect_.x(), top, vertical_layout_rect_.width(), separator_height); + if (loading_bar_) { + SetViewVisibility(loading_bar_, true); + loading_bar_->SetBounds(vertical_layout_rect_.x(), top - 2, + vertical_layout_rect_.width(), + separator_height + 2); + top_container_->ReorderChildView(loading_bar_, -1); + } top += separator_height; } else { SetViewVisibility(contents_separator_, false); + if (loading_bar_) + SetViewVisibility(loading_bar_, false); } return LayoutInfoBar(top);
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.h b/chrome/browser/ui/views/frame/browser_view_layout.h index 1beb8af..bc6841c 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.h +++ b/chrome/browser/ui/views/frame/browser_view_layout.h
@@ -67,6 +67,7 @@ void set_webui_tab_strip(views::View* webui_tab_strip) { webui_tab_strip_ = webui_tab_strip; } + void set_loading_bar(views::View* loading_bar) { loading_bar_ = loading_bar; } void set_bookmark_bar(BookmarkBarView* bookmark_bar) { bookmark_bar_ = bookmark_bar; } @@ -154,6 +155,7 @@ views::View* const contents_separator_; views::View* webui_tab_strip_ = nullptr; + views::View* loading_bar_ = nullptr; TabStrip* tab_strip_ = nullptr; BookmarkBarView* bookmark_bar_ = nullptr; views::View* download_shelf_ = nullptr;
diff --git a/chrome/browser/ui/views/frame/top_container_loading_bar.cc b/chrome/browser/ui/views/frame/top_container_loading_bar.cc new file mode 100644 index 0000000..a8751e1 --- /dev/null +++ b/chrome/browser/ui/views/frame/top_container_loading_bar.cc
@@ -0,0 +1,155 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/frame/top_container_loading_bar.h" + +#include "chrome/browser/favicon/favicon_utils.h" +#include "chrome/browser/ui/tab_ui_helper.h" +#include "ui/gfx/animation/tween.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/color_palette.h" + +LoadingBarView::LoadingBarView() { + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); + animation_.SetDuration(base::TimeDelta::FromMilliseconds(300)); +} + +double LoadingBarView::GetDisplayedLoadingProgress() const { + return gfx::Tween::DoubleValueBetween( + gfx::Tween::CalculateValue(gfx::Tween::EASE_OUT, + animation_.GetCurrentValue()), + start_loading_progress_, target_loading_progress_); +} + +void LoadingBarView::OnThemeChanged() { + SchedulePaint(); +} + +void LoadingBarView::AddedToWidget() { + SchedulePaint(); +} + +void LoadingBarView::HideImmediately() { + is_shown_when_not_animating_ = false; + start_loading_progress_ = 0.0; + target_loading_progress_ = 0.0; + animation_.Stop(); + // If we were previously drawn we have to redraw as invisible. + SchedulePaint(); +} + +void LoadingBarView::Show(double loading_progress) { + is_shown_when_not_animating_ = true; + start_loading_progress_ = loading_progress; + target_loading_progress_ = loading_progress; + animation_.Stop(); + SchedulePaint(); +} + +void LoadingBarView::FinishLoading() { + if (!is_shown_when_not_animating_) + return; + SetLoadingProgress(1.0); + is_shown_when_not_animating_ = false; +} + +void LoadingBarView::SetLoadingProgress(double loading_progress) { + if (loading_progress <= target_loading_progress_) + return; + start_loading_progress_ = GetDisplayedLoadingProgress(); + target_loading_progress_ = loading_progress; + animation_.SetCurrentValue(0.0); + animation_.Start(); +} + +void LoadingBarView::OnPaint(gfx::Canvas* canvas) { + if (is_shown_when_not_animating_ || animation_.is_animating()) { + canvas->FillRect(GetLocalBounds(), gfx::kGoogleBlue100); + gfx::Rect progress_bounds(GetLocalBounds()); + progress_bounds.set_width(gfx::Tween::IntValueBetween( + GetDisplayedLoadingProgress(), 0, progress_bounds.width())); + canvas->FillRect(progress_bounds, gfx::kGoogleBlue500); + } +} + +void LoadingBarView::AnimationEnded(const gfx::Animation* animation) { + SchedulePaint(); +} + +void LoadingBarView::AnimationProgressed(const gfx::Animation* animation) { + SchedulePaint(); +} + +TopContainerLoadingBar::TopContainerLoadingBar() = default; + +void TopContainerLoadingBar::SetWebContents( + content::WebContents* web_contents) { + Observe(web_contents); + + if (!web_contents) { + network_state_ = TabNetworkState::kNone; + HideImmediately(); + return; + } + + // TODO(pbos): Consider storing one loading bar per tab and have it run (and + // observing) in the background. This would remove the need to reset + // loading-bar state during tab transitions as we'd just swap in the visible + // object. Currently Show(GetLoadingProgress()) can decrease from what was + // previously displayed in that tab. + + // Reset network state to update from a clean slate. + network_state_ = TabNetworkState::kNone; + UpdateLoadingProgress(); +} + +void TopContainerLoadingBar::UpdateLoadingProgress() { + DCHECK(web_contents()); + if (!favicon::ShouldDisplayFavicon(web_contents())) { + HideImmediately(); + return; + } + + TabUIHelper* const tab_ui_helper = + TabUIHelper::FromWebContents(web_contents()); + if (tab_ui_helper->ShouldHideThrobber()) { + HideImmediately(); + return; + } + + const TabNetworkState old_network_state = network_state_; + network_state_ = TabNetworkStateForWebContents(web_contents()); + if (old_network_state != network_state_) { + if (network_state_ == TabNetworkState::kWaiting || + network_state_ == TabNetworkState::kLoading) { + // Reset loading state when we go to waiting or loading. + Show(GetLoadingProgress()); + } + } + + switch (network_state_) { + case TabNetworkState::kLoading: + SetLoadingProgress(GetLoadingProgress()); + break; + case TabNetworkState::kError: + // TODO(pbos): Add a better error indicator (fade-out red?). + HideImmediately(); + break; + case TabNetworkState::kWaiting: + break; + case TabNetworkState::kNone: + FinishLoading(); + break; + } +} + +double TopContainerLoadingBar::GetLoadingProgress() { + DCHECK(web_contents()); + return std::min(web_contents()->GetLoadProgress(), 0.9); +} + +void TopContainerLoadingBar::LoadProgressChanged(double progress) { + UpdateLoadingProgress(); +}
diff --git a/chrome/browser/ui/views/frame/top_container_loading_bar.h b/chrome/browser/ui/views/frame/top_container_loading_bar.h new file mode 100644 index 0000000..79fd2d3 --- /dev/null +++ b/chrome/browser/ui/views/frame/top_container_loading_bar.h
@@ -0,0 +1,63 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_TOP_CONTAINER_LOADING_BAR_H_ +#define CHROME_BROWSER_UI_VIEWS_FRAME_TOP_CONTAINER_LOADING_BAR_H_ + +#include "chrome/browser/ui/tabs/tab_network_state.h" +#include "content/public/browser/web_contents_observer.h" +#include "ui/gfx/animation/animation_delegate.h" +#include "ui/gfx/animation/linear_animation.h" +#include "ui/views/view.h" + +class LoadingBarView : public views::View, public gfx::AnimationDelegate { + public: + LoadingBarView(); + LoadingBarView(const LoadingBarView&) = delete; + LoadingBarView& operator=(const LoadingBarView&) = delete; + + void HideImmediately(); + void Show(double loading_progress); + void FinishLoading(); + + void SetLoadingProgress(double loading_progress); + + private: + double GetDisplayedLoadingProgress() const; + + // views::View: + void OnThemeChanged() override; + void AddedToWidget() override; + void OnPaint(gfx::Canvas* canvas) override; + + // gfx::AnimationDelegate: + void AnimationEnded(const gfx::Animation* animation) override; + void AnimationProgressed(const gfx::Animation* animation) override; + + gfx::LinearAnimation animation_{this}; + bool is_shown_when_not_animating_ = false; + double start_loading_progress_ = 0.0; + double target_loading_progress_ = 0.0; +}; + +class TopContainerLoadingBar : public LoadingBarView, + public content::WebContentsObserver { + public: + TopContainerLoadingBar(); + TopContainerLoadingBar(const TopContainerLoadingBar&) = delete; + TopContainerLoadingBar& operator=(const TopContainerLoadingBar&) = delete; + + void SetWebContents(content::WebContents* web_contents); + + private: + void UpdateLoadingProgress(); + double GetLoadingProgress(); + + // content::WebContentsObserver: + void LoadProgressChanged(double progress) override; + + TabNetworkState network_state_ = TabNetworkState::kNone; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_FRAME_TOP_CONTAINER_LOADING_BAR_H_
diff --git a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc index 8db29526..35218a63 100644 --- a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc +++ b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
@@ -70,9 +70,10 @@ ContentSettingImageView::ContentSettingImageView( std::unique_ptr<ContentSettingImageModel> image_model, + IconLabelBubbleView::Delegate* parent_delegate, Delegate* delegate, const gfx::FontList& font_list) - : IconLabelBubbleView(font_list), + : IconLabelBubbleView(font_list, parent_delegate), delegate_(delegate), content_setting_image_model_(std::move(image_model)), bubble_view_(nullptr) { @@ -176,11 +177,6 @@ IconLabelBubbleView::OnThemeChanged(); } -SkColor ContentSettingImageView::GetTextColor() const { - return GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_TextfieldDefaultColor); -} - bool ContentSettingImageView::ShouldShowSeparator() const { return false; } @@ -215,10 +211,6 @@ return bubble_view_ != nullptr; } -SkColor ContentSettingImageView::GetInkDropBaseColor() const { - return delegate_->GetContentSettingInkDropColor(); -} - ContentSettingImageModel::ImageType ContentSettingImageView::GetTypeForTesting() const { return content_setting_image_model_->image_type(); @@ -242,7 +234,7 @@ SetImage(content_setting_image_model_ ->GetIcon(icon_color_ ? icon_color_.value() : color_utils::DeriveDefaultIconColor( - GetTextColor())) + GetForegroundColor())) .AsImageSkia()); }
diff --git a/chrome/browser/ui/views/location_bar/content_setting_image_view.h b/chrome/browser/ui/views/location_bar/content_setting_image_view.h index 3022446..6d4627bb 100644 --- a/chrome/browser/ui/views/location_bar/content_setting_image_view.h +++ b/chrome/browser/ui/views/location_bar/content_setting_image_view.h
@@ -41,9 +41,6 @@ public: class Delegate { public: - // Gets the color to use for the ink highlight. - virtual SkColor GetContentSettingInkDropColor() const = 0; - // Gets the web contents the ContentSettingImageView is for. virtual content::WebContents* GetContentSettingWebContents() = 0; @@ -58,6 +55,7 @@ }; ContentSettingImageView(std::unique_ptr<ContentSettingImageModel> image_model, + IconLabelBubbleView::Delegate* parent_delegate, Delegate* delegate, const gfx::FontList& font_list); ~ContentSettingImageView() override; @@ -78,11 +76,9 @@ bool OnMousePressed(const ui::MouseEvent& event) override; bool OnKeyPressed(const ui::KeyEvent& event) override; void OnThemeChanged() override; - SkColor GetTextColor() const override; bool ShouldShowSeparator() const override; bool ShowBubble(const ui::Event& event) override; bool IsBubbleShowing() const override; - SkColor GetInkDropBaseColor() const override; void AnimationEnded(const gfx::Animation* animation) override; ContentSettingImageModel::ImageType GetTypeForTesting() const;
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc b/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc index 5955fea..1e25fe7 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.cc
@@ -17,8 +17,12 @@ #include "ui/gfx/paint_vector_icon.h" CookieControlsIconView::CookieControlsIconView( - PageActionIconView::Delegate* delegate) - : PageActionIconView(nullptr, 0, delegate) { + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(nullptr, + 0, + icon_label_bubble_delegate, + page_action_icon_delegate) { SetVisible(false); }
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.h b/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.h index 36c2759d..3803f5e 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.h +++ b/chrome/browser/ui/views/location_bar/cookie_controls_icon_view.h
@@ -17,7 +17,9 @@ class CookieControlsIconView : public PageActionIconView, public CookieControlsView { public: - explicit CookieControlsIconView(PageActionIconView::Delegate* delegate); + CookieControlsIconView( + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~CookieControlsIconView() override; // CookieControlsUI:
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc index 32d8e815..510b6d6 100644 --- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
@@ -198,7 +198,7 @@ close_button_ = AddChildView(CreateCloseButton(this, foreground_color)); location_icon_view_ = - AddChildView(std::make_unique<LocationIconView>(font_list, this)); + AddChildView(std::make_unique<LocationIconView>(font_list, this, this)); auto title_origin_view = std::make_unique<CustomTabBarTitleOriginView>(background_color_); @@ -349,6 +349,11 @@ } } +SkColor CustomTabBarView::GetIconLabelBubbleSurroundingForegroundColor() const { + return GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_TextfieldDefaultColor); +} + content::WebContents* CustomTabBarView::GetWebContents() { return delegate_->GetWebContents(); } @@ -384,11 +389,6 @@ GetSecurityChipColor(GetLocationBarModel()->GetSecurityLevel())); } -SkColor CustomTabBarView::GetLocationIconInkDropColor() const { - return GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_TextfieldDefaultColor); -} - const LocationBarModel* CustomTabBarView::GetLocationBarModel() const { return delegate_->GetLocationBarModel(); }
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.h b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.h index 402df26..7669233 100644 --- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.h +++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.h
@@ -35,6 +35,7 @@ public TabStripModelObserver, public ui::SimpleMenuModel::Delegate, public views::ContextMenuController, + public IconLabelBubbleView::Delegate, public LocationIconView::Delegate, public views::ButtonListener { public: @@ -60,6 +61,9 @@ void OnPaintBackground(gfx::Canvas* canvas) override; void ChildPreferredSizeChanged(views::View* child) override; + // IconLabelBubbleView::Delegate: + SkColor GetIconLabelBubbleSurroundingForegroundColor() const override; + // LocationIconView::Delegate: content::WebContents* GetWebContents() override; bool IsEditingOrEmpty() const override; @@ -71,7 +75,6 @@ const LocationBarModel* GetLocationBarModel() const override; gfx::ImageSkia GetLocationIcon(LocationIconView::Delegate::IconFetchedCallback on_icon_fetched) const override; - SkColor GetLocationIconInkDropColor() const override; // ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override;
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.cc b/chrome/browser/ui/views/location_bar/find_bar_icon.cc index 898872a5..588b57cb 100644 --- a/chrome/browser/ui/views/location_bar/find_bar_icon.cc +++ b/chrome/browser/ui/views/location_bar/find_bar_icon.cc
@@ -12,9 +12,15 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/views/animation/ink_drop.h" -FindBarIcon::FindBarIcon(Browser* browser, - PageActionIconView::Delegate* delegate) - : PageActionIconView(nullptr, 0, delegate), browser_(browser) { +FindBarIcon::FindBarIcon( + Browser* browser, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(nullptr, + 0, + icon_label_bubble_delegate, + page_action_icon_delegate), + browser_(browser) { DCHECK(browser_); }
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.h b/chrome/browser/ui/views/location_bar/find_bar_icon.h index d690ce4..96be5e3 100644 --- a/chrome/browser/ui/views/location_bar/find_bar_icon.h +++ b/chrome/browser/ui/views/location_bar/find_bar_icon.h
@@ -13,7 +13,9 @@ // The find icon to show when the find bar is visible. class FindBarIcon : public PageActionIconView { public: - FindBarIcon(Browser* browser, PageActionIconView::Delegate* delegate); + FindBarIcon(Browser* browser, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~FindBarIcon() override; void SetActive(bool activate, bool should_animate);
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc index e254c2e5..24f6b8d 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
@@ -21,7 +21,6 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/scoped_canvas.h" #include "ui/gfx/skia_util.h" -#include "ui/native_theme/native_theme.h" #include "ui/views/accessibility/ax_virtual_view.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/animation/flood_fill_ink_drop_ripple.h" @@ -53,8 +52,9 @@ } // namespace -////////////////////////////////////////////////////////////////// -// SeparatorView class +SkColor IconLabelBubbleView::Delegate::GetIconLabelBubbleInkDropColor() const { + return GetIconLabelBubbleSurroundingForegroundColor(); +} IconLabelBubbleView::SeparatorView::SeparatorView(IconLabelBubbleView* owner) { DCHECK(owner); @@ -103,20 +103,12 @@ duration = kIconLabelBubbleFadeInDurationMs; } - if (disable_animation_for_test_) { - layer()->SetOpacity(opacity); - } else { - ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator()); - animation.SetTransitionDuration( - base::TimeDelta::FromMilliseconds(duration)); - animation.SetTweenType(gfx::Tween::Type::EASE_IN); - layer()->SetOpacity(opacity); - } + ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator()); + animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(duration)); + animation.SetTweenType(gfx::Tween::Type::EASE_IN); + layer()->SetOpacity(opacity); } -////////////////////////////////////////////////////////////////// -// HighlightPathGenerator class - class IconLabelBubbleView::HighlightPathGenerator : public views::HighlightPathGenerator { public: @@ -131,12 +123,13 @@ DISALLOW_COPY_AND_ASSIGN(HighlightPathGenerator); }; -////////////////////////////////////////////////////////////////// -// IconLabelBubbleView class - -IconLabelBubbleView::IconLabelBubbleView(const gfx::FontList& font_list) +IconLabelBubbleView::IconLabelBubbleView(const gfx::FontList& font_list, + Delegate* delegate) : LabelButton(nullptr, base::string16()), + delegate_(delegate), separator_view_(new SeparatorView(this)) { + DCHECK(delegate_); + SetFontList(font_list); SetHorizontalAlignment(gfx::ALIGN_LEFT); @@ -196,6 +189,10 @@ label()->SetFontList(font_list); } +SkColor IconLabelBubbleView::GetForegroundColor() const { + return delegate_->GetIconLabelBubbleSurroundingForegroundColor(); +} + SkColor IconLabelBubbleView::GetParentBackgroundColor() const { return GetNativeTheme()->GetSystemColor( ui::NativeTheme::kColorId_TextfieldDefaultBackground); @@ -310,7 +307,7 @@ // under certain conditions. We don't want that, so unset the background. label()->SetBackground(nullptr); - SetEnabledTextColors(GetTextColor()); + SetEnabledTextColors(GetForegroundColor()); label()->SetBackgroundColor(GetParentBackgroundColor()); SchedulePaint(); } @@ -323,6 +320,10 @@ return std::move(ink_drop); } +SkColor IconLabelBubbleView::GetInkDropBaseColor() const { + return delegate_->GetIconLabelBubbleInkDropColor(); +} + bool IconLabelBubbleView::IsTriggerableEvent(const ui::Event& event) { if (event.IsMouseEvent()) return !IsBubbleShowing() && !suppress_button_release_;
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h index 16ccba50..037f22bc 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.h
@@ -46,31 +46,19 @@ public: static constexpr int kTrailingPaddingPreMd = 2; - // A view that draws the separator. - class SeparatorView : public views::View { + class Delegate { public: - explicit SeparatorView(IconLabelBubbleView* owner); + // Returns the foreground color of items around the IconLabelBubbleView, + // e.g. nearby text items. By default, the IconLabelBubbleView will use + // this as its foreground color and ink drop base color. + virtual SkColor GetIconLabelBubbleSurroundingForegroundColor() const = 0; - // views::View: - void OnPaint(gfx::Canvas* canvas) override; - - // Updates the opacity based on the ink drop's state. - void UpdateOpacity(); - - void set_disable_animation_for_test(bool disable_animation_for_test) { - disable_animation_for_test_ = disable_animation_for_test; - } - - private: - // Weak. - IconLabelBubbleView* owner_; - - bool disable_animation_for_test_ = false; - - DISALLOW_COPY_AND_ASSIGN(SeparatorView); + // Returns the base color for ink drops. If not overridden, this returns + // GetIconLabelBubbleSurroundingForegroundColor(). + virtual SkColor GetIconLabelBubbleInkDropColor() const; }; - explicit IconLabelBubbleView(const gfx::FontList& font_list); + IconLabelBubbleView(const gfx::FontList& font_list, Delegate* delegate); ~IconLabelBubbleView() override; // views::InkDropObserver: @@ -91,7 +79,7 @@ SkColor GetParentBackgroundColor() const; // Exposed for testing. - SeparatorView* separator_view() const { return separator_view_; } + views::View* separator_view() const { return separator_view_; } // Exposed for testing. bool is_animating_label() const { return slide_animation_.is_animating(); } @@ -111,8 +99,8 @@ protected: static constexpr int kOpenTimeMS = 150; - // Gets the color for displaying text. - virtual SkColor GetTextColor() const = 0; + // Gets the color for displaying text and/or icons. + virtual SkColor GetForegroundColor() const; // Returns true when the separator should be visible. virtual bool ShouldShowSeparator() const; @@ -138,7 +126,7 @@ bool OnMousePressed(const ui::MouseEvent& event) override; void OnThemeChanged() override; std::unique_ptr<views::InkDrop> CreateInkDrop() override; - SkColor GetInkDropBaseColor() const override = 0; + SkColor GetInkDropBaseColor() const override; bool IsTriggerableEvent(const ui::Event& event) override; bool ShouldUpdateInkDropOnClickCanceled() const override; void NotifyClick(const ui::Event& event) override; @@ -194,6 +182,24 @@ private: class HighlightPathGenerator; + // A view that draws the separator. + class SeparatorView : public views::View { + public: + explicit SeparatorView(IconLabelBubbleView* owner); + + // views::View: + void OnPaint(gfx::Canvas* canvas) override; + + // Updates the opacity based on the ink drop's state. + void UpdateOpacity(); + + private: + // Weak. + IconLabelBubbleView* owner_; + + DISALLOW_COPY_AND_ASSIGN(SeparatorView); + }; + // Spacing between the image and the label. int GetInternalSpacing() const; @@ -229,6 +235,8 @@ // Sets the border padding around this view. void UpdateBorder(); + Delegate* delegate_; + // The contents of the bubble. SeparatorView* separator_view_;
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc index 2e30b99..a1fce1bd 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc
@@ -11,6 +11,7 @@ #include "chrome/test/views/chrome_views_test_base.h" #include "components/strings/grit/components_strings.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/events/base_event_utils.h" #include "ui/events/gesture_detection/gesture_configuration.h" #include "ui/events/test/event_generator.h" @@ -47,11 +48,11 @@ SHRINKING, }; - explicit TestIconLabelBubbleView(const gfx::FontList& font_list) - : IconLabelBubbleView(font_list), value_(0), is_bubble_showing_(false) { + explicit TestIconLabelBubbleView(const gfx::FontList& font_list, + Delegate* delegate) + : IconLabelBubbleView(font_list, delegate) { GetImageView()->SetImageSize(gfx::Size(kImageSize, kImageSize)); SetLabel(base::ASCIIToUTF16("Label")); - separator_view()->set_disable_animation_for_test(true); } void SetCurrentAnimationValue(int value) { @@ -83,9 +84,6 @@ protected: // IconLabelBubbleView: - SkColor GetTextColor() const override { return kTestColor; } - SkColor GetInkDropBaseColor() const override { return kTestColor; } - bool ShouldShowLabel() const override { return !IsShrinking() || (width() > @@ -119,16 +117,28 @@ } private: - int value_; - bool is_bubble_showing_; + std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_ = + std::make_unique<ui::ScopedAnimationDurationScaleMode>( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); + int value_ = 0; + bool is_bubble_showing_ = false; DISALLOW_COPY_AND_ASSIGN(TestIconLabelBubbleView); }; } // namespace -class IconLabelBubbleViewTest : public ChromeViewsTestBase { +class IconLabelBubbleViewTestBase : public ChromeViewsTestBase, + public IconLabelBubbleView::Delegate { + public: + // IconLabelBubbleView::Delegate: + SkColor GetIconLabelBubbleSurroundingForegroundColor() const override { + return kTestColor; + } +}; + +class IconLabelBubbleViewTest : public IconLabelBubbleViewTestBase { protected: - // ChromeViewsTestBase: + // IconLabelBubbleViewTestBase: void SetUp() override { ChromeViewsTestBase::SetUp(); gfx::FontList font_list; @@ -136,7 +146,7 @@ CreateWidget(); generator_ = std::make_unique<ui::test::EventGenerator>(GetRootWindow(widget_)); - view_ = new TestIconLabelBubbleView(font_list); + view_ = new TestIconLabelBubbleView(font_list, this); view_->SetBoundsRect(gfx::Rect(0, 0, 24, 24)); widget_->SetContentsView(view_); @@ -417,7 +427,7 @@ #if defined(OS_CHROMEOS) // Verifies IconLabelBubbleView::CalculatePreferredSize() doesn't crash when // there is a widget but no compositor. -using IconLabelBubbleViewCrashTest = ChromeViewsTestBase; +using IconLabelBubbleViewCrashTest = IconLabelBubbleViewTestBase; TEST_F(IconLabelBubbleViewCrashTest, GetPreferredSizeDoesntCrashWhenNoCompositor) { @@ -428,7 +438,7 @@ views::Widget widget; widget.Init(std::move(params)); IconLabelBubbleView* icon_label_bubble_view = - new TestIconLabelBubbleView(font_list); + new TestIconLabelBubbleView(font_list, this); icon_label_bubble_view->SetLabel(base::ASCIIToUTF16("x")); widget.GetContentsView()->AddChildView(icon_label_bubble_view); aura::Window* widget_native_view = widget.GetNativeView();
diff --git a/chrome/browser/ui/views/location_bar/intent_picker_view.cc b/chrome/browser/ui/views/location_bar/intent_picker_view.cc index 01f793e..608a886 100644 --- a/chrome/browser/ui/views/location_bar/intent_picker_view.cc +++ b/chrome/browser/ui/views/location_bar/intent_picker_view.cc
@@ -30,9 +30,15 @@ class WebContents; } -IntentPickerView::IntentPickerView(Browser* browser, - PageActionIconView::Delegate* delegate) - : PageActionIconView(nullptr, 0, delegate), browser_(browser) {} +IntentPickerView::IntentPickerView( + Browser* browser, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(nullptr, + 0, + icon_label_bubble_delegate, + page_action_icon_delegate), + browser_(browser) {} IntentPickerView::~IntentPickerView() = default;
diff --git a/chrome/browser/ui/views/location_bar/intent_picker_view.h b/chrome/browser/ui/views/location_bar/intent_picker_view.h index bf8ff24cb..edd90cd 100644 --- a/chrome/browser/ui/views/location_bar/intent_picker_view.h +++ b/chrome/browser/ui/views/location_bar/intent_picker_view.h
@@ -12,7 +12,9 @@ // The entry point for the intent picker. class IntentPickerView : public PageActionIconView { public: - IntentPickerView(Browser* browser, PageActionIconView::Delegate* delegate); + IntentPickerView(Browser* browser, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~IntentPickerView() override; // PageActionIconView:
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 485678e..c5c1797 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -122,10 +122,6 @@ #include "ui/views/controls/label.h" #include "ui/views/widget/widget.h" -#if defined(USE_AURA) || defined(OS_MACOSX) -#include "ui/native_theme/native_theme_dark_aura.h" -#endif - namespace { int IncrementalMinimumWidth(const views::View* view) { @@ -174,9 +170,6 @@ LocationBarView::~LocationBarView() {} -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, public: - void LocationBarView::Init() { // We need to be in a Widget, otherwise GetNativeTheme() may change and we're // not prepared for that. @@ -190,7 +183,8 @@ const gfx::FontList& font_list = views::style::GetFont( CONTEXT_OMNIBOX_PRIMARY, views::style::STYLE_PRIMARY); - auto location_icon_view = std::make_unique<LocationIconView>(font_list, this); + auto location_icon_view = + std::make_unique<LocationIconView>(font_list, this, this); location_icon_view->set_drag_controller(this); location_icon_view_ = AddChildView(std::move(location_icon_view)); @@ -233,7 +227,7 @@ ContentSettingImageModel::GenerateContentSettingImageModels(); for (auto& model : models) { auto image_view = std::make_unique<ContentSettingImageView>( - std::move(model), this, font_list); + std::move(model), this, this, font_list); image_view->SetIconColor(icon_color); image_view->SetVisible(false); content_setting_views_.push_back(AddChildView(std::move(image_view))); @@ -287,6 +281,7 @@ params.font_list = &font_list; params.browser = browser_; params.command_updater = command_updater(); + params.icon_label_bubble_delegate = this; params.page_action_icon_delegate = this; page_action_icon_container_ = AddChildView(std::make_unique<PageActionIconContainerView>(params)); @@ -361,9 +356,6 @@ omnibox_view_->SelectAll(true); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, public LocationBar implementation: - void LocationBarView::FocusLocation(bool is_user_initiated) { omnibox_view_->SetFocus(is_user_initiated); } @@ -376,9 +368,6 @@ return omnibox_view_; } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, public views::View implementation: - bool LocationBarView::HasFocus() const { return omnibox_view_ && omnibox_view_->model()->has_focus(); } @@ -672,9 +661,6 @@ ->ActivateFirstInactiveBubbleForAccessibility(); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, public OmniboxEditController implementation: - void LocationBarView::UpdateWithoutTabRestore() { Update(nullptr); } @@ -687,11 +673,9 @@ return delegate_->GetWebContents(); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, public ContentSettingImageView::Delegate implementation: - -SkColor LocationBarView::GetContentSettingInkDropColor() const { - return GetLocationIconInkDropColor(); +SkColor LocationBarView::GetIconLabelBubbleSurroundingForegroundColor() const { + return GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_TextfieldDefaultColor); } content::WebContents* LocationBarView::GetContentSettingWebContents() { @@ -703,24 +687,14 @@ return delegate_->GetContentSettingBubbleModelDelegate(); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, public PageActionIconView::Delegate implementation: - -SkColor LocationBarView::GetPageActionInkDropColor() const { - return GetLocationIconInkDropColor(); -} - WebContents* LocationBarView::GetWebContentsForPageActionIconView() { return GetWebContents(); } bool LocationBarView::IsLocationBarUserInputInProgress() const { - return omnibox_view() && omnibox_view()->model()->user_input_in_progress(); + return omnibox_view_ && omnibox_view_->model()->user_input_in_progress(); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, public static methods: - // static bool LocationBarView::IsVirtualKeyboardVisible(views::Widget* widget) { if (auto* input_method = widget->GetInputMethod()) { @@ -745,9 +719,6 @@ 0, LocationBarView::GetAvailableTextHeight() - (bubble_padding * 2)); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, private: - int LocationBarView::GetMinimumLeadingWidth() const { // If the keyword bubble is showing, the view can collapse completely. if (ShouldShowKeywordBubble()) @@ -787,9 +758,7 @@ if (omnibox_view_->model()->is_caret_visible()) { background_color = border_color = GetColor(OmniboxPart::RESULTS_BACKGROUND); } else { - const SkColor normal = GetOmniboxColor(GetThemeProvider(), - OmniboxPart::LOCATION_BAR_BACKGROUND, - OmniboxPartState::NORMAL); + const SkColor normal = GetColor(OmniboxPart::LOCATION_BAR_BACKGROUND); const SkColor hovered = GetOmniboxColor( GetThemeProvider(), OmniboxPart::LOCATION_BAR_BACKGROUND, OmniboxPartState::HOVERED); @@ -895,9 +864,6 @@ FocusLocation(false); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, private LocationBar implementation: - GURL LocationBarView::GetDestinationURL() const { return destination_url(); } @@ -958,9 +924,6 @@ return this; } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, private LocationBarTesting implementation: - bool LocationBarView::TestContentSettingImagePressed(size_t index) { if (index >= content_setting_views_.size()) return false; @@ -979,9 +942,6 @@ content_setting_views_[index]->IsBubbleShowing(); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, private views::View implementation: - const char* LocationBarView::GetClassName() const { return kViewClassName; } @@ -1019,9 +979,6 @@ border_color); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, private views::DragController implementation: - void LocationBarView::WriteDragDataForView(views::View* sender, const gfx::Point& press_pt, OSExchangeData* data) { @@ -1053,8 +1010,6 @@ return true; } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, private views::AnimationDelegateViews implementation: void LocationBarView::AnimationProgressed(const gfx::Animation* animation) { DCHECK_EQ(animation, &hover_animation_); RefreshBackground(); @@ -1070,9 +1025,6 @@ AnimationProgressed(animation); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, private OmniboxEditController implementation: - void LocationBarView::OnChanged() { location_icon_view_->Update(/*suppress_animations=*/false); clear_all_button_->SetVisible(IsLocationBarUserInputInProgress() && @@ -1136,16 +1088,10 @@ } } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, private DropdownBarHostDelegate implementation: - void LocationBarView::FocusAndSelectAll() { FocusLocation(true); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, private ui::MaterialDesignControllerObserver implementation: - void LocationBarView::OnTouchUiChanged() { const gfx::FontList& font_list = views::style::GetFont( CONTEXT_OMNIBOX_PRIMARY, views::style::STYLE_PRIMARY); @@ -1160,11 +1106,8 @@ PreferredSizeChanged(); } -//////////////////////////////////////////////////////////////////////////////// -// LocationBarView, LocationBarIconView::Delegate implementation: - bool LocationBarView::IsEditingOrEmpty() const { - return omnibox_view() && omnibox_view()->IsEditingOrEmpty(); + return omnibox_view_ && omnibox_view_->IsEditingOrEmpty(); } void LocationBarView::OnLocationIconPressed(const ui::MouseEvent& event) { @@ -1214,24 +1157,16 @@ *helper->GetVisibleSecurityState(), base::BindOnce(&LocationBarView::OnPageInfoBubbleClosed, weak_factory_.GetWeakPtr())); - bubble->SetHighlightedButton(location_icon_view()); + bubble->SetHighlightedButton(location_icon_view_); bubble->GetWidget()->Show(); return true; } gfx::ImageSkia LocationBarView::GetLocationIcon( LocationIconView::Delegate::IconFetchedCallback on_icon_fetched) const { - security_state::SecurityLevel level = security_state::SecurityLevel::NONE; - if (!IsEditingOrEmpty()) - level = GetLocationBarModel()->GetSecurityLevel(); - return omnibox_view() - ? omnibox_view()->GetIcon( - GetLayoutConstant(LOCATION_BAR_ICON_SIZE), - GetSecurityChipColor(level), std::move(on_icon_fetched)) - : gfx::ImageSkia(); -} - -SkColor LocationBarView::GetLocationIconInkDropColor() const { - return GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_TextfieldDefaultColor); + if (!omnibox_view_) + return gfx::ImageSkia(); + return omnibox_view_->GetIcon(GetLayoutConstant(LOCATION_BAR_ICON_SIZE), + location_icon_view_->GetForegroundColor(), + std::move(on_icon_fetched)); }
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index 00743002..c8c1c29 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -70,6 +70,7 @@ public ChromeOmniboxEditController, public DropdownBarHostDelegate, public views::ButtonListener, + public IconLabelBubbleView::Delegate, public LocationIconView::Delegate, public ContentSettingImageView::Delegate, public PageActionIconView::Delegate, @@ -186,8 +187,10 @@ LocationBarModel* GetLocationBarModel() override; content::WebContents* GetWebContents() override; + // IconLabelBubbleView::Delegate: + SkColor GetIconLabelBubbleSurroundingForegroundColor() const override; + // ContentSettingImageView::Delegate: - SkColor GetContentSettingInkDropColor() const override; content::WebContents* GetContentSettingWebContents() override; ContentSettingBubbleModelDelegate* GetContentSettingBubbleModelDelegate() override; @@ -213,7 +216,7 @@ Browser* browser() { return browser_; } Profile* profile() { return profile_; } - // LocationIconView::Delegate + // LocationIconView::Delegate: bool IsEditingOrEmpty() const override; void OnLocationIconPressed(const ui::MouseEvent& event) override; void OnLocationIconDragged(const ui::MouseEvent& event) override; @@ -222,7 +225,6 @@ security_state::SecurityLevel security_level) const override; gfx::ImageSkia GetLocationIcon(LocationIconView::Delegate::IconFetchedCallback on_icon_fetched) const override; - SkColor GetLocationIconInkDropColor() const override; private: FRIEND_TEST_ALL_PREFIXES(SecurityIndicatorTest, CheckIndicatorText); @@ -306,7 +308,6 @@ const gfx::Point& p) override; // PageActionIconView::Delegate: - SkColor GetPageActionInkDropColor() const override; content::WebContents* GetWebContentsForPageActionIconView() override; bool IsLocationBarUserInputInProgress() const override;
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view.cc b/chrome/browser/ui/views/location_bar/location_icon_view.cc index 222fab0..dc1a34d5 100644 --- a/chrome/browser/ui/views/location_bar/location_icon_view.cc +++ b/chrome/browser/ui/views/location_bar/location_icon_view.cc
@@ -28,9 +28,13 @@ using content::WebContents; using security_state::SecurityLevel; -LocationIconView::LocationIconView(const gfx::FontList& font_list, - Delegate* delegate) - : IconLabelBubbleView(font_list), delegate_(delegate) { +LocationIconView::LocationIconView( + const gfx::FontList& font_list, + IconLabelBubbleView::Delegate* parent_delegate, + Delegate* delegate) + : IconLabelBubbleView(font_list, parent_delegate), delegate_(delegate) { + DCHECK(delegate_); + SetID(VIEW_ID_LOCATION_ICON); Update(true); SetUpForAnimation(); @@ -45,19 +49,12 @@ return GetMinimumSizeForPreferredSize(GetPreferredSize()); } -bool LocationIconView::OnMousePressed(const ui::MouseEvent& event) { - delegate_->OnLocationIconPressed(event); - - IconLabelBubbleView::OnMousePressed(event); - return true; -} - bool LocationIconView::OnMouseDragged(const ui::MouseEvent& event) { delegate_->OnLocationIconDragged(event); return IconLabelBubbleView::OnMouseDragged(event); } -SkColor LocationIconView::GetTextColor() const { +SkColor LocationIconView::GetForegroundColor() const { SecurityLevel security_level = SecurityLevel::NONE; if (!delegate_->IsEditingOrEmpty()) security_level = delegate_->GetLocationBarModel()->GetSecurityLevel(); @@ -73,8 +70,16 @@ return delegate_->ShowPageInfoDialog(); } -SkColor LocationIconView::GetInkDropBaseColor() const { - return delegate_->GetLocationIconInkDropColor(); +bool LocationIconView::IsBubbleShowing() const { + return PageInfoBubbleView::GetShownBubbleType() != + PageInfoBubbleView::BUBBLE_NONE; +} + +bool LocationIconView::OnMousePressed(const ui::MouseEvent& event) { + delegate_->OnLocationIconPressed(event); + + IconLabelBubbleView::OnMousePressed(event); + return true; } void LocationIconView::GetAccessibleNodeData(ui::AXNodeData* node_data) { @@ -96,11 +101,6 @@ node_data->role = ax::mojom::Role::kPopUpButton; } -bool LocationIconView::IsBubbleShowing() const { - return PageInfoBubbleView::GetShownBubbleType() != - PageInfoBubbleView::BUBBLE_NONE; -} - int LocationIconView::GetMinimumLabelTextWidth() const { int width = 0;
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view.h b/chrome/browser/ui/views/location_bar/location_icon_view.h index 30fa313..8c5c4d3 100644 --- a/chrome/browser/ui/views/location_bar/location_icon_view.h +++ b/chrome/browser/ui/views/location_bar/location_icon_view.h
@@ -56,27 +56,22 @@ // Gets an icon for the location bar icon chip. virtual gfx::ImageSkia GetLocationIcon( IconFetchedCallback on_icon_fetched) const = 0; - - // Gets the color to use for icon ink highlights. - virtual SkColor GetLocationIconInkDropColor() const = 0; - - protected: - virtual ~Delegate() {} }; - LocationIconView(const gfx::FontList& font_list, Delegate* delagate); + LocationIconView(const gfx::FontList& font_list, + IconLabelBubbleView::Delegate* parent_delegate, + Delegate* delegate); ~LocationIconView() override; // IconLabelBubbleView: gfx::Size GetMinimumSize() const override; - bool OnMousePressed(const ui::MouseEvent& event) override; bool OnMouseDragged(const ui::MouseEvent& event) override; - SkColor GetTextColor() const override; + SkColor GetForegroundColor() const override; bool ShouldShowSeparator() const override; bool ShowBubble(const ui::Event& event) override; - void GetAccessibleNodeData(ui::AXNodeData* node_data) override; bool IsBubbleShowing() const override; - SkColor GetInkDropBaseColor() const override; + bool OnMousePressed(const ui::MouseEvent& event) override; + void GetAccessibleNodeData(ui::AXNodeData* node_data) override; // Returns what the minimum width for the label text. int GetMinimumLabelTextWidth() const;
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view_browsertest.cc b/chrome/browser/ui/views/location_bar/location_icon_view_browsertest.cc index c807b6f..9422599 100644 --- a/chrome/browser/ui/views/location_bar/location_icon_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/location_icon_view_browsertest.cc
@@ -22,7 +22,8 @@ BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); location_bar_ = browser_view->GetLocationBarView(); - icon_view_ = std::make_unique<LocationIconView>(font_list, location_bar_); + icon_view_ = std::make_unique<LocationIconView>(font_list, location_bar_, + location_bar_); } LocationBarView* location_bar() const { return location_bar_; }
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view_unittest.cc b/chrome/browser/ui/views/location_bar/location_icon_view_unittest.cc index 83c91c66..d528bae 100644 --- a/chrome/browser/ui/views/location_bar/location_icon_view_unittest.cc +++ b/chrome/browser/ui/views/location_bar/location_icon_view_unittest.cc
@@ -11,38 +11,37 @@ namespace { -class TestLocationIconDelegate : public LocationIconView::Delegate { +class TestLocationIconDelegate : public IconLabelBubbleView::Delegate, + public LocationIconView::Delegate { public: explicit TestLocationIconDelegate(LocationBarModel* location_bar_model) : location_bar_model_(location_bar_model) {} + virtual ~TestLocationIconDelegate() = default; - content::WebContents* GetWebContents() override { return nullptr; } - - bool IsEditingOrEmpty() const override { return is_editing_or_empty_; } - void set_is_editing_or_empty(bool is_editing_or_empty) { - is_editing_or_empty_ = is_editing_or_empty; + // IconLabelBubbleView::Delegate: + SkColor GetIconLabelBubbleSurroundingForegroundColor() const override { + return SK_ColorBLACK; } + // LocationIconView::Delegate: + content::WebContents* GetWebContents() override { return nullptr; } + bool IsEditingOrEmpty() const override { return is_editing_or_empty_; } SkColor GetSecurityChipColor( security_state::SecurityLevel security_level) const override { return SK_ColorWHITE; } - bool ShowPageInfoDialog() override { return false; } - - // Gets the LocationBarModel. const LocationBarModel* GetLocationBarModel() const override { return location_bar_model_; } - - // Gets an icon for the location bar icon chip. gfx::ImageSkia GetLocationIcon( IconFetchedCallback on_icon_fetched) const override { return gfx::ImageSkia(); } - // Gets the color to use for icon ink highlights. - SkColor GetLocationIconInkDropColor() const override { return SK_ColorBLACK; } + void set_is_editing_or_empty(bool is_editing_or_empty) { + is_editing_or_empty_ = is_editing_or_empty; + } private: LocationBarModel* location_bar_model_; @@ -64,7 +63,7 @@ delegate_ = std::make_unique<TestLocationIconDelegate>(location_bar_model()); - view_ = new LocationIconView(font_list, delegate()); + view_ = new LocationIconView(font_list, delegate(), delegate()); view_->SetBoundsRect(gfx::Rect(0, 0, 24, 24)); widget_->SetContentsView(view_);
diff --git a/chrome/browser/ui/views/location_bar/selected_keyword_view.cc b/chrome/browser/ui/views/location_bar/selected_keyword_view.cc index 97cb93d..6d501acf 100644 --- a/chrome/browser/ui/views/location_bar/selected_keyword_view.cc +++ b/chrome/browser/ui/views/location_bar/selected_keyword_view.cc
@@ -22,7 +22,7 @@ SelectedKeywordView::SelectedKeywordView(LocationBarView* location_bar, const gfx::FontList& font_list, Profile* profile) - : IconLabelBubbleView(font_list), + : IconLabelBubbleView(font_list, location_bar), location_bar_(location_bar), profile_(profile) { full_label_.SetFontList(font_list); @@ -37,21 +37,17 @@ void SelectedKeywordView::ResetImage() { SetImage(gfx::CreateVectorIcon(vector_icons::kSearchIcon, GetLayoutConstant(LOCATION_BAR_ICON_SIZE), - GetTextColor())); + GetForegroundColor())); } void SelectedKeywordView::OnBoundsChanged(const gfx::Rect& previous_bounds) { SetLabelForCurrentWidth(); } -SkColor SelectedKeywordView::GetTextColor() const { +SkColor SelectedKeywordView::GetForegroundColor() const { return location_bar_->GetColor(OmniboxPart::LOCATION_BAR_SELECTED_KEYWORD); } -SkColor SelectedKeywordView::GetInkDropBaseColor() const { - return location_bar_->GetLocationIconInkDropColor(); -} - gfx::Size SelectedKeywordView::CalculatePreferredSize() const { // Height will be ignored by the LocationBarView. return GetSizeForLabelWidth(full_label_.GetPreferredSize().width());
diff --git a/chrome/browser/ui/views/location_bar/selected_keyword_view.h b/chrome/browser/ui/views/location_bar/selected_keyword_view.h index f4a43343..cf4c773 100644 --- a/chrome/browser/ui/views/location_bar/selected_keyword_view.h +++ b/chrome/browser/ui/views/location_bar/selected_keyword_view.h
@@ -36,8 +36,7 @@ // IconLabelBubbleView: gfx::Size CalculatePreferredSize() const override; gfx::Size GetMinimumSize() const override; - SkColor GetTextColor() const override; - SkColor GetInkDropBaseColor() const override; + SkColor GetForegroundColor() const override; // The current keyword, or an empty string if no keyword is displayed. void SetKeyword(const base::string16& keyword);
diff --git a/chrome/browser/ui/views/location_bar/star_view.cc b/chrome/browser/ui/views/location_bar/star_view.cc index 1615a97..8559616 100644 --- a/chrome/browser/ui/views/location_bar/star_view.cc +++ b/chrome/browser/ui/views/location_bar/star_view.cc
@@ -53,8 +53,12 @@ StarView::StarView(CommandUpdater* command_updater, Browser* browser, - PageActionIconView::Delegate* delegate) - : PageActionIconView(command_updater, IDC_BOOKMARK_THIS_TAB, delegate), + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(command_updater, + IDC_BOOKMARK_THIS_TAB, + icon_label_bubble_delegate, + page_action_icon_delegate), browser_(browser) { DCHECK(browser_); extension_observer_.Add(
diff --git a/chrome/browser/ui/views/location_bar/star_view.h b/chrome/browser/ui/views/location_bar/star_view.h index d5dbf9ae..bb242fe 100644 --- a/chrome/browser/ui/views/location_bar/star_view.h +++ b/chrome/browser/ui/views/location_bar/star_view.h
@@ -24,7 +24,8 @@ public: StarView(CommandUpdater* command_updater, Browser* browser, - PageActionIconView::Delegate* delegate); + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~StarView() override; // Shows the BookmarkPromoBubbleView when the BookmarkTracker calls for it.
diff --git a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc index 402a6d6..19ca3a41 100644 --- a/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc +++ b/chrome/browser/ui/views/media_router/media_router_dialog_controller_views.cc
@@ -121,14 +121,12 @@ } void MediaRouterDialogControllerViews::InitializeMediaRouterUI() { - ui_ = std::make_unique<MediaRouterViewsUI>(); - PresentationServiceDelegateImpl* delegate = - PresentationServiceDelegateImpl::FromWebContents(initiator()); - if (!start_presentation_context_) { - ui_->InitWithDefaultMediaSource(initiator(), delegate); - } else { + ui_ = std::make_unique<MediaRouterViewsUI>(initiator()); + if (start_presentation_context_) { ui_->InitWithStartPresentationContext( - initiator(), delegate, std::move(start_presentation_context_)); + std::move(start_presentation_context_)); + } else { + ui_->InitWithDefaultMediaSource(); } }
diff --git a/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc b/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc index 08e2b98..88bc450b 100644 --- a/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc +++ b/chrome/browser/ui/views/media_router/media_router_ui_browsertest.cc
@@ -16,7 +16,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" #include "chrome/browser/ui/media_router/media_router_ui_service.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/media_router_action_controller.h"
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.cc b/chrome/browser/ui/views/media_router/media_router_views_ui.cc index 1a8bb26..e68e11b 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui.cc +++ b/chrome/browser/ui/views/media_router/media_router_views_ui.cc
@@ -26,7 +26,6 @@ #include "chrome/browser/media/router/media_router_factory.h" #include "chrome/browser/media/router/media_router_metrics.h" #include "chrome/browser/media/router/media_routes_observer.h" -#include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h" #include "chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h" #include "chrome/browser/media/webrtc/desktop_media_picker_controller.h" #include "chrome/browser/profiles/profile.h" @@ -198,7 +197,13 @@ base::OneShotTimer capture_poll_timer_; }; -MediaRouterViewsUI::MediaRouterViewsUI() = default; +MediaRouterViewsUI::MediaRouterViewsUI(content::WebContents* initiator) + : presentation_manager_(WebContentsPresentationManager::Get(initiator)), + initiator_(initiator) { + CHECK(initiator_); + if (presentation_manager_) + presentation_manager_->AddObserver(this); +} MediaRouterViewsUI::~MediaRouterViewsUI() { for (CastDialogController::Observer& observer : observers_) @@ -206,9 +211,9 @@ if (query_result_manager_.get()) query_result_manager_->RemoveObserver(this); - if (presentation_service_delegate_.get()) - presentation_service_delegate_->RemoveDefaultPresentationRequestObserver( - this); + if (presentation_manager_) + presentation_manager_->RemoveObserver(this); + // If |start_presentation_context_| still exists, then it means presentation // route request was never attempted. if (start_presentation_context_) { @@ -264,21 +269,14 @@ RemoveIssue(issue_id); } -void MediaRouterViewsUI::InitWithDefaultMediaSource( - content::WebContents* initiator, - PresentationServiceDelegateImpl* delegate) { - DCHECK(initiator); - DCHECK(!presentation_service_delegate_); +void MediaRouterViewsUI::InitWithDefaultMediaSource() { DCHECK(!query_result_manager_); + InitCommon(); - InitCommon(initiator); - if (delegate) { - presentation_service_delegate_ = delegate->GetWeakPtr(); - presentation_service_delegate_->AddDefaultPresentationRequestObserver(this); - } - - if (delegate && delegate->HasDefaultPresentationRequest()) { - OnDefaultPresentationChanged(delegate->GetDefaultPresentationRequest()); + if (presentation_manager_ && + presentation_manager_->HasDefaultPresentationRequest()) { + OnDefaultPresentationChanged( + &presentation_manager_->GetDefaultPresentationRequest()); } else { // Register for MediaRoute updates without a media source. routes_observer_ = std::make_unique<UIMediaRoutesObserver>( @@ -289,21 +287,16 @@ } void MediaRouterViewsUI::InitWithStartPresentationContext( - content::WebContents* initiator, - PresentationServiceDelegateImpl* delegate, std::unique_ptr<StartPresentationContext> context) { - DCHECK(initiator); - DCHECK(delegate); DCHECK(context); DCHECK(!start_presentation_context_); DCHECK(!query_result_manager_); start_presentation_context_ = std::move(context); - presentation_service_delegate_ = delegate->GetWeakPtr(); - InitCommon(initiator); + InitCommon(); OnDefaultPresentationChanged( - start_presentation_context_->presentation_request()); + &start_presentation_context_->presentation_request()); } bool MediaRouterViewsUI::CreateRoute(const MediaSink::Id& sink_id, @@ -379,7 +372,7 @@ // the best place to do this, but the Media Router browser service and // extension process are shared between normal and incognito, so incognito // behaviors around sink availability have to be handled at the UI layer. - if (initiator()->GetBrowserContext()->IsOffTheRecord()) { + if (initiator_->GetBrowserContext()->IsOffTheRecord()) { base::EraseIf(enabled_sinks, [](const MediaSinkWithCastModes& sink) { return sink.sink.IsMaybeCloudSink(); }); @@ -390,7 +383,6 @@ base::string16 MediaRouterViewsUI::GetPresentationRequestSourceName() const { GURL gurl = GetFrameURL(); - CHECK(initiator_); // Presentation URLs are only possible on https: and other secure contexts, // so we can omit http/https schemes here. return gurl.SchemeIs(extensions::kExtensionScheme) @@ -482,10 +474,7 @@ // TODO(crbug.com/868186): Close the dialog. } -void MediaRouterViewsUI::InitCommon(content::WebContents* initiator) { - DCHECK(initiator); - initiator_ = initiator; - +void MediaRouterViewsUI::InitCommon() { GetMediaRouter()->OnUserGesture(); // Create |collator_| before |query_result_manager_| so that |collator_| is @@ -514,7 +503,7 @@ query_result_manager_->SetSourcesForCastMode( MediaCastMode::LOCAL_FILE, {MediaSource::ForTab(0)}, origin); - SessionID::id_type tab_id = SessionTabHelper::IdForTab(initiator).id(); + SessionID::id_type tab_id = SessionTabHelper::IdForTab(initiator_).id(); if (tab_id != -1) { MediaSource mirroring_source(MediaSource::ForTab(tab_id)); query_result_manager_->SetSourcesForCastMode(MediaCastMode::TAB_MIRROR, @@ -533,12 +522,17 @@ } void MediaRouterViewsUI::OnDefaultPresentationChanged( - const content::PresentationRequest& presentation_request) { + const content::PresentationRequest* presentation_request) { + if (!presentation_request) { + OnDefaultPresentationRemoved(); + return; + } + std::vector<MediaSource> sources; - for (const auto& url : presentation_request.presentation_urls) { + for (const auto& url : presentation_request->presentation_urls) { sources.push_back(MediaSource::ForPresentationUrl(url)); } - presentation_request_ = presentation_request; + presentation_request_ = *presentation_request; query_result_manager_->SetSourcesForCastMode( MediaCastMode::PRESENTATION, sources, presentation_request_->frame_origin); @@ -589,8 +583,6 @@ const MediaSink::Id& sink_id, MediaCastMode cast_mode) { DCHECK(query_result_manager_); - DCHECK(initiator_); - RouteParameters params; // Note that there is a rarely-encountered bug, where the MediaCastMode to @@ -636,7 +628,7 @@ // The StartPresentationContext will need to be answered with the route // response. // (3) Browser-initiated presentation route request. If successful, - // PresentationServiceDelegateImpl will have to be notified. Note that we + // WebContentsPresentationManager will have to be notified. Note that we // treat subsequent route requests from a Presentation API-initiated // dialogs as browser-initiated. // TODO(https://crbug.com/868186): Close the Views dialog in case (2). @@ -654,15 +646,14 @@ params.route_result_callbacks.push_back(base::BindOnce( &MediaRouterViewsUI::HandleCreateSessionRequestRouteResponse, weak_factory_.GetWeakPtr())); - } else if (presentation_service_delegate_) { + } else if (presentation_manager_) { params.presentation_callback = base::BindOnce( - &PresentationServiceDelegateImpl::OnRouteResponse, - presentation_service_delegate_, *presentation_request_); + &WebContentsPresentationManager::OnPresentationResponse, + presentation_manager_, *presentation_request_); } } params.timeout = GetRouteRequestTimeout(cast_mode); - CHECK(initiator_); params.incognito = initiator_->GetBrowserContext()->IsOffTheRecord(); return base::make_optional(std::move(params)); @@ -948,13 +939,11 @@ } MediaRouter* MediaRouterViewsUI::GetMediaRouter() const { - CHECK(initiator_); return MediaRouterFactory::GetApiForBrowserContext( initiator_->GetBrowserContext()); } Browser* MediaRouterViewsUI::GetBrowser() { - CHECK(initiator_); return chrome::FindBrowserWithWebContents(initiator_); }
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.h b/chrome/browser/ui/views/media_router/media_router_views_ui.h index 80915f7..6060b0a5 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui.h +++ b/chrome/browser/ui/views/media_router/media_router_views_ui.h
@@ -19,7 +19,7 @@ #include "build/build_config.h" #include "chrome/browser/media/router/issues_observer.h" #include "chrome/browser/media/router/media_router_dialog_controller.h" -#include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h" +#include "chrome/browser/media/router/presentation/web_contents_presentation_manager.h" #include "chrome/browser/ui/media_router/cast_dialog_controller.h" #include "chrome/browser/ui/media_router/cast_dialog_model.h" #include "chrome/browser/ui/media_router/media_cast_mode.h" @@ -53,11 +53,10 @@ class MediaRouterViewsUI : public CastDialogController, public QueryResultManager::Observer, - public PresentationServiceDelegateImpl:: - DefaultPresentationRequestObserver, + public WebContentsPresentationManager::Observer, public MediaRouterFileDialog::MediaRouterFileDialogDelegate { public: - MediaRouterViewsUI(); + explicit MediaRouterViewsUI(content::WebContents* initiator); ~MediaRouterViewsUI() override; // CastDialogController: @@ -71,36 +70,22 @@ void ClearIssue(const Issue::Id& issue_id) override; // Initializes internal state (e.g. starts listening for MediaSinks) for - // targeting the default MediaSource (if any) of the initiator tab that owns - // |delegate|, as well as mirroring sources of that tab. - // The contents of the UI will change as the default MediaSource changes. - // If there is a default MediaSource, then PRESENTATION MediaCastMode will be - // added to |cast_modes_|. - // Init* methods can only be called once. - // |initiator|: Reference to the WebContents that initiated the dialog. - // Must not be null. - // |delegate|: PresentationServiceDelegateImpl of the initiator tab. - // Must not be null. - // TODO(imcheng): Replace use of impl with an intermediate abstract - // interface. - void InitWithDefaultMediaSource(content::WebContents* initiator, - PresentationServiceDelegateImpl* delegate); + // targeting the default MediaSource (if any) of |initiator_|, as well as + // mirroring sources of that tab. The contents of the UI will change as the + // default MediaSource changes. If there is a default MediaSource, then + // PRESENTATION MediaCastMode will be added to |cast_modes_|. Init* methods + // can only be called once. + void InitWithDefaultMediaSource(); // Initializes internal state targeting the presentation specified in - // |context|. Also sets up mirroring sources based on |initiator|. + // |context|. Also sets up mirroring sources based on |initiator_|. // This is different from InitWithDefaultMediaSource() in that it does not // listen for default media source changes, as the UI is fixed to the source - // in |request|. + // in |context|. // Init* methods can only be called once. - // |initiator|: Reference to the WebContents that initiated the dialog. - // Must not be null. - // |delegate|: PresentationServiceDelegateImpl of the initiator tab. - // Must not be null. // |context|: Context object for the PresentationRequest. This instance will // take ownership of it. Must not be null. void InitWithStartPresentationContext( - content::WebContents* initiator, - PresentationServiceDelegateImpl* delegate, std::unique_ptr<StartPresentationContext> context); // Requests a route be created from the source mapped to @@ -225,13 +210,14 @@ virtual void HandleCreateSessionRequestRouteResponse( const RouteRequestResult&); - // Initializes the dialog with mirroring sources derived from |initiator|. - virtual void InitCommon(content::WebContents* initiator); + // Initializes the dialog with mirroring sources derived from |initiator_|. + virtual void InitCommon(); - // PresentationServiceDelegateImpl::DefaultPresentationObserver + // WebContentsPresentationManager::Observer void OnDefaultPresentationChanged( - const content::PresentationRequest& presentation_request) override; - void OnDefaultPresentationRemoved() override; + const content::PresentationRequest* presentation_request) override; + + void OnDefaultPresentationRemoved(); // Called to update the dialog with the current list of of enabled sinks. void UpdateSinks(); @@ -392,17 +378,12 @@ // mode, if supported. Otherwise set to nullopt. base::Optional<content::PresentationRequest> presentation_request_; - // It's possible for PresentationServiceDelegateImpl to be destroyed before - // this class. - // (e.g. if a tab with the UI open is closed, then the tab WebContents will - // be destroyed first momentarily before the UI WebContents). - // Holding a WeakPtr to PresentationServiceDelegateImpl is the cleanest way to - // handle this. - // TODO(imcheng): hold a weak ptr to an abstract type instead. - base::WeakPtr<PresentationServiceDelegateImpl> presentation_service_delegate_; + // |presentation_manager_| notifies |this| whenever there is an update to the + // default PresentationRequest or MediaRoutes associated with |initiator_|. + base::WeakPtr<WebContentsPresentationManager> presentation_manager_; // WebContents for the tab for which the Cast dialog is shown. - content::WebContents* initiator_ = nullptr; + content::WebContents* const initiator_; // The dialog that handles opening the file dialog and validating and // returning the results.
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui_unittest.cc b/chrome/browser/ui/views/media_router/media_router_views_ui_unittest.cc index 10a65852..d1e70ec 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui_unittest.cc +++ b/chrome/browser/ui/views/media_router/media_router_views_ui_unittest.cc
@@ -10,6 +10,7 @@ #include <vector> #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/media/router/media_router_factory.h" #include "chrome/browser/media/router/media_sinks_observer.h" #include "chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h" #include "chrome/browser/media/router/test/mock_media_router.h" @@ -107,19 +108,6 @@ blink::mojom::PresentationError expected_error_; }; -// Injects a MediaRouter instance into MediaRouterViewsUI. -class TestMediaRouterViewsUI : public MediaRouterViewsUI { - public: - explicit TestMediaRouterViewsUI(MediaRouter* router) : router_(router) {} - ~TestMediaRouterViewsUI() override = default; - - MediaRouter* GetMediaRouter() const override { return router_; } - - private: - MediaRouter* router_; - DISALLOW_COPY_AND_ASSIGN(TestMediaRouterViewsUI); -}; - class TestWebContentsDisplayObserver : public WebContentsDisplayObserver { public: explicit TestWebContentsDisplayObserver(const display::Display& display) @@ -143,16 +131,20 @@ void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); + SetMediaRouterFactory(); + mock_router_ = static_cast<MockMediaRouter*>( + MediaRouterFactory::GetApiForBrowserContext(GetBrowserContext())); + // Store sink observers so that they can be notified in tests. - ON_CALL(mock_router_, RegisterMediaSinksObserver(_)) - .WillByDefault(Invoke([this](MediaSinksObserver* observer) { + ON_CALL(*mock_router_, RegisterMediaSinksObserver(_)) + .WillByDefault([this](MediaSinksObserver* observer) { media_sinks_observers_.push_back(observer); return true; - })); + }); SessionTabHelper::CreateForWebContents(web_contents()); - ui_ = std::make_unique<TestMediaRouterViewsUI>(&mock_router_); - ui_->InitWithDefaultMediaSource(web_contents(), nullptr); + ui_ = std::make_unique<MediaRouterViewsUI>(web_contents()); + ui_->InitWithDefaultMediaSource(); } void TearDown() override { @@ -160,14 +152,19 @@ ChromeRenderViewHostTestHarness::TearDown(); } + virtual void SetMediaRouterFactory() { + MediaRouterFactory::GetInstance()->SetTestingFactory( + GetBrowserContext(), base::BindRepeating(&MockMediaRouter::Create)); + } + void CreateMediaRouterUIForURL(const GURL& url) { web_contents()->GetController().LoadURL(url, content::Referrer(), ui::PAGE_TRANSITION_LINK, ""); content::RenderFrameHostTester::CommitPendingLoad( &web_contents()->GetController()); SessionTabHelper::CreateForWebContents(web_contents()); - ui_ = std::make_unique<TestMediaRouterViewsUI>(&mock_router_); - ui_->InitWithDefaultMediaSource(web_contents(), nullptr); + ui_ = std::make_unique<MediaRouterViewsUI>(web_contents()); + ui_->InitWithDefaultMediaSource(); } // These methods are used so that we don't have to friend each test case that @@ -186,7 +183,7 @@ MediaSource media_source = MediaSource::ForTab(SessionTabHelper::IdForTab(web_contents()).id()); EXPECT_CALL( - mock_router_, + *mock_router_, CreateRouteInternal(media_source.id(), kSinkId, _, web_contents(), _, base::TimeDelta::FromSeconds(60), is_incognito)); MediaSink sink(kSinkId, kSinkName, SinkIconType::GENERIC); @@ -202,7 +199,7 @@ MediaSink sink(kSinkId, kSinkName, SinkIconType::CAST); ui_->OnResultsUpdated({{sink, {cast_mode}}}); MediaRouteResponseCallback callback; - EXPECT_CALL(mock_router_, + EXPECT_CALL(*mock_router_, CreateRouteInternal( _, _, _, _, _, base::TimeDelta::FromSeconds(timeout_seconds), false)) @@ -210,7 +207,7 @@ for (MediaSinksObserver* sinks_observer : media_sinks_observers_) sinks_observer->OnSinksUpdated({sink}, std::vector<url::Origin>()); ui_->StartCasting(kSinkId, cast_mode); - Mock::VerifyAndClearExpectations(&mock_router_); + Mock::VerifyAndClearExpectations(mock_router_); EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce(WithArg<0>([&](const CastDialogModel& model) { @@ -238,13 +235,13 @@ base::Unretained(request_callbacks.get()))); StartPresentationContext* context_ptr = context.get(); ui_->set_start_presentation_context_for_test(std::move(context)); - ui_->OnDefaultPresentationChanged(context_ptr->presentation_request()); + ui_->OnDefaultPresentationChanged(&context_ptr->presentation_request()); return request_callbacks; } protected: std::vector<MediaSinksObserver*> media_sinks_observers_; - MockMediaRouter mock_router_; + MockMediaRouter* mock_router_ = nullptr; std::unique_ptr<MediaRouterViewsUI> ui_; std::unique_ptr<StartPresentationContext> start_presentation_context_; content::PresentationRequest presentation_request_{ @@ -326,8 +323,9 @@ GURL gurl("https://example.com"); url::Origin origin = url::Origin::Create(gurl); - ui_->OnDefaultPresentationChanged(content::PresentationRequest( - content::GlobalFrameRoutingId(), {gurl}, origin)); + content::PresentationRequest presentation_request( + content::GlobalFrameRoutingId(), {gurl}, origin); + ui_->OnDefaultPresentationChanged(&presentation_request); // Now that the presentation request has been set, the dialog header contains // its origin. @@ -347,7 +345,7 @@ } TEST_F(MediaRouterViewsUITest, StopCasting) { - EXPECT_CALL(mock_router_, TerminateRoute(kRouteId)); + EXPECT_CALL(*mock_router_, TerminateRoute(kRouteId)); ui_->StopCasting(kRouteId); } @@ -430,7 +428,7 @@ {sink2, {MediaCastMode::TAB_MIRROR}}}); MockControllerObserver observer(ui_.get()); - MockIssuesObserver issues_observer(mock_router_.GetIssueManager()); + MockIssuesObserver issues_observer(mock_router_->GetIssueManager()); issues_observer.Init(); const std::string issue_title("Issue 1"); IssueInfo issue(issue_title, IssueInfo::Action::DISMISS, @@ -450,7 +448,7 @@ EXPECT_EQ(model.media_sinks()[1].id, sink2.id()); EXPECT_EQ(model.media_sinks()[1].issue->info().title, issue_title); }))); - mock_router_.GetIssueManager()->AddIssue(issue); + mock_router_->GetIssueManager()->AddIssue(issue); EXPECT_CALL(observer, OnModelUpdated(_)) .WillOnce(WithArg<0>(Invoke([&sink2](const CastDialogModel& model) { @@ -458,7 +456,7 @@ EXPECT_EQ(model.media_sinks()[1].id, sink2.id()); EXPECT_FALSE(model.media_sinks()[1].issue.has_value()); }))); - mock_router_.GetIssueManager()->ClearIssue(issue_id); + mock_router_->GetIssueManager()->ClearIssue(issue_id); } TEST_F(MediaRouterViewsUITest, ShowDomainForHangouts) { @@ -514,7 +512,7 @@ content::PresentationRequest presentation_request( {0, 0}, {GURL("https://presentationurl.com")}, url::Origin::Create(GURL("https://frameurl.fakeurl"))); - ui_->OnDefaultPresentationChanged(presentation_request); + ui_->OnDefaultPresentationChanged(&presentation_request); StartCastingAndExpectTimeout( MediaCastMode::PRESENTATION, l10n_util::GetStringFUTF8(IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT, @@ -535,7 +533,7 @@ EXPECT_CALL(*file_dialog_ptr, GetLastSelectedFileUrl()) .WillOnce(Return(GURL(file_url))); content::WebContents* location_file_opened = nullptr; - EXPECT_CALL(mock_router_, CreateRouteInternal(_, _, _, _, _, _, _)) + EXPECT_CALL(*mock_router_, CreateRouteInternal(_, _, _, _, _, _, _)) .WillOnce(SaveArgWithMove<3>(&location_file_opened)); ui_->CreateRoute(kSinkId, MediaCastMode::LOCAL_FILE); @@ -695,6 +693,13 @@ class MediaRouterViewsUIIncognitoTest : public MediaRouterViewsUITest { protected: + void SetMediaRouterFactory() override { + // We must set the factory on the non-incognito browser context. + MediaRouterFactory::GetInstance()->SetTestingFactory( + MediaRouterViewsUITest::GetBrowserContext(), + base::BindRepeating(&MockMediaRouter::Create)); + } + content::BrowserContext* GetBrowserContext() override { return static_cast<Profile*>(MediaRouterViewsUITest::GetBrowserContext()) ->GetOffTheRecordProfile();
diff --git a/chrome/browser/ui/views/native_file_system/native_file_system_access_icon_view.cc b/chrome/browser/ui/views/native_file_system/native_file_system_access_icon_view.cc index 836be4d..72654fdf 100644 --- a/chrome/browser/ui/views/native_file_system/native_file_system_access_icon_view.cc +++ b/chrome/browser/ui/views/native_file_system/native_file_system_access_icon_view.cc
@@ -22,8 +22,12 @@ base::FEATURE_DISABLED_BY_DEFAULT}; NativeFileSystemAccessIconView::NativeFileSystemAccessIconView( - Delegate* delegate) - : PageActionIconView(nullptr, 0, delegate) { + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(nullptr, + 0, + icon_label_bubble_delegate, + page_action_icon_delegate) { SetVisible(false); }
diff --git a/chrome/browser/ui/views/native_file_system/native_file_system_access_icon_view.h b/chrome/browser/ui/views/native_file_system/native_file_system_access_icon_view.h index e291e9b..69ba98f5 100644 --- a/chrome/browser/ui/views/native_file_system/native_file_system_access_icon_view.h +++ b/chrome/browser/ui/views/native_file_system/native_file_system_access_icon_view.h
@@ -12,7 +12,9 @@ // access to files or directories. class NativeFileSystemAccessIconView : public PageActionIconView { public: - explicit NativeFileSystemAccessIconView(Delegate* delegate); + NativeFileSystemAccessIconView( + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); // PageActionIconView: views::BubbleDialogDelegateView* GetBubble() const override;
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_controller.cc b/chrome/browser/ui/views/page_action/page_action_icon_controller.cc index 34da019..5036000e 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_controller.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_controller.cc
@@ -36,6 +36,7 @@ PageActionIconContainer* icon_container) { DCHECK(icon_container); DCHECK(!icon_container_); + DCHECK(params.icon_label_bubble_delegate); DCHECK(params.page_action_icon_delegate); icon_container_ = icon_container; @@ -45,12 +46,13 @@ case PageActionIconType::kBookmarkStar: bookmark_star_icon_ = new StarView(params.command_updater, params.browser, + params.icon_label_bubble_delegate, params.page_action_icon_delegate); page_action_icons_.push_back(bookmark_star_icon_); break; case PageActionIconType::kClickToCall: click_to_call_icon_ = new SharingIconView( - params.page_action_icon_delegate, + params.icon_label_bubble_delegate, params.page_action_icon_delegate, base::BindRepeating([](content::WebContents* contents) { return static_cast<SharingUiController*>( ClickToCallUiController::GetOrCreateFromWebContents( @@ -61,66 +63,77 @@ break; case PageActionIconType::kCookieControls: cookie_controls_icon_ = - new CookieControlsIconView(params.page_action_icon_delegate); + new CookieControlsIconView(params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(cookie_controls_icon_); break; case PageActionIconType::kFind: find_icon_ = - new FindBarIcon(params.browser, params.page_action_icon_delegate); + new FindBarIcon(params.browser, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(find_icon_); break; case PageActionIconType::kIntentPicker: intent_picker_icon_ = new IntentPickerView( - params.browser, params.page_action_icon_delegate); + params.browser, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(intent_picker_icon_); break; case PageActionIconType::kLocalCardMigration: local_card_migration_icon_ = new autofill::LocalCardMigrationIconView( - params.command_updater, params.page_action_icon_delegate); + params.command_updater, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(local_card_migration_icon_); break; case PageActionIconType::kManagePasswords: DCHECK(params.command_updater); manage_passwords_icon_ = new ManagePasswordsIconViews( - params.command_updater, params.page_action_icon_delegate); + params.command_updater, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(manage_passwords_icon_); break; case PageActionIconType::kNativeFileSystemAccess: native_file_system_access_icon_ = new NativeFileSystemAccessIconView( + params.icon_label_bubble_delegate, params.page_action_icon_delegate); page_action_icons_.push_back(native_file_system_access_icon_); break; case PageActionIconType::kPwaInstall: DCHECK(params.command_updater); pwa_install_icon_ = new PwaInstallView( - params.command_updater, params.page_action_icon_delegate); + params.command_updater, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(pwa_install_icon_); break; case PageActionIconType::kQRCodeGenerator: qrcode_generator_icon_view_ = new qrcode_generator::QRCodeGeneratorIconView( - params.command_updater, params.page_action_icon_delegate); + params.command_updater, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(qrcode_generator_icon_view_); break; case PageActionIconType::kReaderMode: DCHECK(params.command_updater); reader_mode_icon_ = new ReaderModeIconView( - params.command_updater, params.page_action_icon_delegate); + params.command_updater, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(reader_mode_icon_); break; case PageActionIconType::kSaveCard: save_card_icon_ = new autofill::SaveCardIconView( - params.command_updater, params.page_action_icon_delegate); + params.command_updater, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(save_card_icon_); break; case PageActionIconType::kSendTabToSelf: send_tab_to_self_icon_ = new send_tab_to_self::SendTabToSelfIconView( - params.command_updater, params.page_action_icon_delegate); + params.command_updater, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(send_tab_to_self_icon_); break; case PageActionIconType::kSharedClipboard: shared_clipboard_icon_ = new SharingIconView( - params.page_action_icon_delegate, + params.icon_label_bubble_delegate, params.page_action_icon_delegate, base::BindRepeating([](content::WebContents* contents) { return static_cast<SharingUiController*>( SharedClipboardUiController::GetOrCreateFromWebContents( @@ -132,11 +145,13 @@ case PageActionIconType::kTranslate: DCHECK(params.command_updater); translate_icon_ = new TranslateIconView( - params.command_updater, params.page_action_icon_delegate); + params.command_updater, params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(translate_icon_); break; case PageActionIconType::kZoom: - zoom_icon_ = new ZoomView(params.page_action_icon_delegate); + zoom_icon_ = new ZoomView(params.icon_label_bubble_delegate, + params.page_action_icon_delegate); page_action_icons_.push_back(zoom_icon_); break; }
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_params.h b/chrome/browser/ui/views/page_action/page_action_icon_params.h index 9bbe561f..f60ff98 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_params.h +++ b/chrome/browser/ui/views/page_action/page_action_icon_params.h
@@ -40,6 +40,7 @@ int between_icon_spacing = 0; Browser* browser = nullptr; CommandUpdater* command_updater = nullptr; + IconLabelBubbleView::Delegate* icon_label_bubble_delegate = nullptr; PageActionIconView::Delegate* page_action_icon_delegate = nullptr; views::ButtonObserver* button_observer = nullptr; views::ViewObserver* view_observer = nullptr;
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_view.cc index 4f8e4531..ccefb1d6f 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_view.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
@@ -46,11 +46,13 @@ return nullptr; } -PageActionIconView::PageActionIconView(CommandUpdater* command_updater, - int command_id, - PageActionIconView::Delegate* delegate, - const gfx::FontList& font_list) - : IconLabelBubbleView(font_list), +PageActionIconView::PageActionIconView( + CommandUpdater* command_updater, + int command_id, + IconLabelBubbleView::Delegate* parent_delegate, + PageActionIconView::Delegate* delegate, + const gfx::FontList& font_list) + : IconLabelBubbleView(font_list, parent_delegate), command_updater_(command_updater), delegate_(delegate), command_id_(command_id) { @@ -88,11 +90,6 @@ OnExecuting(EXECUTE_SOURCE_MOUSE); } -SkColor PageActionIconView::GetTextColor() const { - return GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_TextfieldDefaultColor); -} - void PageActionIconView::GetAccessibleNodeData(ui::AXNodeData* node_data) { node_data->role = ax::mojom::Role::kButton; node_data->SetName(GetTextForTooltipAndAccessibleName()); @@ -115,10 +112,6 @@ UpdateIconImage(); } -SkColor PageActionIconView::GetInkDropBaseColor() const { - return delegate_->GetPageActionInkDropColor(); -} - bool PageActionIconView::ShouldShowSeparator() const { return false; }
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.h b/chrome/browser/ui/views/page_action/page_action_icon_view.h index a63a276..42c3a4d 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_view.h +++ b/chrome/browser/ui/views/page_action/page_action_icon_view.h
@@ -40,9 +40,6 @@ public: class Delegate { public: - // Gets the color to use for the ink highlight. - virtual SkColor GetPageActionInkDropColor() const = 0; - // Gets the opacity to use for the ink highlight. virtual float GetPageActionInkDropVisibleOpacity() const; @@ -96,6 +93,7 @@ PageActionIconView(CommandUpdater* command_updater, int command_id, + IconLabelBubbleView::Delegate* parent_delegate, Delegate* delegate, const gfx::FontList& = gfx::FontList()); @@ -116,13 +114,11 @@ virtual void OnPressed(bool activated) {} // views::IconLabelBubbleView: - SkColor GetTextColor() const override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; base::string16 GetTooltipText(const gfx::Point& p) const override; void ViewHierarchyChanged( const views::ViewHierarchyChangedDetails& details) override; void OnThemeChanged() override; - SkColor GetInkDropBaseColor() const override; bool ShouldShowSeparator() const final; void NotifyClick(const ui::Event& event) override; bool IsTriggerableEvent(const ui::Event& event) override;
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.cc b/chrome/browser/ui/views/page_action/pwa_install_view.cc index c794434..069001a4 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view.cc
@@ -17,9 +17,14 @@ #include "components/omnibox/browser/vector_icons.h" #include "ui/base/l10n/l10n_util.h" -PwaInstallView::PwaInstallView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate) - : PageActionIconView(nullptr, 0, delegate) { +PwaInstallView::PwaInstallView( + CommandUpdater* command_updater, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(nullptr, + 0, + icon_label_bubble_delegate, + page_action_icon_delegate) { SetVisible(false); SetLabel(l10n_util::GetStringUTF16(IDS_OMNIBOX_PWA_INSTALL_ICON_LABEL)); SetUpForInOutAnimation();
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.h b/chrome/browser/ui/views/page_action/pwa_install_view.h index 5f15e81..6d634a5 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view.h +++ b/chrome/browser/ui/views/page_action/pwa_install_view.h
@@ -12,8 +12,10 @@ // installability checks and can be installed. class PwaInstallView : public PageActionIconView { public: - explicit PwaInstallView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate); + explicit PwaInstallView( + CommandUpdater* command_updater, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~PwaInstallView() override; protected:
diff --git a/chrome/browser/ui/views/page_action/zoom_view.cc b/chrome/browser/ui/views/page_action/zoom_view.cc index 359bb6b..78a9e20 100644 --- a/chrome/browser/ui/views/page_action/zoom_view.cc +++ b/chrome/browser/ui/views/page_action/zoom_view.cc
@@ -16,8 +16,13 @@ #include "ui/events/event.h" #include "ui/gfx/geometry/size.h" -ZoomView::ZoomView(PageActionIconView::Delegate* delegate) - : PageActionIconView(nullptr, 0, delegate), icon_(&kZoomMinusIcon) { +ZoomView::ZoomView(IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(nullptr, + 0, + icon_label_bubble_delegate, + page_action_icon_delegate), + icon_(&kZoomMinusIcon) { SetVisible(false); }
diff --git a/chrome/browser/ui/views/page_action/zoom_view.h b/chrome/browser/ui/views/page_action/zoom_view.h index 8ef782c3..632b284 100644 --- a/chrome/browser/ui/views/page_action/zoom_view.h +++ b/chrome/browser/ui/views/page_action/zoom_view.h
@@ -15,7 +15,8 @@ // WebContents. Because the current WebContents changes as the user switches // tabs, a LocationBarView::Delegate is supplied to queried for the current // WebContents when needed. - explicit ZoomView(PageActionIconView::Delegate* delegate); + ZoomView(IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~ZoomView() override; // Updates the image and its tooltip appropriately, hiding or showing the icon
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc index 99b7dcf..5422a6bc 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
@@ -18,10 +18,12 @@ ManagePasswordsIconViews::ManagePasswordsIconViews( CommandUpdater* updater, - PageActionIconView::Delegate* delegate) - : PageActionIconView(updater, IDC_MANAGE_PASSWORDS_FOR_PAGE, delegate) { - DCHECK(delegate); -} + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(updater, + IDC_MANAGE_PASSWORDS_FOR_PAGE, + icon_label_bubble_delegate, + page_action_icon_delegate) {} ManagePasswordsIconViews::~ManagePasswordsIconViews() = default;
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h index b30b5cb..835e1613 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h +++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h
@@ -20,8 +20,10 @@ public: static const char kClassName[]; - ManagePasswordsIconViews(CommandUpdater* updater, - PageActionIconView::Delegate* delegate); + ManagePasswordsIconViews( + CommandUpdater* updater, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~ManagePasswordsIconViews() override; // ManagePasswordsIconView:
diff --git a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_icon_view.cc b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_icon_view.cc index 65e4192..894ef83 100644 --- a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_icon_view.cc +++ b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_icon_view.cc
@@ -18,8 +18,12 @@ QRCodeGeneratorIconView::QRCodeGeneratorIconView( CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate) - : PageActionIconView(command_updater, IDC_QRCODE_GENERATOR, delegate) { + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(command_updater, + IDC_QRCODE_GENERATOR, + icon_label_bubble_delegate, + page_action_icon_delegate) { SetVisible(false); SetLabel(l10n_util::GetStringUTF16(IDS_OMNIBOX_QRCODE_GENERATOR_ICON_LABEL)); } @@ -63,7 +67,7 @@ return kQrcodeGeneratorIcon; } -SkColor QRCodeGeneratorIconView::GetTextColor() const { +SkColor QRCodeGeneratorIconView::GetForegroundColor() const { return GetOmniboxColor(GetThemeProvider(), OmniboxPart::LOCATION_BAR_TEXT_DEFAULT); }
diff --git a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_icon_view.h b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_icon_view.h index 788dccb..07106ed 100644 --- a/chrome/browser/ui/views/qrcode_generator/qrcode_generator_icon_view.h +++ b/chrome/browser/ui/views/qrcode_generator/qrcode_generator_icon_view.h
@@ -16,14 +16,16 @@ // can generate a QR code for the current page or a selected image. class QRCodeGeneratorIconView : public PageActionIconView { public: - QRCodeGeneratorIconView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate); + QRCodeGeneratorIconView( + CommandUpdater* command_updater, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~QRCodeGeneratorIconView() override; // PageActionIconView: views::BubbleDialogDelegateView* GetBubble() const override; void UpdateImpl() override; - SkColor GetTextColor() const override; + SkColor GetForegroundColor() const override; base::string16 GetTextForTooltipAndAccessibleName() const override; protected:
diff --git a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc index 9a7c2eed..222b201 100644 --- a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc +++ b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc
@@ -14,9 +14,14 @@ using dom_distiller::url_utils::IsDistilledPage; -ReaderModeIconView::ReaderModeIconView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate) - : PageActionIconView(command_updater, IDC_DISTILL_PAGE, delegate) {} +ReaderModeIconView::ReaderModeIconView( + CommandUpdater* command_updater, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(command_updater, + IDC_DISTILL_PAGE, + icon_label_bubble_delegate, + page_action_icon_delegate) {} void ReaderModeIconView::DidFinishNavigation( content::NavigationHandle* navigation_handle) {
diff --git a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.h b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.h index 7ce196e..f4361dd6 100644 --- a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.h +++ b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.h
@@ -26,7 +26,8 @@ public content::WebContentsObserver { public: ReaderModeIconView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate); + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~ReaderModeIconView() override = default; protected:
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_icon_view.cc b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_icon_view.cc index da5e5dd..5fdf6d1 100644 --- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_icon_view.cc +++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_icon_view.cc
@@ -20,8 +20,12 @@ SendTabToSelfIconView::SendTabToSelfIconView( CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate) - : PageActionIconView(command_updater, IDC_SEND_TAB_TO_SELF, delegate) { + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(command_updater, + IDC_SEND_TAB_TO_SELF, + icon_label_bubble_delegate, + page_action_icon_delegate) { SetVisible(false); SetLabel(l10n_util::GetStringUTF16(IDS_OMNIBOX_ICON_SEND_TAB_TO_SELF)); SetUpForInOutAnimation(); @@ -81,7 +85,7 @@ return kSendTabToSelfIcon; } -SkColor SendTabToSelfIconView::GetTextColor() const { +SkColor SendTabToSelfIconView::GetForegroundColor() const { return GetOmniboxColor(GetThemeProvider(), OmniboxPart::LOCATION_BAR_TEXT_DEFAULT); }
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_icon_view.h b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_icon_view.h index 725560e..319bfea 100644 --- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_icon_view.h +++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_icon_view.h
@@ -18,14 +18,16 @@ // choose to share the url to a target device. class SendTabToSelfIconView : public PageActionIconView { public: - SendTabToSelfIconView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate); + SendTabToSelfIconView( + CommandUpdater* command_updater, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~SendTabToSelfIconView() override; // PageActionIconView: views::BubbleDialogDelegateView* GetBubble() const override; void UpdateImpl() override; - SkColor GetTextColor() const override; + SkColor GetForegroundColor() const override; base::string16 GetTextForTooltipAndAccessibleName() const override; // gfx::AnimationDelegate:
diff --git a/chrome/browser/ui/views/sharing/sharing_icon_view.cc b/chrome/browser/ui/views/sharing/sharing_icon_view.cc index cf0dca0..00fe3f1 100644 --- a/chrome/browser/ui/views/sharing/sharing_icon_view.cc +++ b/chrome/browser/ui/views/sharing/sharing_icon_view.cc
@@ -17,12 +17,15 @@ constexpr double kAnimationTextFullLengthShownProgressState = 0.5; } // namespace -SharingIconView::SharingIconView(PageActionIconView::Delegate* delegate, - GetControllerCallback get_controller_callback, - GetBubbleCallback get_bubble_callback) +SharingIconView::SharingIconView( + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate, + GetControllerCallback get_controller_callback, + GetBubbleCallback get_bubble_callback) : PageActionIconView(/*command_updater=*/nullptr, /*command_id=*/0, - delegate), + icon_label_bubble_delegate, + page_action_icon_delegate), get_controller_callback_(std::move(get_controller_callback)), get_bubble_callback_(std::move(get_bubble_callback)) { SetVisible(false);
diff --git a/chrome/browser/ui/views/sharing/sharing_icon_view.h b/chrome/browser/ui/views/sharing/sharing_icon_view.h index 3cf860b..7bcff96 100644 --- a/chrome/browser/ui/views/sharing/sharing_icon_view.h +++ b/chrome/browser/ui/views/sharing/sharing_icon_view.h
@@ -18,9 +18,11 @@ using GetBubbleCallback = base::RepeatingCallback<views::BubbleDialogDelegateView*(SharingDialog*)>; - explicit SharingIconView(PageActionIconView::Delegate* delegate, - GetControllerCallback get_controller, - GetBubbleCallback get_bubble); + explicit SharingIconView( + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate, + GetControllerCallback get_controller, + GetBubbleCallback get_bubble); ~SharingIconView() override; void StartLoadingAnimation();
diff --git a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.h b/chrome/browser/ui/views/toolbar/browser_action_test_util_views.h deleted file mode 100644 index f708bc2..0000000 --- a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.h +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_TEST_UTIL_VIEWS_H_ -#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_TEST_UTIL_VIEWS_H_ - -#include <memory> - -#include "chrome/browser/ui/extensions/browser_action_test_util.h" - -class BrowserActionsContainer; - -class BrowserActionTestUtilViews : public BrowserActionTestUtil { - public: - BrowserActionTestUtilViews(const BrowserActionTestUtilViews&) = delete; - BrowserActionTestUtilViews& operator=(const BrowserActionTestUtilViews&) = - delete; - ~BrowserActionTestUtilViews() override; - - // BrowserActionTestUtil: - int NumberOfBrowserActions() override; - int VisibleBrowserActions() override; - void InspectPopup(int index) override; - bool HasIcon(int index) override; - gfx::Image GetIcon(int index) override; - void Press(int index) override; - std::string GetExtensionId(int index) override; - std::string GetTooltip(int index) override; - gfx::NativeView GetPopupNativeView() override; - bool HasPopup() override; - gfx::Size GetPopupSize() override; - bool HidePopup() override; - bool ActionButtonWantsToRun(size_t index) override; - void SetWidth(int width) override; - ToolbarActionsBar* GetToolbarActionsBar() override; - ExtensionsContainer* GetExtensionsContainer() override; - std::unique_ptr<BrowserActionTestUtil> CreateOverflowBar( - Browser* browser) override; - gfx::Size GetMinPopupSize() override; - gfx::Size GetMaxPopupSize() override; - gfx::Size GetToolbarActionSize() override; - bool CanBeResized() override; - - private: - friend class BrowserActionTestUtil; - - class TestToolbarActionsBarHelper; - - // Constructs a version of BrowserActionTestUtilViews that does not own the - // BrowserActionsContainer it tests. - explicit BrowserActionTestUtilViews( - BrowserActionsContainer* browser_actions_container); - // Constructs a version of BrowserActionTestUtilViews given a |test_helper| - // responsible for owning the BrowserActionsContainer. - explicit BrowserActionTestUtilViews( - std::unique_ptr<TestToolbarActionsBarHelper> test_helper); - - std::unique_ptr<TestToolbarActionsBarHelper> test_helper_; - - // The associated BrowserActionsContainer. Not owned. - BrowserActionsContainer* const browser_actions_container_; -}; - -#endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_BROWSER_ACTION_TEST_UTIL_VIEWS_H_
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc index 1ef68e8..d6153f9 100644 --- a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc +++ b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" #include "chrome/browser/extensions/extension_context_menu_model.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "chrome/browser/ui/toolbar/browser_actions_bar_browsertest.h" #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" #include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
diff --git a/chrome/browser/ui/views/toolbar/browser_action_test_util_views_aura.cc b/chrome/browser/ui/views/toolbar/extension_action_test_helper_aura.cc similarity index 93% rename from chrome/browser/ui/views/toolbar/browser_action_test_util_views_aura.cc rename to chrome/browser/ui/views/toolbar/extension_action_test_helper_aura.cc index 6a4f6e8e..98cfbc9 100644 --- a/chrome/browser/ui/views/toolbar/browser_action_test_util_views_aura.cc +++ b/chrome/browser/ui/views/toolbar/extension_action_test_helper_aura.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include "base/logging.h" #include "base/run_loop.h" @@ -40,7 +40,7 @@ } // namespace -bool BrowserActionTestUtil::WaitForPopup() { +bool ExtensionActionTestHelper::WaitForPopup() { // The popup starts out active but invisible, so all we need to really do is // look for visibility. aura::Window* native_view = GetPopupNativeView();
diff --git a/chrome/browser/ui/views/toolbar/browser_action_test_util_views_mac.mm b/chrome/browser/ui/views/toolbar/extension_action_test_helper_mac.mm similarity index 86% rename from chrome/browser/ui/views/toolbar/browser_action_test_util_views_mac.mm rename to chrome/browser/ui/views/toolbar/extension_action_test_helper_mac.mm index 002419d..adfc337 100644 --- a/chrome/browser/ui/views/toolbar/browser_action_test_util_views_mac.mm +++ b/chrome/browser/ui/views/toolbar/extension_action_test_helper_mac.mm
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include <AppKit/AppKit.h> #import "base/mac/scoped_nsobject.h" #import "ui/base/test/windowed_nsnotification_observer.h" -bool BrowserActionTestUtil::WaitForPopup() { +bool ExtensionActionTestHelper::WaitForPopup() { NSWindow* window = [GetPopupNativeView().GetNativeNSView() window]; if (!window) return false;
diff --git a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc b/chrome/browser/ui/views/toolbar/extension_action_test_helper_views.cc similarity index 71% rename from chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc rename to chrome/browser/ui/views/toolbar/extension_action_test_helper_views.cc index eaae10b6..ab65a49 100644 --- a/chrome/browser/ui/views/toolbar/browser_action_test_util_views.cc +++ b/chrome/browser/ui/views/toolbar/extension_action_test_helper_views.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/extensions/browser_action_test_util.h" +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" #include <stddef.h> @@ -16,8 +16,8 @@ #include "chrome/browser/ui/views/extensions/extension_popup.h" #include "chrome/browser/ui/views/extensions/extensions_menu_test_util.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/toolbar/browser_action_test_util_views.h" #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" +#include "chrome/browser/ui/views/toolbar/extension_action_test_helper_views.h" #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "ui/gfx/geometry/rect.h" @@ -29,7 +29,7 @@ // A helper class that owns an instance of a BrowserActionsContainer; this is // used when testing without an associated browser window, or if this is for // the overflow version of the bar. -class BrowserActionTestUtilViews::TestToolbarActionsBarHelper +class ExtensionActionTestHelperViews::TestToolbarActionsBarHelper : public BrowserActionsContainer::Delegate { public: TestToolbarActionsBarHelper(Browser* browser, @@ -71,117 +71,117 @@ views::ResizeAwareParentView container_parent_; }; -BrowserActionTestUtilViews::~BrowserActionTestUtilViews() = default; +ExtensionActionTestHelperViews::~ExtensionActionTestHelperViews() = default; -int BrowserActionTestUtilViews::NumberOfBrowserActions() { +int ExtensionActionTestHelperViews::NumberOfBrowserActions() { return browser_actions_container_->num_toolbar_actions(); } -int BrowserActionTestUtilViews::VisibleBrowserActions() { +int ExtensionActionTestHelperViews::VisibleBrowserActions() { return browser_actions_container_->VisibleBrowserActions(); } -void BrowserActionTestUtilViews::InspectPopup(int index) { +void ExtensionActionTestHelperViews::InspectPopup(int index) { ToolbarActionView* view = browser_actions_container_->GetToolbarActionViewAt(index); - static_cast<ExtensionActionViewController*>(view->view_controller())-> - InspectPopup(); + static_cast<ExtensionActionViewController*>(view->view_controller()) + ->InspectPopup(); } -bool BrowserActionTestUtilViews::HasIcon(int index) { +bool ExtensionActionTestHelperViews::HasIcon(int index) { return !browser_actions_container_->GetToolbarActionViewAt(index) ->GetImage(views::Button::STATE_NORMAL) .isNull(); } -gfx::Image BrowserActionTestUtilViews::GetIcon(int index) { +gfx::Image ExtensionActionTestHelperViews::GetIcon(int index) { gfx::ImageSkia icon = browser_actions_container_->GetToolbarActionViewAt(index) ->GetIconForTest(); return gfx::Image(icon); } -void BrowserActionTestUtilViews::Press(int index) { +void ExtensionActionTestHelperViews::Press(int index) { browser_actions_container_->GetToolbarActionViewAt(index) ->view_controller() ->ExecuteAction(true); } -std::string BrowserActionTestUtilViews::GetExtensionId(int index) { +std::string ExtensionActionTestHelperViews::GetExtensionId(int index) { return browser_actions_container_->GetToolbarActionViewAt(index) ->view_controller() ->GetId(); } -std::string BrowserActionTestUtilViews::GetTooltip(int index) { +std::string ExtensionActionTestHelperViews::GetTooltip(int index) { base::string16 tooltip = browser_actions_container_->GetToolbarActionViewAt(index)->GetTooltipText( gfx::Point()); return base::UTF16ToUTF8(tooltip); } -gfx::NativeView BrowserActionTestUtilViews::GetPopupNativeView() { +gfx::NativeView ExtensionActionTestHelperViews::GetPopupNativeView() { ToolbarActionViewController* popup_owner = GetToolbarActionsBar()->popup_owner(); return popup_owner ? popup_owner->GetPopupNativeView() : nullptr; } -bool BrowserActionTestUtilViews::HasPopup() { +bool ExtensionActionTestHelperViews::HasPopup() { return GetPopupNativeView() != nullptr; } -gfx::Size BrowserActionTestUtilViews::GetPopupSize() { +gfx::Size ExtensionActionTestHelperViews::GetPopupSize() { gfx::NativeView popup = GetPopupNativeView(); views::Widget* widget = views::Widget::GetWidgetForNativeView(popup); return widget->GetWindowBoundsInScreen().size(); } -bool BrowserActionTestUtilViews::HidePopup() { +bool ExtensionActionTestHelperViews::HidePopup() { GetToolbarActionsBar()->HideActivePopup(); return !HasPopup(); } -bool BrowserActionTestUtilViews::ActionButtonWantsToRun(size_t index) { +bool ExtensionActionTestHelperViews::ActionButtonWantsToRun(size_t index) { return browser_actions_container_->GetToolbarActionViewAt(index) ->wants_to_run_for_testing(); } -void BrowserActionTestUtilViews::SetWidth(int width) { +void ExtensionActionTestHelperViews::SetWidth(int width) { browser_actions_container_->SetSize( gfx::Size(width, browser_actions_container_->height())); } -ToolbarActionsBar* BrowserActionTestUtilViews::GetToolbarActionsBar() { +ToolbarActionsBar* ExtensionActionTestHelperViews::GetToolbarActionsBar() { return browser_actions_container_->toolbar_actions_bar(); } -ExtensionsContainer* BrowserActionTestUtilViews::GetExtensionsContainer() { +ExtensionsContainer* ExtensionActionTestHelperViews::GetExtensionsContainer() { return GetToolbarActionsBar(); } -std::unique_ptr<BrowserActionTestUtil> -BrowserActionTestUtilViews::CreateOverflowBar(Browser* browser) { +std::unique_ptr<ExtensionActionTestHelper> +ExtensionActionTestHelperViews::CreateOverflowBar(Browser* browser) { CHECK(!GetToolbarActionsBar()->in_overflow_mode()) << "Only a main bar can create an overflow bar!"; - return base::WrapUnique(new BrowserActionTestUtilViews( + return base::WrapUnique(new ExtensionActionTestHelperViews( std::make_unique<TestToolbarActionsBarHelper>( browser, browser_actions_container_))); } -gfx::Size BrowserActionTestUtilViews::GetMinPopupSize() { +gfx::Size ExtensionActionTestHelperViews::GetMinPopupSize() { return gfx::Size(ExtensionPopup::kMinWidth, ExtensionPopup::kMinHeight); } -gfx::Size BrowserActionTestUtilViews::GetMaxPopupSize() { +gfx::Size ExtensionActionTestHelperViews::GetMaxPopupSize() { return gfx::Size(ExtensionPopup::kMaxWidth, ExtensionPopup::kMaxHeight); } -gfx::Size BrowserActionTestUtilViews::GetToolbarActionSize() { +gfx::Size ExtensionActionTestHelperViews::GetToolbarActionSize() { return GetToolbarActionsBar()->GetViewSize(); } -bool BrowserActionTestUtilViews::CanBeResized() { +bool ExtensionActionTestHelperViews::CanBeResized() { // The container can only be resized if we can start a drag for the view. DCHECK_LE(1u, browser_actions_container_->num_toolbar_actions()); ToolbarActionView* action_view = @@ -191,38 +191,40 @@ point); } -BrowserActionTestUtilViews::BrowserActionTestUtilViews( +ExtensionActionTestHelperViews::ExtensionActionTestHelperViews( BrowserActionsContainer* browser_actions_container) : browser_actions_container_(browser_actions_container) {} -BrowserActionTestUtilViews::BrowserActionTestUtilViews( +ExtensionActionTestHelperViews::ExtensionActionTestHelperViews( std::unique_ptr<TestToolbarActionsBarHelper> test_helper) : test_helper_(std::move(test_helper)), browser_actions_container_(test_helper_->browser_actions_container()) {} // static -std::unique_ptr<BrowserActionTestUtil> BrowserActionTestUtil::Create( +std::unique_ptr<ExtensionActionTestHelper> ExtensionActionTestHelper::Create( Browser* browser, bool is_real_window) { // If the ExtensionsMenu is enabled, then use a separate implementation of - // the BrowserActionTestUtil. + // the ExtensionActionTestHelper. if (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) return std::make_unique<ExtensionsMenuTestUtil>(browser, is_real_window); - std::unique_ptr<BrowserActionTestUtil> browser_action_test_util; + std::unique_ptr<ExtensionActionTestHelper> browser_action_test_util; if (is_real_window) { - browser_action_test_util = base::WrapUnique(new BrowserActionTestUtilViews( - BrowserView::GetBrowserViewForBrowser(browser) - ->toolbar() - ->browser_actions())); + browser_action_test_util = + base::WrapUnique(new ExtensionActionTestHelperViews( + BrowserView::GetBrowserViewForBrowser(browser) + ->toolbar() + ->browser_actions())); } else { // This is the main bar. BrowserActionsContainer* main_bar = nullptr; - browser_action_test_util = base::WrapUnique(new BrowserActionTestUtilViews( - std::make_unique< - BrowserActionTestUtilViews::TestToolbarActionsBarHelper>( - browser, main_bar))); + browser_action_test_util = + base::WrapUnique(new ExtensionActionTestHelperViews( + std::make_unique< + ExtensionActionTestHelperViews::TestToolbarActionsBarHelper>( + browser, main_bar))); } return browser_action_test_util;
diff --git a/chrome/browser/ui/views/toolbar/extension_action_test_helper_views.h b/chrome/browser/ui/views/toolbar/extension_action_test_helper_views.h new file mode 100644 index 0000000..6a819194 --- /dev/null +++ b/chrome/browser/ui/views/toolbar/extension_action_test_helper_views.h
@@ -0,0 +1,66 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_EXTENSION_ACTION_TEST_HELPER_VIEWS_H_ +#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_EXTENSION_ACTION_TEST_HELPER_VIEWS_H_ + +#include <memory> + +#include "chrome/browser/ui/extensions/extension_action_test_helper.h" + +class BrowserActionsContainer; + +class ExtensionActionTestHelperViews : public ExtensionActionTestHelper { + public: + ExtensionActionTestHelperViews(const ExtensionActionTestHelperViews&) = + delete; + ExtensionActionTestHelperViews& operator=( + const ExtensionActionTestHelperViews&) = delete; + ~ExtensionActionTestHelperViews() override; + + // ExtensionActionTestHelper: + int NumberOfBrowserActions() override; + int VisibleBrowserActions() override; + void InspectPopup(int index) override; + bool HasIcon(int index) override; + gfx::Image GetIcon(int index) override; + void Press(int index) override; + std::string GetExtensionId(int index) override; + std::string GetTooltip(int index) override; + gfx::NativeView GetPopupNativeView() override; + bool HasPopup() override; + gfx::Size GetPopupSize() override; + bool HidePopup() override; + bool ActionButtonWantsToRun(size_t index) override; + void SetWidth(int width) override; + ToolbarActionsBar* GetToolbarActionsBar() override; + ExtensionsContainer* GetExtensionsContainer() override; + std::unique_ptr<ExtensionActionTestHelper> CreateOverflowBar( + Browser* browser) override; + gfx::Size GetMinPopupSize() override; + gfx::Size GetMaxPopupSize() override; + gfx::Size GetToolbarActionSize() override; + bool CanBeResized() override; + + private: + friend class ExtensionActionTestHelper; + + class TestToolbarActionsBarHelper; + + // Constructs a version of ExtensionActionTestHelperViews that does not own + // the BrowserActionsContainer it tests. + explicit ExtensionActionTestHelperViews( + BrowserActionsContainer* browser_actions_container); + // Constructs a version of ExtensionActionTestHelperViews given a + // |test_helper| responsible for owning the BrowserActionsContainer. + explicit ExtensionActionTestHelperViews( + std::unique_ptr<TestToolbarActionsBarHelper> test_helper); + + std::unique_ptr<TestToolbarActionsBarHelper> test_helper_; + + // The associated BrowserActionsContainer. Not owned. + BrowserActionsContainer* const browser_actions_container_; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_EXTENSION_ACTION_TEST_HELPER_VIEWS_H_
diff --git a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc index 59696cfd..6dfc124 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc
@@ -42,6 +42,7 @@ }; params.browser = browser_; params.command_updater = browser_->command_controller(); + params.icon_label_bubble_delegate = this; params.page_action_icon_delegate = this; params.button_observer = this; params.view_observer = this; @@ -64,7 +65,15 @@ avatar_->UpdateIcon(); } -SkColor ToolbarAccountIconContainerView::GetPageActionInkDropColor() const { +SkColor +ToolbarAccountIconContainerView::GetIconLabelBubbleSurroundingForegroundColor() + const { + return GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_TextfieldDefaultColor); +} + +SkColor ToolbarAccountIconContainerView::GetIconLabelBubbleInkDropColor() + const { return GetToolbarInkDropBaseColor(this); }
diff --git a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h index bf1f112..85ccf27d 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h
@@ -17,6 +17,7 @@ // A container view for user-account-related PageActionIconViews and the profile // avatar icon. class ToolbarAccountIconContainerView : public ToolbarIconContainerView, + public IconLabelBubbleView::Delegate, public PageActionIconView::Delegate { public: explicit ToolbarAccountIconContainerView(Browser* browser); @@ -29,8 +30,11 @@ // ToolbarIconContainerView: void UpdateAllIcons() override; + // IconLabelBubbleView::Delegate: + SkColor GetIconLabelBubbleSurroundingForegroundColor() const override; + SkColor GetIconLabelBubbleInkDropColor() const override; + // PageActionIconView::Delegate: - SkColor GetPageActionInkDropColor() const override; float GetPageActionInkDropVisibleOpacity() const override; content::WebContents* GetWebContentsForPageActionIconView() override; std::unique_ptr<views::Border> CreatePageActionIconBorder() const override;
diff --git a/chrome/browser/ui/views/translate/translate_icon_view.cc b/chrome/browser/ui/views/translate/translate_icon_view.cc index 4dc88dfe..9c94a701 100644 --- a/chrome/browser/ui/views/translate/translate_icon_view.cc +++ b/chrome/browser/ui/views/translate/translate_icon_view.cc
@@ -18,10 +18,14 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" -TranslateIconView::TranslateIconView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate) - : PageActionIconView(command_updater, IDC_TRANSLATE_PAGE, delegate) { - DCHECK(delegate); +TranslateIconView::TranslateIconView( + CommandUpdater* command_updater, + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate) + : PageActionIconView(command_updater, + IDC_TRANSLATE_PAGE, + icon_label_bubble_delegate, + page_action_icon_delegate) { SetID(VIEW_ID_TRANSLATE_BUTTON); }
diff --git a/chrome/browser/ui/views/translate/translate_icon_view.h b/chrome/browser/ui/views/translate/translate_icon_view.h index f2bd30fc..541f8a3a 100644 --- a/chrome/browser/ui/views/translate/translate_icon_view.h +++ b/chrome/browser/ui/views/translate/translate_icon_view.h
@@ -15,7 +15,8 @@ class TranslateIconView : public PageActionIconView { public: TranslateIconView(CommandUpdater* command_updater, - PageActionIconView::Delegate* delegate); + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + PageActionIconView::Delegate* page_action_icon_delegate); ~TranslateIconView() override; // PageActionIconView:
diff --git a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc index d34d16a..6460aa6 100644 --- a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc +++ b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc
@@ -173,8 +173,9 @@ class WebAppFrameToolbarView::ContentSettingsContainer : public views::View { public: - explicit ContentSettingsContainer( - ContentSettingImageView::Delegate* delegate); + ContentSettingsContainer( + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + ContentSettingImageView::Delegate* content_setting_image_delegate); ~ContentSettingsContainer() override = default; void UpdateContentSettingViewsVisibility() { @@ -224,7 +225,8 @@ }; WebAppFrameToolbarView::ContentSettingsContainer::ContentSettingsContainer( - ContentSettingImageView::Delegate* delegate) { + IconLabelBubbleView::Delegate* icon_label_bubble_delegate, + ContentSettingImageView::Delegate* content_setting_image_delegate) { views::BoxLayout& layout = *SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), @@ -237,7 +239,8 @@ ContentSettingImageModel::GenerateContentSettingImageModels(); for (auto& model : models) { auto image_view = std::make_unique<ContentSettingImageView>( - std::move(model), delegate, + std::move(model), icon_label_bubble_delegate, + content_setting_image_delegate, views::CustomFrameView::GetWindowTitleFontList()); // Padding around content setting icons. constexpr auto kContentSettingIconInteriorPadding = gfx::Insets(4); @@ -367,6 +370,7 @@ class WebAppFrameToolbarView::ToolbarButtonContainer : public views::View, public BrowserActionsContainer::Delegate, + public IconLabelBubbleView::Delegate, public ContentSettingImageView::Delegate, public ImmersiveModeController::Observer, public PageActionIconView::Delegate, @@ -468,8 +472,16 @@ main_bar); } + // IconLabelBubbleView::Delegate: + SkColor GetIconLabelBubbleSurroundingForegroundColor() const override { + return GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_TextfieldDefaultColor); + } + SkColor GetIconLabelBubbleInkDropColor() const override { + return icon_color_; + } + // ContentSettingImageView::Delegate: - SkColor GetContentSettingInkDropColor() const override { return icon_color_; } content::WebContents* GetContentSettingWebContents() override { return browser_view_->GetActiveWebContents(); } @@ -493,7 +505,6 @@ } // PageActionIconView::Delegate: - SkColor GetPageActionInkDropColor() const override { return icon_color_; } content::WebContents* GetWebContentsForPageActionIconView() override { return browser_view_->GetActiveWebContents(); } @@ -548,7 +559,7 @@ if (app_controller->HasTitlebarContentSettings()) { content_settings_container_ = - AddChildView(std::make_unique<ContentSettingsContainer>(this)); + AddChildView(std::make_unique<ContentSettingsContainer>(this, this)); views::SetHitTestComponent(content_settings_container_, static_cast<int>(HTCLIENT)); } @@ -569,6 +580,7 @@ HorizontalPaddingBetweenPageActionsAndAppMenuButtons(); params.browser = browser_view_->browser(); params.command_updater = browser_view_->browser()->command_controller(); + params.icon_label_bubble_delegate = this; params.page_action_icon_delegate = this; page_action_icon_container_view_ = AddChildView(std::make_unique<PageActionIconContainerView>(params)); @@ -863,12 +875,8 @@ ->get_content_setting_views(); } -SkColor WebAppFrameToolbarView::GetCaptionColor() const { - return paint_as_active_ ? active_color_ : inactive_color_; -} - void WebAppFrameToolbarView::UpdateChildrenColor() { - SkColor icon_color = GetCaptionColor(); + const SkColor icon_color = paint_as_active_ ? active_color_ : inactive_color_; if (left_container_) left_container_->SetIconColor(icon_color); right_container_->SetIconColor(icon_color);
diff --git a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h index 4b4cca4..a0e56e53 100644 --- a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h +++ b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h
@@ -111,7 +111,6 @@ const std::vector<ContentSettingImageView*>& GetContentSettingViewsForTesting() const; - SkColor GetCaptionColor() const; void UpdateChildrenColor(); // The containing browser view.
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc index 70d59dd..e741359 100644 --- a/chrome/browser/ui/webui/settings/about_handler.cc +++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -22,6 +22,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/system/sys_info.h" #include "base/task/post_task.h" #include "base/time/time.h" #include "base/values.h"
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc index e3de038..c8f8af5 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc
@@ -89,7 +89,8 @@ DISALLOW_COPY_AND_ASSIGN(WindowSizerTest); }; -IN_PROC_BROWSER_TEST_F(WindowSizerTest, OpenBrowserUsingShelfItem) { +// TODO(crbug.com/1038342): Test is flaky. +IN_PROC_BROWSER_TEST_F(WindowSizerTest, DISABLED_OpenBrowserUsingShelfItem) { // Don't shutdown when closing the last browser window. ScopedKeepAlive test_keep_alive(KeepAliveOrigin::BROWSER_PROCESS_CHROMEOS, KeepAliveRestartOption::DISABLED); @@ -133,7 +134,8 @@ EXPECT_EQ(root_windows[0], ash::Shell::GetRootWindowForNewWindows()); } -IN_PROC_BROWSER_TEST_F(WindowSizerTest, OpenBrowserUsingContextMenu) { +// TODO(crbug.com/1038342): Test is flaky. +IN_PROC_BROWSER_TEST_F(WindowSizerTest, DISABLED_OpenBrowserUsingContextMenu) { // Don't shutdown when closing the last browser window. ScopedKeepAlive test_keep_alive(KeepAliveOrigin::BROWSER_PROCESS_CHROMEOS, KeepAliveRestartOption::DISABLED);
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc index 068acda..5c7cd804 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
@@ -457,7 +457,8 @@ ASSERT_EQ(S_OK, SetGlobalFlagForTesting(L"enable_ad_association", 0)); } -TEST_P(GcpCredentialProviderWithGaiaUsersTest, ReauthCredentialTest) { +// TODO(crbug.com/1038339): Test is failing consistently. +TEST_P(GcpCredentialProviderWithGaiaUsersTest, DISABLED_ReauthCredentialTest) { const bool has_token_handle = std::get<0>(GetParam()); const bool valid_token_handle = std::get<1>(GetParam()); const bool has_internet = std::get<2>(GetParam()); @@ -551,7 +552,13 @@ ASSERT_EQ(S_OK, SetGlobalFlagForTesting(L"enable_ad_association", 1)); } -TEST_P(GcpCredentialProviderWithADUsersTest, ReauthCredentialTest) { +// TODO(crbug.com/1038351): Test fails on Windows. +#if defined(OS_WIN) +#define MAYBE_ReauthCredentialTest DISABLED_ReauthCredentialTest +#else +#define MAYBE_ReauthCredentialTest ReauthCredentialTest +#endif +TEST_P(GcpCredentialProviderWithADUsersTest, MAYBE_ReauthCredentialTest) { const bool has_user_id = std::get<0>(GetParam()); const bool valid_token_handle = std::get<1>(GetParam()); const bool is_ad_user = std::get<2>(GetParam());
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index b59c01e..3bb7b98 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1012,6 +1012,7 @@ "../browser/net/chrome_network_service_browsertest.cc", "../browser/net/chrome_network_service_restart_browsertest.cc", "../browser/net/cookie_policy_browsertest.cc", + "../browser/net/dns_over_https_browsertest.cc", "../browser/net/dns_probe_browsertest.cc", "../browser/net/errorpage_browsertest.cc", "../browser/net/ftp_browsertest.cc",
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 21bbc55..6988d18 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
@@ -9,19 +9,16 @@ import androidx.annotation.WorkerThread; -import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.signin.IdentityServicesProvider; import org.chromium.chrome.browser.signin.SigninHelper; import org.chromium.components.signin.AccountIdProvider; import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.ChromeSigninController; -import org.chromium.components.signin.identitymanager.ProfileOAuth2TokenServiceDelegate; import org.chromium.components.signin.test.util.AccountHolder; import org.chromium.components.signin.test.util.FakeAccountManagerDelegate; import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; /** @@ -139,11 +136,6 @@ public static void resetSigninState() { // Clear cached signed account name and accounts list. ChromeSigninController.get().setSignedInAccountName(null); - ContextUtils.getAppSharedPreferences() - .edit() - .putStringSet( - ProfileOAuth2TokenServiceDelegate.STORED_ACCOUNTS_KEY, new HashSet<>()) - .apply(); } private SigninTestUtil() {}
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index 9ccda16..19d33b3 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc
@@ -164,14 +164,6 @@ } #endif -std::unique_ptr<storage::QuotaSettings> -InProcessBrowserTest::CreateQuotaSettings() { - // By default use hardcoded quota settings to have a consistent testing - // environment. - const int kQuota = 5 * 1024 * 1024; - return std::make_unique<storage::QuotaSettings>(kQuota * 5, kQuota, 0, 0); -} - void InProcessBrowserTest::Initialize() { CreateTestServer(GetChromeTestDataDir()); base::FilePath src_dir; @@ -289,10 +281,6 @@ ash::ShellTestApi::SetTabletControllerUseScreenshotForTest(false); #endif // defined(OS_CHROMEOS) - quota_settings_ = CreateQuotaSettings(); - ChromeContentBrowserClient::SetDefaultQuotaSettingsForTesting( - quota_settings_.get()); - // Redirect the default download directory to a temporary directory. ASSERT_TRUE(default_download_dir_.CreateUniqueTempDir()); CHECK(base::PathService::Override(chrome::DIR_DEFAULT_DOWNLOADS, @@ -323,7 +311,6 @@ #if defined(OS_MACOSX) || defined(OS_LINUX) OSCryptMocker::TearDown(); #endif - ChromeContentBrowserClient::SetDefaultQuotaSettingsForTesting(nullptr); #if defined(OS_CHROMEOS) chromeos::device_sync::DeviceSyncImpl::Factory::SetInstanceForTesting(
diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h index 0cc16a2..8bd4494 100644 --- a/chrome/test/base/in_process_browser_test.h +++ b/chrome/test/base/in_process_browser_test.h
@@ -17,7 +17,6 @@ #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_base.h" -#include "storage/browser/quota/quota_settings.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/page_transition_types.h" @@ -264,8 +263,6 @@ open_about_blank_on_browser_launch_ = value; } - virtual std::unique_ptr<storage::QuotaSettings> CreateQuotaSettings(); - private: void Initialize(); @@ -293,11 +290,6 @@ // True if the about:blank tab should be opened when the browser is launched. bool open_about_blank_on_browser_launch_ = true; - // We use fake quota settings by default to have a consistent testing - // environment. These can be overridden by subclasses via the - // CreateQuotaSettings() method. - std::unique_ptr<storage::QuotaSettings> quota_settings_; - // Use a default download directory to make sure downloads don't end up in the // system default location. base::ScopedTempDir default_download_dir_;
diff --git a/chrome/test/chromedriver/BUILD.gn b/chrome/test/chromedriver/BUILD.gn index cc839593..4993ce8 100644 --- a/chrome/test/chromedriver/BUILD.gn +++ b/chrome/test/chromedriver/BUILD.gn
@@ -344,6 +344,7 @@ pydeps_file = "test/run_py_tests.pydeps" data = [ "//chrome/test/data/chromedriver/", + "//chrome/test/chromedriver/js/", "//testing/scripts/run_chromedriver_tests.py", "//testing/scripts/common.py", "//testing/xvfb.py",
diff --git a/chrome/test/chromedriver/js/test.js b/chrome/test/chromedriver/js/test.js index 2ec380d..bd3741d 100644 --- a/chrome/test/chromedriver/js/test.js +++ b/chrome/test/chromedriver/js/test.js
@@ -43,7 +43,12 @@ } }; - test(runner); + try { + test(runner); + } catch (error) { + window.CDCJStestRunStatus = "FAIL: " + error.stack; + throw error; + } if (shouldContinue) onPass(); } @@ -52,6 +57,7 @@ * Runs all tests and reports the results via the console. */ function runTests() { + window.CDCJStestRunStatus; var tests = []; for (var i in window) { if (i.indexOf('test') == 0) @@ -62,6 +68,7 @@ var testNo = 0; function runNextTest() { if (testNo >= tests.length) { + window.CDCJStestRunStatus = "PASS" console.log('All tests passed'); return; }
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 11b979e..09bcdad 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -78,6 +78,10 @@ 'ChromeDriverTest.testAlertOnNewWindow', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2532 'ChromeDriverPageLoadTimeoutTest.testRefreshWithPageLoadTimeout', + # testFocus is failing + 'JavaScriptTests.testFocus', + # https://bugs.chromium.org/p/chromium/issues/detail?id=1038366 + 'JavaScriptTests.testAllJS', ] @@ -4201,6 +4205,46 @@ self.CreateDriver('http://[::1]:' + str(chromedriver_server.GetPort())) +class JavaScriptTests(ChromeDriverBaseTestWithWebServer): + def GetFileUrl(self, filename): + return 'file://' + self.js_root + filename + + def setUp(self): + self._driver = self.CreateDriver() + self.js_root = os.path.dirname(os.path.realpath(__file__)) + '/../js/' + + def checkTestResult(self): + def getStatus(): + return self._driver.ExecuteScript('return window.CDCJStestRunStatus') + + self.WaitForCondition(getStatus) + self.assertEquals('PASS', getStatus()) + + def testAllJS(self): + self._driver.Load(self.GetFileUrl('call_function_test.html')) + self.checkTestResult() + + self._driver.Load(self.GetFileUrl('dispatch_touch_event_test.html')) + self.checkTestResult() + + self._driver.Load(self.GetFileUrl('execute_async_script_test.html')) + self.checkTestResult() + + self._driver.Load(self.GetFileUrl('execute_script_test.html')) + self.checkTestResult() + + self._driver.Load(self.GetFileUrl('get_element_location_test.html')) + self.checkTestResult() + + self._driver.Load(self.GetFileUrl('get_element_region_test.html')) + self.checkTestResult() + + self._driver.Load(self.GetFileUrl('is_option_element_toggleable_test.html')) + self.checkTestResult() + + def testFocus(self): + self._driver.Load(self.GetFileUrl('focus_test.html')) + self.checkTestResult() # 'Z' in the beginning is to make test executed in the end of suite. class ZChromeStartRetryCountTest(unittest.TestCase):
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 36fd705..e6257d9 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -25,6 +25,7 @@ 'BasicMouseInterfaceTest.testMoveMouseByOffsetOverAndOutOfAnElement', 'BasicMouseInterfaceTest.testMovingMouseToRelativeElementOffset', 'BasicMouseInterfaceTest.testMovingMouseToRelativeZeroElementOffset', + 'ChromeOptionsFunctionalTest.canAddExtensionFromFile', 'CombinedInputActionsTest.testClickAfterMoveToAnElementWithAnOffsetShouldUseLastMousePosition', 'ContentEditableTest.appendsTextToEndOfContentEditableWithMultipleTextNodes', 'ContentEditableTest.testShouldAppendToTinyMCE', @@ -35,6 +36,7 @@ 'PageLoadingTest.testEagerStrategyShouldNotWaitForResources', 'PageLoadingTest.testEagerStrategyShouldNotWaitForResourcesOnRefresh', 'PageLoadingTest.testEagerStrategyShouldWaitForDocumentToBeLoaded', + 'TextHandlingTest.canHandleTextTransformProperty', 'WindowSwitchingTest.canOpenANewWindow', 'LocationContextTest.testShouldSetAndGetLatitude', 'LocationContextTest.testShouldSetAndGetLongitude',
diff --git a/chrome/test/data/prerender/prerender_new_entry.html b/chrome/test/data/prerender/prerender_new_entry.html deleted file mode 100644 index 1a20122..0000000 --- a/chrome/test/data/prerender/prerender_new_entry.html +++ /dev/null
@@ -1,17 +0,0 @@ -<html> - <!-- - This test navigates to prerender_page.html after the onload event to create a - new navigation entry. - --> - <head> - <title>Prerender navigate after load</title> - <script> - window.onload = function() { - setTimeout(function() { - location.href = "prerender_page.html"; - }); - }; - </script> - </head> - <body></body> -</html>
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index ca955d2..ff12c5a 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -550,15 +550,6 @@ return new CastQuotaPermissionContext(); } -void CastContentBrowserClient::GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - storage::GetNominalDynamicSettings( - partition->GetPath(), context->IsOffTheRecord(), - storage::GetDefaultDeviceInfoHelper(), std::move(callback)); -} - void CastContentBrowserClient::AllowCertificateError( content::WebContents* web_contents, int cert_error,
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 7bd355a..4297593 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -168,10 +168,6 @@ std::string GetApplicationLocale() override; scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) override; void AllowCertificateError( content::WebContents* web_contents, int cert_error,
diff --git a/chromeos/profiles/airmont.afdo.newest.txt b/chromeos/profiles/airmont.afdo.newest.txt index c1d35aa..7f6e565 100644 --- a/chromeos/profiles/airmont.afdo.newest.txt +++ b/chromeos/profiles/airmont.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-airmont-81-3987.0-1577100150-benchmark-81.0.4009.0-r1-redacted.afdo.xz \ No newline at end of file +chromeos-chrome-amd64-airmont-81-3987.18-1577702544-benchmark-81.0.4011.0-r1-redacted.afdo.xz \ No newline at end of file
diff --git a/chromeos/profiles/broadwell.afdo.newest.txt b/chromeos/profiles/broadwell.afdo.newest.txt index cc729739..b527432 100644 --- a/chromeos/profiles/broadwell.afdo.newest.txt +++ b/chromeos/profiles/broadwell.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-broadwell-81-3945.86-1577097374-benchmark-81.0.4009.0-r1-redacted.afdo.xz \ No newline at end of file +chromeos-chrome-amd64-broadwell-81-3987.18-1577704324-benchmark-81.0.4011.0-r1-redacted.afdo.xz \ No newline at end of file
diff --git a/chromeos/profiles/orderfile.newest.txt b/chromeos/profiles/orderfile.newest.txt index 7e384c3d..ac20ebf 100644 --- a/chromeos/profiles/orderfile.newest.txt +++ b/chromeos/profiles/orderfile.newest.txt
@@ -1 +1 @@ -chromeos-chrome-orderfile-field-81-3987.0-1577099071-benchmark-81.0.4005.0-r1.orderfile.xz \ No newline at end of file +chromeos-chrome-orderfile-field-81-3987.0-1577099071-benchmark-81.0.4009.0-r1.orderfile.xz \ No newline at end of file
diff --git a/chromeos/profiles/silvermont.afdo.newest.txt b/chromeos/profiles/silvermont.afdo.newest.txt index 4bee3e6..9cb6b04 100644 --- a/chromeos/profiles/silvermont.afdo.newest.txt +++ b/chromeos/profiles/silvermont.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-silvermont-81-3987.0-1577099071-benchmark-81.0.4009.0-r1-redacted.afdo.xz \ No newline at end of file +chromeos-chrome-amd64-silvermont-81-3987.18-1577705382-benchmark-81.0.4011.0-r1-redacted.afdo.xz \ No newline at end of file
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc index be304c1..10082e3 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -333,13 +333,13 @@ data_usage_reporting_enabled_.Init( prefs::kDataUsageReportingEnabled, pref_service_, - base::Bind( + base::BindRepeating( &DataReductionProxyCompressionStats::OnDataUsageReportingPrefChanged, weak_factory_.GetWeakPtr())); if (data_usage_reporting_enabled_.GetValue()) { current_data_usage_load_status_ = LOADING; - service_->LoadCurrentDataUsageBucket(base::Bind( + service_->LoadCurrentDataUsageBucket(base::BindRepeating( &DataReductionProxyCompressionStats::OnCurrentDataUsageLoaded, weak_factory_.GetWeakPtr())); } @@ -522,8 +522,9 @@ } void DataReductionProxyCompressionStats::GetHistoricalDataUsage( - const HistoricalDataUsageCallback& get_data_usage_callback) { - GetHistoricalDataUsageImpl(get_data_usage_callback, base::Time::Now()); + HistoricalDataUsageCallback get_data_usage_callback) { + GetHistoricalDataUsageImpl(std::move(get_data_usage_callback), + base::Time::Now()); } void DataReductionProxyCompressionStats::DeleteBrowsingHistory( @@ -751,7 +752,7 @@ } void DataReductionProxyCompressionStats::GetHistoricalDataUsageImpl( - const HistoricalDataUsageCallback& get_data_usage_callback, + HistoricalDataUsageCallback get_data_usage_callback, const base::Time& now) { #if !defined(OS_ANDROID) if (current_data_usage_load_status_ != LOADED) { @@ -759,8 +760,8 @@ // extension can retry after a slight delay. // This use case is unlikely to occur in practice since current data usage // should have sufficient time to load before user tries to view data usage. - get_data_usage_callback.Run( - std::make_unique<std::vector<DataUsageBucket>>()); + std::move(get_data_usage_callback) + .Run(std::make_unique<std::vector<DataUsageBucket>>()); return; } #endif @@ -779,14 +780,14 @@ service_->StoreCurrentDataUsageBucket(std::move(data_usage_bucket)); } - service_->LoadHistoricalDataUsage(get_data_usage_callback); + service_->LoadHistoricalDataUsage(std::move(get_data_usage_callback)); } void DataReductionProxyCompressionStats::OnDataUsageReportingPrefChanged() { if (data_usage_reporting_enabled_.GetValue()) { if (current_data_usage_load_status_ == NOT_LOADED) { current_data_usage_load_status_ = LOADING; - service_->LoadCurrentDataUsageBucket(base::Bind( + service_->LoadCurrentDataUsageBucket(base::BindOnce( &DataReductionProxyCompressionStats::OnCurrentDataUsageLoaded, weak_factory_.GetWeakPtr())); }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h index 7e05e74d..708c9db 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h
@@ -135,7 +135,7 @@ // in-memory stats could be initialized from storage. Data usage is sorted // chronologically with the last entry corresponding to |base::Time::Now()|. void GetHistoricalDataUsage( - const HistoricalDataUsageCallback& get_data_usage_callback); + HistoricalDataUsageCallback get_data_usage_callback); // Deletes browsing history from storage and memory for the given time // range. Currently, this method deletes all data usage for the given range. @@ -242,7 +242,7 @@ // Actual implementation of |GetHistoricalDataUsage|. This helper method // explicitly passes |base::Time::Now()| to make testing easier. void GetHistoricalDataUsageImpl( - const HistoricalDataUsageCallback& get_data_usage_callback, + HistoricalDataUsageCallback get_data_usage_callback, const base::Time& now); // Called when |prefs::kDataUsageReportingEnabled| pref values changes.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc index 850e7edc..c8accb3 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
@@ -302,15 +302,15 @@ original_size, time); } - void GetHistoricalDataUsage( - const HistoricalDataUsageCallback& onLoadDataUsage, - const base::Time& now) { - compression_stats_->GetHistoricalDataUsageImpl(onLoadDataUsage, now); + void GetHistoricalDataUsage(HistoricalDataUsageCallback on_load_data_usage, + const base::Time& now) { + compression_stats_->GetHistoricalDataUsageImpl( + std::move(on_load_data_usage), now); } - void LoadHistoricalDataUsage( - const HistoricalDataUsageCallback& onLoadDataUsage) { - compression_stats_->service_->LoadHistoricalDataUsage(onLoadDataUsage); + void LoadHistoricalDataUsage(HistoricalDataUsageCallback on_load_data_usage) { + compression_stats_->service_->LoadHistoricalDataUsage( + std::move(on_load_data_usage)); } void DeleteHistoricalDataUsage() { @@ -700,8 +700,8 @@ DataUsageLoadVerifier verifier(std::move(expected_data_usage)); - GetHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier)), + GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage, + base::Unretained(&verifier)), now); base::RunLoop().RunUntilIdle(); } @@ -722,15 +722,15 @@ std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>( kNumExpectedBuckets); DataUsageLoadVerifier verifier1(std::move(expected_data_usage1)); - LoadHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier1))); + LoadHistoricalDataUsage(base::BindOnce( + &DataUsageLoadVerifier::OnLoadDataUsage, base::Unretained(&verifier1))); // Public API must return an empty array. auto expected_data_usage2 = std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>(); DataUsageLoadVerifier verifier2(std::move(expected_data_usage2)); - GetHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier2)), + GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage, + base::Unretained(&verifier2)), now); #else // For Android don't delete data usage. @@ -747,8 +747,8 @@ DataUsageLoadVerifier verifier(std::move(expected_data_usage)); - GetHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier)), + GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage, + base::Unretained(&verifier)), now); #endif @@ -787,8 +787,8 @@ DataUsageLoadVerifier verifier(std::move(expected_data_usage)); - GetHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier)), + GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage, + base::Unretained(&verifier)), now); base::RunLoop().RunUntilIdle(); } @@ -825,8 +825,8 @@ DataUsageLoadVerifier verifier(std::move(expected_data_usage)); - GetHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier)), + GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage, + base::Unretained(&verifier)), now); base::RunLoop().RunUntilIdle(); } @@ -856,8 +856,8 @@ DataUsageLoadVerifier verifier(std::move(expected_data_usage)); - GetHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier)), + GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage, + base::Unretained(&verifier)), now); base::RunLoop().RunUntilIdle(); } @@ -881,8 +881,8 @@ kNumExpectedBuckets); DataUsageLoadVerifier verifier(std::move(expected_data_usage)); - GetHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier)), + GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage, + base::Unretained(&verifier)), now); base::RunLoop().RunUntilIdle(); } @@ -918,8 +918,8 @@ site_usage->set_original_size(1100); DataUsageLoadVerifier verifier1(std::move(expected_data_usage)); - LoadHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier1))); + LoadHistoricalDataUsage(base::BindOnce( + &DataUsageLoadVerifier::OnLoadDataUsage, base::Unretained(&verifier1))); base::RunLoop().RunUntilIdle(); // This should delete in-storage usage as well. @@ -930,8 +930,8 @@ std::make_unique<std::vector<data_reduction_proxy::DataUsageBucket>>( kNumExpectedBuckets); DataUsageLoadVerifier verifier2(std::move(expected_data_usage)); - LoadHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier2))); + LoadHistoricalDataUsage(base::BindOnce( + &DataUsageLoadVerifier::OnLoadDataUsage, base::Unretained(&verifier2))); base::RunLoop().RunUntilIdle(); } @@ -965,8 +965,8 @@ kNumExpectedBuckets); DataUsageLoadVerifier verifier(std::move(expected_data_usage)); - GetHistoricalDataUsage(base::Bind(&DataUsageLoadVerifier::OnLoadDataUsage, - base::Unretained(&verifier)), + GetHistoricalDataUsage(base::BindOnce(&DataUsageLoadVerifier::OnLoadDataUsage, + base::Unretained(&verifier)), now); base::RunLoop().RunUntilIdle();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index 13eac80..72789a5f 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -347,9 +347,9 @@ // It is safe to use base::Unretained here, since it gets executed // synchronously on the IO thread, and |this| outlives // |secure_proxy_checker_|. - SecureProxyCheck( - base::Bind(&DataReductionProxyConfig::HandleSecureProxyCheckResponse, - base::Unretained(this))); + SecureProxyCheck(base::BindRepeating( + &DataReductionProxyConfig::HandleSecureProxyCheckResponse, + base::Unretained(this))); } network_properties_manager_->ResetWarmupURLFetchMetrics(); FetchWarmupProbeURL(); @@ -601,9 +601,9 @@ // It is safe to use base::Unretained here, since it gets executed // synchronously on the IO thread, and |this| outlives // |secure_proxy_checker_|. - SecureProxyCheck( - base::Bind(&DataReductionProxyConfig::HandleSecureProxyCheckResponse, - base::Unretained(this))); + SecureProxyCheck(base::BindRepeating( + &DataReductionProxyConfig::HandleSecureProxyCheckResponse, + base::Unretained(this))); } }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h index 3a034f3..fc9507d5 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h
@@ -44,7 +44,7 @@ class DataReductionProxyMutableConfigValues; class DataReductionProxyRequestOptions; -typedef base::Callback<void(const std::string&)> ConfigStorer; +using ConfigStorer = base::RepeatingCallback<void(const std::string&)>; // Retrieves the default net::BackoffEntry::Policy for the Data Reduction Proxy // configuration service client.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc index 98d7f48e..164a249 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
@@ -321,7 +321,7 @@ } void DataReductionProxyService::LoadHistoricalDataUsage( - const HistoricalDataUsageCallback& load_data_usage_callback) { + HistoricalDataUsageCallback load_data_usage_callback) { std::unique_ptr<std::vector<DataUsageBucket>> data_usage( new std::vector<DataUsageBucket>()); std::vector<DataUsageBucket>* data_usage_ptr = data_usage.get(); @@ -330,11 +330,12 @@ base::BindOnce(&DBDataOwner::LoadHistoricalDataUsage, db_data_owner_->GetWeakPtr(), base::Unretained(data_usage_ptr)), - base::BindOnce(load_data_usage_callback, std::move(data_usage))); + base::BindOnce(std::move(load_data_usage_callback), + std::move(data_usage))); } void DataReductionProxyService::LoadCurrentDataUsageBucket( - const LoadCurrentDataUsageCallback& load_current_data_usage_callback) { + LoadCurrentDataUsageCallback load_current_data_usage_callback) { std::unique_ptr<DataUsageBucket> bucket(new DataUsageBucket()); DataUsageBucket* bucket_ptr = bucket.get(); db_task_runner_->PostTaskAndReply( @@ -342,7 +343,8 @@ base::BindOnce(&DBDataOwner::LoadCurrentDataUsageBucket, db_data_owner_->GetWeakPtr(), base::Unretained(bucket_ptr)), - base::BindOnce(load_current_data_usage_callback, std::move(bucket))); + base::BindOnce(std::move(load_current_data_usage_callback), + std::move(bucket))); } void DataReductionProxyService::StoreCurrentDataUsageBucket(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h index 73c96e7f..b59b72d 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h
@@ -119,9 +119,9 @@ virtual void SetProxyPrefs(bool enabled, bool at_startup); void LoadHistoricalDataUsage( - const HistoricalDataUsageCallback& load_data_usage_callback); + HistoricalDataUsageCallback load_data_usage_callback); void LoadCurrentDataUsageBucket( - const LoadCurrentDataUsageCallback& load_current_data_usage_callback); + LoadCurrentDataUsageCallback load_current_data_usage_callback); void StoreCurrentDataUsageBucket(std::unique_ptr<DataUsageBucket> current); void DeleteHistoricalDataUsage(); void DeleteBrowsingHistory(const base::Time& start, const base::Time& end);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h index 6eb2b74c..a2bcc08 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
@@ -80,7 +80,7 @@ class DataReductionProxySettings { public: using SyntheticFieldTrialRegistrationCallback = - base::Callback<bool(base::StringPiece, base::StringPiece)>; + base::RepeatingCallback<bool(base::StringPiece, base::StringPiece)>; explicit DataReductionProxySettings(bool is_off_the_record_profile); virtual ~DataReductionProxySettings();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc index dde964e..2190ece7 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
@@ -126,7 +126,7 @@ settings_->InitDataReductionProxySettings( test_context_->pref_service(), std::move(settings_->data_reduction_proxy_service_)); - settings_->SetCallbackToRegisterSyntheticFieldTrial(base::Bind( + settings_->SetCallbackToRegisterSyntheticFieldTrial(base::BindRepeating( &DataReductionProxySettingsTestBase::OnSyntheticFieldTrialRegistration, base::Unretained(this)));
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc index 485cbdf..008f0f9 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -468,8 +468,8 @@ config_client.reset(new DataReductionProxyConfigServiceClient( GetBackoffPolicy(), request_options.get(), raw_mutable_config, config.get(), service.get(), test_network_connection_tracker, - base::Bind(&TestConfigStorer::StoreSerializedConfig, - base::Unretained(config_storer.get())))); + base::BindRepeating(&TestConfigStorer::StoreSerializedConfig, + base::Unretained(config_storer.get())))); } service->SetDependenciesForTesting(
diff --git a/components/data_reduction_proxy/core/browser/db_data_owner.h b/components/data_reduction_proxy/core/browser/db_data_owner.h index 6acb002..9a63addf 100644 --- a/components/data_reduction_proxy/core/browser/db_data_owner.h +++ b/components/data_reduction_proxy/core/browser/db_data_owner.h
@@ -19,12 +19,12 @@ class DataUsageStore; // Callback for loading the historical data usage. -typedef base::Callback<void(std::unique_ptr<std::vector<DataUsageBucket>>)> - HistoricalDataUsageCallback; +using HistoricalDataUsageCallback = + base::OnceCallback<void(std::unique_ptr<std::vector<DataUsageBucket>>)>; // Callback for loading data usage for the current bucket. -typedef base::Callback<void(std::unique_ptr<DataUsageBucket>)> - LoadCurrentDataUsageCallback; +using LoadCurrentDataUsageCallback = + base::OnceCallback<void(std::unique_ptr<DataUsageBucket>)>; // Contains and initializes all Data Reduction Proxy objects that have a // lifetime based on the DB task runner.
diff --git a/components/optimization_guide/optimization_guide_features.cc b/components/optimization_guide/optimization_guide_features.cc index ff7c4fe..adc0434 100644 --- a/components/optimization_guide/optimization_guide_features.cc +++ b/components/optimization_guide/optimization_guide_features.cc
@@ -193,6 +193,17 @@ "max_store_duration_for_host_model_features_in_days", 7)); } +size_t MaxHostsForOptimizationGuideServiceModelsFetch() { + return GetFieldTrialParamByFeatureAsInt( + kOptimizationTargetPrediction, + "max_hosts_for_optimization_guide_service_models_fetch", 30); +} + +size_t MaxHostModelFeaturesCacheSize() { + return GetFieldTrialParamByFeatureAsInt( + kOptimizationTargetPrediction, "max_host_model_features_cache_size", 100); +} + bool IsOptimizationTargetPredictionEnabled() { return base::FeatureList::IsEnabled(kOptimizationTargetPrediction); }
diff --git a/components/optimization_guide/optimization_guide_features.h b/components/optimization_guide/optimization_guide_features.h index 05aff07..1ce8a9ed 100644 --- a/components/optimization_guide/optimization_guide_features.h +++ b/components/optimization_guide/optimization_guide_features.h
@@ -99,6 +99,14 @@ // to be used and remain in the OptimizationGuideStore. base::TimeDelta StoredHostModelFeaturesFreshnessDuration(); +// The maximum number of hosts allowed to be requested by the client to the +// remote Optimzation Guide Service for use by prediction models. +size_t MaxHostsForOptimizationGuideServiceModelsFetch(); + +// The maximum number of hosts allowed to be maintained in a least-recently-used +// cache by the prediction manager. +size_t MaxHostModelFeaturesCacheSize(); + // Returns true if the optimization target decision for |optimization_target| // should not be propagated to the caller in an effort to fully understand the // statistics for the served model and not taint the resulting data.
diff --git a/components/optimization_guide/optimization_guide_store.cc b/components/optimization_guide/optimization_guide_store.cc index 0a24bea..7bfc4758 100644 --- a/components/optimization_guide/optimization_guide_store.cc +++ b/components/optimization_guide/optimization_guide_store.cc
@@ -88,6 +88,12 @@ return base::StartsWith(key, key_prefix, base::CompareCase::SENSITIVE); } +// Returns true if |key| is in |keys_to_remove|. +bool ExpiredKeyFilter(const base::flat_set<std::string>& keys_to_remove, + const std::string& key) { + return keys_to_remove.find(key) != keys_to_remove.end(); +} + } // namespace OptimizationGuideStore::OptimizationGuideStore( @@ -258,40 +264,50 @@ void OptimizationGuideStore::PurgeExpiredFetchedHints() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!IsAvailable()) { + if (!IsAvailable()) return; - } // Load all the fetched hints to check their expiry times. database_->LoadKeysAndEntriesWithFilter( base::BindRepeating(&DatabasePrefixFilter, GetFetchedHintEntryKeyPrefix()), - base::BindOnce(&OptimizationGuideStore::OnLoadFetchedHintsToPurgeExpired, + base::BindOnce(&OptimizationGuideStore::OnLoadEntriesToPurgeExpired, weak_ptr_factory_.GetWeakPtr())); } -void OptimizationGuideStore::OnLoadFetchedHintsToPurgeExpired( - bool success, - std::unique_ptr<EntryMap> fetched_entries) { +void OptimizationGuideStore::PurgeExpiredHostModelFeatures() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!success) { + if (!IsAvailable()) return; - } - auto keys_to_remove = std::make_unique<EntryKeySet>(); + // Load all the host model features to check their expiry times. + database_->LoadKeysAndEntriesWithFilter( + base::BindRepeating(&DatabasePrefixFilter, + GetHostModelFeaturesEntryKeyPrefix()), + base::BindOnce(&OptimizationGuideStore::OnLoadEntriesToPurgeExpired, + weak_ptr_factory_.GetWeakPtr())); +} + +void OptimizationGuideStore::OnLoadEntriesToPurgeExpired( + bool success, + std::unique_ptr<EntryMap> entries) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!success) + return; + + EntryKeySet expired_keys_to_remove; int64_t now_since_epoch = base::Time::Now().ToDeltaSinceWindowsEpoch().InSeconds(); - for (const auto& entry : *fetched_entries) { - if (entry.second.expiry_time_secs() <= now_since_epoch) { - keys_to_remove->insert(entry.first); + for (const auto& entry : *entries) { + if (entry.second.has_expiry_time_secs() && + entry.second.expiry_time_secs() <= now_since_epoch) { + expired_keys_to_remove.insert(entry.first); } } - // TODO(mcrouse): Record the number of hints that will be expired from the - // store. - data_update_in_flight_ = true; entry_keys_.reset(); @@ -299,11 +315,7 @@ database_->UpdateEntriesWithRemoveFilter( std::move(empty_entries), - base::BindRepeating( - [](EntryKeySet* keys_to_remove, const std::string& key) { - return keys_to_remove->find(key) != keys_to_remove->end(); - }, - keys_to_remove.get()), + base::BindRepeating(&ExpiredKeyFilter, std::move(expired_keys_to_remove)), base::BindOnce(&OptimizationGuideStore::OnUpdateStore, weak_ptr_factory_.GetWeakPtr(), base::DoNothing::Once())); }
diff --git a/components/optimization_guide/optimization_guide_store.h b/components/optimization_guide/optimization_guide_store.h index 9526708..7a82002 100644 --- a/components/optimization_guide/optimization_guide_store.h +++ b/components/optimization_guide/optimization_guide_store.h
@@ -170,6 +170,11 @@ // removed. void PurgeExpiredFetchedHints(); + // Removes all host model features that have expired from the store. + // |entry_keys_| is updated after the expired host model features are + // removed. + void PurgeExpiredHostModelFeatures(); + // Creates and returns a StoreUpdateData object for Prediction Models. This // object is used to collect a batch of prediction models in a format that is // usable to update the store on a background thread. This is always created @@ -344,11 +349,10 @@ EntryKey* out_entry_key, const EntryKeyPrefix& entry_key_prefix) const; - // Callback that identifies any expired hints from |fetched_entries| and + // Callback that identifies any expired |entries| and // asynchronously removes them from the store. - void OnLoadFetchedHintsToPurgeExpired( - bool success, - std::unique_ptr<EntryMap> fetched_entries); + void OnLoadEntriesToPurgeExpired(bool success, + std::unique_ptr<EntryMap> entries); // Callback that runs after the database finishes being initialized. If // |purge_existing_data| is true, then unconditionally purges the database;
diff --git a/components/optimization_guide/optimization_guide_store_unittest.cc b/components/optimization_guide/optimization_guide_store_unittest.cc index 1f99630..c468415 100644 --- a/components/optimization_guide/optimization_guide_store_unittest.cc +++ b/components/optimization_guide/optimization_guide_store_unittest.cc
@@ -314,7 +314,18 @@ void PurgeExpiredFetchedHints() { guide_store()->PurgeExpiredFetchedHints(); - // OnFetchedHintsLoadedToMaybePurge + // OnLoadExpiredEntriesToPurge + db()->LoadCallback(true); + // OnUpdateStore + db()->UpdateCallback(true); + // OnLoadEntryKeys callback + db()->LoadCallback(true); + } + + void PurgeExpiredHostModelFeatures() { + guide_store()->PurgeExpiredHostModelFeatures(); + + // OnLoadExpiredEntriesToPurge db()->LoadCallback(true); // OnUpdateStore db()->UpdateCallback(true); @@ -2019,4 +2030,41 @@ } } +TEST_F(OptimizationGuideStoreTest, PurgeExpiredHostModelFeatures) { + base::HistogramTester histogram_tester; + size_t update_host_model_features_count = 5; + MetadataSchemaState schema_state = MetadataSchemaState::kValid; + base::Time update_time = base::Time().Now(); + SeedInitialData(schema_state, 0, base::Time().Now()); + CreateDatabase(); + InitializeStore(schema_state); + + std::unique_ptr<StoreUpdateData> update_data = + guide_store()->CreateUpdateDataForHostModelFeatures( + update_time, update_time - + optimization_guide::features:: + StoredHostModelFeaturesFreshnessDuration()); + ASSERT_TRUE(update_data); + SeedHostModelFeaturesUpdateData(update_data.get(), + update_host_model_features_count); + UpdateHostModelFeatures(std::move(update_data)); + + for (size_t i = 0; i < update_host_model_features_count; ++i) { + std::string host_suffix = GetHostSuffix(i); + OptimizationGuideStore::EntryKey entry_key; + EXPECT_TRUE( + guide_store()->FindHostModelFeaturesEntryKey(host_suffix, &entry_key)); + } + + // Remove expired host model features from the opt. guide store. + PurgeExpiredHostModelFeatures(); + + for (size_t i = 0; i < update_host_model_features_count; ++i) { + std::string host_suffix = GetHostSuffix(i); + OptimizationGuideStore::EntryKey entry_key; + EXPECT_FALSE( + guide_store()->FindHostModelFeaturesEntryKey(host_suffix, &entry_key)); + } +} + } // namespace optimization_guide
diff --git a/components/optimization_guide/proto/hints.proto b/components/optimization_guide/proto/hints.proto index f1fff87..5b641d9 100644 --- a/components/optimization_guide/proto/hints.proto +++ b/components/optimization_guide/proto/hints.proto
@@ -27,12 +27,21 @@ optional MatchedHintInfo matched_hint = 2; } +// Information about a URL to request hints for. +message UrlInfo { + // The URL that the client is requesting information for. + optional string url = 1; +} + // Request to return a set of hints that guide what optimizations to perform // on those hosts. message GetHintsRequest { // Information about the set of hosts to retrieve hints for. repeated HostInfo hosts = 1; + // Information about the set of URLs to retrieve hints for. + repeated UrlInfo urls = 4; + // The set of optimization types that the requesting client can support // and perform. // @@ -124,6 +133,11 @@ // Example: A host suffix of example.com would match pages with host // sports.example.com, but not fooexample.com. HOST_SUFFIX = 1; + // The full URL to match. + // + // This will be an exact match of a page load URL, including query params and + // fragments. + FULL_URL = 2; } message Optimization { @@ -206,6 +220,8 @@ // It is expected that this version be sent along with subsequent requests // for hosts that match this hint. optional string version = 5; + // The maximum duration for which the hint should be used for. + optional Duration max_cache_duration = 6; } // Configuration and data for a Bloom filter.
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc index d487731..3573d3b3 100644 --- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc +++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
@@ -239,23 +239,7 @@ std::vector<CoreAccountId> ProfileOAuth2TokenServiceDelegateAndroid::GetAccounts() const { - std::vector<std::string> accounts; - JNIEnv* env = AttachCurrentThread(); - - // TODO(crbug.com/1028580) Pass |j_accounts| as a list of - // org.chromium.components.signin.identitymanager.CoreAccountId and convert it - // to CoreAccountId using ConvertFromJavaCoreAccountId. - ScopedJavaLocalRef<jobjectArray> j_accounts = - signin::Java_ProfileOAuth2TokenServiceDelegate_getAccounts(env); - ; - // TODO(fgorski): We may decide to filter out some of the accounts. - base::android::AppendJavaStringArrayToStringVector(env, j_accounts, - &accounts); - std::vector<CoreAccountId> account_ids; - for (auto& account : accounts) - account_ids.push_back(CoreAccountId::FromString(account)); - - return account_ids; + return accounts_; } std::vector<std::string> @@ -301,11 +285,7 @@ void ProfileOAuth2TokenServiceDelegateAndroid::SetAccounts( const std::vector<CoreAccountId>& accounts) { - JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobjectArray> java_accounts( - base::android::ToJavaArrayOfStrings(env, ToStringList(accounts))); - signin::Java_ProfileOAuth2TokenServiceDelegate_setAccounts(env, - java_accounts); + accounts_ = accounts; } std::unique_ptr<OAuth2AccessTokenFetcher>
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h index 7766266..f8755a56 100644 --- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h +++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h
@@ -130,11 +130,14 @@ std::vector<CoreAccountId> GetSystemAccounts(); // As |GetAccounts| but with only validated account IDs. std::vector<CoreAccountId> GetValidAccounts(); - // Set accounts using Java's Oauth2TokenService.setAccounts. + // Set accounts that have been advertised by OnRefreshTokenAvailable. virtual void SetAccounts(const std::vector<CoreAccountId>& accounts); base::android::ScopedJavaGlobalRef<jobject> java_ref_; + // Accounts that have been advertised by OnRefreshTokenAvailable. + std::vector<CoreAccountId> accounts_; + // Maps account_id to the last error for that account. std::map<CoreAccountId, GoogleServiceAuthError> errors_;
diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegate.java b/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegate.java index 8da601e..b5ecc669 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegate.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegate.java
@@ -11,7 +11,6 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.StrictModeContext; import org.chromium.base.ThreadUtils; @@ -23,10 +22,7 @@ import org.chromium.components.signin.AuthException; import org.chromium.net.NetworkChangeNotifier; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -42,8 +38,6 @@ implements AccountTrackerService.OnSystemAccountsSeededListener { private static final String TAG = "OAuth2TokenService"; - public static final String STORED_ACCOUNTS_KEY = "google.services.stored_accounts"; - /** * A simple callback for getAccessToken. */ @@ -129,18 +123,6 @@ } /** - * Called by native to list the accounts Id with OAuth2 refresh tokens. - * This can differ from getSystemAccountNames as the user add/remove accounts - * from the OS. updateAccountList should be called to keep these two - * in sync. - */ - @CalledByNative - @VisibleForTesting - static String[] getAccounts() { - return getStoredAccounts(); - } - - /** * Called by native to retrieve OAuth2 tokens. * @param username The native username (email address). * @param scope The scope to get an auth token for (without Android-style 'oauth2:' prefix). @@ -327,26 +309,6 @@ mNativeProfileOAuth2TokenServiceDelegate, accountId); } - private static String[] getStoredAccounts() { - Set<String> accounts = - ContextUtils.getAppSharedPreferences().getStringSet(STORED_ACCOUNTS_KEY, null); - return accounts == null ? new String[] {} : accounts.toArray(new String[0]); - } - - /** - * Called by native to save the account IDs that have associated OAuth2 refresh tokens. - * This is called during updateAccountList to sync with getSystemAccountNames. - * @param accounts IDs to save. - */ - @CalledByNative - private static void setAccounts(String[] accounts) { - Set<String> set = new HashSet<>(Arrays.asList(accounts)); - ContextUtils.getAppSharedPreferences() - .edit() - .putStringSet(STORED_ACCOUNTS_KEY, set) - .apply(); - } - private interface AuthTask<T> { T run() throws AuthException; void onSuccess(T result);
diff --git a/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc b/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc index 57bf523..1c17395 100644 --- a/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc +++ b/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc
@@ -113,10 +113,13 @@ std::vector<GrBackendSemaphore> begin_semaphores; SkSurfaceProps surface_props{0, kUnknown_SkPixelGeometry}; + // Buffer queue is internal to GPU proc and handles texture initialization, + // so allow uncleared access. // TODO(vasilyt): Props and MSAA scoped_write_access_ = skia_representation_->BeginScopedWriteAccess( 0 /* final_msaa_count */, surface_props, &begin_semaphores, - &end_semaphores_); + &end_semaphores_, + gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes); DCHECK(scoped_write_access_); if (!begin_semaphores.empty()) { scoped_write_access_->surface()->wait(begin_semaphores.size(), @@ -137,13 +140,18 @@ SkSurface::BackendSurfaceAccess::kNoAccess, flush_info); scoped_write_access_.reset(); end_semaphores_.clear(); + + // SkiaRenderer always draws the full frame. + skia_representation_->SetCleared(); } void SkiaOutputDeviceBufferQueue::Image::BeginPresent() { DCHECK(!scoped_write_access_); DCHECK(!scoped_read_access_); scoped_read_access_ = gl_representation_->BeginScopedAccess( - GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); + GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM, + gpu::SharedImageRepresentation::AllowUnclearedAccess::kNo); + DCHECK(scoped_read_access_); } void SkiaOutputDeviceBufferQueue::Image::EndPresent() {
diff --git a/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc b/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc index 19ab3df..adf4e82e 100644 --- a/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc +++ b/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc
@@ -251,7 +251,13 @@ EXPECT_EQ(images.size(), (size_t)CountBuffers()); } - Image* GetCurrentImage() { return output_device_->GetCurrentImage(); } + Image* GetCurrentImage() { + // Call Begin/EndPaint to ensusre the image is initialized before use. + output_device_->BeginPaint(); + GrBackendSemaphore semaphore; + output_device_->EndPaint(semaphore); + return output_device_->GetCurrentImage(); + } void SwapBuffers() { auto present_callback =
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index 995f59d..da293d9 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -60,6 +60,7 @@ #include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/database/database_util.h" #include "storage/browser/quota/quota_manager.h" +#include "storage/browser/quota/quota_settings.h" #include "url/gurl.h" #include "url/origin.h" @@ -84,6 +85,12 @@ void SetUp() override { GetTestClassFactory()->Reset(); IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(GetIDBClassFactory); + + // Some tests need more space than the default used for browser tests. + static storage::QuotaSettings quota_settings = + storage::GetHardCodedSettings(100 * 1024 * 1024); + StoragePartition::SetDefaultQuotaSettingsForTesting("a_settings); + ContentBrowserTest::SetUp(); } @@ -92,6 +99,12 @@ ContentBrowserTest::TearDown(); } + bool UseProductionQuotaSettings() override { + // So that the browser test harness doesn't call + // SetDefaultQuotaSettingsForTesting and overwrite the settings above. + return true; + } + void FailOperation(FailClass failure_class, FailMethod failure_method, int fail_on_instance_num,
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index f4430f1..6978dcbf 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -87,6 +87,7 @@ #include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/database/database_tracker.h" #include "storage/browser/quota/quota_manager.h" +#include "storage/browser/quota/quota_settings.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" #if defined(OS_ANDROID) @@ -106,6 +107,8 @@ namespace { +const storage::QuotaSettings* g_test_quota_settings; + // A callback to create a URLLoaderFactory that is used in tests. StoragePartitionImpl::CreateNetworkFactoryCallback& GetCreateURLLoaderFactoryCallback() { @@ -2284,8 +2287,15 @@ void StoragePartitionImpl::GetQuotaSettings( storage::OptionalQuotaSettingsCallback callback) { - GetContentClient()->browser()->GetQuotaSettings(browser_context_, this, - std::move(callback)); + if (g_test_quota_settings) { + // For debugging tests harness can inject settings. + std::move(callback).Run(*g_test_quota_settings); + return; + } + + storage::GetNominalDynamicSettings( + GetPath(), browser_context_->IsOffTheRecord(), + storage::GetDefaultDeviceInfoHelper(), std::move(callback)); } void StoragePartitionImpl::InitNetworkContext() { @@ -2370,4 +2380,9 @@ origin_policy_manager_for_browser_process_.reset(); } +void StoragePartition::SetDefaultQuotaSettingsForTesting( + const storage::QuotaSettings* settings) { + g_test_quota_settings = settings; +} + } // namespace content
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 6b11e44..dc800f6 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -395,16 +395,6 @@ return nullptr; } -void ContentBrowserClient::GetQuotaSettings( - BrowserContext* context, - StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - DCHECK(context); - - // By default, no quota is provided, embedders should override. - std::move(callback).Run(storage::GetNoQuotaSettings()); -} - GeneratedCodeCacheSettings ContentBrowserClient::GetGeneratedCodeCacheSettings( BrowserContext* context) { // By default, code cache is disabled, embedders should override.
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 272fa03d..c10ea616 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -157,7 +157,6 @@ namespace storage { class FileSystemBackend; -struct QuotaSettings; } // namespace storage namespace content { @@ -751,15 +750,6 @@ // Create and return a new quota permission context. virtual scoped_refptr<QuotaPermissionContext> CreateQuotaPermissionContext(); - // Allows the embedder to provide settings that determine the amount - // of disk space that may be used by content facing storage apis like - // IndexedDatabase and ServiceWorker::CacheStorage and others. - virtual void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - base::OnceCallback<void(base::Optional<storage::QuotaSettings>)> - callback); - // Allows the embedder to provide settings that determine if generated code // can be cached and the amount of disk space used for caching generated code. virtual GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings(
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h index da224f4..0e68e34 100644 --- a/content/public/browser/storage_partition.h +++ b/content/public/browser/storage_partition.h
@@ -42,6 +42,7 @@ namespace storage { class QuotaManager; class SpecialStoragePolicy; +struct QuotaSettings; } namespace storage { @@ -264,6 +265,11 @@ // Wait until code cache's shutdown is complete. For test use only. virtual void WaitForCodeCacheShutdownForTesting() = 0; + // The value pointed to by |settings| should remain valid until the + // the function is called again with a new value or a nullptr. + static void SetDefaultQuotaSettingsForTesting( + const storage::QuotaSettings* settings); + protected: virtual ~StoragePartition() {} };
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc index fc255f5b..6f027f5 100644 --- a/content/public/test/browser_test_base.cc +++ b/content/public/test/browser_test_base.cc
@@ -38,6 +38,7 @@ #include "content/browser/scheduler/browser_task_executor.h" #include "content/browser/startup_data_impl.h" #include "content/browser/startup_helper.h" +#include "content/browser/storage_partition_impl.h" #include "content/browser/tracing/memory_instrumentation_util.h" #include "content/browser/tracing/tracing_controller_impl.h" #include "content/public/app/content_main.h" @@ -217,6 +218,16 @@ void BrowserTestBase::SetUp() { set_up_called_ = true; + if (!UseProductionQuotaSettings()) { + // By default use hardcoded quota settings to have a consistent testing + // environment. + const int kQuota = 5 * 1024 * 1024; + quota_settings_ = + std::make_unique<storage::QuotaSettings>(kQuota * 5, kQuota, 0, 0); + StoragePartitionImpl::SetDefaultQuotaSettingsForTesting( + quota_settings_.get()); + } + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); // Features that depend on external factors (e.g. memory pressure monitor) can @@ -322,7 +333,8 @@ // not affect the results. command_line->AppendSwitchASCII(switches::kForceDisplayColorProfile, "srgb"); - test_host_resolver_ = std::make_unique<TestHostResolver>(); + if (!allow_network_access_to_host_resolutions_) + test_host_resolver_ = std::make_unique<TestHostResolver>(); ContentBrowserSanityChecker scoped_enable_sanity_checks; @@ -514,12 +526,18 @@ ui::test::EventGeneratorDelegate::SetFactoryFunction( ui::test::EventGeneratorDelegate::FactoryFunction()); #endif + + StoragePartitionImpl::SetDefaultQuotaSettingsForTesting(nullptr); } bool BrowserTestBase::AllowFileAccessFromFiles() { return true; } +bool BrowserTestBase::UseProductionQuotaSettings() { + return false; +} + void BrowserTestBase::SimulateNetworkServiceCrash() { CHECK(!IsInProcessNetworkService()) << "Can't crash the network service if it's running in-process!"; @@ -734,6 +752,7 @@ return; initialized_network_process_ = true; + host_resolver()->DisableModifications(); // Send the host resolver rules to the network service if it's in use. No need @@ -741,6 +760,18 @@ if (!IsOutOfProcessNetworkService()) return; + mojo::Remote<network::mojom::NetworkServiceTest> network_service_test; + content::GetNetworkService()->BindTestInterface( + network_service_test.BindNewPipeAndPassReceiver()); + + // Do not set up host resolver rules if we allow the test to access + // the network. + if (allow_network_access_to_host_resolutions_) { + mojo::ScopedAllowSyncCallForTesting allow_sync_call; + network_service_test->SetAllowNetworkAccessToHostResolutions(); + return; + } + net::RuleBasedHostResolverProc::RuleList rules = host_resolver()->GetRules(); std::vector<network::mojom::RulePtr> mojo_rules; for (const auto& rule : rules) { @@ -792,10 +823,6 @@ if (mojo_rules.empty()) return; - mojo::Remote<network::mojom::NetworkServiceTest> network_service_test; - content::GetNetworkService()->BindTestInterface( - network_service_test.BindNewPipeAndPassReceiver()); - // Send the DNS rules to network service process. Android needs the RunLoop // to dispatch a Java callback that makes network process to enter native // code.
diff --git a/content/public/test/browser_test_base.h b/content/public/test/browser_test_base.h index 36a06126..4ee8ea0 100644 --- a/content/public/test/browser_test_base.h +++ b/content/public/test/browser_test_base.h
@@ -16,6 +16,7 @@ #include "content/public/test/test_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/spawned_test_server/spawned_test_server.h" +#include "storage/browser/quota/quota_settings.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -58,6 +59,11 @@ // Override this to disallow accesses to be production-compatible. virtual bool AllowFileAccessFromFiles(); + // By default browser tests use hardcoded quota settings for consistency, + // instead of dynamically based on available disk space. Tests can override + // this if they want to use the production path. + virtual bool UseProductionQuotaSettings(); + // Crash the Network Service process. Should only be called when // out-of-process Network Service is enabled. Re-applies any added host // resolver rules, though network tasks started before the call returns may @@ -105,6 +111,12 @@ // Sets expected browser exit code, in case it's different than 0 (success). void set_expected_exit_code(int code) { expected_exit_code_ = code; } + // Sets flag to allow host resolutions to reach the network. Must be called + // before Setup() to take effect. + void set_allow_network_access_to_host_resolutions() { + allow_network_access_to_host_resolutions_ = true; + } + const net::SpawnedTestServer* spawned_test_server() const { return spawned_test_server_.get(); } @@ -201,10 +213,14 @@ // not run and report a false positive result. bool set_up_called_; + std::unique_ptr<storage::QuotaSettings> quota_settings_; + std::unique_ptr<NoRendererCrashesAssertion> no_renderer_crashes_assertion_; bool initialized_network_process_ = false; + bool allow_network_access_to_host_resolutions_ = false; + #if defined(OS_POSIX) bool handle_sigterm_; #endif
diff --git a/content/public/test/network_service_test_helper.cc b/content/public/test/network_service_test_helper.cc index 642ea508..96a42fd 100644 --- a/content/public/test/network_service_test_helper.cc +++ b/content/public/test/network_service_test_helper.cc
@@ -72,7 +72,8 @@ public base::MessageLoopCurrent::DestructionObserver { public: NetworkServiceTestImpl() - : memory_pressure_listener_( + : test_host_resolver_(new TestHostResolver()), + memory_pressure_listener_( base::DoNothing(), base::BindRepeating(&NetworkServiceTestHelper:: NetworkServiceTestImpl::OnMemoryPressure, @@ -102,7 +103,10 @@ // network::mojom::NetworkServiceTest: void AddRules(std::vector<network::mojom::RulePtr> rules, AddRulesCallback callback) override { - auto* host_resolver = test_host_resolver_.host_resolver(); + // test_host_resolver_ may be empty if + // SetAllowNetworkAccessToHostResolutions was invoked. + DCHECK(test_host_resolver_); + auto* host_resolver = test_host_resolver_->host_resolver(); for (const auto& rule : rules) { switch (rule->resolver_type) { case network::mojom::ResolverType::kResolverTypeFail: @@ -198,6 +202,12 @@ std::move(callback).Run(); } + void SetAllowNetworkAccessToHostResolutions( + SetAllowNetworkAccessToHostResolutionsCallback callback) override { + test_host_resolver_.reset(); + std::move(callback).Run(); + } + void CrashOnResolveHost(const std::string& host) override { network::HostResolver::SetResolveHostCallbackForTesting( base::BindRepeating(CrashResolveHost, host)); @@ -261,7 +271,7 @@ bool registered_as_destruction_observer_ = false; mojo::ReceiverSet<network::mojom::NetworkServiceTest> receivers_; - TestHostResolver test_host_resolver_; + std::unique_ptr<TestHostResolver> test_host_resolver_; std::unique_ptr<net::MockCertVerifier> mock_cert_verifier_; std::unique_ptr<net::ScopedTransportSecurityStateSource> transport_security_state_source_;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 1621fe0..bd58e47 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -53,7 +53,6 @@ #include "services/network/public/mojom/network_service.mojom.h" #include "services/service_manager/public/cpp/manifest.h" #include "services/service_manager/public/cpp/manifest_builder.h" -#include "storage/browser/quota/quota_settings.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "ui/base/ui_base_features.h" @@ -301,13 +300,6 @@ return new ShellQuotaPermissionContext(); } -void ShellContentBrowserClient::GetQuotaSettings( - BrowserContext* context, - StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - std::move(callback).Run(storage::GetHardCodedSettings(100 * 1024 * 1024)); -} - GeneratedCodeCacheSettings ShellContentBrowserClient::GetGeneratedCodeCacheSettings( content::BrowserContext* context) {
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h index 0bbbf81..1fec69a 100644 --- a/content/shell/browser/shell_content_browser_client.h +++ b/content/shell/browser/shell_content_browser_client.h
@@ -14,7 +14,6 @@ #include "build/build_config.h" #include "content/public/browser/content_browser_client.h" #include "content/shell/browser/shell_speech_recognition_manager_delegate.h" -#include "storage/browser/quota/quota_settings.h" namespace content { @@ -49,10 +48,6 @@ WebContents* web_contents) override; scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) override; GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( content::BrowserContext* context) override; base::OnceClosure SelectClientCertificate(
diff --git a/content/shell/browser/web_test/web_test_content_browser_client.cc b/content/shell/browser/web_test/web_test_content_browser_client.cc index 5908c91..700996b 100644 --- a/content/shell/browser/web_test/web_test_content_browser_client.cc +++ b/content/shell/browser/web_test/web_test_content_browser_client.cc
@@ -44,6 +44,7 @@ #include "gpu/config/gpu_switches.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "services/service_manager/public/cpp/binder_map.h" +#include "storage/browser/quota/quota_settings.h" #include "url/origin.h" namespace content { @@ -97,6 +98,12 @@ DCHECK(!g_web_test_browser_client); g_web_test_browser_client = this; + + // The 1GB limit is intended to give a large headroom to tests that need to + // build up a large data set and issue many concurrent reads or writes. + static storage::QuotaSettings quota_settings( + storage::GetHardCodedSettings(1024 * 1024 * 1024)); + StoragePartition::SetDefaultQuotaSettingsForTesting("a_settings); } WebTestContentBrowserClient::~WebTestContentBrowserClient() { @@ -240,15 +247,6 @@ return browser_main_parts; } -void WebTestContentBrowserClient::GetQuotaSettings( - BrowserContext* context, - StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - // The 1GB limit is intended to give a large headroom to tests that need to - // build up a large data set and issue many concurrent reads or writes. - std::move(callback).Run(storage::GetHardCodedSettings(1024 * 1024 * 1024)); -} - std::unique_ptr<OverlayWindow> WebTestContentBrowserClient::CreateWindowForPictureInPicture( PictureInPictureWindowController* controller) {
diff --git a/content/shell/browser/web_test/web_test_content_browser_client.h b/content/shell/browser/web_test/web_test_content_browser_client.h index 63252a35..0cd293f 100644 --- a/content/shell/browser/web_test/web_test_content_browser_client.h +++ b/content/shell/browser/web_test/web_test_content_browser_client.h
@@ -50,10 +50,6 @@ int child_process_id) override; std::unique_ptr<BrowserMainParts> CreateBrowserMainParts( const MainFunctionParams& parameters) override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) override; std::vector<url::Origin> GetOriginsRequiringDedicatedProcess() override; std::unique_ptr<OverlayWindow> CreateWindowForPictureInPicture( PictureInPictureWindowController* controller) override;
diff --git a/content/test/test_content_browser_client.cc b/content/test/test_content_browser_client.cc index fc70a57d..6d0e1be 100644 --- a/content/test/test_content_browser_client.cc +++ b/content/test/test_content_browser_client.cc
@@ -7,7 +7,6 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "content/public/browser/browser_context.h" -#include "storage/browser/quota/quota_settings.h" #if defined(OS_ANDROID) #include "content/shell/android/shell_descriptors.h" @@ -38,13 +37,6 @@ return GeneratedCodeCacheSettings(true, 0, context->GetPath()); } -void TestContentBrowserClient::GetQuotaSettings( - BrowserContext* context, - StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - std::move(callback).Run(storage::GetHardCodedSettings(100 * 1024 * 1024)); -} - std::string TestContentBrowserClient::GetUserAgent() { return std::string("TestContentClient"); }
diff --git a/content/test/test_content_browser_client.h b/content/test/test_content_browser_client.h index 18df270..78e2aeb 100644 --- a/content/test/test_content_browser_client.h +++ b/content/test/test_content_browser_client.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "build/build_config.h" #include "content/public/browser/content_browser_client.h" -#include "storage/browser/quota/quota_settings.h" namespace content { @@ -24,10 +23,6 @@ base::FilePath GetDefaultDownloadDirectory() override; GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( content::BrowserContext* context) override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) override; std::string GetUserAgent() override; #if defined(OS_ANDROID) void GetAdditionalMappedFilesForChildProcess(
diff --git a/device/fido/bio/enrollment_handler.cc b/device/fido/bio/enrollment_handler.cc index 5466e99..7ed63cc 100644 --- a/device/fido/bio/enrollment_handler.cc +++ b/device/fido/bio/enrollment_handler.cc
@@ -163,29 +163,10 @@ void BioEnrollmentHandler::OnHavePIN(std::string pin) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(state_, State::kWaitingForPIN); - state_ = State::kGettingEphemeralKey; - authenticator_->GetEphemeralKey( - base::BindOnce(&BioEnrollmentHandler::OnHaveEphemeralKey, - weak_factory_.GetWeakPtr(), std::move(pin))); -} - -void BioEnrollmentHandler::OnHaveEphemeralKey( - std::string pin, - CtapDeviceResponseCode status, - base::Optional<pin::KeyAgreementResponse> response) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(State::kGettingEphemeralKey, state_); - - if (status != CtapDeviceResponseCode::kSuccess) { - Finish(BioEnrollmentStatus::kAuthenticatorResponseInvalid); - return; - } - state_ = State::kGettingPINToken; authenticator_->GetPINToken( - std::move(pin), *response, - base::BindOnce(&BioEnrollmentHandler::OnHavePINToken, - weak_factory_.GetWeakPtr())); + std::move(pin), base::BindOnce(&BioEnrollmentHandler::OnHavePINToken, + weak_factory_.GetWeakPtr())); } void BioEnrollmentHandler::OnHavePINToken(
diff --git a/device/fido/bio/enrollment_handler.h b/device/fido/bio/enrollment_handler.h index 73f570c..d69d392 100644 --- a/device/fido/bio/enrollment_handler.h +++ b/device/fido/bio/enrollment_handler.h
@@ -85,7 +85,6 @@ kWaitingForTouch, kGettingRetries, kWaitingForPIN, - kGettingEphemeralKey, kGettingPINToken, kReady, kEnrolling, @@ -105,9 +104,6 @@ void OnRetriesResponse(CtapDeviceResponseCode, base::Optional<pin::RetriesResponse>); void OnHavePIN(std::string pin); - void OnHaveEphemeralKey(std::string, - CtapDeviceResponseCode, - base::Optional<pin::KeyAgreementResponse>); void OnHavePINToken(CtapDeviceResponseCode, base::Optional<pin::TokenResponse>); void OnEnrollResponse(SampleCallback,
diff --git a/device/fido/credential_management_handler.cc b/device/fido/credential_management_handler.cc index e49d31f3..d5cb44f 100644 --- a/device/fido/credential_management_handler.cc +++ b/device/fido/credential_management_handler.cc
@@ -115,29 +115,9 @@ return; } - state_ = State::kGettingEphemeralKey; - authenticator_->GetEphemeralKey( - base::BindOnce(&CredentialManagementHandler::OnHaveEphemeralKey, - weak_factory_.GetWeakPtr(), std::move(pin))); -} - -void CredentialManagementHandler::OnHaveEphemeralKey( - std::string pin, - CtapDeviceResponseCode status, - base::Optional<pin::KeyAgreementResponse> response) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(State::kGettingEphemeralKey, state_); - - if (status != CtapDeviceResponseCode::kSuccess) { - state_ = State::kFinished; - std::move(finished_callback_) - .Run(CredentialManagementStatus::kAuthenticatorResponseInvalid); - return; - } - state_ = State::kGettingPINToken; authenticator_->GetPINToken( - std::move(pin), *response, + std::move(pin), base::BindOnce(&CredentialManagementHandler::OnHavePINToken, weak_factory_.GetWeakPtr())); }
diff --git a/device/fido/credential_management_handler.h b/device/fido/credential_management_handler.h index b6528d12..757f399 100644 --- a/device/fido/credential_management_handler.h +++ b/device/fido/credential_management_handler.h
@@ -90,7 +90,6 @@ kWaitingForTouch, kGettingRetries, kWaitingForPIN, - kGettingEphemeralKey, kGettingPINToken, kReady, kGettingMetadata, @@ -108,9 +107,6 @@ void OnRetriesResponse(CtapDeviceResponseCode status, base::Optional<pin::RetriesResponse> response); void OnHavePIN(std::string pin); - void OnHaveEphemeralKey(std::string pin, - CtapDeviceResponseCode status, - base::Optional<pin::KeyAgreementResponse> response); void OnHavePINToken(CtapDeviceResponseCode status, base::Optional<pin::TokenResponse> response); void OnCredentialsMetadata(
diff --git a/device/fido/fido_authenticator.cc b/device/fido/fido_authenticator.cc index 11f8d3b..2d6208e 100644 --- a/device/fido/fido_authenticator.cc +++ b/device/fido/fido_authenticator.cc
@@ -9,7 +9,6 @@ #include "base/callback.h" #include "base/logging.h" #include "device/fido/fido_constants.h" -#include "device/fido/pin.h" namespace device { @@ -25,27 +24,19 @@ NOTREACHED(); } -void FidoAuthenticator::GetEphemeralKey( - FidoAuthenticator::GetEphemeralKeyCallback callback) { - NOTREACHED(); -} - void FidoAuthenticator::GetPINToken( std::string pin, - const pin::KeyAgreementResponse& peer_key, FidoAuthenticator::GetPINTokenCallback callback) { NOTREACHED(); } void FidoAuthenticator::SetPIN(const std::string& pin, - const pin::KeyAgreementResponse& peer_key, FidoAuthenticator::SetPINCallback callback) { NOTREACHED(); } void FidoAuthenticator::ChangePIN(const std::string& old_pin, const std::string& new_pin, - pin::KeyAgreementResponse& peer_key, SetPINCallback callback) { NOTREACHED(); }
diff --git a/device/fido/fido_authenticator.h b/device/fido/fido_authenticator.h index 8216874..96de5c5 100644 --- a/device/fido/fido_authenticator.h +++ b/device/fido/fido_authenticator.h
@@ -21,7 +21,6 @@ #include "device/fido/credential_management.h" #include "device/fido/fido_request_handler_base.h" #include "device/fido/fido_transport_protocol.h" -#include "device/fido/pin.h" namespace device { @@ -30,7 +29,6 @@ namespace pin { struct RetriesResponse; -struct KeyAgreementResponse; struct EmptyResponse; class TokenResponse; } // namespace pin @@ -49,9 +47,6 @@ using GetRetriesCallback = base::OnceCallback<void(CtapDeviceResponseCode, base::Optional<pin::RetriesResponse>)>; - using GetEphemeralKeyCallback = - base::OnceCallback<void(CtapDeviceResponseCode, - base::Optional<pin::KeyAgreementResponse>)>; using GetPINTokenCallback = base::OnceCallback<void(CtapDeviceResponseCode, base::Optional<pin::TokenResponse>)>; @@ -94,30 +89,21 @@ // authenticator locks. It is only valid to call this method if |Options| // indicates that the authenticator supports PINs. virtual void GetRetries(GetRetriesCallback callback); - // GetEphemeralKey fetches an ephemeral P-256 key from the authenticator for - // use in protecting transmitted PINs. It is only valid to call this method if - // |Options| indicates that the authenticator supports PINs. - virtual void GetEphemeralKey(GetEphemeralKeyCallback callback); // GetPINToken uses the given PIN to request a PIN-token from an // authenticator. It is only valid to call this method if |Options| indicates // that the authenticator supports PINs. - virtual void GetPINToken(std::string pin, - const pin::KeyAgreementResponse& peer_key, - GetPINTokenCallback callback); + virtual void GetPINToken(std::string pin, GetPINTokenCallback callback); // SetPIN sets a new PIN on a device that does not currently have one. The // length of |pin| must respect |pin::kMinLength| and |pin::kMaxLength|. It is // only valid to call this method if |Options| indicates that the // authenticator supports PINs. - virtual void SetPIN(const std::string& pin, - const pin::KeyAgreementResponse& peer_key, - SetPINCallback callback); + virtual void SetPIN(const std::string& pin, SetPINCallback callback); // ChangePIN alters the PIN on a device that already has a PIN set. The // length of |pin| must respect |pin::kMinLength| and |pin::kMaxLength|. It is // only valid to call this method if |Options| indicates that the // authenticator supports PINs. virtual void ChangePIN(const std::string& old_pin, const std::string& new_pin, - pin::KeyAgreementResponse& peer_key, SetPINCallback callback); // MakeCredentialPINDisposition enumerates the possible interactions between
diff --git a/device/fido/fido_device_authenticator.cc b/device/fido/fido_device_authenticator.cc index 3ca8dd6..ea7ac3127 100644 --- a/device/fido/fido_device_authenticator.cc +++ b/device/fido/fido_device_authenticator.cc
@@ -120,13 +120,26 @@ void FidoDeviceAuthenticator::GetPINToken( std::string pin, - const pin::KeyAgreementResponse& peer_key, GetPINTokenCallback callback) { DCHECK(Options()); DCHECK(Options()->client_pin_availability != AuthenticatorSupportedOptions::ClientPinAvailability::kNotSupported); - pin::TokenRequest request(pin, peer_key); + GetEphemeralKey(base::BindOnce( + &FidoDeviceAuthenticator::OnHaveEphemeralKeyForGetPINToken, + weak_factory_.GetWeakPtr(), std::move(pin), std::move(callback))); +} + +void FidoDeviceAuthenticator::OnHaveEphemeralKeyForGetPINToken( + std::string pin, + GetPINTokenCallback callback, + CtapDeviceResponseCode status, + base::Optional<pin::KeyAgreementResponse> key) { + if (status != CtapDeviceResponseCode::kSuccess) { + std::move(callback).Run(status, base::nullopt); + return; + } + pin::TokenRequest request(pin, *key); std::array<uint8_t, 32> shared_key = request.shared_key(); RunOperation<pin::TokenRequest, pin::TokenResponse>( std::move(request), std::move(callback), @@ -134,27 +147,57 @@ } void FidoDeviceAuthenticator::SetPIN(const std::string& pin, - const pin::KeyAgreementResponse& peer_key, SetPINCallback callback) { DCHECK(Options()); DCHECK(Options()->client_pin_availability != AuthenticatorSupportedOptions::ClientPinAvailability::kNotSupported); + GetEphemeralKey(base::BindOnce( + &FidoDeviceAuthenticator::OnHaveEphemeralKeyForSetPIN, + weak_factory_.GetWeakPtr(), std::move(pin), std::move(callback))); +} + +void FidoDeviceAuthenticator::OnHaveEphemeralKeyForSetPIN( + std::string pin, + SetPINCallback callback, + CtapDeviceResponseCode status, + base::Optional<pin::KeyAgreementResponse> key) { + if (status != CtapDeviceResponseCode::kSuccess) { + std::move(callback).Run(status, base::nullopt); + return; + } + RunOperation<pin::SetRequest, pin::EmptyResponse>( - pin::SetRequest(pin, peer_key), std::move(callback), + pin::SetRequest(pin, *key), std::move(callback), base::BindOnce(&pin::EmptyResponse::Parse)); } void FidoDeviceAuthenticator::ChangePIN(const std::string& old_pin, const std::string& new_pin, - pin::KeyAgreementResponse& peer_key, SetPINCallback callback) { DCHECK(Options()); DCHECK(Options()->client_pin_availability != AuthenticatorSupportedOptions::ClientPinAvailability::kNotSupported); + GetEphemeralKey( + base::BindOnce(&FidoDeviceAuthenticator::OnHaveEphemeralKeyForChangePIN, + weak_factory_.GetWeakPtr(), std::move(old_pin), + std::move(new_pin), std::move(callback))); +} + +void FidoDeviceAuthenticator::OnHaveEphemeralKeyForChangePIN( + std::string old_pin, + std::string new_pin, + SetPINCallback callback, + CtapDeviceResponseCode status, + base::Optional<pin::KeyAgreementResponse> key) { + if (status != CtapDeviceResponseCode::kSuccess) { + std::move(callback).Run(status, base::nullopt); + return; + } + RunOperation<pin::ChangeRequest, pin::EmptyResponse>( - pin::ChangeRequest(old_pin, new_pin, peer_key), std::move(callback), + pin::ChangeRequest(old_pin, new_pin, *key), std::move(callback), base::BindOnce(&pin::EmptyResponse::Parse)); }
diff --git a/device/fido/fido_device_authenticator.h b/device/fido/fido_device_authenticator.h index 0f0c2b7..d554188 100644 --- a/device/fido/fido_device_authenticator.h +++ b/device/fido/fido_device_authenticator.h
@@ -50,16 +50,12 @@ void GetNextAssertion(GetAssertionCallback callback) override; void GetTouch(base::OnceCallback<void()> callback) override; void GetRetries(GetRetriesCallback callback) override; - void GetEphemeralKey(GetEphemeralKeyCallback callback) override; void GetPINToken(std::string pin, - const pin::KeyAgreementResponse& peer_key, GetPINTokenCallback callback) override; void SetPIN(const std::string& pin, - const pin::KeyAgreementResponse& peer_key, SetPINCallback callback) override; void ChangePIN(const std::string& old_pin, const std::string& new_pin, - pin::KeyAgreementResponse& peer_key, SetPINCallback callback) override; MakeCredentialPINDisposition WillNeedPINToMakeCredential( const CtapMakeCredentialRequest& request, @@ -125,7 +121,27 @@ base::Optional<std::vector<uint8_t>> response_data); private: + using GetEphemeralKeyCallback = + base::OnceCallback<void(CtapDeviceResponseCode, + base::Optional<pin::KeyAgreementResponse>)>; void InitializeAuthenticatorDone(base::OnceClosure callback); + void GetEphemeralKey(GetEphemeralKeyCallback callback); + void OnHaveEphemeralKeyForGetPINToken( + std::string pin, + GetPINTokenCallback callback, + CtapDeviceResponseCode status, + base::Optional<pin::KeyAgreementResponse> key); + void OnHaveEphemeralKeyForSetPIN( + std::string pin, + SetPINCallback callback, + CtapDeviceResponseCode status, + base::Optional<pin::KeyAgreementResponse> key); + void OnHaveEphemeralKeyForChangePIN( + std::string old_pin, + std::string new_pin, + SetPINCallback callback, + CtapDeviceResponseCode status, + base::Optional<pin::KeyAgreementResponse> key); template <typename... Args> void TaskClearProxy(base::OnceCallback<void(Args...)> callback, Args... args);
diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc index f515d7e1..10e72a05 100644 --- a/device/fido/get_assertion_request_handler.cc +++ b/device/fido/get_assertion_request_handler.cc
@@ -559,30 +559,9 @@ return; } - state_ = State::kGetEphemeralKey; - authenticator_->GetEphemeralKey( - base::BindOnce(&GetAssertionRequestHandler::OnHaveEphemeralKey, - weak_factory_.GetWeakPtr(), std::move(pin))); -} - -void GetAssertionRequestHandler::OnHaveEphemeralKey( - std::string pin, - CtapDeviceResponseCode status, - base::Optional<pin::KeyAgreementResponse> response) { - DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); - DCHECK_EQ(State::kGetEphemeralKey, state_); - - if (status != CtapDeviceResponseCode::kSuccess) { - state_ = State::kFinished; - std::move(completion_callback_) - .Run(GetAssertionStatus::kAuthenticatorResponseInvalid, base::nullopt, - nullptr); - return; - } - state_ = State::kRequestWithPIN; authenticator_->GetPINToken( - std::move(pin), *response, + std::move(pin), base::BindOnce(&GetAssertionRequestHandler::OnHavePINToken, weak_factory_.GetWeakPtr())); }
diff --git a/device/fido/get_assertion_request_handler.h b/device/fido/get_assertion_request_handler.h index 78121eb5..f02b7c5 100644 --- a/device/fido/get_assertion_request_handler.h +++ b/device/fido/get_assertion_request_handler.h
@@ -25,7 +25,6 @@ class FidoDiscoveryFactory; namespace pin { -struct KeyAgreementResponse; struct RetriesResponse; class TokenResponse; } // namespace pin @@ -69,7 +68,6 @@ kWaitingForSecondTouch, kGettingRetries, kWaitingForPIN, - kGetEphemeralKey, kRequestWithPIN, kReadingMultipleResponses, kFinished, @@ -95,9 +93,6 @@ void OnRetriesResponse(CtapDeviceResponseCode status, base::Optional<pin::RetriesResponse> response); void OnHavePIN(std::string pin); - void OnHaveEphemeralKey(std::string pin, - CtapDeviceResponseCode status, - base::Optional<pin::KeyAgreementResponse> response); void OnHavePINToken(CtapDeviceResponseCode status, base::Optional<pin::TokenResponse> response);
diff --git a/device/fido/make_credential_request_handler.cc b/device/fido/make_credential_request_handler.cc index a3d41f54..84c810d 100644 --- a/device/fido/make_credential_request_handler.cc +++ b/device/fido/make_credential_request_handler.cc
@@ -489,15 +489,19 @@ } if (state_ == State::kWaitingForPIN) { - state_ = State::kGetEphemeralKey; - } else { - DCHECK_EQ(state_, State::kWaitingForNewPIN); - state_ = State::kGetEphemeralKeyForNewPIN; + state_ = State::kRequestWithPIN; + authenticator_->GetPINToken( + std::move(pin), + base::BindOnce(&MakeCredentialRequestHandler::OnHavePINToken, + weak_factory_.GetWeakPtr())); + return; } - authenticator_->GetEphemeralKey( - base::BindOnce(&MakeCredentialRequestHandler::OnHaveEphemeralKey, - weak_factory_.GetWeakPtr(), std::move(pin))); + DCHECK_EQ(state_, State::kWaitingForNewPIN); + state_ = State::kSettingPIN; + authenticator_->SetPIN( + pin, base::BindOnce(&MakeCredentialRequestHandler::OnHaveSetPIN, + weak_factory_.GetWeakPtr(), pin)); } void MakeCredentialRequestHandler::OnRetriesResponse( @@ -525,41 +529,8 @@ weak_factory_.GetWeakPtr())); } -void MakeCredentialRequestHandler::OnHaveEphemeralKey( - std::string pin, - CtapDeviceResponseCode status, - base::Optional<pin::KeyAgreementResponse> response) { - DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); - DCHECK(state_ == State::kGetEphemeralKey || - state_ == State::kGetEphemeralKeyForNewPIN); - - if (status != CtapDeviceResponseCode::kSuccess) { - state_ = State::kFinished; - std::move(completion_callback_) - .Run(MakeCredentialStatus::kAuthenticatorResponseInvalid, base::nullopt, - nullptr); - return; - } - - if (state_ == State::kGetEphemeralKey) { - state_ = State::kRequestWithPIN; - authenticator_->GetPINToken( - std::move(pin), *response, - base::BindOnce(&MakeCredentialRequestHandler::OnHavePINToken, - weak_factory_.GetWeakPtr())); - } else { - DCHECK_EQ(state_, State::kGetEphemeralKeyForNewPIN); - state_ = State::kSettingPIN; - authenticator_->SetPIN( - pin, *response, - base::BindOnce(&MakeCredentialRequestHandler::OnHaveSetPIN, - weak_factory_.GetWeakPtr(), pin, *response)); - } -} - void MakeCredentialRequestHandler::OnHaveSetPIN( std::string pin, - pin::KeyAgreementResponse key_agreement, CtapDeviceResponseCode status, base::Optional<pin::EmptyResponse> response) { DCHECK_EQ(state_, State::kSettingPIN); @@ -576,7 +547,7 @@ // get a PIN token. state_ = State::kRequestWithPIN; authenticator_->GetPINToken( - std::move(pin), key_agreement, + std::move(pin), base::BindOnce(&MakeCredentialRequestHandler::OnHavePINToken, weak_factory_.GetWeakPtr())); }
diff --git a/device/fido/make_credential_request_handler.h b/device/fido/make_credential_request_handler.h index 1970a007..3938f04 100644 --- a/device/fido/make_credential_request_handler.h +++ b/device/fido/make_credential_request_handler.h
@@ -28,7 +28,6 @@ namespace pin { struct EmptyResponse; -struct KeyAgreementResponse; struct RetriesResponse; class TokenResponse; } // namespace pin @@ -76,8 +75,6 @@ kGettingRetries, kWaitingForPIN, kWaitingForNewPIN, - kGetEphemeralKey, - kGetEphemeralKeyForNewPIN, kSettingPIN, kRequestWithPIN, kFinished, @@ -97,11 +94,7 @@ void OnHavePIN(std::string pin); void OnRetriesResponse(CtapDeviceResponseCode status, base::Optional<pin::RetriesResponse> response); - void OnHaveEphemeralKey(std::string pin, - CtapDeviceResponseCode status, - base::Optional<pin::KeyAgreementResponse> response); void OnHaveSetPIN(std::string pin, - pin::KeyAgreementResponse key_agreement, CtapDeviceResponseCode status, base::Optional<pin::EmptyResponse> response); void OnHavePINToken(CtapDeviceResponseCode status,
diff --git a/device/fido/set_pin_request_handler.cc b/device/fido/set_pin_request_handler.cc index 149074e..bfd663d 100644 --- a/device/fido/set_pin_request_handler.cc +++ b/device/fido/set_pin_request_handler.cc
@@ -44,10 +44,18 @@ return; } - state_ = State::kGetEphemeralKey; - authenticator_->GetEphemeralKey(base::BindOnce( - &SetPINRequestHandler::OnHaveEphemeralKey, weak_factory_.GetWeakPtr(), - std::move(old_pin), std::move(new_pin))); + state_ = State::kSettingPIN; + + if (old_pin.empty()) { + authenticator_->SetPIN( + new_pin, base::BindOnce(&SetPINRequestHandler::OnSetPINComplete, + weak_factory_.GetWeakPtr())); + } else { + authenticator_->ChangePIN( + old_pin, new_pin, + base::BindOnce(&SetPINRequestHandler::OnSetPINComplete, + weak_factory_.GetWeakPtr())); + } } void SetPINRequestHandler::DispatchRequest(FidoAuthenticator* authenticator) { @@ -120,35 +128,6 @@ std::move(get_pin_callback_).Run(response->retries); } -void SetPINRequestHandler::OnHaveEphemeralKey( - std::string old_pin, - std::string new_pin, - CtapDeviceResponseCode status, - base::Optional<pin::KeyAgreementResponse> response) { - DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); - DCHECK_EQ(state_, State::kGetEphemeralKey); - - if (status != CtapDeviceResponseCode::kSuccess) { - state_ = State::kFinished; - finished_callback_.Run(status); - return; - } - - state_ = State::kSettingPIN; - - if (old_pin.empty()) { - authenticator_->SetPIN( - new_pin, *response, - base::BindOnce(&SetPINRequestHandler::OnSetPINComplete, - weak_factory_.GetWeakPtr())); - } else { - authenticator_->ChangePIN( - old_pin, new_pin, *response, - base::BindOnce(&SetPINRequestHandler::OnSetPINComplete, - weak_factory_.GetWeakPtr())); - } -} - void SetPINRequestHandler::OnSetPINComplete( CtapDeviceResponseCode status, base::Optional<pin::EmptyResponse> response) {
diff --git a/device/fido/set_pin_request_handler.h b/device/fido/set_pin_request_handler.h index c78dfb0..0c13e60 100644 --- a/device/fido/set_pin_request_handler.h +++ b/device/fido/set_pin_request_handler.h
@@ -24,7 +24,6 @@ namespace pin { struct RetriesResponse; -struct KeyAgreementResponse; struct EmptyResponse; } // namespace pin @@ -74,7 +73,6 @@ kWaitingForTouch, kGettingRetries, kWaitingForPIN, - kGetEphemeralKey, kSettingPIN, kFinished, }; @@ -89,11 +87,6 @@ void OnRetriesResponse(CtapDeviceResponseCode status, base::Optional<pin::RetriesResponse> response); - void OnHaveEphemeralKey(std::string old_pin, - std::string new_pin, - CtapDeviceResponseCode status, - base::Optional<pin::KeyAgreementResponse> response); - void OnSetPINComplete(CtapDeviceResponseCode status, base::Optional<pin::EmptyResponse> response);
diff --git a/extensions/browser/extension_registrar.cc b/extensions/browser/extension_registrar.cc index cd41cfd..55a5cba 100644 --- a/extensions/browser/extension_registrar.cc +++ b/extensions/browser/extension_registrar.cc
@@ -434,13 +434,17 @@ base::Bind(&ExtensionRegistrar::OnExtensionRegisteredWithRequestContexts, weak_factory_.GetWeakPtr(), WrapRefCounted(extension))); - renderer_helper_->OnExtensionLoaded(*extension); - + // Activate the extension before calling + // RendererStartupHelper::OnExtensionLoaded() below, so that we have + // activation information ready while we send ExtensionMsg_Load IPC. + // // TODO(lazyboy): We should move all logic that is required to start up an // extension to a separate class, instead of calling adhoc methods like // service worker ones below. ActivateTaskQueueForExtension(browser_context_, extension); + renderer_helper_->OnExtensionLoaded(*extension); + // Tell subsystems that use the ExtensionRegistryObserver::OnExtensionLoaded // about the new extension. //
diff --git a/extensions/browser/extension_service_worker_message_filter.cc b/extensions/browser/extension_service_worker_message_filter.cc index 33f883da..cb246ae3 100644 --- a/extensions/browser/extension_service_worker_message_filter.cc +++ b/extensions/browser/extension_service_worker_message_filter.cc
@@ -146,6 +146,7 @@ void ExtensionServiceWorkerMessageFilter::OnDidStartServiceWorkerContext( const ExtensionId& extension_id, + int activation_sequence, const GURL& service_worker_scope, int64_t service_worker_version_id, int thread_id) { @@ -161,12 +162,13 @@ ServiceWorkerTaskQueue::Get(browser_context_) ->DidStartServiceWorkerContext(render_process_id_, extension_id, - service_worker_scope, + activation_sequence, service_worker_scope, service_worker_version_id, thread_id); } void ExtensionServiceWorkerMessageFilter::OnDidStopServiceWorkerContext( const ExtensionId& extension_id, + int activation_sequence, const GURL& service_worker_scope, int64_t service_worker_version_id, int thread_id) { @@ -182,7 +184,7 @@ ServiceWorkerTaskQueue::Get(browser_context_) ->DidStopServiceWorkerContext(render_process_id_, extension_id, - service_worker_scope, + activation_sequence, service_worker_scope, service_worker_version_id, thread_id); }
diff --git a/extensions/browser/extension_service_worker_message_filter.h b/extensions/browser/extension_service_worker_message_filter.h index 049d5771..07a72ab 100644 --- a/extensions/browser/extension_service_worker_message_filter.h +++ b/extensions/browser/extension_service_worker_message_filter.h
@@ -56,10 +56,12 @@ int64_t service_worker_version_id, int thread_id); void OnDidStartServiceWorkerContext(const ExtensionId& extension_id, + int activation_sequence, const GURL& service_worker_scope, int64_t service_worker_version_id, int thread_id); void OnDidStopServiceWorkerContext(const ExtensionId& extension_id, + int activation_sequence, const GURL& service_worker_scope, int64_t service_worker_version_id, int thread_id);
diff --git a/extensions/browser/renderer_startup_helper.cc b/extensions/browser/renderer_startup_helper.cc index ff445f5..0c05644 100644 --- a/extensions/browser/renderer_startup_helper.cc +++ b/extensions/browser/renderer_startup_helper.cc
@@ -23,12 +23,14 @@ #include "extensions/browser/extension_util.h" #include "extensions/browser/extensions_browser_client.h" #include "extensions/browser/guest_view/web_view/web_view_guest.h" +#include "extensions/browser/service_worker_task_queue.h" #include "extensions/common/cors_util.h" #include "extensions/common/extension_messages.h" #include "extensions/common/extension_set.h" #include "extensions/common/extensions_client.h" #include "extensions/common/features/feature_channel.h" #include "extensions/common/features/feature_session_type.h" +#include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/permissions/permissions_data.h" #include "ui/base/webui/web_ui_util.h" #include "url/origin.h" @@ -56,6 +58,17 @@ util::IsIncognitoEnabled(extension.id(), browser_context); } +// Returns the current ActivationSequence of |extension| if the extension is +// Service Worker-based, otherwise returns base::nullopt. +base::Optional<int> GetWorkerActivationSequence(BrowserContext* browser_context, + const Extension& extension) { + if (BackgroundInfo::IsServiceWorkerBased(&extension)) { + return ServiceWorkerTaskQueue::Get(browser_context) + ->GetCurrentSequence(extension.id()); + } + return base::nullopt; +} + } // namespace RendererStartupHelper::RendererStartupHelper(BrowserContext* browser_context) @@ -153,8 +166,9 @@ // I am not sure this is possible to know this here, at such a low // level of the stack. Perhaps site isolation can help. bool include_tab_permissions = true; - loaded_extensions.push_back( - ExtensionMsg_Loaded_Params(ext.get(), include_tab_permissions)); + loaded_extensions.push_back(ExtensionMsg_Loaded_Params( + ext.get(), include_tab_permissions, + GetWorkerActivationSequence(renderer_context, *ext))); extension_process_map_[ext->id()].insert(process); } @@ -248,7 +262,8 @@ // Uninitialized renderers will be informed of the extension load during the // first batch of messages. std::vector<ExtensionMsg_Loaded_Params> params; - params.emplace_back(&extension, false /* no tab permissions */); + params.emplace_back(&extension, false /* no tab permissions */, + GetWorkerActivationSequence(browser_context_, extension)); for (content::RenderProcessHost* process : initialized_processes_) { if (!IsExtensionVisibleToContext(extension, process->GetBrowserContext()))
diff --git a/extensions/browser/service_worker/worker_id.cc b/extensions/browser/service_worker/worker_id.cc index bdfa21d..7e66ff0 100644 --- a/extensions/browser/service_worker/worker_id.cc +++ b/extensions/browser/service_worker/worker_id.cc
@@ -24,4 +24,8 @@ version_id == other.version_id && thread_id == other.thread_id; } +bool WorkerId::operator!=(const WorkerId& other) const { + return !this->operator==(other); +} + } // namespace extensions
diff --git a/extensions/browser/service_worker/worker_id.h b/extensions/browser/service_worker/worker_id.h index 21f91c6..5ce79cd 100644 --- a/extensions/browser/service_worker/worker_id.h +++ b/extensions/browser/service_worker/worker_id.h
@@ -20,6 +20,7 @@ bool operator<(const WorkerId& other) const; bool operator==(const WorkerId& other) const; + bool operator!=(const WorkerId& other) const; }; } // namespace extensions
diff --git a/extensions/browser/service_worker_task_queue.cc b/extensions/browser/service_worker_task_queue.cc index ec55c41..18cac2d 100644 --- a/extensions/browser/service_worker_task_queue.cc +++ b/extensions/browser/service_worker_task_queue.cc
@@ -41,6 +41,36 @@ ServiceWorkerTaskQueue::TestObserver* g_test_observer = nullptr; +// ServiceWorkerRegistration state of an activated extension. +enum class RegistrationState { + // Not registered. + kNotRegistered, + // Registration is inflight. + kPending, + // Registration is complete. + kRegistered, +}; + +// Browser process worker state of an activated extension. +enum class BrowserState { + // Initial state, not started. + kInitial, + // Worker is in the process of starting from the browser process. + kStarting, + // Worker has completed starting (i.e. has seen DidStartWorkerForScope). + kStarted, +}; + +// Render process worker state of an activated extension. +enum class RendererState { + // Initial state, neither started nor stopped. + kInitial, + // Worker thread has started. + kStarted, + // Worker thread has not started or has been stopped. + kStopped, +}; + } // namespace ServiceWorkerTaskQueue::ServiceWorkerTaskQueue(BrowserContext* browser_context) @@ -109,19 +139,44 @@ context_id, task_queue_weak)); } -// The current state of a worker. -struct ServiceWorkerTaskQueue::WorkerState { - // Whether or not worker has completed starting (DidStartWorkerForScope). - bool browser_ready = false; - - // Whether or not worker is ready in the renderer - // (DidStartServiceWorkerContext). - bool renderer_ready = false; - - // If |browser_ready| = true, this is the ActivationSequence of the worker. - base::Optional<ActivationSequence> sequence; - +// The current worker related state of an activated extension. +class ServiceWorkerTaskQueue::WorkerState { + public: WorkerState() = default; + + WorkerState(const WorkerState&) = delete; + WorkerState& operator=(const WorkerState&) = delete; + + void SetWorkerId(const WorkerId& worker_id, ProcessManager* process_manager) { + if (worker_id_ && *worker_id_ != worker_id) { + // Sanity check that the old worker is gone. + DCHECK(!process_manager->HasServiceWorker(*worker_id_)); + // Clear stale renderer state if there's any. + renderer_state_ = RendererState::kInitial; + } + worker_id_ = worker_id; + } + + bool ready() const { + return registration_state_ == RegistrationState::kRegistered && + browser_state_ == BrowserState::kStarted && + renderer_state_ == RendererState::kStarted && worker_id_.has_value(); + } + bool has_pending_tasks() const { return !pending_tasks_.empty(); } + + private: + friend class ServiceWorkerTaskQueue; + + RegistrationState registration_state_ = RegistrationState::kNotRegistered; + BrowserState browser_state_ = BrowserState::kInitial; + RendererState renderer_state_ = RendererState::kInitial; + + // Pending tasks that will be run once the worker becomes ready. + std::vector<PendingTask> pending_tasks_; + + // Contains the worker's WorkerId associated with this WorkerState, once we + // have discovered info about the worker. + base::Optional<WorkerId> worker_id_; }; void ServiceWorkerTaskQueue::DidStartWorkerForScope( @@ -136,11 +191,12 @@ // Extension run with |sequence| was already deactivated. // TODO(lazyboy): Add a DCHECK that the worker in question is actually // shutting down soon. - DCHECK(!base::Contains(pending_tasks_, context_id)); + DCHECK(!GetWorkerState(context_id)); return; } - const LazyContextId& lazy_context_id = context_id.first; + WorkerState* worker_state = GetWorkerState(context_id); + DCHECK(worker_state); const WorkerId worker_id = {extension_id, process_id, version_id, thread_id}; // Note: If the worker has already stopped on worker thread @@ -151,15 +207,12 @@ // renderer before we execute tasks in the browser process. This will also // avoid holding the worker in |worker_state_map_| until deactivation as noted // above. - WorkerState* worker_state = - GetOrCreateWorkerState(WorkerKey(lazy_context_id, worker_id)); - DCHECK(worker_state); - DCHECK(!worker_state->browser_ready) << "Worker was already loaded"; - worker_state->browser_ready = true; - worker_state->sequence = sequence; + DCHECK_NE(BrowserState::kStarted, worker_state->browser_state_) + << "Worker was already loaded"; + worker_state->SetWorkerId(worker_id, ProcessManager::Get(browser_context_)); + worker_state->browser_state_ = BrowserState::kStarted; - RunPendingTasksIfWorkerReady(lazy_context_id, version_id, process_id, - thread_id); + RunPendingTasksIfWorkerReady(context_id); } void ServiceWorkerTaskQueue::DidStartWorkerFail( @@ -168,9 +221,10 @@ if (!IsCurrentSequence(context_id.first.extension_id(), context_id.second)) { // This can happen is when the registration got unregistered right before we // tried to start it. See crbug.com/999027 for details. - DCHECK(!base::Contains(pending_tasks_, context_id)); + DCHECK(!GetWorkerState(context_id)); return; } + // TODO(lazyboy): Handle failure cases. DCHECK(false) << "DidStartWorkerFail: " << context_id.first.extension_id(); } @@ -189,50 +243,70 @@ void ServiceWorkerTaskQueue::DidStartServiceWorkerContext( int render_process_id, const ExtensionId& extension_id, + int activation_sequence, const GURL& service_worker_scope, int64_t service_worker_version_id, int thread_id) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - LazyContextId context_id(browser_context_, extension_id, - service_worker_scope); + if (!IsCurrentSequence(extension_id, activation_sequence)) + return; + + SequencedContextId context_id( + LazyContextId(browser_context_, extension_id, service_worker_scope), + activation_sequence); const WorkerId worker_id = {extension_id, render_process_id, service_worker_version_id, thread_id}; - WorkerState* worker_state = - GetOrCreateWorkerState(WorkerKey(context_id, worker_id)); - DCHECK(!worker_state->renderer_ready) << "Worker already started"; - worker_state->renderer_ready = true; + WorkerState* worker_state = GetWorkerState(context_id); + DCHECK(worker_state); + // If |worker_state| had a worker running previously, for which we didn't + // see DidStopServiceWorkerContext notification (typically happens on render + // process shutdown), then we'd preserve stale state in |renderer_state_|. + // + // This isn't a problem because the next browser process readiness + // (DidStartWorkerForScope) or the next renderer process readiness + // (DidStartServiceWorkerContext) will clear the state, whichever happens + // first. + // + // TODO(lazyboy): Update the renderer state in RenderProcessExited() and + // uncomment the following DCHECK: + // DCHECK_NE(RendererState::kStarted, worker_state->renderer_state_) + // << "Worker already started"; + worker_state->SetWorkerId(worker_id, ProcessManager::Get(browser_context_)); + worker_state->renderer_state_ = RendererState::kStarted; - RunPendingTasksIfWorkerReady(context_id, service_worker_version_id, - render_process_id, thread_id); + RunPendingTasksIfWorkerReady(context_id); } void ServiceWorkerTaskQueue::DidStopServiceWorkerContext( int render_process_id, const ExtensionId& extension_id, + int activation_sequence, const GURL& service_worker_scope, int64_t service_worker_version_id, int thread_id) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (!IsCurrentSequence(extension_id, activation_sequence)) + return; + const WorkerId worker_id = {extension_id, render_process_id, service_worker_version_id, thread_id}; ProcessManager::Get(browser_context_)->UnregisterServiceWorker(worker_id); - LazyContextId context_id(browser_context_, extension_id, - service_worker_scope); + SequencedContextId context_id( + LazyContextId(browser_context_, extension_id, service_worker_scope), + activation_sequence); - WorkerKey worker_key(context_id, worker_id); - WorkerState* worker_state = GetWorkerState(worker_key); - if (!worker_state) { + WorkerState* worker_state = GetWorkerState(context_id); + DCHECK(worker_state); + + if (worker_state->worker_id_ != worker_id) { // We can see DidStopServiceWorkerContext right after DidInitialize and // without DidStartServiceWorkerContext. return; } - // Clean up both the renderer and browser readiness states. - // One caveat is that although this is renderer notification, we also clear - // the browser readiness state, this is because a worker can be - // |browser_ready| and was waiting for DidStartServiceWorkerContext, but - // instead received DidStopServiceWorkerContext. - worker_state_map_.erase(worker_key); + DCHECK_NE(RendererState::kStopped, worker_state->renderer_state_); + worker_state->renderer_state_ = RendererState::kStopped; + worker_state->worker_id_ = base::nullopt; } // static @@ -259,11 +333,13 @@ DCHECK(sequence) << "Trying to add pending task to an inactive extension: " << lazy_context_id.extension_id(); const SequencedContextId context_id(lazy_context_id, *sequence); - auto& tasks = pending_tasks_[context_id]; + WorkerState* worker_state = GetWorkerState(context_id); + DCHECK(worker_state); + auto& tasks = worker_state->pending_tasks_; bool needs_start_worker = tasks.empty(); tasks.push_back(std::move(task)); - if (pending_registrations_.count(context_id) > 0) { + if (worker_state->registration_state_ != RegistrationState::kRegistered) { // If the worker hasn't finished registration, wait for it to complete. // DidRegisterServiceWorker will Start worker to run |task| later. return; @@ -281,6 +357,11 @@ const ExtensionId extension_id = extension->id(); ActivationSequence current_sequence = ++next_activation_sequence_; activation_sequences_[extension_id] = current_sequence; + SequencedContextId context_id( + LazyContextId(browser_context_, extension_id, extension->url()), + current_sequence); + DCHECK(!base::Contains(worker_state_map_, context_id)); + WorkerState& worker_state = worker_state_map_[context_id]; // Note: version.IsValid() = false implies we didn't have any prefs stored. base::Version version = RetrieveRegisteredServiceWorkerVersion(extension_id); @@ -292,15 +373,13 @@ } if (service_worker_already_registered) { + worker_state.registration_state_ = RegistrationState::kRegistered; // TODO(https://crbug.com/901101): We should kick off an async check to see // if the registration is *actually* there and re-register if necessary. return; } - SequencedContextId context_id( - LazyContextId(browser_context_, extension_id, extension->url()), - current_sequence); - pending_registrations_.insert(context_id); + worker_state.registration_state_ = RegistrationState::kPending; GURL script_url = extension->GetResourceURL( BackgroundInfo::GetBackgroundServiceWorkerScript(extension)); blink::mojom::ServiceWorkerRegistrationOptions option; @@ -329,14 +408,11 @@ SequencedContextId context_id( LazyContextId(browser_context_, extension_id, extension->url()), *sequence); - ClearPendingTasks(context_id); - - // Clear loaded worker if it was waiting for start. - // Note that we don't clear the entire state here as we expect the renderer to - // stop shortly after this and its notification will clear the state. - ClearBrowserReadyForWorkers( - LazyContextId(browser_context_, extension_id, extension->url()), - *sequence); + WorkerState* worker_state = GetWorkerState(context_id); + DCHECK(worker_state); + // TODO(lazyboy): Run orphaned tasks with nullptr ContextInfo. + worker_state->pending_tasks_.clear(); + worker_state_map_.erase(context_id); util::GetStoragePartitionForExtensionId(extension->id(), browser_context_) ->GetServiceWorkerContext() @@ -354,6 +430,9 @@ if (lazy_context_id.browser_context() != browser_context_) return; + WorkerState* worker_state = GetWorkerState(context_id); + DCHECK_NE(BrowserState::kStarted, worker_state->browser_state_); + content::StoragePartition* partition = util::GetStoragePartitionForExtensionId( lazy_context_id.extension_id(), lazy_context_id.browser_context()); @@ -377,35 +456,30 @@ void ServiceWorkerTaskQueue::DidRegisterServiceWorker( const SequencedContextId& context_id, bool success) { - pending_registrations_.erase(context_id); ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); const ExtensionId& extension_id = context_id.first.extension_id(); DCHECK(registry); const Extension* extension = registry->enabled_extensions().GetByID(extension_id); if (!extension) { - // DeactivateExtension must have cleared |pending_tasks_| already. - DCHECK(!base::Contains(pending_tasks_, context_id)); return; } + if (!IsCurrentSequence(extension_id, context_id.second)) + return; + + WorkerState* worker_state = GetWorkerState(context_id); + DCHECK(worker_state); if (!success) { - if (!IsCurrentSequence(extension_id, context_id.second)) { - // DeactivateExtension must have cleared |pending_tasks_| already. - DCHECK(!base::Contains(pending_tasks_, context_id)); - return; - } // TODO(lazyboy): Handle failure case thoroughly. DCHECK(false) << "Failed to register Service Worker"; return; } + worker_state->registration_state_ = RegistrationState::kRegistered; SetRegisteredServiceWorkerInfo(extension->id(), extension->version()); - auto pending_tasks_iter = pending_tasks_.find(context_id); - const bool has_pending_tasks = pending_tasks_iter != pending_tasks_.end() && - pending_tasks_iter->second.size() > 0u; - if (has_pending_tasks) { + if (worker_state->has_pending_tasks()) { // TODO(lazyboy): If worker for |context_id| is already running, consider // not calling StartWorker. This isn't straightforward as service worker's // internal state is mostly on the core thread. @@ -467,45 +541,35 @@ } void ServiceWorkerTaskQueue::RunPendingTasksIfWorkerReady( - const LazyContextId& context_id, - int64_t version_id, - int process_id, - int thread_id) { - WorkerState* worker_state = GetWorkerState(WorkerKey( - context_id, - {context_id.extension_id(), process_id, version_id, thread_id})); + const SequencedContextId& context_id) { + WorkerState* worker_state = GetWorkerState(context_id); DCHECK(worker_state); - if (!worker_state->browser_ready || !worker_state->renderer_ready) { + if (!worker_state->ready()) { // Worker isn't ready yet, wait for next event and run the tasks then. return; } - base::Optional<int> sequence = worker_state->sequence; - DCHECK(sequence.has_value()); // Running |pending_tasks_[context_id]| marks the completion of // DidStartWorkerForScope, clean up |browser_ready| state of the worker so // that new tasks can be queued up. - worker_state->browser_ready = false; + worker_state->browser_state_ = BrowserState::kInitial; - auto iter = pending_tasks_.find(SequencedContextId(context_id, *sequence)); - DCHECK(iter != pending_tasks_.end()) << "Worker ready, but no tasks to run!"; - std::vector<PendingTask> tasks = std::move(iter->second); - pending_tasks_.erase(iter); + DCHECK(worker_state->has_pending_tasks()) + << "Worker ready, but no tasks to run!"; + std::vector<PendingTask> tasks; + std::swap(worker_state->pending_tasks_, tasks); + DCHECK(worker_state->worker_id_); + const auto& worker_id = *worker_state->worker_id_; for (auto& task : tasks) { auto context_info = std::make_unique<LazyContextTaskQueue::ContextInfo>( - context_id.extension_id(), - content::RenderProcessHost::FromID(process_id), version_id, thread_id, - context_id.service_worker_scope()); + context_id.first.extension_id(), + content::RenderProcessHost::FromID(worker_id.render_process_id), + worker_id.version_id, worker_id.thread_id, + context_id.first.service_worker_scope()); std::move(task).Run(std::move(context_info)); } } -void ServiceWorkerTaskQueue::ClearPendingTasks( - const SequencedContextId& context_id) { - // TODO(lazyboy): Run orphaned tasks with nullptr ContextInfo. - pending_tasks_.erase(context_id); -} - bool ServiceWorkerTaskQueue::IsCurrentSequence( const ExtensionId& extension_id, ActivationSequence sequence) const { @@ -522,44 +586,11 @@ return iter->second; } -ServiceWorkerTaskQueue::WorkerState* -ServiceWorkerTaskQueue::GetOrCreateWorkerState(const WorkerKey& worker_key) { - auto iter = worker_state_map_.find(worker_key); - if (iter == worker_state_map_.end()) - iter = worker_state_map_.emplace(worker_key, WorkerState()).first; - return &(iter->second); -} - ServiceWorkerTaskQueue::WorkerState* ServiceWorkerTaskQueue::GetWorkerState( - const WorkerKey& worker_key) { - auto iter = worker_state_map_.find(worker_key); - if (iter == worker_state_map_.end()) - return nullptr; - return &(iter->second); -} - -void ServiceWorkerTaskQueue::ClearBrowserReadyForWorkers( - const LazyContextId& context_id, - ActivationSequence sequence) { - // TODO(lazyboy): We could use |worker_state_map_|.lower_bound() to avoid - // iterating over all workers. Note that it would require creating artificial - // WorkerKey with |context_id|. - for (auto iter = worker_state_map_.begin(); - iter != worker_state_map_.end();) { - if (iter->first.first != context_id || iter->second.sequence != sequence) { - ++iter; - continue; - } - - iter->second.browser_ready = false; - iter->second.sequence = base::nullopt; - - // Clean up stray entries if renderer readiness was also gone. - if (!iter->second.renderer_ready) - iter = worker_state_map_.erase(iter); - else - ++iter; - } + const SequencedContextId& context_id) { + auto worker_iter = worker_state_map_.find(context_id); + return worker_iter == worker_state_map_.end() ? nullptr + : &worker_iter->second; } } // namespace extensions
diff --git a/extensions/browser/service_worker_task_queue.h b/extensions/browser/service_worker_task_queue.h index 2e5e215b..76b2285 100644 --- a/extensions/browser/service_worker_task_queue.h +++ b/extensions/browser/service_worker_task_queue.h
@@ -72,6 +72,12 @@ class ServiceWorkerTaskQueue : public KeyedService, public LazyContextTaskQueue { public: + // Unique identifier for an extension's activation->deactivation span. + // TODO(lazyboy): Move this under extensions/common/ for consistency, so that + // renderer process can use this instead of using "int" directly. We'd also + // want StrongAlias for this. + using ActivationSequence = int; + explicit ServiceWorkerTaskQueue(content::BrowserContext* browser_context); ~ServiceWorkerTaskQueue() override; @@ -102,16 +108,24 @@ // has completed executing. void DidStartServiceWorkerContext(int render_process_id, const ExtensionId& extension_id, + int activation_sequence, const GURL& service_worker_scope, int64_t service_worker_version_id, int thread_id); // Called once an extension Service Worker was destroyed. void DidStopServiceWorkerContext(int render_process_id, const ExtensionId& extension_id, + int activation_sequence, const GURL& service_worker_scope, int64_t service_worker_version_id, int thread_id); + // Returns the current ActivationSequence for an extension, if the extension + // is currently activated. Returns base::nullopt if the extension isn't + // activated. + base::Optional<ActivationSequence> GetCurrentSequence( + const ExtensionId& extension_id) const; + class TestObserver { public: TestObserver(); @@ -130,14 +144,9 @@ static void SetObserverForTest(TestObserver* observer); private: - // Unique identifier for an extension's activation->deactivation span. - using ActivationSequence = int; using SequencedContextId = std::pair<LazyContextId, ActivationSequence>; - // Key used to identify a WorkerState within the worker container. - using WorkerKey = std::pair<LazyContextId, WorkerId>; - - struct WorkerState; + class WorkerState; static void DidStartWorkerForScopeOnCoreThread( const SequencedContextId& context_id, @@ -184,40 +193,19 @@ // If the worker with |context_id| has seen worker start // (DidStartWorkerForScope) and load (DidStartServiceWorkerContext) then runs // all pending tasks for that worker. - void RunPendingTasksIfWorkerReady(const LazyContextId& context_id, - int64_t version_id, - int process_id, - int thread_id); - - void ClearPendingTasks(const SequencedContextId& context_id); + void RunPendingTasksIfWorkerReady(const SequencedContextId& context_id); // Returns true if |sequence| is the current activation sequence for // |extension_id|. bool IsCurrentSequence(const ExtensionId& extension_id, ActivationSequence sequence) const; - // Returns the current ActivationSequence for an extension, if the extension - // is currently activated. Returns base::nullopt if the extension isn't - // activated. - base::Optional<ActivationSequence> GetCurrentSequence( - const ExtensionId& extension_id) const; - - WorkerState* GetOrCreateWorkerState(const WorkerKey& worker_key); - WorkerState* GetWorkerState(const WorkerKey& worker_key); - void ClearBrowserReadyForWorkers(const LazyContextId& context_id, - ActivationSequence sequence); + WorkerState* GetWorkerState(const SequencedContextId& context_id); ActivationSequence next_activation_sequence_ = 0; - // Set of extension ids that hasn't completed Service Worker registration. - std::set<SequencedContextId> pending_registrations_; - - // The state of each workers we know about. - std::map<WorkerKey, WorkerState> worker_state_map_; - - // Pending tasks for a |LazyContextId| with an ActivationSequence. - // These tasks will be run once the corresponding worker becomes ready. - std::map<SequencedContextId, std::vector<PendingTask>> pending_tasks_; + // The state of worker of each activated extension. + std::map<SequencedContextId, WorkerState> worker_state_map_; content::BrowserContext* const browser_context_ = nullptr;
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json index c44279a..c83c6e6 100644 --- a/extensions/common/api/_api_features.json +++ b/extensions/common/api/_api_features.json
@@ -161,11 +161,6 @@ "channel": "beta", "location": "unpacked" }, - "declarativeNetRequest.setActionCountAsBadgeText": { - "dependencies": ["permission:declarativeNetRequest"], - "contexts": ["blessed_extension"], - "channel": "trunk" - }, "declarativeWebRequest": { "dependencies": ["permission:declarativeWebRequest"], "contexts": ["blessed_extension"]
diff --git a/extensions/common/api/declarative_net_request.idl b/extensions/common/api/declarative_net_request.idl index 1036e39..541bc63 100644 --- a/extensions/common/api/declarative_net_request.idl +++ b/extensions/common/api/declarative_net_request.idl
@@ -384,9 +384,6 @@ // Sets whether to automatically badge extension's icon to the matched // action count for a tab. This preference is persisted across sessions and // is false by default. - // TODO(crbug.com/973211): Add documentation once implementation is - // complete. - [nodoc] static void setActionCountAsBadgeText(boolean enable); };
diff --git a/extensions/common/extension_messages.cc b/extensions/common/extension_messages.cc index 1edd698..9f8d1b04 100644 --- a/extensions/common/extension_messages.cc +++ b/extensions/common/extension_messages.cc
@@ -61,7 +61,8 @@ ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params( const Extension* extension, - bool include_tab_permissions) + bool include_tab_permissions, + base::Optional<int> worker_activation_sequence) : manifest(static_cast<base::DictionaryValue&&>( extension->manifest()->value()->Clone())), location(extension->location()), @@ -76,6 +77,7 @@ uses_default_policy_blocked_allowed_hosts( extension->permissions_data()->UsesDefaultPolicyHostRestrictions()), id(extension->id()), + worker_activation_sequence(worker_activation_sequence), creation_flags(extension->creation_flags()) { if (include_tab_permissions) { for (const auto& pair : @@ -327,6 +329,7 @@ WriteParam(m, p.policy_blocked_hosts); WriteParam(m, p.policy_allowed_hosts); WriteParam(m, p.uses_default_policy_blocked_allowed_hosts); + WriteParam(m, p.worker_activation_sequence); } bool ParamTraits<ExtensionMsg_Loaded_Params>::Read(const base::Pickle* m, @@ -341,7 +344,8 @@ ReadParam(m, iter, &p->tab_specific_permissions) && ReadParam(m, iter, &p->policy_blocked_hosts) && ReadParam(m, iter, &p->policy_allowed_hosts) && - ReadParam(m, iter, &p->uses_default_policy_blocked_allowed_hosts); + ReadParam(m, iter, &p->uses_default_policy_blocked_allowed_hosts) && + ReadParam(m, iter, &p->worker_activation_sequence); } void ParamTraits<ExtensionMsg_Loaded_Params>::Log(const param_type& p,
diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index dfd0f3b..f73c4452 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h
@@ -356,7 +356,8 @@ ExtensionMsg_Loaded_Params(); ~ExtensionMsg_Loaded_Params(); ExtensionMsg_Loaded_Params(const extensions::Extension* extension, - bool include_tab_permissions); + bool include_tab_permissions, + base::Optional<int> worker_activation_sequence); ExtensionMsg_Loaded_Params(ExtensionMsg_Loaded_Params&& other); ExtensionMsg_Loaded_Params& operator=(ExtensionMsg_Loaded_Params&& other); @@ -391,6 +392,10 @@ // We keep this separate so that it can be used in logging. std::string id; + // If this extension is Service Worker based, then this contains the + // activation sequence of the extension. + base::Optional<int> worker_activation_sequence; + // Send creation flags so extension is initialized identically. int creation_flags; @@ -1060,16 +1065,18 @@ // straightforward as it changes SW IPC ordering with respect of rest of // Chrome. // See https://crbug.com/879015#c4 for details. -IPC_MESSAGE_CONTROL4(ExtensionHostMsg_DidStartServiceWorkerContext, +IPC_MESSAGE_CONTROL5(ExtensionHostMsg_DidStartServiceWorkerContext, std::string /* extension_id */, + int /* activation_sequence */, GURL /* service_worker_scope */, int64_t /* service_worker_version_id */, int /* worker_thread_id */) // Tells the browser that an extension service worker context has been // destroyed. -IPC_MESSAGE_CONTROL4(ExtensionHostMsg_DidStopServiceWorkerContext, +IPC_MESSAGE_CONTROL5(ExtensionHostMsg_DidStopServiceWorkerContext, std::string /* extension_id */, + int /* activation_sequence */, GURL /* service_worker_scope */, int64_t /* service_worker_version_id */, int /* worker_thread_id */)
diff --git a/extensions/common/extension_messages_unittest.cc b/extensions/common/extension_messages_unittest.cc index 208436d..f99d59e6 100644 --- a/extensions/common/extension_messages_unittest.cc +++ b/extensions/common/extension_messages_unittest.cc
@@ -81,7 +81,7 @@ extension->permissions_data()->SetPolicyHostRestrictions( runtime_blocked_hosts, runtime_allowed_hosts); - ExtensionMsg_Loaded_Params params_in(extension.get(), true); + ExtensionMsg_Loaded_Params params_in(extension.get(), true, base::nullopt); EXPECT_EQ(extension->id(), params_in.id); {
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 82e432e..6410d9c 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -451,8 +451,11 @@ std::unique_ptr<IPCMessageSender> ipc_sender = IPCMessageSender::CreateWorkerThreadIPCMessageSender( worker_dispatcher, service_worker_version_id); + int worker_activation_sequence = + *RendererExtensionRegistry::Get()->GetWorkerActivationSequence( + extension->id()); worker_dispatcher->AddWorkerData( - service_worker_version_id, context, + service_worker_version_id, worker_activation_sequence, context, CreateBindingsSystem(std::move(ipc_sender))); worker_thread_util::SetWorkerContextProxy(context_proxy); @@ -986,6 +989,10 @@ // consider making this a release CHECK. NOTREACHED(); } + if (param.worker_activation_sequence) { + extension_registry->SetWorkerActivationSequence( + extension, *param.worker_activation_sequence); + } if (param.uses_default_policy_blocked_allowed_hosts) { extension->permissions_data()->SetUsesDefaultHostRestrictions(); } else {
diff --git a/extensions/renderer/renderer_extension_registry.cc b/extensions/renderer/renderer_extension_registry.cc index 4fb14dd..93936af5 100644 --- a/extensions/renderer/renderer_extension_registry.cc +++ b/extensions/renderer/renderer_extension_registry.cc
@@ -7,6 +7,7 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "content/public/renderer/render_thread.h" +#include "extensions/common/manifest_handlers/background_info.h" namespace extensions { @@ -102,4 +103,24 @@ return extensions_.ExtensionBindingsAllowed(url); } +void RendererExtensionRegistry::SetWorkerActivationSequence( + const scoped_refptr<const Extension>& extension, + int worker_activation_sequence) { + DCHECK(content::RenderThread::Get()); + DCHECK(Contains(extension->id())); + DCHECK(BackgroundInfo::IsServiceWorkerBased(extension.get())); + + base::AutoLock lock(lock_); + worker_activation_sequences_[extension->id()] = worker_activation_sequence; +} + +base::Optional<int> RendererExtensionRegistry::GetWorkerActivationSequence( + const ExtensionId& extension_id) const { + base::AutoLock lock(lock_); + auto iter = worker_activation_sequences_.find(extension_id); + if (iter == worker_activation_sequences_.end()) + return base::nullopt; + return iter->second; +} + } // namespace extensions
diff --git a/extensions/renderer/renderer_extension_registry.h b/extensions/renderer/renderer_extension_registry.h index 97c24bb..a62d26c 100644 --- a/extensions/renderer/renderer_extension_registry.h +++ b/extensions/renderer/renderer_extension_registry.h
@@ -10,7 +10,9 @@ #include <string> #include "base/macros.h" +#include "base/optional.h" #include "base/synchronization/lock.h" +#include "extensions/common/extension_id.h" #include "extensions/common/extension_set.h" class GURL; @@ -49,9 +51,23 @@ ExtensionIdSet GetIDs() const; bool ExtensionBindingsAllowed(const GURL& url) const; + // ActivationSequence related methods. + // + // Sets ActivationSequence for a Service Worker based |extension|. + void SetWorkerActivationSequence( + const scoped_refptr<const Extension>& extension, + int worker_activation_sequence); + // Returns the current activation sequence for worker based extension with + // |extension_id|. Returns base::nullopt otherwise. + base::Optional<int> GetWorkerActivationSequence( + const ExtensionId& extension_id) const; + private: ExtensionSet extensions_; + // Maps extension id to ActivationSequence, for worker based extensions. + std::map<ExtensionId, int> worker_activation_sequences_; + mutable base::Lock lock_; DISALLOW_COPY_AND_ASSIGN(RendererExtensionRegistry);
diff --git a/extensions/renderer/service_worker_data.cc b/extensions/renderer/service_worker_data.cc index 3c96f09..1f95bd2 100644 --- a/extensions/renderer/service_worker_data.cc +++ b/extensions/renderer/service_worker_data.cc
@@ -10,9 +10,11 @@ ServiceWorkerData::ServiceWorkerData( int64_t service_worker_version_id, + int activation_sequence, ScriptContext* context, std::unique_ptr<NativeExtensionBindingsSystem> bindings_system) : service_worker_version_id_(service_worker_version_id), + activation_sequence_(activation_sequence), context_(context), v8_schema_registry_(new V8SchemaRegistry), bindings_system_(std::move(bindings_system)) {}
diff --git a/extensions/renderer/service_worker_data.h b/extensions/renderer/service_worker_data.h index 1ee28d1..5cd152a 100644 --- a/extensions/renderer/service_worker_data.h +++ b/extensions/renderer/service_worker_data.h
@@ -20,6 +20,7 @@ public: ServiceWorkerData( int64_t service_worker_version_id, + int activation_sequence, ScriptContext* context, std::unique_ptr<NativeExtensionBindingsSystem> bindings_system); ~ServiceWorkerData(); @@ -31,10 +32,12 @@ int64_t service_worker_version_id() const { return service_worker_version_id_; } + int activation_sequence() const { return activation_sequence_; } ScriptContext* context() const { return context_; } private: const int64_t service_worker_version_id_; + const int activation_sequence_; ScriptContext* const context_ = nullptr; std::unique_ptr<V8SchemaRegistry> v8_schema_registry_;
diff --git a/extensions/renderer/worker_thread_dispatcher.cc b/extensions/renderer/worker_thread_dispatcher.cc index efbcdc3..9906e300 100644 --- a/extensions/renderer/worker_thread_dispatcher.cc +++ b/extensions/renderer/worker_thread_dispatcher.cc
@@ -264,12 +264,14 @@ void WorkerThreadDispatcher::AddWorkerData( int64_t service_worker_version_id, + int activation_sequence, ScriptContext* script_context, std::unique_ptr<NativeExtensionBindingsSystem> bindings_system) { ServiceWorkerData* data = g_data_tls.Pointer()->Get(); if (!data) { - ServiceWorkerData* new_data = new ServiceWorkerData( - service_worker_version_id, script_context, std::move(bindings_system)); + ServiceWorkerData* new_data = + new ServiceWorkerData(service_worker_version_id, activation_sequence, + script_context, std::move(bindings_system)); g_data_tls.Pointer()->Set(new_data); } @@ -300,8 +302,8 @@ const int thread_id = content::WorkerThread::GetCurrentId(); DCHECK_NE(thread_id, kMainThreadId); Send(new ExtensionHostMsg_DidStartServiceWorkerContext( - data->context()->GetExtensionID(), service_worker_scope, - service_worker_version_id, thread_id)); + data->context()->GetExtensionID(), data->activation_sequence(), + service_worker_scope, service_worker_version_id, thread_id)); } void WorkerThreadDispatcher::DidStopContext(const GURL& service_worker_scope, @@ -311,8 +313,8 @@ DCHECK_NE(thread_id, kMainThreadId); DCHECK_EQ(service_worker_version_id, data->service_worker_version_id()); Send(new ExtensionHostMsg_DidStopServiceWorkerContext( - data->context()->GetExtensionID(), service_worker_scope, - service_worker_version_id, thread_id)); + data->context()->GetExtensionID(), data->activation_sequence(), + service_worker_scope, service_worker_version_id, thread_id)); } void WorkerThreadDispatcher::RemoveWorkerData(
diff --git a/extensions/renderer/worker_thread_dispatcher.h b/extensions/renderer/worker_thread_dispatcher.h index dc341bb6..f13874ef 100644 --- a/extensions/renderer/worker_thread_dispatcher.h +++ b/extensions/renderer/worker_thread_dispatcher.h
@@ -63,6 +63,7 @@ void AddWorkerData( int64_t service_worker_version_id, + int activation_sequence, ScriptContext* script_context, std::unique_ptr<NativeExtensionBindingsSystem> bindings_system); void RemoveWorkerData(int64_t service_worker_version_id);
diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc index e411dab..182dc53b 100644 --- a/extensions/shell/browser/shell_content_browser_client.cc +++ b/extensions/shell/browser/shell_content_browser_client.cc
@@ -48,7 +48,6 @@ #include "extensions/shell/browser/shell_navigation_ui_data.h" #include "extensions/shell/browser/shell_speech_recognition_manager_delegate.h" #include "extensions/shell/common/version.h" // Generated file. -#include "storage/browser/quota/quota_settings.h" #include "url/gurl.h" #if BUILDFLAG(ENABLE_NACL) @@ -132,15 +131,6 @@ return true; } -void ShellContentBrowserClient::GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - storage::GetNominalDynamicSettings( - partition->GetPath(), context->IsOffTheRecord(), - storage::GetDefaultDeviceInfoHelper(), std::move(callback)); -} - bool ShellContentBrowserClient::IsHandledURL(const GURL& url) { if (!url.is_valid()) return false;
diff --git a/extensions/shell/browser/shell_content_browser_client.h b/extensions/shell/browser/shell_content_browser_client.h index c41b63d..ba5e219 100644 --- a/extensions/shell/browser/shell_content_browser_client.h +++ b/extensions/shell/browser/shell_content_browser_client.h
@@ -13,7 +13,6 @@ #include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "storage/browser/quota/quota_settings.h" class GURL; @@ -49,10 +48,6 @@ void RenderProcessWillLaunch(content::RenderProcessHost* host) override; bool ShouldUseProcessPerSite(content::BrowserContext* browser_context, const GURL& effective_url) override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) override; bool IsHandledURL(const GURL& url) override; void SiteInstanceGotProcess(content::SiteInstance* site_instance) override; void SiteInstanceDeleting(content::SiteInstance* site_instance) override;
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index 04bf17c..acc467ab 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -295,6 +295,7 @@ "command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc", "command_buffer/service/shared_image_factory_unittest.cc", "command_buffer/service/shared_image_manager_unittest.cc", + "command_buffer/service/shared_image_representation_unittest.cc", "command_buffer/service/shared_image_test_utils.cc", "command_buffer/service/shared_image_test_utils.h", "command_buffer/tests/compressed_texture_test.cc",
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_shared_image.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_shared_image.txt index def75e9..d540307 100644 --- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_shared_image.txt +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_shared_image.txt
@@ -81,6 +81,10 @@ mode - the access mode with which to begin access. + This function indicates that the calling context will access the SharedImage + bound to <texture> until glEndSharedImageAccessDirectCHROMIUM is called, or + the calling context deletes <texture>. + INVALID_OPERATION is generated if the texture id indicated is not backed by a shared image.
diff --git a/gpu/command_buffer/service/external_vk_image_dawn_representation.cc b/gpu/command_buffer/service/external_vk_image_dawn_representation.cc index f7f0427..be4d292 100644 --- a/gpu/command_buffer/service/external_vk_image_dawn_representation.cc +++ b/gpu/command_buffer/service/external_vk_image_dawn_representation.cc
@@ -93,7 +93,7 @@ // the result. // TODO(cwallez@chromium.org): This is incorrect and allows reading // uninitialized data. When !IsCleared we should tell dawn_native to - // consider the texture lazy-cleared. + // consider the texture lazy-cleared. crbug.com/1036080 SetCleared(); }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index a876c06a..00965e3d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -391,7 +391,10 @@ bool PassthroughResources::SharedImageData::BeginAccess(GLenum mode, gl::GLApi* api) { DCHECK(!is_being_accessed()); - scoped_access_ = representation_->BeginScopedAccess(mode); + // When importing a texture for use in passthrough cmd decoder, always allow + // uncleared access. We ensure the texture is cleared below. + scoped_access_ = representation_->BeginScopedAccess( + mode, SharedImageRepresentation::AllowUnclearedAccess::kYes); if (!scoped_access_) { return false; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_textures.cc index 9069424..f2fffe2c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_textures.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_unittest_textures.cc
@@ -166,17 +166,10 @@ EXPECT_EQ(GL_NO_ERROR, GetGLError()); cmds::EndSharedImageAccessDirectCHROMIUM readwrite_end_cmd; readwrite_end_cmd.Init(client_id); - // EXPECT_EQ(error::kNoError, ExecuteCmd(readwrite_end_cmd)); - // EXPECT_EQ(GL_NO_ERROR, GetGLError()); - } - - for (int i = 20; i > 10; --i) { - cmds::EndSharedImageAccessDirectCHROMIUM readwrite_end_cmd; - readwrite_end_cmd.Init(kNewClientId + i); EXPECT_EQ(error::kNoError, ExecuteCmd(readwrite_end_cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); - DoDeleteTexture(kNewClientId + i); - fprintf(stderr, "EEEE DoDeleteTexture() i=%d\n", i); + + DoDeleteTexture(client_id); } // Cleanup
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 6ab2f00..c333429c 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -1796,16 +1796,19 @@ std::unique_ptr<SharedImageRepresentationGLTexturePassthrough::ScopedAccess> source_access = source_shared_image->BeginScopedAccess( - GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); + GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kNo); if (!source_access) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTexture", "unable to access source for read"); return; } + // Allow uncleared access, as we manually handle clear tracking. std::unique_ptr<SharedImageRepresentationGLTexturePassthrough::ScopedAccess> dest_access = dest_shared_image->BeginScopedAccess( - GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kYes); if (!dest_access) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTexture", "unable to access destination for write"); @@ -1872,7 +1875,8 @@ std::unique_ptr<SharedImageRepresentationGLTexture::ScopedAccess> source_access = source_shared_image->BeginScopedAccess( - GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); + GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kNo); if (!source_access) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTexture", "unable to access source for read"); @@ -1891,9 +1895,11 @@ return; } + // Allow uncleared access, as we manually handle clear tracking. std::unique_ptr<SharedImageRepresentationGLTexture::ScopedAccess> dest_access = dest_shared_image->BeginScopedAccess( - GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kYes); if (!dest_access) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTexture", "unable to access destination for write"); @@ -2116,9 +2122,11 @@ std::vector<GrBackendSemaphore> begin_semaphores; std::vector<GrBackendSemaphore> end_semaphores; + // Allow uncleared access, as we manually handle clear tracking. std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> dest_scoped_access = dest_shared_image->BeginScopedWriteAccess( - &begin_semaphores, &end_semaphores); + &begin_semaphores, &end_semaphores, + SharedImageRepresentation::AllowUnclearedAccess::kYes); if (!dest_scoped_access) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTexture", "Dest shared image is not writable"); @@ -2336,8 +2344,11 @@ std::vector<GrBackendSemaphore> begin_semaphores; DCHECK(end_semaphores_.empty()); DCHECK(!scoped_shared_image_write_); + // Allow uncleared access, as raster specifically handles uncleared images by + // clearing them before writing. scoped_shared_image_write_ = shared_image_->BeginScopedWriteAccess( - final_msaa_count, surface_props, &begin_semaphores, &end_semaphores_); + final_msaa_count, surface_props, &begin_semaphores, &end_semaphores_, + SharedImageRepresentation::AllowUnclearedAccess::kYes); if (!scoped_shared_image_write_) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", "failed to create surface");
diff --git a/gpu/command_buffer/service/raster_decoder_unittest.cc b/gpu/command_buffer/service/raster_decoder_unittest.cc index 425b7f6..ac90def 100644 --- a/gpu/command_buffer/service/raster_decoder_unittest.cc +++ b/gpu/command_buffer/service/raster_decoder_unittest.cc
@@ -297,6 +297,11 @@ init.extensions.push_back("GL_EXT_texture_rg"); InitDecoder(init); + // Recreate |client_texture_mailbox_| as a cleared mailbox. + client_texture_mailbox_ = CreateFakeTexture( + kServiceTextureId, viz::ResourceFormat::RGBA_8888, /*width=*/2, + /*height=*/2, /*cleared=*/true); + // Create dest texture. gpu::Mailbox dest_texture_mailbox = CreateFakeTexture(kNewServiceId, viz::ResourceFormat::RED_8,
diff --git a/gpu/command_buffer/service/shared_image_backing_egl_image.cc b/gpu/command_buffer/service/shared_image_backing_egl_image.cc index 71803a0c..6f93bfe 100644 --- a/gpu/command_buffer/service/shared_image_backing_egl_image.cc +++ b/gpu/command_buffer/service/shared_image_backing_egl_image.cc
@@ -59,11 +59,6 @@ egl_backing()->EndRead(this, std::move(egl_fence)); } else if (mode_ == RepresentationAccessMode::kWrite) { egl_backing()->EndWrite(std::move(egl_fence)); - - if (texture_) { - if (texture_->IsLevelCleared(texture_->target(), 0)) - backing()->SetCleared(); - } } else { NOTREACHED(); }
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc index 183dcdd..68becc3 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -234,11 +234,6 @@ ahb_backing()->EndRead(this, std::move(sync_fd)); } else if (mode_ == RepresentationAccessMode::kWrite) { ahb_backing()->EndWrite(std::move(sync_fd)); - - if (texture_) { - if (texture_->IsLevelCleared(texture_->target(), 0)) - backing()->SetCleared(); - } } mode_ = RepresentationAccessMode::kNone;
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc index 6e7db40..f34ebf15 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc
@@ -127,7 +127,8 @@ std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> scoped_write_access; scoped_write_access = skia_representation->BeginScopedWriteAccess( - &begin_semaphores, &end_semaphores); + &begin_semaphores, &end_semaphores, + SharedImageRepresentation::AllowUnclearedAccess::kYes); EXPECT_TRUE(scoped_write_access); auto* surface = scoped_write_access->surface(); EXPECT_TRUE(surface); @@ -325,7 +326,8 @@ std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> scoped_write_access; scoped_write_access = skia_representation->BeginScopedWriteAccess( - &begin_semaphores, &end_semaphores); + &begin_semaphores, &end_semaphores, + SharedImageRepresentation::AllowUnclearedAccess::kYes); EXPECT_TRUE(scoped_write_access); EXPECT_EQ(0u, begin_semaphores.size()); EXPECT_EQ(0u, end_semaphores.size()); @@ -337,7 +339,8 @@ std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> scoped_write_access2; scoped_write_access2 = skia_representation2->BeginScopedWriteAccess( - &begin_semaphores2, &end_semaphores2); + &begin_semaphores2, &end_semaphores2, + SharedImageRepresentation::AllowUnclearedAccess::kYes); EXPECT_FALSE(scoped_write_access); EXPECT_EQ(0u, begin_semaphores2.size()); EXPECT_EQ(0u, end_semaphores2.size()); @@ -419,7 +422,8 @@ std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> scoped_write_access; scoped_write_access = skia_representation2->BeginScopedWriteAccess( - &begin_semaphores2, &end_semaphores2); + &begin_semaphores2, &end_semaphores2, + SharedImageRepresentation::AllowUnclearedAccess::kYes); EXPECT_FALSE(scoped_write_access); EXPECT_EQ(0u, begin_semaphores2.size()); EXPECT_EQ(0u, end_semaphores2.size()); @@ -446,7 +450,8 @@ std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> scoped_write_access; scoped_write_access = skia_representation->BeginScopedWriteAccess( - &begin_semaphores, &end_semaphores); + &begin_semaphores, &end_semaphores, + SharedImageRepresentation::AllowUnclearedAccess::kYes); EXPECT_TRUE(scoped_write_access); EXPECT_EQ(0u, begin_semaphores.size()); EXPECT_EQ(0u, end_semaphores.size());
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc b/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc index 9308011d..4b55763 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
@@ -460,7 +460,7 @@ // the result. // TODO(cwallez@chromium.org): This is incorrect and allows reading // uninitialized data. When !IsCleared we should tell dawn_native to - // consider the texture lazy-cleared. + // consider the texture lazy-cleared. crbug.com/1036080 SetCleared(); } else { d3d_image_backing->EndAccessD3D12();
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc index 475d0261..2c5bb23 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc
@@ -514,7 +514,8 @@ std::unique_ptr<SharedImageRepresentationGLTexturePassthrough::ScopedAccess> scoped_access = gl_representation->BeginScopedAccess( - GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kYes); EXPECT_TRUE(scoped_access); // Create an FBO. @@ -584,7 +585,8 @@ ASSERT_TRUE(dawn_representation); auto scoped_access = dawn_representation->BeginScopedAccess( - WGPUTextureUsage_OutputAttachment); + WGPUTextureUsage_OutputAttachment, + SharedImageRepresentation::AllowUnclearedAccess::kNo); ASSERT_TRUE(scoped_access); wgpu::Texture texture = wgpu::Texture::Acquire(scoped_access->texture());
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc index e9a32cc..beab91e 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
@@ -270,7 +270,8 @@ std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> scoped_write_access; scoped_write_access = skia_representation->BeginScopedWriteAccess( - &begin_semaphores, &end_semaphores); + &begin_semaphores, &end_semaphores, + SharedImageRepresentation::AllowUnclearedAccess::kYes); auto* surface = scoped_write_access->surface(); EXPECT_TRUE(surface); EXPECT_EQ(size.width(), surface->width()); @@ -381,7 +382,8 @@ std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> scoped_write_access; scoped_write_access = skia_representation->BeginScopedWriteAccess( - &begin_semaphores, &end_semaphores); + &begin_semaphores, &end_semaphores, + SharedImageRepresentation::AllowUnclearedAccess::kYes); auto* surface = scoped_write_access->surface(); EXPECT_TRUE(surface); EXPECT_EQ(size.width(), surface->width()); @@ -884,7 +886,8 @@ // Begin writing to the underlying texture of the backing via ScopedAccess. std::unique_ptr<SharedImageRepresentationGLTexture::ScopedAccess> writer_scoped_access = gl_representation->BeginScopedAccess( - GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); + GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kNo); DCHECK(writer_scoped_access); @@ -903,6 +906,8 @@ // Set the clear color to green. api->glClearColorFn(0.0f, 1.0f, 0.0f, 1.0f); api->glClearFn(GL_COLOR_BUFFER_BIT); + gl_representation->GetTexture()->SetLevelCleared( + gl_representation->GetTexture()->target(), 0, true); // End writing. writer_scoped_access.reset(); @@ -991,7 +996,8 @@ std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> scoped_write_access; scoped_write_access = skia_representation->BeginScopedWriteAccess( - &begin_semaphores, &end_semaphores); + &begin_semaphores, &end_semaphores, + SharedImageRepresentation::AllowUnclearedAccess::kNo); auto* surface = scoped_write_access->surface(); EXPECT_TRUE(surface); EXPECT_EQ(size_.width(), surface->width());
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm b/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm index 31afb13..b460c93 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm +++ b/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm
@@ -304,7 +304,7 @@ // the result. // TODO(cwallez@chromium.org): This is incorrect and allows reading // uninitialized data. When !IsCleared we should tell dawn_native to - // consider the texture lazy-cleared. + // consider the texture lazy-cleared. crbug.com/1036080 SetCleared(); }
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc index 46cb3d7f..cc58235 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc
@@ -143,7 +143,8 @@ scoped_write_access; scoped_write_access = skia_representation->BeginScopedWriteAccess( - &begin_semaphores, &end_semaphores); + &begin_semaphores, &end_semaphores, + SharedImageRepresentation::AllowUnclearedAccess::kYes); auto* surface = scoped_write_access->surface(); EXPECT_TRUE(surface); EXPECT_EQ(size.width(), surface->width()); @@ -189,27 +190,36 @@ memory_type_tracker_.get()); // Create a SharedImageRepresentationGLTexture. - auto gl_representation = - shared_image_representation_factory_->ProduceGLTexture(mailbox); - EXPECT_TRUE(gl_representation); - EXPECT_EQ(expected_target, gl_representation->GetTexture()->target()); + { + auto gl_representation = + shared_image_representation_factory_->ProduceGLTexture(mailbox); + EXPECT_TRUE(gl_representation); + EXPECT_EQ(expected_target, gl_representation->GetTexture()->target()); - // Create an FBO. - GLuint fbo = 0; - gl::GLApi* api = gl::g_current_gl_context; - api->glGenFramebuffersEXTFn(1, &fbo); - api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, fbo); + // Access the SharedImageRepresentationGLTexutre + auto scoped_write_access = gl_representation->BeginScopedAccess( + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kYes); - // Attach the texture to FBO. - api->glFramebufferTexture2DEXTFn( - GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - gl_representation->GetTexture()->target(), - gl_representation->GetTexture()->service_id(), 0); + // Create an FBO. + GLuint fbo = 0; + gl::GLApi* api = gl::g_current_gl_context; + api->glGenFramebuffersEXTFn(1, &fbo); + api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, fbo); - // Set the clear color to green. - api->glClearColorFn(0.0f, 1.0f, 0.0f, 1.0f); - api->glClearFn(GL_COLOR_BUFFER_BIT); - gl_representation.reset(); + // Attach the texture to FBO. + api->glFramebufferTexture2DEXTFn( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + gl_representation->GetTexture()->target(), + gl_representation->GetTexture()->service_id(), 0); + + // Set the clear color to green. + api->glClearColorFn(0.0f, 1.0f, 0.0f, 1.0f); + api->glClearFn(GL_COLOR_BUFFER_BIT); + + gl_representation->GetTexture()->SetLevelCleared( + gl_representation->GetTexture()->target(), 0, true); + } // Next create a SharedImageRepresentationSkia to read back the texture data. auto skia_representation = shared_image_representation_factory_->ProduceSkia( @@ -353,7 +363,8 @@ // Clear the shared image to green using Dawn. { auto scoped_access = dawn_representation->BeginScopedAccess( - WGPUTextureUsage_OutputAttachment); + WGPUTextureUsage_OutputAttachment, + SharedImageRepresentation::AllowUnclearedAccess::kYes); ASSERT_TRUE(scoped_access); wgpu::Texture texture = wgpu::Texture::Acquire(scoped_access->texture());
diff --git a/gpu/command_buffer/service/shared_image_representation.cc b/gpu/command_buffer/service/shared_image_representation.cc index 7234e590..5a42baba 100644 --- a/gpu/command_buffer/service/shared_image_representation.cc +++ b/gpu/command_buffer/service/shared_image_representation.cc
@@ -4,6 +4,7 @@ #include "gpu/command_buffer/service/shared_image_representation.h" +#include "gpu/command_buffer/service/texture_manager.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" namespace gpu { @@ -22,7 +23,14 @@ } std::unique_ptr<SharedImageRepresentationGLTexture::ScopedAccess> -SharedImageRepresentationGLTextureBase::BeginScopedAccess(GLenum mode) { +SharedImageRepresentationGLTextureBase::BeginScopedAccess( + GLenum mode, + AllowUnclearedAccess allow_uncleared) { + if (allow_uncleared != AllowUnclearedAccess::kYes && !IsCleared()) { + LOG(ERROR) << "Attempt to access an uninitialized ShardImage"; + return nullptr; + } + if (!BeginAccess(mode)) return nullptr; @@ -44,6 +52,15 @@ return false; } +void SharedImageRepresentationGLTexture::UpdateClearedStateOnEndAccess() { + auto* texture = GetTexture(); + // Operations on the gles2::Texture may have cleared or uncleared it. Make + // sure this state is reflected back in the SharedImage. + gfx::Rect cleared_rect = texture->GetLevelClearedRect(texture->target(), 0); + if (cleared_rect != ClearedRect()) + SetClearedRect(cleared_rect); +} + SharedImageRepresentationSkia::ScopedWriteAccess::ScopedWriteAccess( util::PassKey<SharedImageRepresentationSkia> /* pass_key */, SharedImageRepresentationSkia* representation, @@ -59,7 +76,13 @@ int final_msaa_count, const SkSurfaceProps& surface_props, std::vector<GrBackendSemaphore>* begin_semaphores, - std::vector<GrBackendSemaphore>* end_semaphores) { + std::vector<GrBackendSemaphore>* end_semaphores, + AllowUnclearedAccess allow_uncleared) { + if (allow_uncleared != AllowUnclearedAccess::kYes && !IsCleared()) { + LOG(ERROR) << "Attempt to write to an uninitialized ShardImage"; + return nullptr; + } + sk_sp<SkSurface> surface = BeginWriteAccess(final_msaa_count, surface_props, begin_semaphores, end_semaphores); if (!surface) @@ -72,11 +95,12 @@ std::unique_ptr<SharedImageRepresentationSkia::ScopedWriteAccess> SharedImageRepresentationSkia::BeginScopedWriteAccess( std::vector<GrBackendSemaphore>* begin_semaphores, - std::vector<GrBackendSemaphore>* end_semaphores) { + std::vector<GrBackendSemaphore>* end_semaphores, + AllowUnclearedAccess allow_uncleared) { return BeginScopedWriteAccess( 0 /* final_msaa_count */, SkSurfaceProps(0 /* flags */, kUnknown_SkPixelGeometry), begin_semaphores, - end_semaphores); + end_semaphores, allow_uncleared); } SharedImageRepresentationSkia::ScopedReadAccess::ScopedReadAccess( @@ -94,6 +118,11 @@ SharedImageRepresentationSkia::BeginScopedReadAccess( std::vector<GrBackendSemaphore>* begin_semaphores, std::vector<GrBackendSemaphore>* end_semaphores) { + if (!IsCleared()) { + LOG(ERROR) << "Attempt to read from an uninitialized ShardImage"; + return nullptr; + } + sk_sp<SkPromiseImageTexture> promise_image_texture = BeginReadAccess(begin_semaphores, end_semaphores); if (!promise_image_texture) @@ -106,6 +135,11 @@ std::unique_ptr<SharedImageRepresentationOverlay::ScopedReadAccess> SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) { + if (!IsCleared()) { + LOG(ERROR) << "Attempt to read from an uninitialized ShardImage"; + return nullptr; + } + BeginReadAccess(); return std::make_unique<ScopedReadAccess>( util::PassKey<SharedImageRepresentationOverlay>(), this, @@ -123,7 +157,14 @@ } std::unique_ptr<SharedImageRepresentationDawn::ScopedAccess> -SharedImageRepresentationDawn::BeginScopedAccess(WGPUTextureUsage usage) { +SharedImageRepresentationDawn::BeginScopedAccess( + WGPUTextureUsage usage, + AllowUnclearedAccess allow_uncleared) { + if (allow_uncleared != AllowUnclearedAccess::kYes && !IsCleared()) { + LOG(ERROR) << "Attempt to access an uninitialized ShardImage"; + return nullptr; + } + WGPUTexture texture = BeginAccess(usage); if (!texture) return nullptr;
diff --git a/gpu/command_buffer/service/shared_image_representation.h b/gpu/command_buffer/service/shared_image_representation.h index 96699f1..da832e8 100644 --- a/gpu/command_buffer/service/shared_image_representation.h +++ b/gpu/command_buffer/service/shared_image_representation.h
@@ -44,6 +44,9 @@ // api. class GPU_GLES2_EXPORT SharedImageRepresentation { public: + // Used by derived classes. + enum class AllowUnclearedAccess { kYes, kNo }; + SharedImageRepresentation(SharedImageManager* manager, SharedImageBacking* backing, MemoryTypeTracker* tracker); @@ -106,7 +109,10 @@ ScopedAccess(util::PassKey<SharedImageRepresentationGLTextureBase> pass_key, SharedImageRepresentationGLTextureBase* representation) : representation_(representation) {} - ~ScopedAccess() { representation_->EndAccess(); } + ~ScopedAccess() { + representation_->UpdateClearedStateOnEndAccess(); + representation_->EndAccess(); + } private: SharedImageRepresentationGLTextureBase* representation_ = nullptr; @@ -119,11 +125,16 @@ MemoryTypeTracker* tracker) : SharedImageRepresentation(manager, backing, tracker) {} - std::unique_ptr<ScopedAccess> BeginScopedAccess(GLenum mode); + std::unique_ptr<ScopedAccess> BeginScopedAccess( + GLenum mode, + AllowUnclearedAccess allow_uncleared); protected: friend class SharedImageRepresentationSkiaGL; + // Can be overridden to handle clear state tracking when GL access ends. + virtual void UpdateClearedStateOnEndAccess() {} + // TODO(ericrk): Make these pure virtual and ensure real implementations // exist. virtual bool BeginAccess(GLenum mode); @@ -140,6 +151,9 @@ // TODO(ericrk): Move this to the ScopedAccess object. crbug.com/1003686 virtual gles2::Texture* GetTexture() = 0; + + protected: + void UpdateClearedStateOnEndAccess() override; }; class GPU_GLES2_EXPORT SharedImageRepresentationGLTexturePassthrough @@ -203,10 +217,13 @@ int final_msaa_count, const SkSurfaceProps& surface_props, std::vector<GrBackendSemaphore>* begin_semaphores, - std::vector<GrBackendSemaphore>* end_semaphores); + std::vector<GrBackendSemaphore>* end_semaphores, + AllowUnclearedAccess allow_uncleared); + std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess( std::vector<GrBackendSemaphore>* begin_semaphores, - std::vector<GrBackendSemaphore>* end_semaphores); + std::vector<GrBackendSemaphore>* end_semaphores, + AllowUnclearedAccess allow_uncleared); // Note: See BeginReadAccess below for a description of the semaphore // parameters. @@ -271,7 +288,9 @@ // Calls BeginAccess and returns a ScopedAccess object which will EndAccess // when it goes out of scope. The Representation must outlive the returned // ScopedAccess. - std::unique_ptr<ScopedAccess> BeginScopedAccess(WGPUTextureUsage usage); + std::unique_ptr<ScopedAccess> BeginScopedAccess( + WGPUTextureUsage usage, + AllowUnclearedAccess allow_uncleared); private: // This can return null in case of a Dawn validation error, for example if
diff --git a/gpu/command_buffer/service/shared_image_representation_dawn_ozone.cc b/gpu/command_buffer/service/shared_image_representation_dawn_ozone.cc index 1b7d95f..df4a9d4 100644 --- a/gpu/command_buffer/service/shared_image_representation_dawn_ozone.cc +++ b/gpu/command_buffer/service/shared_image_representation_dawn_ozone.cc
@@ -90,7 +90,7 @@ // the result. // TODO(cwallez@chromium.org): This is incorrect and allows reading // uninitialized data. When !IsCleared we should tell dawn_native to - // consider the texture lazy-cleared. + // consider the texture lazy-cleared. crbug.com/1036080 SetCleared(); } else { close(fd);
diff --git a/gpu/command_buffer/service/shared_image_representation_unittest.cc b/gpu/command_buffer/service/shared_image_representation_unittest.cc new file mode 100644 index 0000000..81c6055 --- /dev/null +++ b/gpu/command_buffer/service/shared_image_representation_unittest.cc
@@ -0,0 +1,235 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/service/shared_image_representation.h" + +#include "components/viz/common/resources/resource_format_utils.h" +#include "gpu/command_buffer/common/mailbox.h" +#include "gpu/command_buffer/common/shared_image_usage.h" +#include "gpu/command_buffer/service/shared_context_state.h" +#include "gpu/command_buffer/service/shared_image_backing.h" +#include "gpu/command_buffer/service/shared_image_representation.h" +#include "gpu/command_buffer/service/test_shared_image_backing.h" +#include "gpu/command_buffer/service/texture_manager.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkPromiseImageTexture.h" +#include "third_party/skia/include/gpu/GrBackendSurface.h" + +namespace gpu { + +class SharedImageRepresentationTest : public ::testing::Test { + public: + void SetUp() override { + tracker_ = std::make_unique<MemoryTypeTracker>(nullptr); + mailbox_ = Mailbox::GenerateForSharedImage(); + auto format = viz::ResourceFormat::RGBA_8888; + gfx::Size size(256, 256); + auto color_space = gfx::ColorSpace::CreateSRGB(); + uint32_t usage = SHARED_IMAGE_USAGE_GLES2; + + auto backing = std::make_unique<TestSharedImageBacking>( + mailbox_, format, size, color_space, usage, 0 /* estimated_size */); + factory_ref_ = manager_.Register(std::move(backing), tracker_.get()); + } + + protected: + gpu::Mailbox mailbox_; + SharedImageManager manager_; + std::unique_ptr<MemoryTypeTracker> tracker_; + std::unique_ptr<SharedImageRepresentationFactoryRef> factory_ref_; +}; + +TEST_F(SharedImageRepresentationTest, GLTextureClearing) { + auto representation = manager_.ProduceGLTexture(mailbox_, tracker_.get()); + EXPECT_FALSE(representation->IsCleared()); + + // We should not be able to begin access when |allow_uncleared| is false. + { + auto scoped_access = representation->BeginScopedAccess( + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kNo); + EXPECT_FALSE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // Begin/End access should not modify clear status on its own. + { + auto scoped_access = representation->BeginScopedAccess( + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kYes); + EXPECT_TRUE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // Clearing underlying GL texture should clear the SharedImage. + { + auto scoped_access = representation->BeginScopedAccess( + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kYes); + ASSERT_TRUE(scoped_access); + representation->GetTexture()->SetLevelCleared(GL_TEXTURE_2D, 0, + true /* cleared */); + } + EXPECT_TRUE(representation->IsCleared()); + + // We can now begin accdess with |allow_uncleared| == false. + { + auto scoped_access = representation->BeginScopedAccess( + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kNo); + EXPECT_TRUE(scoped_access); + } +} + +TEST_F(SharedImageRepresentationTest, GLTexturePassthroughClearing) { + auto representation = + manager_.ProduceGLTexturePassthrough(mailbox_, tracker_.get()); + EXPECT_FALSE(representation->IsCleared()); + + // We should not be able to begin access when |allow_uncleared| is false. + { + auto scoped_access = representation->BeginScopedAccess( + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kNo); + EXPECT_FALSE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // Begin/End access will not clear the representation on its own. + { + auto scoped_access = representation->BeginScopedAccess( + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kYes); + EXPECT_TRUE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // Clear the SharedImage. + representation->SetCleared(); + EXPECT_TRUE(representation->IsCleared()); + + // We can now begin accdess with |allow_uncleared| == false. + { + auto scoped_access = representation->BeginScopedAccess( + GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM, + SharedImageRepresentation::AllowUnclearedAccess::kNo); + EXPECT_TRUE(scoped_access); + } +} + +TEST_F(SharedImageRepresentationTest, SkiaClearing) { + auto representation = manager_.ProduceSkia(mailbox_, tracker_.get(), nullptr); + EXPECT_FALSE(representation->IsCleared()); + + // We should not be able to begin read access. + { + auto scoped_access = + representation->BeginScopedReadAccess(nullptr, nullptr); + EXPECT_FALSE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // We should not be able to begin write access when |allow_uncleared| is + // false. + { + auto scoped_access = representation->BeginScopedWriteAccess( + nullptr, nullptr, SharedImageRepresentation::AllowUnclearedAccess::kNo); + EXPECT_FALSE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // We can begin write access when |allow_uncleared| is true. + { + auto scoped_access = representation->BeginScopedWriteAccess( + nullptr, nullptr, + SharedImageRepresentation::AllowUnclearedAccess::kYes); + EXPECT_TRUE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // Clear the SharedImage. + representation->SetCleared(); + EXPECT_TRUE(representation->IsCleared()); + + // We can now begin read access. + { + auto scoped_access = + representation->BeginScopedReadAccess(nullptr, nullptr); + EXPECT_TRUE(scoped_access); + } + EXPECT_TRUE(representation->IsCleared()); + + // We can also begin write access with |allow_uncleared| == false. + { + auto scoped_access = representation->BeginScopedWriteAccess( + nullptr, nullptr, SharedImageRepresentation::AllowUnclearedAccess::kNo); + EXPECT_TRUE(scoped_access); + } + EXPECT_TRUE(representation->IsCleared()); +} + +TEST_F(SharedImageRepresentationTest, DawnClearing) { + auto representation = + manager_.ProduceDawn(mailbox_, tracker_.get(), nullptr /* device */); + EXPECT_FALSE(representation->IsCleared()); + + // We should not be able to begin access with |allow_uncleared| == false. + { + auto scoped_access = representation->BeginScopedAccess( + WGPUTextureUsage_None, + SharedImageRepresentation::AllowUnclearedAccess::kNo); + EXPECT_FALSE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // We can begin access when |allow_uncleared| is true. + { + auto scoped_access = representation->BeginScopedAccess( + WGPUTextureUsage_None, + SharedImageRepresentation::AllowUnclearedAccess::kYes); + EXPECT_TRUE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // Clear the SharedImage. + representation->SetCleared(); + EXPECT_TRUE(representation->IsCleared()); + + // We can also begin access with |allow_uncleared| == false. + { + auto scoped_access = representation->BeginScopedAccess( + WGPUTextureUsage_None, + SharedImageRepresentation::AllowUnclearedAccess::kNo); + EXPECT_TRUE(scoped_access); + } + EXPECT_TRUE(representation->IsCleared()); +} + +TEST_F(SharedImageRepresentationTest, OverlayClearing) { + auto representation = manager_.ProduceOverlay(mailbox_, tracker_.get()); + EXPECT_FALSE(representation->IsCleared()); + + // We should not be able to begin read ccess. + { + auto scoped_access = + representation->BeginScopedReadAccess(false /* needs_gl_image */); + EXPECT_FALSE(scoped_access); + } + EXPECT_FALSE(representation->IsCleared()); + + // Clear the SharedImage. + representation->SetCleared(); + EXPECT_TRUE(representation->IsCleared()); + + // We can now begin read access. + { + auto scoped_access = + representation->BeginScopedReadAccess(false /* needs_gl_image */); + EXPECT_TRUE(scoped_access); + } + EXPECT_TRUE(representation->IsCleared()); +} + +} // namespace gpu
diff --git a/gpu/command_buffer/service/test_shared_image_backing.cc b/gpu/command_buffer/service/test_shared_image_backing.cc index 62fac229..3427f341a 100644 --- a/gpu/command_buffer/service/test_shared_image_backing.cc +++ b/gpu/command_buffer/service/test_shared_image_backing.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "gpu/command_buffer/service/test_shared_image_backing.h" +#include "build/build_config.h" #include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/service/shared_context_state.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" @@ -55,6 +56,75 @@ const scoped_refptr<gles2::TexturePassthrough> texture_; }; +class TestSharedImageRepresentationSkia : public SharedImageRepresentationSkia { + public: + TestSharedImageRepresentationSkia(SharedImageManager* manager, + SharedImageBacking* backing, + MemoryTypeTracker* tracker) + : SharedImageRepresentationSkia(manager, backing, tracker) {} + + protected: + sk_sp<SkSurface> BeginWriteAccess( + int final_msaa_count, + const SkSurfaceProps& surface_props, + std::vector<GrBackendSemaphore>* begin_semaphores, + std::vector<GrBackendSemaphore>* end_semaphores) override { + if (!static_cast<TestSharedImageBacking*>(backing())->can_access()) { + return nullptr; + } + return SkSurface::MakeRasterN32Premul(size().width(), size().height()); + } + void EndWriteAccess(sk_sp<SkSurface> surface) override {} + sk_sp<SkPromiseImageTexture> BeginReadAccess( + std::vector<GrBackendSemaphore>* begin_semaphores, + std::vector<GrBackendSemaphore>* end_semaphores) override { + if (!static_cast<TestSharedImageBacking*>(backing())->can_access()) { + return nullptr; + } + GrBackendTexture backend_tex(size().width(), size().height(), + GrMipMapped::kNo, GrMockTextureInfo()); + return SkPromiseImageTexture::Make(backend_tex); + } + void EndReadAccess() override {} +}; + +class TestSharedImageRepresentationDawn : public SharedImageRepresentationDawn { + public: + TestSharedImageRepresentationDawn(SharedImageManager* manager, + SharedImageBacking* backing, + MemoryTypeTracker* tracker) + : SharedImageRepresentationDawn(manager, backing, tracker) {} + + WGPUTexture BeginAccess(WGPUTextureUsage usage) override { + if (!static_cast<TestSharedImageBacking*>(backing())->can_access()) { + return nullptr; + } + + // Return a dummy value. + return reinterpret_cast<WGPUTexture>(203); + } + + void EndAccess() override {} +}; + +class TestSharedImageRepresentationOverlay + : public SharedImageRepresentationOverlay { + public: + TestSharedImageRepresentationOverlay(SharedImageManager* manager, + SharedImageBacking* backing, + MemoryTypeTracker* tracker) + : SharedImageRepresentationOverlay(manager, backing, tracker) {} + + void BeginReadAccess() override {} + void EndReadAccess() override {} + gl::GLImage* GetGLImage() override { return nullptr; } + +#if defined(OS_ANDROID) + void NotifyOverlayPromotion(bool promotion, + const gfx::Rect& bounds) override {} +#endif +}; + } // namespace TestSharedImageBacking::TestSharedImageBacking( @@ -146,4 +216,28 @@ manager, this, tracker, texture_passthrough_); } +std::unique_ptr<SharedImageRepresentationSkia> +TestSharedImageBacking::ProduceSkia( + SharedImageManager* manager, + MemoryTypeTracker* tracker, + scoped_refptr<SharedContextState> context_state) { + return std::make_unique<TestSharedImageRepresentationSkia>(manager, this, + tracker); +} + +std::unique_ptr<SharedImageRepresentationDawn> +TestSharedImageBacking::ProduceDawn(SharedImageManager* manager, + MemoryTypeTracker* tracker, + WGPUDevice device) { + return std::make_unique<TestSharedImageRepresentationDawn>(manager, this, + tracker); +} + +std::unique_ptr<SharedImageRepresentationOverlay> +TestSharedImageBacking::ProduceOverlay(SharedImageManager* manager, + MemoryTypeTracker* tracker) { + return std::make_unique<TestSharedImageRepresentationOverlay>(manager, this, + tracker); +} + } // namespace gpu
diff --git a/gpu/command_buffer/service/test_shared_image_backing.h b/gpu/command_buffer/service/test_shared_image_backing.h index 93540b8..14d3654 100644 --- a/gpu/command_buffer/service/test_shared_image_backing.h +++ b/gpu/command_buffer/service/test_shared_image_backing.h
@@ -52,6 +52,20 @@ ProduceGLTexturePassthrough(SharedImageManager* manager, MemoryTypeTracker* tracker) override; + // ProduceSkia/Dawn/Overlay all create dummy representations that + // don't link up to a real texture. + std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia( + SharedImageManager* manager, + MemoryTypeTracker* tracker, + scoped_refptr<SharedContextState> context_state) override; + std::unique_ptr<SharedImageRepresentationDawn> ProduceDawn( + SharedImageManager* manager, + MemoryTypeTracker* tracker, + WGPUDevice device) override; + std::unique_ptr<SharedImageRepresentationOverlay> ProduceOverlay( + SharedImageManager* manager, + MemoryTypeTracker* tracker) override; + private: const GLuint service_id_ = 0; gles2::Texture* texture_ = nullptr;
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index 4ca4a0a..b889041 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc
@@ -2106,15 +2106,27 @@ } bool TextureRef::BeginAccessSharedImage(GLenum mode) { - shared_image_scoped_access_ = shared_image_->BeginScopedAccess(mode); + // When accessing through TextureManager, we are using legacy GL logic which + // tracks clearning internally. Always allow access to uncleared + // SharedImages. + shared_image_scoped_access_ = shared_image_->BeginScopedAccess( + mode, SharedImageRepresentation::AllowUnclearedAccess::kYes); if (!shared_image_scoped_access_) { return false; } + // After beginning access, the returned gles2::Texture's cleared status + // should match the SharedImage's. + DCHECK_EQ(shared_image_->ClearedRect(), + texture_->GetLevelClearedRect(texture_->target(), 0)); return true; } void TextureRef::EndAccessSharedImage() { shared_image_scoped_access_.reset(); + // After ending access, the SharedImages cleared rect should be synchronized + // with |texture_|'s. + DCHECK_EQ(shared_image_->ClearedRect(), + texture_->GetLevelClearedRect(texture_->target(), 0)); } void TextureRef::ForceContextLost() {
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc index adb00ed1..343088a3 100644 --- a/gpu/command_buffer/service/webgpu_decoder_impl.cc +++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -836,8 +836,12 @@ return error::kInvalidArguments; } + // TODO(cwallez@chromium.org): Handle texture clearing. We should either + // pre-clear textures, or implement a way to detect whether DAWN has cleared + // a texture. crbug.com/1036080 std::unique_ptr<SharedImageRepresentationDawn::ScopedAccess> - shared_image_access = shared_image->BeginScopedAccess(wgpu_usage); + shared_image_access = shared_image->BeginScopedAccess( + wgpu_usage, SharedImageRepresentation::AllowUnclearedAccess::kYes); if (!shared_image_access) { DLOG(ERROR) << "AssociateMailbox: Couldn't begin shared image access"; return error::kInvalidArguments;
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc index 528b8f9..d8c46b23f 100644 --- a/gpu/command_buffer/service/wrapped_sk_image.cc +++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -157,6 +157,7 @@ if (!image_) return false; + SetCleared(); OnWriteSucceeded(); } else { // Initializing to bright green makes it obvious if the pixels are not
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index 0713b65b..aac5672 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -34,7 +34,6 @@ #include "net/ssl/client_cert_identity.h" #include "printing/buildflags/buildflags.h" #include "services/service_manager/sandbox/switches.h" -#include "storage/browser/quota/quota_settings.h" #include "ui/base/ui_base_switches.h" #include "ui/gfx/switches.h" @@ -149,15 +148,6 @@ return new HeadlessQuotaPermissionContext(); } -void HeadlessContentBrowserClient::GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - ::storage::OptionalQuotaSettingsCallback callback) { - ::storage::GetNominalDynamicSettings( - partition->GetPath(), context->IsOffTheRecord(), - ::storage::GetDefaultDeviceInfoHelper(), std::move(callback)); -} - content::GeneratedCodeCacheSettings HeadlessContentBrowserClient::GetGeneratedCodeCacheSettings( content::BrowserContext* context) {
diff --git a/headless/lib/browser/headless_content_browser_client.h b/headless/lib/browser/headless_content_browser_client.h index 82b45cb..51576d29 100644 --- a/headless/lib/browser/headless_content_browser_client.h +++ b/headless/lib/browser/headless_content_browser_client.h
@@ -9,7 +9,6 @@ #include "content/public/browser/content_browser_client.h" #include "headless/public/headless_browser.h" -#include "storage/browser/quota/quota_settings.h" namespace headless { @@ -28,10 +27,6 @@ content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - ::storage::OptionalQuotaSettingsCallback callback) override; content::GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( content::BrowserContext* context) override; #if defined(OS_POSIX) && !defined(OS_MACOSX)
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn index 0c129f5..535e9f31 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn +++ b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn
@@ -4,6 +4,8 @@ source_set("infobar_banner") { sources = [ + "infobar_banner_overlay_responses.cc", + "infobar_banner_overlay_responses.h", "save_password_infobar_banner_overlay.h", "save_password_infobar_banner_overlay.mm", ]
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.cc b/ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.cc new file mode 100644 index 0000000..75603b2 --- /dev/null +++ b/ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.cc
@@ -0,0 +1,31 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h" + +#pragma mark - InfobarBannerMainActionResponse + +OVERLAY_USER_DATA_SETUP_IMPL(InfobarBannerMainActionResponse); + +InfobarBannerMainActionResponse::InfobarBannerMainActionResponse() = default; + +InfobarBannerMainActionResponse::~InfobarBannerMainActionResponse() = default; + +#pragma mark - InfobarBannerShowModalResponse + +OVERLAY_USER_DATA_SETUP_IMPL(InfobarBannerShowModalResponse); + +InfobarBannerShowModalResponse::InfobarBannerShowModalResponse() = default; + +InfobarBannerShowModalResponse::~InfobarBannerShowModalResponse() = default; + +#pragma mark - InfobarBannerCompletionResponse + +OVERLAY_USER_DATA_SETUP_IMPL(InfobarBannerCompletionResponse); + +InfobarBannerCompletionResponse::InfobarBannerCompletionResponse( + bool user_initiated) + : user_initiated_(user_initiated) {} + +InfobarBannerCompletionResponse::~InfobarBannerCompletionResponse() = default;
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h b/ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h new file mode 100644 index 0000000..92f60c9 --- /dev/null +++ b/ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h
@@ -0,0 +1,52 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_RESPONSES_H_ +#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_RESPONSES_H_ + +#include "ios/chrome/browser/overlays/public/overlay_user_data.h" + +// Response info used to create dispatched OverlayResponses that trigger the +// infobar's main action. +class InfobarBannerMainActionResponse + : public OverlayUserData<InfobarBannerMainActionResponse> { + public: + ~InfobarBannerMainActionResponse() override; + + private: + OVERLAY_USER_DATA_SETUP(InfobarBannerMainActionResponse); + InfobarBannerMainActionResponse(); +}; + +// Response info used to create dispatched OverlayResponses that trigger the +// presentation of the infobar's modal. +class InfobarBannerShowModalResponse + : public OverlayUserData<InfobarBannerShowModalResponse> { + public: + ~InfobarBannerShowModalResponse() override; + + private: + OVERLAY_USER_DATA_SETUP(InfobarBannerShowModalResponse); + InfobarBannerShowModalResponse(); +}; + +// Response info used to create completion OverlayResponses for an infobar +// banner OverlayRequest. Executed when the banner is dismissed by the user or +// the request is cancelled. +class InfobarBannerCompletionResponse + : public OverlayUserData<InfobarBannerCompletionResponse> { + public: + ~InfobarBannerCompletionResponse() override; + + // Whether the banner dismissal was user-initiated. + bool user_initiated() const { return user_initiated_; } + + private: + OVERLAY_USER_DATA_SETUP(InfobarBannerCompletionResponse); + explicit InfobarBannerCompletionResponse(bool user_initiated); + + bool user_initiated_ = false; +}; + +#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_RESPONSES_H_
diff --git a/ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h b/ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h index 6042ec1..601ad67 100644 --- a/ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h +++ b/ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h
@@ -5,7 +5,7 @@ #ifndef IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_INFOBAR_BANNER_CONSUMER_H_ #define IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_INFOBAR_BANNER_CONSUMER_H_ -#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> @protocol InfobarBannerConsumer <NSObject>
diff --git a/ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h b/ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h index 33891e9..bddedbc 100644 --- a/ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h +++ b/ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h
@@ -5,7 +5,7 @@ #ifndef IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_INFOBAR_BANNER_DELEGATE_H_ #define IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_INFOBAR_BANNER_DELEGATE_H_ -#import <Foundation/Foundation.h> +#import <UIKit/UIKit.h> // Delegate to handle InfobarBanner actions. @protocol InfobarBannerDelegate
diff --git a/ios/chrome/browser/ui/infobars/banners/test/BUILD.gn b/ios/chrome/browser/ui/infobars/banners/test/BUILD.gn new file mode 100644 index 0000000..dd71e84 --- /dev/null +++ b/ios/chrome/browser/ui/infobars/banners/test/BUILD.gn
@@ -0,0 +1,18 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("test") { + testonly = true + sources = [ + "fake_infobar_banner_consumer.h", + "fake_infobar_banner_consumer.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + "//base", + "//ios/chrome/browser/ui/infobars/banners", + ] +}
diff --git a/ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.h b/ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.h new file mode 100644 index 0000000..2c4421e --- /dev/null +++ b/ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.h
@@ -0,0 +1,21 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_TEST_FAKE_INFOBAR_BANNER_CONSUMER_H_ +#define IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_TEST_FAKE_INFOBAR_BANNER_CONSUMER_H_ + +#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h" + +// Fake InfobarBannerConsumer used in tests. +@interface FakeInfobarBannerConsumer : NSObject <InfobarBannerConsumer> +// Redefine InfobarBannerConsumer properties as readwrite. +@property(nonatomic, copy) NSString* bannerAccessibilityLabel; +@property(nonatomic, copy) NSString* buttonText; +@property(nonatomic, strong) UIImage* iconImage; +@property(nonatomic, assign) BOOL presentsModal; +@property(nonatomic, copy) NSString* titleText; +@property(nonatomic, copy) NSString* subtitleText; +@end + +#endif // IOS_CHROME_BROWSER_UI_INFOBARS_BANNERS_TEST_FAKE_INFOBAR_BANNER_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.mm b/ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.mm new file mode 100644 index 0000000..4fe97c0b --- /dev/null +++ b/ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.mm
@@ -0,0 +1,12 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation FakeInfobarBannerConsumer +@end
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm index a71eea54..f1b1a28 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm
@@ -233,13 +233,8 @@ assertWithMatcher:grey_nil()]; } -// TODO(crbug.com/1037651): Enable for EG2. -#if defined(CHROME_EARL_GREY_2) -#define MAYBE_testCloseNTPWhenSwitching DISABLED_testCloseNTPWhenSwitching -#else -#define MAYBE_testCloseNTPWhenSwitching testCloseNTPWhenSwitching -#endif -- (void)MAYBE_testCloseNTPWhenSwitching { +// TODO(crbug.com/1037651): Test fails. +- (void)DISABLED_testCloseNTPWhenSwitching { // Open the first page. GURL URL1 = self.testServer->GetURL(kPage1URL); [ChromeEarlGrey loadURL:URL1];
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn index 6611898..f2656eb7 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn
@@ -14,3 +14,52 @@ deps = [] } + +source_set("common") { + sources = [ + "infobar_banner_overlay_coordinator.h", + "infobar_banner_overlay_coordinator.mm", + "infobar_banner_overlay_mediator+consumer_support.h", + "infobar_banner_overlay_mediator.h", + "infobar_banner_overlay_mediator.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + "//base", + "//components/infobars/core", + "//ios/chrome/browser/overlays", + "//ios/chrome/browser/overlays/public/common/infobars", + "//ios/chrome/browser/overlays/public/infobar_banner", + "//ios/chrome/browser/ui/infobars/banners", + "//ios/chrome/browser/ui/infobars/banners:public", + "//ios/chrome/browser/ui/overlays:coordinators", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ + "infobar_banner_overlay_mediator_unittest.mm", + ] + + configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + ":common", + "//components/infobars/core", + "//ios/chrome/browser/infobars/test", + "//ios/chrome/browser/overlays", + "//ios/chrome/browser/overlays/public/common/infobars", + "//ios/chrome/browser/overlays/public/infobar_banner", + "//ios/chrome/browser/ui/elements", + "//ios/chrome/browser/ui/infobars/banners", + "//ios/chrome/browser/ui/infobars/banners:public", + "//ios/chrome/browser/ui/infobars/banners/test", + "//ios/chrome/browser/ui/overlays/test", + "//testing/gtest", + "//third_party/ocmock", + "//ui/base", + ] +}
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.h b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.h new file mode 100644 index 0000000..3e3add8 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.h
@@ -0,0 +1,14 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_COORDINATOR_H_ + +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator.h" + +// A coordinator that displays infobar banner UI using OverlayPresenter. +@interface InfobarBannerOverlayCoordinator : OverlayRequestCoordinator +@end + +#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm new file mode 100644 index 0000000..007400de --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm
@@ -0,0 +1,136 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.h" + +#include "base/logging.h" +#include "base/mac/foundation_util.h" +#include "base/no_destructor.h" +#include "ios/chrome/browser/overlays/public/aggregate_overlay_request_support.h" +#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h" +#import "ios/chrome/browser/overlays/public/overlay_request.h" +#import "ios/chrome/browser/overlays/public/overlay_response.h" +#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_accessibility_util.h" +#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.h" +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator+subclassing.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +// Creates a vector containing the OverlayRequestSupports for each +// OverlayRequestMediator class in |mediator_classes| +const std::vector<const OverlayRequestSupport*> GetSupportsForMediatorClasses( + NSArray<Class>* mediator_classes) { + std::vector<const OverlayRequestSupport*> supports(mediator_classes.count); + for (NSUInteger index = 0; index < mediator_classes.count; ++index) { + supports[index] = [mediator_classes[index] requestSupport]; + } + return supports; +} +} // namespace + +@interface InfobarBannerOverlayCoordinator () +// The list of supported mediator classes. +@property(class, nonatomic, readonly) NSArray<Class>* supportedMediatorClasses; +// The banner view being managed by this coordinator. +@property(nonatomic) InfobarBannerViewController* bannerViewController; +@end + +@implementation InfobarBannerOverlayCoordinator + +#pragma mark - Accessors + ++ (NSArray<Class>*)supportedMediatorClasses { + // TODO(crbug.com/1030357): Add more mediator classes here. + return @[]; +} + ++ (const OverlayRequestSupport*)requestSupport { + static base::NoDestructor<AggregateOverlayRequestSupport> kSupport( + GetSupportsForMediatorClasses(self.supportedMediatorClasses)); + return kSupport.get(); +} + +#pragma mark - OverlayRequestCoordinator + +- (void)startAnimated:(BOOL)animated { + if (self.started || !self.request) + return; + // Create the mediator and use it aas the delegate for the banner view. + InfobarOverlayRequestConfig* config = + self.request->GetConfig<InfobarOverlayRequestConfig>(); + InfobarBannerOverlayMediator* mediator = [self newMediator]; + self.bannerViewController = [[InfobarBannerViewController alloc] + initWithDelegate:mediator + presentsModal:config->has_badge() + type:config->infobar_type()]; + mediator.consumer = self.bannerViewController; + self.mediator = mediator; + // Present the banner. + // TODO(crbug.com/1030357): Use custom presentation. + self.bannerViewController.modalPresentationStyle = + UIModalPresentationOverCurrentContext; + self.bannerViewController.modalTransitionStyle = + UIModalTransitionStyleCrossDissolve; + [self.baseViewController presentViewController:self.viewController + animated:animated + completion:^{ + [self finishPresentation]; + }]; + self.started = YES; +} + +- (void)stopAnimated:(BOOL)animated { + if (!self.started) + return; + [self.baseViewController dismissViewControllerAnimated:animated + completion:^{ + [self finishDismissal]; + }]; + self.started = NO; +} + +- (UIViewController*)viewController { + return self.bannerViewController; +} + +#pragma mark - Private + +// Called when the presentation of the banner UI is completed. +- (void)finishPresentation { + // Notify the presentation context that the presentation has finished. This + // is necessary to synchronize OverlayPresenter scheduling logic with the UI + // layer. + self.delegate->OverlayUIDidFinishPresentation(self.request); + UpdateBannerAccessibilityForPresentation(self.baseViewController, + self.viewController.view); +} + +// Called when the dismissal of the banner UI is finished. +- (void)finishDismissal { + self.bannerViewController = nil; + self.mediator = nil; + // Notify the presentation context that the dismissal has finished. This + // is necessary to synchronize OverlayPresenter scheduling logic with the UI + // layer. + self.delegate->OverlayUIDidFinishDismissal(self.request); + UpdateBannerAccessibilityForDismissal(self.baseViewController); +} + +// Creates a mediator instance from the supported mediator class list that +// supports the coordinator's request. +- (InfobarBannerOverlayMediator*)newMediator { + for (Class mediatorClass in [self class].supportedMediatorClasses) { + if (mediatorClass.requestSupport->IsRequestSupported(self.request)) + return [[mediatorClass alloc] initWithRequest:self.request]; + } + NOTREACHED() << "None of the supported mediator classes support request."; + return nil; +} + +@end
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator+consumer_support.h b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator+consumer_support.h new file mode 100644 index 0000000..6561216 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator+consumer_support.h
@@ -0,0 +1,20 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_CONSUMER_SUPPORT_H_ +#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_CONSUMER_SUPPORT_H_ + +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" + +// Category used by the InfobarBannerOverlayMediator superclass in order to +// configure its consumer. +@interface InfobarBannerOverlayMediator (ConsumerSupport) + +// Sets up the banner consumer using the configuration information from the +// mediator's OverlayRequest. Subclasses must implement. +- (void)configureConsumer; + +@end + +#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_CONSUMER_SUPPORT_H_
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h new file mode 100644 index 0000000..db2d895 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h
@@ -0,0 +1,23 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_ +#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_ + +#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_mediator.h" + +@protocol InfobarBannerConsumer; + +// Mediator superclass for configuring InfobarBannerConsumers. +@interface InfobarBannerOverlayMediator + : OverlayRequestMediator <InfobarBannerDelegate> + +// The consumer to be updated by this mediator. Setting to a new value updates +// the new consumer. +@property(nonatomic, weak) id<InfobarBannerConsumer> consumer; + +@end + +#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_OVERLAY_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.mm new file mode 100644 index 0000000..fe4090f2 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.mm
@@ -0,0 +1,116 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" + +#import <UIKit/UIKit.h> + +#include "base/logging.h" +#import "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/overlays/public/common/infobars/infobar_banner_overlay_request_config.h" +#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h" +#include "ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h" +#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h" +#include "ios/chrome/browser/overlays/public/overlay_request.h" +#include "ios/chrome/browser/overlays/public/overlay_response.h" +#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h" +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator+consumer_support.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface InfobarBannerOverlayMediator () +// The banner config from the request. +@property(nonatomic, readonly) InfobarBannerOverlayRequestConfig* config; +@end + +@implementation InfobarBannerOverlayMediator + +- (instancetype)initWithRequest:(OverlayRequest*)request { + if (self = [super initWithRequest:request]) { + DCHECK(request->GetConfig<InfobarBannerOverlayRequestConfig>()); + } + return self; +} + +#pragma mark - Accessors + +- (void)setConsumer:(id<InfobarBannerConsumer>)consumer { + if (_consumer == consumer) + return; + _consumer = consumer; + if (_consumer) + [self configureConsumer]; +} + +- (InfobarBannerOverlayRequestConfig*)config { + return self.request + ? self.request->GetConfig<InfobarBannerOverlayRequestConfig>() + : nullptr; +} + +#pragma mark - InfobarBannerDelegate + +- (void)bannerInfobarButtonWasPressed:(UIButton*)sender { + // Notify the model layer to perform the infobar's main action before + // dismissing the banner. + [self dispatchResponseAndStopOverlay:OverlayResponse::CreateWithInfo< + InfobarBannerMainActionResponse>()]; +} + +- (void)dismissInfobarBannerForUserInteraction:(BOOL)userInitiated { + if (self.request) { + // Add a completion response notifying the requesting code of whether the + // dismissal was user-initiated. Provided to the request's completion + // callbacks that are executed when the UI is finished being dismissed. + self.request->GetCallbackManager()->SetCompletionResponse( + OverlayResponse::CreateWithInfo<InfobarBannerCompletionResponse>( + userInitiated)); + } + [self.delegate stopOverlayForMediator:self]; +} + +- (void)presentInfobarModalFromBanner { + // Notify the model layer to show the infobar modal before dismissing the + // banner. + [self dispatchResponseAndStopOverlay:OverlayResponse::CreateWithInfo< + InfobarBannerShowModalResponse>()]; +} + +- (void)infobarBannerWasDismissed { + // Only needed in legacy implementation. Dismissal completion cleanup occurs + // in InfobarBannerOverlayCoordinator. +} + +#pragma mark - Private + +// Dispatches |response| through the OverlayRequest, then stops the overlay UI. +- (void)dispatchResponseAndStopOverlay: + (std::unique_ptr<OverlayResponse>)response { + if (self.request) + self.request->GetCallbackManager()->DispatchResponse(std::move(response)); + [self.delegate stopOverlayForMediator:self]; +} + +@end + +@implementation InfobarBannerOverlayMediator (ConsumerSupport) + +- (void)configureConsumer { + // TODO(crbug.com/1030357): Add NOTREACHED() here to enforce that subclasses + // implement. + InfobarBannerOverlayRequestConfig* config = self.config; + if (!config) + return; + [self.consumer + setBannerAccessibilityLabel:config->banner_accessibility_label()]; + [self.consumer setButtonText:config->button_text()]; + [self.consumer setIconImage:[UIImage imageNamed:config->icon_image_name()]]; + [self.consumer setPresentsModal:config->presents_modal()]; + [self.consumer setTitleText:config->title_text()]; + [self.consumer setSubtitleText:config->subtitle_text()]; +} + +@end
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator_unittest.mm new file mode 100644 index 0000000..4791ddc --- /dev/null +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator_unittest.mm
@@ -0,0 +1,135 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" + +#import "base/bind.h" +#include "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/overlays/public/common/infobars/infobar_banner_overlay_request_config.h" +#include "ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h" +#include "ios/chrome/browser/overlays/public/overlay_callback_manager.h" +#include "ios/chrome/browser/overlays/public/overlay_request.h" +#include "ios/chrome/browser/overlays/public/overlay_response.h" +#import "ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.h" +#import "testing/gtest_mac.h" +#include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#import "third_party/ocmock/gtest_support.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +NSString* const kBannerAccessibilityLabel = @"a11y label"; +NSString* const kButtonText = @"button text"; +NSString* const kIconImageName = @""; +const bool kPresentsModal(false); +NSString* const kTitleText = @"title text"; +NSString* const kSubtitleText = @"subtitle text"; +} + +// Test fixture for InfobarBannerOverlayMediator. +class InfobarBannerOverlayMediatorTest : public PlatformTest { + public: + InfobarBannerOverlayMediatorTest() + : request_( + OverlayRequest::CreateWithConfig<InfobarBannerOverlayRequestConfig>( + kBannerAccessibilityLabel, + kButtonText, + kIconImageName, + kPresentsModal, + kTitleText, + kSubtitleText)), + delegate_( + OCMStrictProtocolMock(@protocol(OverlayRequestMediatorDelegate))), + mediator_([[InfobarBannerOverlayMediator alloc] + initWithRequest:request_.get()]) { + mediator_.delegate = delegate_; + } + ~InfobarBannerOverlayMediatorTest() override { + EXPECT_OCMOCK_VERIFY(delegate_); + } + + protected: + std::unique_ptr<OverlayRequest> request_; + id<OverlayRequestMediatorDelegate> delegate_ = nil; + InfobarBannerOverlayMediator* mediator_ = nil; +}; + +// Tests that an InfobarBannerOverlayMediator correctly sets up its consumer. +TEST_F(InfobarBannerOverlayMediatorTest, SetUpConsumer) { + FakeInfobarBannerConsumer* consumer = + [[FakeInfobarBannerConsumer alloc] init]; + mediator_.consumer = consumer; + EXPECT_NSEQ(kBannerAccessibilityLabel, consumer.bannerAccessibilityLabel); + EXPECT_NSEQ(kButtonText, consumer.buttonText); + EXPECT_NSEQ(nil, consumer.iconImage); + EXPECT_EQ(kPresentsModal, consumer.presentsModal); + EXPECT_NSEQ(kTitleText, consumer.titleText); + EXPECT_NSEQ(kSubtitleText, consumer.subtitleText); +} + +// Tests that an InfobarBannerOverlayMediator correctly dispatches a response +// for confirm button taps before stopping itself. +TEST_F(InfobarBannerOverlayMediatorTest, ConfirmButtonTapped) { + __block bool confirm_button_tapped = false; + void (^confirm_button_tapped_callback)(OverlayResponse* response) = + ^(OverlayResponse* response) { + confirm_button_tapped = true; + }; + request_->GetCallbackManager() + ->AddDispatchCallback<InfobarBannerMainActionResponse>( + base::BindRepeating(confirm_button_tapped_callback)); + ASSERT_FALSE(confirm_button_tapped); + + // Notify the mediator of the button tap via its InfobarBannerDelegate + // implementation and verify that the confirm button callback was executed and + // that the mediator's delegate was instructed to stop. + OCMExpect([delegate_ stopOverlayForMediator:mediator_]); + [mediator_ bannerInfobarButtonWasPressed:nil]; + EXPECT_TRUE(confirm_button_tapped); +} + +// Tests that an InfobarBannerOverlayMediator correctly dispatches a response +// for modal button taps before stopping itself. +TEST_F(InfobarBannerOverlayMediatorTest, ModalButtonTapped) { + __block bool modal_button_tapped = false; + void (^modal_button_tapped_callback)(OverlayResponse* response) = + ^(OverlayResponse* response) { + modal_button_tapped = true; + }; + request_->GetCallbackManager() + ->AddDispatchCallback<InfobarBannerShowModalResponse>( + base::BindRepeating(modal_button_tapped_callback)); + ASSERT_FALSE(modal_button_tapped); + + // Notify the mediator of the button tap via its InfobarBannerDelegate + // implementation and verify that the modal button callback was executed and + // that the mediator's delegate was instructed to stop. + OCMExpect([delegate_ stopOverlayForMediator:mediator_]); + [mediator_ presentInfobarModalFromBanner]; + EXPECT_TRUE(modal_button_tapped); +} + +// Tests that an InfobarBannerOverlayMediator correctly sets the completion +// response for user-initiated dismissals triggered by the banner UI. +TEST_F(InfobarBannerOverlayMediatorTest, UserInitiatedDismissal) { + __block bool user_initiated = false; + void (^completion_callback)(OverlayResponse* response) = + ^(OverlayResponse* response) { + user_initiated = true; + }; + request_->GetCallbackManager()->AddCompletionCallback( + base::BindOnce(completion_callback)); + ASSERT_FALSE(user_initiated); + + // Notify the mediator of the dismissal via its InfobarBannerDelegate + // implementation and verify that the completion callback was executed with + // the correct info and that the mediator's delegate was instructed to stop. + OCMExpect([delegate_ stopOverlayForMediator:mediator_]); + [mediator_ dismissInfobarBannerForUserInteraction:YES]; + request_ = nullptr; + EXPECT_TRUE(user_initiated); +}
diff --git a/ios/chrome/browser/ui/settings/google_services/BUILD.gn b/ios/chrome/browser/ui/settings/google_services/BUILD.gn index 5aeff8c..e5102dfc 100644 --- a/ios/chrome/browser/ui/settings/google_services/BUILD.gn +++ b/ios/chrome/browser/ui/settings/google_services/BUILD.gn
@@ -34,6 +34,7 @@ "manage_sync_settings_view_controller_model_delegate.h", ] deps = [ + ":constants", "resources:google_services_enterprise", "resources:google_services_sync_error", "//base", @@ -78,9 +79,6 @@ "//ios/public/provider/chrome/browser/signin", "//ui/base", ] - public_deps = [ - ":constants", - ] allow_circular_includes_from = [ "//ios/chrome/browser/ui/signin_interaction" ] } @@ -109,7 +107,7 @@ "google_services_settings_egtest.mm", ] deps = [ - ":google_services", + ":constants", ":test_support", "//ios/chrome/app/strings", "//ios/chrome/browser/tabs",
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.h b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.h index 936281a..0e40217 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.h +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.h
@@ -5,7 +5,6 @@ #ifndef IOS_CHROME_BROWSER_UI_SETTINGS_GOOGLE_SERVICES_ACCOUNTS_TABLE_VIEW_CONTROLLER_H_ #define IOS_CHROME_BROWSER_UI_SETTINGS_GOOGLE_SERVICES_ACCOUNTS_TABLE_VIEW_CONTROLLER_H_ -#import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller_constants.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm index 5da7c23..c63feb30 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
@@ -28,6 +28,7 @@ #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/icons/chrome_icon.h" #import "ios/chrome/browser/ui/settings/cells/settings_text_item.h" +#import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller_constants.h" #import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h" #import "ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_detail_text_item.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h index 0925ba8..20cc76da 100644 --- a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h +++ b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h
@@ -7,7 +7,6 @@ #import "base/ios/block_types.h" #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" -#import "ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_constants.h" @class AdvancedSigninSettingsCoordinator; @protocol ApplicationCommands;
diff --git a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm index cf90c6f..28cd527 100644 --- a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm +++ b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm
@@ -20,6 +20,7 @@ #include "ios/chrome/browser/sync/sync_setup_service_factory.h" #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" #import "ios/chrome/browser/ui/icons/chrome_icon.h" +#import "ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_constants.h" #import "ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_mode.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.h b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.h index abce854..5b52197 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.h +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.h
@@ -7,7 +7,6 @@ #import <UIKit/UIKit.h> -#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_constants.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_consumer.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_mode.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_service_delegate.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm index 36bc700..ebf6cd9b 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
@@ -26,6 +26,7 @@ #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_command_handler.h" +#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_constants.h" #import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h" #import "ios/chrome/browser/ui/settings/utils/observable_boolean.h" #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller.h b/ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller.h index 13a68dd..95cb9d6 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller.h +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller.h
@@ -7,7 +7,6 @@ #import "ios/chrome/browser/ui/settings/settings_root_table_view_controller.h" -#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_constants.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_consumer.h" @class GoogleServicesSettingsViewController;
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller.mm index 0711791..f534e29 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller.mm
@@ -7,6 +7,7 @@ #include "base/mac/foundation_util.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h" #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" +#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_constants.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_service_delegate.h" #import "ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller_model_delegate.h" #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.h b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.h index 1a8347bd..fe34aa6e 100644 --- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.h +++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.h
@@ -7,7 +7,6 @@ #import <UIKit/UIKit.h> -#import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_constants.h" #import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_service_delegate.h" #import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_view_controller_model_delegate.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm index 4721d2f..12c0095 100644 --- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm +++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
@@ -16,6 +16,7 @@ #import "ios/chrome/browser/ui/list_model/list_model.h" #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" #import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_command_handler.h" +#import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_constants.h" #import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_consumer.h" #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_table_view_controller.mm index 918570d..34e0aab 100644 --- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_table_view_controller.mm
@@ -7,6 +7,7 @@ #include "base/mac/foundation_util.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_cell.h" #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h" +#import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_constants.h" #import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_service_delegate.h" #import "ios/chrome/browser/ui/settings/google_services/manage_sync_settings_view_controller_model_delegate.h" #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/settings/settings_egtest.mm b/ios/chrome/browser/ui/settings/settings_egtest.mm index 1decdb1..1ef8c11 100644 --- a/ios/chrome/browser/ui/settings/settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/settings_egtest.mm
@@ -351,14 +351,10 @@ // Tests that clearing the cookies through the UI does clear all of them. Use a // local server to navigate to a page that sets then tests a cookie, and then // clears the cookie and tests it is not set. -#if defined(CHROME_EARL_GREY_1) -#define MAYBE_testClearCookies testClearCookies -#elif defined(CHROME_EARL_GREY_2) -#define MAYBE_testClearCookies DISABLED_testClearCookies -#endif // TODO(crbug.com/1036133): [ChromeEarlGrey cookies] does not work correctly in // this test. -- (void)MAYBE_testClearCookies { +// TODO(crbug.com/1038398): This test crashes flakily. +- (void)DISABLED_testClearCookies { // Creates a map of canned responses and set up the test HTML server. std::map<GURL, std::pair<std::string, std::string>> response;
diff --git a/ios/chrome/browser/ui/signin_interaction/BUILD.gn b/ios/chrome/browser/ui/signin_interaction/BUILD.gn index c4300e9..48a65ff 100644 --- a/ios/chrome/browser/ui/signin_interaction/BUILD.gn +++ b/ios/chrome/browser/ui/signin_interaction/BUILD.gn
@@ -97,7 +97,7 @@ "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant", "//ios/chrome/browser/ui/recent_tabs:recent_tabs_ui_constants", "//ios/chrome/browser/ui/settings", - "//ios/chrome/browser/ui/settings/google_services", + "//ios/chrome/browser/ui/settings/google_services:constants", "//ios/chrome/browser/ui/table_view/cells", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index d31098b4..f8bfa17 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -266,6 +266,7 @@ "//ios/chrome/browser/ui/open_in:unit_tests", "//ios/chrome/browser/ui/overlays:unit_tests", "//ios/chrome/browser/ui/overlays/common/alerts:unit_tests", + "//ios/chrome/browser/ui/overlays/infobar_banner:unit_tests", "//ios/chrome/browser/ui/overlays/web_content_area/app_launcher:unit_tests", "//ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs:unit_tests", "//ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs:unit_tests",
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 67de4f91..45e14d40 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -262,6 +262,7 @@ "//ios/chrome/browser/ui/safe_mode:test_support", "//ios/chrome/browser/ui/settings:constants", "//ios/chrome/browser/ui/settings:settings", + "//ios/chrome/browser/ui/settings:settings_root", "//ios/chrome/browser/ui/settings:settings_root_constants", "//ios/chrome/browser/ui/settings/autofill", "//ios/chrome/browser/ui/settings/autofill:constants", @@ -269,7 +270,7 @@ "//ios/chrome/browser/ui/settings/cells", "//ios/chrome/browser/ui/settings/clear_browsing_data", "//ios/chrome/browser/ui/settings/credit_card_scanner", - "//ios/chrome/browser/ui/settings/google_services", + "//ios/chrome/browser/ui/settings/google_services:constants", "//ios/chrome/browser/ui/settings/password:eg_test_support", "//ios/chrome/browser/ui/settings/password:password_constants", "//ios/chrome/browser/ui/settings/sync", @@ -410,6 +411,7 @@ "//ios/chrome/browser/ui/settings:constants", "//ios/chrome/browser/ui/settings:eg_app_support+eg2", "//ios/chrome/browser/ui/settings:settings", + "//ios/chrome/browser/ui/settings:settings_root", "//ios/chrome/browser/ui/settings:settings_root_constants", "//ios/chrome/browser/ui/settings/autofill", "//ios/chrome/browser/ui/settings/autofill:constants", @@ -417,8 +419,7 @@ "//ios/chrome/browser/ui/settings/cells", "//ios/chrome/browser/ui/settings/clear_browsing_data", "//ios/chrome/browser/ui/settings/credit_card_scanner", - "//ios/chrome/browser/ui/settings/google_services", - "//ios/chrome/browser/ui/settings/google_services:eg_app_support+eg2", + "//ios/chrome/browser/ui/settings/google_services:constants", "//ios/chrome/browser/ui/settings/password:eg_app_support+eg2", "//ios/chrome/browser/ui/settings/password:password_constants", "//ios/chrome/browser/ui/settings/sync",
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm index 94e8f89e..8b79eea 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -42,12 +42,13 @@ #import "ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_collection_view_controller.h" #import "ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_ui_constants.h" #import "ios/chrome/browser/ui/settings/credit_card_scanner/credit_card_scanner_view_controller.h" -#import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.h" -#import "ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h" -#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_view_controller.h" +#import "ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller_constants.h" +#import "ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_constants.h" +#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_constants.h" #import "ios/chrome/browser/ui/settings/import_data_table_view_controller.h" #import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h" #import "ios/chrome/browser/ui/settings/privacy_table_view_controller.h" +#import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/settings_root_table_constants.h" #import "ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h" #import "ios/chrome/browser/ui/tab_grid/grid/grid_constants.h"
diff --git a/net/dns/dns_util.cc b/net/dns/dns_util.cc index dd010fbf..20a2128 100644 --- a/net/dns/dns_util.cc +++ b/net/dns/dns_util.cc
@@ -477,6 +477,20 @@ return entries[0]->provider; } +std::map<std::string, std::string> GetDohServerTemplatesListForTesting() { + const std::vector<DohUpgradeEntry>& upgradable_servers = GetDohUpgradeList(); + std::map<std::string, std::string> server_templates; + for (const auto& upgrade_entry : upgradable_servers) { + auto return_val = server_templates.insert( + std::make_pair(upgrade_entry.provider, + upgrade_entry.dns_over_https_config.server_template)); + // Check that the new element was inserted. The map's key is the DoH + // provider name which should be unique. + DCHECK(return_val.second); + } + return server_templates; +} + std::string SecureDnsModeToString( const DnsConfig::SecureDnsMode secure_dns_mode) { switch (secure_dns_mode) {
diff --git a/net/dns/dns_util.h b/net/dns/dns_util.h index f5c7c44..18fbddc 100644 --- a/net/dns/dns_util.h +++ b/net/dns/dns_util.h
@@ -141,6 +141,11 @@ NET_EXPORT_PRIVATE std::string SecureDnsModeToString( const DnsConfig::SecureDnsMode secure_dns_mode); +// Returns a map of DoH provider names and server templates +// from the auto-upgrade list for testing. +NET_EXPORT_PRIVATE std::map<std::string, std::string> +GetDohServerTemplatesListForTesting(); + } // namespace net #endif // NET_DNS_DNS_UTIL_H_
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc index 5d9a913..795386a 100644 --- a/net/dns/host_resolver_manager.cc +++ b/net/dns/host_resolver_manager.cc
@@ -600,7 +600,9 @@ results_ = std::move(results); } - void set_error_info(int error) { error_info_ = ResolveErrorInfo(error); } + void set_error_info(int error, bool is_secure_network_error) { + error_info_ = ResolveErrorInfo(error, is_secure_network_error); + } void set_stale_info(HostCache::EntryStaleness stale_info) { // Should only be called at most once and before request is marked @@ -634,9 +636,10 @@ } // Cleans up Job assignment, marks request completed, and calls the completion - // callback. - void OnJobCompleted(Job* job, int error) { - set_error_info(error); + // callback. |is_secure_network_error| indicates whether |error| came from a + // secure DNS lookup. + void OnJobCompleted(Job* job, int error, bool is_secure_network_error) { + set_error_info(error, is_secure_network_error); DCHECK_EQ(job_, job); job_ = nullptr; @@ -2591,7 +2594,9 @@ req->set_results( results.CopyWithDefaultPort(req->request_host().port())); } - req->OnJobCompleted(this, results.error()); + req->OnJobCompleted( + this, results.error(), + secure && results.error() != OK /* is_secure_network_error */); // Check if the resolver was destroyed as a result of running the // callback. If it was, we could continue, but we choose to bail. @@ -2985,7 +2990,8 @@ request->set_stale_info(std::move(stale_info).value()); RecordTotalTime(request->parameters().is_speculative, true /* from_cache */, effective_secure_dns_mode, base::TimeDelta()); - request->set_error_info(results.error()); + request->set_error_info(results.error(), + false /* is_secure_network_error */); return results.error(); }
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc index 7d465e2..73a6844 100644 --- a/net/dns/host_resolver_manager_unittest.cc +++ b/net/dns/host_resolver_manager_unittest.cc
@@ -5300,6 +5300,8 @@ HostPortPair("automatic", 80), NetworkIsolationKey(), NetLogWithSource(), base::nullopt, request_context_.get(), host_cache_.get())); ASSERT_THAT(response_secure.result_error(), IsOk()); + EXPECT_FALSE( + response_secure.request()->GetResolveErrorInfo().is_secure_network_error); EXPECT_THAT( response_secure.request()->GetAddressResults().value().endpoints(), testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), @@ -5318,6 +5320,9 @@ NetLogWithSource(), base::nullopt, request_context_.get(), host_cache_.get())); ASSERT_THAT(response_insecure.result_error(), IsOk()); + EXPECT_FALSE(response_insecure.request() + ->GetResolveErrorInfo() + .is_secure_network_error); EXPECT_THAT( response_insecure.request()->GetAddressResults().value().endpoints(), testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), @@ -5360,6 +5365,9 @@ NetLogWithSource(), base::nullopt, request_context_.get(), host_cache_.get())); EXPECT_THAT(response_secure_cached.result_error(), IsOk()); + EXPECT_FALSE(response_secure_cached.request() + ->GetResolveErrorInfo() + .is_secure_network_error); EXPECT_THAT( response_secure_cached.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(kExpectedSecureIP)); @@ -5387,6 +5395,9 @@ NetLogWithSource(), base::nullopt, request_context_.get(), host_cache_.get())); EXPECT_THAT(response_insecure_cached.result_error(), IsOk()); + EXPECT_FALSE(response_insecure_cached.request() + ->GetResolveErrorInfo() + .is_secure_network_error); EXPECT_THAT(response_insecure_cached.request() ->GetAddressResults() .value() @@ -5473,6 +5484,9 @@ HostPortPair("automatic", 80), NetworkIsolationKey(), NetLogWithSource(), base::nullopt, request_context_.get(), host_cache_.get())); ASSERT_THAT(response_automatic.result_error(), IsOk()); + EXPECT_FALSE(response_automatic.request() + ->GetResolveErrorInfo() + .is_secure_network_error); EXPECT_THAT( response_automatic.request()->GetAddressResults().value().endpoints(), testing::UnorderedElementsAre(CreateExpected("127.0.0.1", 80), @@ -5505,6 +5519,8 @@ HostPortPair("secure", 80), NetworkIsolationKey(), NetLogWithSource(), base::nullopt, request_context_.get(), host_cache_.get())); ASSERT_THAT(response_secure.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); + EXPECT_FALSE( + response_secure.request()->GetResolveErrorInfo().is_secure_network_error); HostCache::Key secure_key = HostCache::Key( "secure", DnsQueryType::UNSPECIFIED, 0 /* host_resolver_flags */, @@ -5546,6 +5562,8 @@ NetLogWithSource(), stale_allowed_parameters, request_context_.get(), host_cache_.get())); EXPECT_THAT(response_stale.result_error(), IsOk()); + EXPECT_FALSE( + response_stale.request()->GetResolveErrorInfo().is_secure_network_error); EXPECT_THAT(response_stale.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(kExpectedStaleIP)); EXPECT_TRUE(response_stale.request()->GetStaleInfo()->is_stale()); @@ -5652,6 +5670,9 @@ host_cache_.get())); proc_->SignalMultiple(1u); ASSERT_THAT(response_insecure.result_error(), IsOk()); + EXPECT_FALSE(response_insecure.request() + ->GetResolveErrorInfo() + .is_secure_network_error); EXPECT_THAT( response_insecure.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(CreateExpected("192.168.1.100", 80))); @@ -5675,6 +5696,9 @@ NetLogWithSource(), base::nullopt, request_context_.get(), host_cache_.get())); EXPECT_THAT(response_insecure_cached.result_error(), IsOk()); + EXPECT_FALSE(response_insecure_cached.request() + ->GetResolveErrorInfo() + .is_secure_network_error); EXPECT_THAT(response_insecure_cached.request() ->GetAddressResults() .value() @@ -5696,6 +5720,8 @@ HostPortPair("secure", 80), NetworkIsolationKey(), NetLogWithSource(), base::nullopt, request_context_.get(), host_cache_.get())); ASSERT_THAT(response_secure.result_error(), IsOk()); + EXPECT_FALSE( + response_secure.request()->GetResolveErrorInfo().is_secure_network_error); HostCache::Key secure_key = HostCache::Key( "secure", DnsQueryType::UNSPECIFIED, 0 /* host_resolver_flags */, HostResolverSource::ANY, NetworkIsolationKey()); @@ -5707,6 +5733,9 @@ HostPortPair("ok", 80), NetworkIsolationKey(), NetLogWithSource(), base::nullopt, request_context_.get(), host_cache_.get())); ASSERT_THAT(response_insecure.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); + EXPECT_TRUE(response_insecure.request() + ->GetResolveErrorInfo() + .is_secure_network_error); HostCache::Key insecure_key = HostCache::Key( "ok", DnsQueryType::UNSPECIFIED, 0 /* host_resolver_flags */, HostResolverSource::ANY, NetworkIsolationKey()); @@ -5719,6 +5748,8 @@ base::nullopt, request_context_.get(), host_cache_.get())); proc_->SignalMultiple(1u); EXPECT_THAT(response_proc.result_error(), IsError(ERR_NAME_NOT_RESOLVED)); + EXPECT_TRUE( + response_proc.request()->GetResolveErrorInfo().is_secure_network_error); } TEST_F(HostResolverManagerDnsTest, SecureDnsMode_Secure_InsecureAsyncDisabled) { @@ -5768,6 +5799,9 @@ source_none_parameters, request_context_.get(), host_cache_.get())); EXPECT_TRUE(cache_miss_request.complete()); EXPECT_THAT(cache_miss_request.result_error(), IsError(ERR_DNS_CACHE_MISS)); + EXPECT_FALSE(cache_miss_request.request() + ->GetResolveErrorInfo() + .is_secure_network_error); EXPECT_FALSE(cache_miss_request.request()->GetAddressResults()); EXPECT_FALSE(cache_miss_request.request()->GetStaleInfo()); } @@ -5796,6 +5830,8 @@ base::nullopt, request_context_.get(), host_cache_.get())); EXPECT_TRUE(response_cached.complete()); EXPECT_THAT(response_cached.result_error(), IsOk()); + EXPECT_FALSE( + response_cached.request()->GetResolveErrorInfo().is_secure_network_error); EXPECT_THAT( response_cached.request()->GetAddressResults().value().endpoints(), testing::ElementsAre(kExpectedSecureIP));
diff --git a/net/dns/public/resolve_error_info.cc b/net/dns/public/resolve_error_info.cc index 9a1b499..f61c3a4 100644 --- a/net/dns/public/resolve_error_info.cc +++ b/net/dns/public/resolve_error_info.cc
@@ -8,8 +8,10 @@ ResolveErrorInfo::ResolveErrorInfo() {} -ResolveErrorInfo::ResolveErrorInfo(int resolve_error) { - error = resolve_error; +ResolveErrorInfo::ResolveErrorInfo(int resolve_error, + bool is_secure_network_error) + : error(resolve_error), is_secure_network_error(is_secure_network_error) { + DCHECK(!(is_secure_network_error && resolve_error == net::OK)); } ResolveErrorInfo::ResolveErrorInfo(const ResolveErrorInfo& resolve_error_info) = @@ -24,7 +26,8 @@ default; bool ResolveErrorInfo::operator==(const ResolveErrorInfo& other) const { - return error == other.error; + return error == other.error && + is_secure_network_error == other.is_secure_network_error; } bool ResolveErrorInfo::operator!=(const ResolveErrorInfo& other) const {
diff --git a/net/dns/public/resolve_error_info.h b/net/dns/public/resolve_error_info.h index b108fa79..07274f67 100644 --- a/net/dns/public/resolve_error_info.h +++ b/net/dns/public/resolve_error_info.h
@@ -13,7 +13,7 @@ // Host resolution error info. struct NET_EXPORT ResolveErrorInfo { ResolveErrorInfo(); - ResolveErrorInfo(int resolve_error); + ResolveErrorInfo(int resolve_error, bool is_secure_network_error = false); ResolveErrorInfo(const ResolveErrorInfo& resolve_error_info); ResolveErrorInfo(ResolveErrorInfo&& other); @@ -24,6 +24,12 @@ bool operator!=(const ResolveErrorInfo& other) const; int error = net::OK; + // Whether |error| resulted from a DNS-over-HTTPS lookup. If an answer was + // obtained from the cache this field will be false, regardless of whether the + // answer was originally obtained securely, because this field is intended to + // identify secure DNS *network* failures. This field will also always be + // false if |error| is net::OK. + bool is_secure_network_error = false; }; } // namespace net
diff --git a/net/url_request/http_with_dns_over_https_unittest.cc b/net/url_request/http_with_dns_over_https_unittest.cc index d1ff9f8..d65a847 100644 --- a/net/url_request/http_with_dns_over_https_unittest.cc +++ b/net/url_request/http_with_dns_over_https_unittest.cc
@@ -287,5 +287,37 @@ EXPECT_EQ(d.data_received(), kTestBody); } +TEST_F(HttpWithDnsOverHttpsTest, EndToEndFail) { + // Shutdown the DoH server so that all DoH requests are refused. + EXPECT_TRUE(doh_server_.ShutdownAndWaitUntilComplete()); + + // Make a request that will trigger a DoH query. + TestDelegate d; + GURL main_url = test_server_.GetURL("fail.example.com", "/test"); + std::unique_ptr<URLRequest> req(context()->CreateRequest( + main_url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); + req->Start(); + base::RunLoop().Run(); + EXPECT_TRUE(test_server_.ShutdownAndWaitUntilComplete()); + + // The two DoH lookups for "fail.example.com" (both A and AAAA + // records are queried) should both have failed to reach the DoH server + // since it was not running. + EXPECT_EQ(doh_queries_served_, 0u); + // The requests to the DoH server are pooled, so there should only be one + // insecure lookup for the DoH server hostname. + EXPECT_EQ(host_resolver_proc_->insecure_queries_served(), 1u); + // No HTTPS connection to the test server will be attempted due to the + // host resolution error. + EXPECT_EQ(test_https_requests_served_, 0u); + + EXPECT_TRUE(d.response_completed()); + EXPECT_EQ(d.request_status(), net::ERR_CONNECTION_REFUSED); + + const auto& resolve_error_info = req->response_info().resolve_error_info; + EXPECT_TRUE(resolve_error_info.is_secure_network_error); + EXPECT_EQ(resolve_error_info.error, net::ERR_CONNECTION_REFUSED); +} + } // namespace } // namespace net
diff --git a/services/network/public/cpp/host_resolver_mojom_traits.cc b/services/network/public/cpp/host_resolver_mojom_traits.cc index 6211ddc..f5303393 100644 --- a/services/network/public/cpp/host_resolver_mojom_traits.cc +++ b/services/network/public/cpp/host_resolver_mojom_traits.cc
@@ -422,11 +422,16 @@ return false; } +// static bool StructTraits< network::mojom::ResolveErrorInfoDataView, net::ResolveErrorInfo>::Read(network::mojom::ResolveErrorInfoDataView data, net::ResolveErrorInfo* out) { - *out = net::ResolveErrorInfo(data.error()); + // There should not be a secure network error if the error code indicates no + // error. + if (data.error() == net::OK && data.is_secure_network_error()) + return false; + *out = net::ResolveErrorInfo(data.error(), data.is_secure_network_error()); return true; }
diff --git a/services/network/public/cpp/host_resolver_mojom_traits.h b/services/network/public/cpp/host_resolver_mojom_traits.h index 80e1267..084ca52 100644 --- a/services/network/public/cpp/host_resolver_mojom_traits.h +++ b/services/network/public/cpp/host_resolver_mojom_traits.h
@@ -131,6 +131,11 @@ return resolve_error_info.error; } + static bool is_secure_network_error( + net::ResolveErrorInfo resolve_error_info) { + return resolve_error_info.is_secure_network_error; + } + static bool Read(network::mojom::ResolveErrorInfoDataView data, net::ResolveErrorInfo* out); };
diff --git a/services/network/public/cpp/net_ipc_param_traits.cc b/services/network/public/cpp/net_ipc_param_traits.cc index edd0c305..8e79469 100644 --- a/services/network/public/cpp/net_ipc_param_traits.cc +++ b/services/network/public/cpp/net_ipc_param_traits.cc
@@ -317,11 +317,13 @@ void ParamTraits<net::ResolveErrorInfo>::Write(base::Pickle* m, const param_type& p) { WriteParam(m, p.error); + WriteParam(m, p.is_secure_network_error); } bool ParamTraits<net::ResolveErrorInfo>::Read(const base::Pickle* m, base::PickleIterator* iter, param_type* r) { - return ReadParam(m, iter, &r->error); + return ReadParam(m, iter, &r->error) && + ReadParam(m, iter, &r->is_secure_network_error); } void ParamTraits<net::ResolveErrorInfo>::Log(const param_type& p, std::string* l) {
diff --git a/services/network/public/mojom/host_resolver.mojom b/services/network/public/mojom/host_resolver.mojom index 04fa980..2648dda 100644 --- a/services/network/public/mojom/host_resolver.mojom +++ b/services/network/public/mojom/host_resolver.mojom
@@ -117,6 +117,11 @@ // Underlying network error code. See net/base/net_error_list.h for error // descriptions. int32 error; + + // Whether |error| came from a DNS-over-HTTPS lookup. This will be false if + // the answer was obtained from the cache or if |error| is net::OK since this + // field is intended to identify secure DNS *network* failures. + bool is_secure_network_error = false; }; // Control handle used to control outstanding NetworkContext::ResolveHost
diff --git a/services/network/public/mojom/network_service_test.mojom b/services/network/public/mojom/network_service_test.mojom index 9d7686e..bed4308a8 100644 --- a/services/network/public/mojom/network_service_test.mojom +++ b/services/network/public/mojom/network_service_test.mojom
@@ -74,6 +74,12 @@ [Sync] SetTransportSecurityStateSource(uint16 reporting_port) => (); + // Allow host resolutions to reach the network. Since going to the network + // can be a source of flakiness, this should only be called in tests that + // can tolerate this, such as those run manually or on an FYI bot. + [Sync] + SetAllowNetworkAccessToHostResolutions() => (); + // Causes the next host resolve to the given hostname to crash the process. CrashOnResolveHost(string host);
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index 3be8788..a82660e 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -55,7 +55,8 @@ "-v", "--browser=android-chrome-bundle", "--upload-results", - "--test-shard-map-filename=android-pixel2-perf-aab-fyi_map.json" + "--test-shard-map-filename=android-pixel2-perf-aab-fyi_map.json", + "--run-ref-build" ], "isolate_name": "performance_test_suite", "merge": {
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index 3fd405af..f78d704 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -2188,6 +2188,45 @@ { "args": [ "--gtest-benchmark-name", + "dawn_perf_tests", + "--shard-timeout=300" + ], + "isolate_name": "dawn_perf_tests", + "merge": { + "script": "//tools/perf/process_perf_results.py" + }, + "name": "dawn_perf_tests", + "override_compile_targets": [ + "dawn_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:5912-23.20.16.4877", + "os": "Windows-10-16299.309", + "pool": "chrome.tests.perf", + "synthetic_product_name": "OptiPlex 7050 (Dell Inc.)" + } + ], + "expiration": 7200, + "hard_timeout": 19800, + "ignore_task_failure": false, + "io_timeout": 19800, + "shards": 1 + }, + "trigger_script": { + "args": [ + "--multiple-dimension-script-verbose", + "True" + ], + "requires_simultaneous_shard_dispatch": true, + "script": "//testing/trigger_scripts/perf_device_trigger.py" + } + }, + { + "args": [ + "--gtest-benchmark-name", "media_perftests" ], "isolate_name": "media_perftests",
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py index 5f981f1..11c6fa2 100755 --- a/testing/scripts/run_performance_tests.py +++ b/testing/scripts/run_performance_tests.py
@@ -162,10 +162,12 @@ class GtestCommandGenerator(object): - def __init__(self, options, override_executable=None, additional_flags=None): + def __init__(self, options, override_executable=None, additional_flags=None, + ignore_shard_env_vars=False): self._options = options self._override_executable = override_executable self._additional_flags = additional_flags or [] + self._ignore_shard_env_vars = ignore_shard_env_vars def generate(self, output_dir): """Generate the command to run to start the gtest perf test. @@ -178,6 +180,7 @@ self._generate_repeat_args() + self._generate_also_run_disabled_tests_args() + self._generate_output_args(output_dir) + + self._generate_shard_args() + self._get_passthrough_args() ) @@ -196,6 +199,17 @@ def _get_passthrough_args(self): return self._options.passthrough_args + self._additional_flags + def _generate_shard_args(self): + """Teach the gtest to ignore the environment variables. + + GTEST_SHARD_INDEX and GTEST_TOTAL_SHARDS will confuse the gtest + and convince it to only run some of its tests. Instead run all + of them. + """ + if self._ignore_shard_env_vars: + return ['--test-launcher-total-shards=1', '--test-launcher-shard-index=0'] + return [] + def _generate_filter_args(self): if self._options.isolated_script_test_filter: filter_list = common.extract_filter_list( @@ -377,7 +391,12 @@ def _generate_reference_build_args(self): if self._is_reference: - return ['--browser=reference', + reference_browser_flag = '--browser=reference' + # TODO(crbug.com/1038137): Make the logic generic once more reference + # settings are added + if '--browser=android-chrome-bundle' in self._get_passthrough_args(): + reference_browser_flag = '--browser=reference-android-chrome-bundle' + return [reference_browser_flag, '--max-failures=5'] return [] @@ -618,7 +637,7 @@ additional_flags = configuration['arguments'] command_generator = GtestCommandGenerator( options, override_executable=configuration['path'], - additional_flags=additional_flags) + additional_flags=additional_flags, ignore_shard_env_vars=True) output_paths = OutputFilePaths(isolated_out_dir, name).SetUp() print('\n### {folder} ###'.format(folder=name)) return_code = execute_gtest_perf_test(
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py b/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py index 85d59f31..d22d56f 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py
@@ -203,7 +203,7 @@ if default_value.is_type_compatible_with(member_type): idl_type = member_type break - assert False + assert default_value.is_type_compatible_with(idl_type) type_info = blink_type_info(idl_type) is_initializer_lightweight = False
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py b/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py index f218b33..6e84e8a6 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py
@@ -144,7 +144,7 @@ return uniq_terms -def expr_from_exposure(exposure, in_global=None): +def expr_from_exposure(exposure, global_names=None): """ Args: exposure: web_idl.Exposure @@ -152,7 +152,9 @@ supposed to be / represent. """ assert isinstance(exposure, web_idl.Exposure) - assert in_global is None or isinstance(in_global, str) + assert (global_names is None + or (isinstance(global_names, (list, tuple)) + and all(isinstance(name, str) for name in global_names))) def ref_enabled(feature): return _Expr("RuntimeEnabledFeatures::{}Enabled()".format(feature)) @@ -172,16 +174,10 @@ "Worker": "IsWorkerGlobalScope", "Worklet": "IsWorkletGlobalScope", } - in_globals = set() - if in_global: - in_globals.add(in_global) - for category_name in ("Worker", "Worklet"): - if in_global.endswith(category_name): - in_globals.add(category_name) exposed_terms = [] for entry in exposure.global_names_and_features: terms = [] - if entry.global_name not in in_globals: + if entry.global_name not in (global_names or []): pred = GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name] terms.append(_Expr("${{execution_context}}->{}()".format(pred))) if entry.feature:
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py index 2e01e5a..94748d8b 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -1818,7 +1818,7 @@ assert isinstance(operation_entries, list) interface = cg_context.interface - global_name = interface.extended_attributes.value_of("Global") + global_names = interface.extended_attributes.values_of("Global") callback_def_nodes = ListNode() @@ -1826,7 +1826,7 @@ for member in members: is_context_dependent = member.exposure.is_context_dependent exposure_conditional = expr_from_exposure(member.exposure, - global_name) + global_names) if "PerWorldBindings" in member.extended_attributes: worlds = (CodeGenContext.MAIN_WORLD,
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/mako_renderer.py b/third_party/blink/renderer/bindings/scripts/bind_gen/mako_renderer.py index ba196f1..f99a03be 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/mako_renderer.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/mako_renderer.py
@@ -13,6 +13,8 @@ class MakoTemplate(object): """Represents a compiled template object.""" + _mako_template_cache = {} + def __init__(self, template_text): assert isinstance(template_text, str) @@ -20,8 +22,12 @@ "strict_undefined": True, } - self._template = mako.template.Template( - text=template_text, **template_params) + template = self._mako_template_cache.get(template_text) + if template is None: + template = mako.template.Template( + text=template_text, **template_params) + self._mako_template_cache[template_text] = template + self._template = template def mako_template(self, pass_key=None): assert pass_key is _MAKO_TEMPLATE_PASS_KEY
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/function_like.py b/third_party/blink/renderer/bindings/scripts/web_idl/function_like.py index 20841226..648c70d 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/function_like.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/function_like.py
@@ -271,6 +271,9 @@ return True # step 4. Consider the two "innermost" types ... + def is_string_type(idl_type): + return idl_type.is_string or idl_type.is_enumeration + def is_interface_like(idl_type): return idl_type.is_interface or idl_type.is_buffer_source_type @@ -291,11 +294,11 @@ return not type2.is_boolean if type1.is_numeric: return not type2.is_numeric - if type1.is_string: - return not type2.is_string + if is_string_type(type1): + return not is_string_type(type2) if type1.is_object: - return (type2.is_boolean or type2.is_numeric or type2.is_string - or type2.is_symbol) + return (type2.is_boolean or type2.is_numeric + or is_string_type(type2) or type2.is_symbol) if type1.is_symbol: return not type2.is_symbol if is_interface_like(type1):
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 5f7d9abe..7d154ea 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -3035,12 +3035,14 @@ View()->InvokeFragmentAnchor(); auto& frame_loader = GetFrame()->Loader(); - auto& document_loader = *frame_loader.GetDocumentLoader(); + auto* document_loader = frame_loader.GetDocumentLoader(); + if (!document_loader) + return; if (frame_->IsLoading() && - !FrameLoader::NeedsHistoryItemRestore(document_loader.LoadType())) + !FrameLoader::NeedsHistoryItemRestore(document_loader->LoadType())) return; - auto* history_item = frame_loader.GetDocumentLoader()->GetHistoryItem(); + auto* history_item = document_loader->GetHistoryItem(); if (!history_item || !history_item->GetViewState()) return; @@ -3062,18 +3064,14 @@ scroll_offset; bool can_restore_without_annoying_user = - !document_loader.GetInitialScrollState().was_scrolled_by_user && + !document_loader->GetInitialScrollState().was_scrolled_by_user && (can_restore_without_clamping || !frame_->IsLoading() || !should_restore_scroll); if (!can_restore_without_annoying_user) return; frame_loader.RestoreScrollPositionAndViewState(); - if (View()->GetScrollableArea()->ApplyPendingHistoryRestoreScrollOffset()) { - if (ScrollingCoordinator* scrolling_coordinator = - View()->GetFrame().GetPage()->GetScrollingCoordinator()) - scrolling_coordinator->FrameViewRootLayerDidChange(View()); - } + View()->GetScrollableArea()->ApplyPendingHistoryRestoreScrollOffset(); } void Document::UpdateStyleAndLayout(ForcedLayoutStatus status) {
diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h index 25ed2647..cbe914ae 100644 --- a/third_party/blink/renderer/core/dom/node.h +++ b/third_party/blink/renderer/core/dom/node.h
@@ -80,14 +80,14 @@ class WebPluginContainerImpl; struct PhysicalRect; -const int kDOMNodeTypeShift = 1; +const int kDOMNodeTypeShift = 2; const int kElementNamespaceTypeShift = 4; const int kNodeStyleChangeShift = 17; const int kNodeCustomElementShift = 19; // Values for kChildNeedsStyleRecalcFlag, controlling whether a node gets its // style recalculated. -enum StyleChangeType { +enum StyleChangeType : uint32_t { // This node does not need style recalculation. kNoStyleChange = 0, // This node needs style recalculation. @@ -96,7 +96,7 @@ kSubtreeStyleChange = 2 << kNodeStyleChangeShift, }; -enum class CustomElementState { +enum class CustomElementState : uint32_t { // https://dom.spec.whatwg.org/#concept-element-custom-element-state kUncustomized = 0, kCustom = 1 << kNodeCustomElementShift, @@ -272,11 +272,7 @@ // Other methods (not part of DOM) bool IsTextNode() const { return GetDOMNodeType() == DOMNodeType::kText; } - bool IsContainerNode() const { - auto type = GetDOMNodeType(); - return type == DOMNodeType::kContainer || type == DOMNodeType::kElement || - type == DOMNodeType::kDocumentFragment; - } + bool IsContainerNode() const { return GetFlag(kIsContainerFlag); } bool IsElementNode() const { return GetDOMNodeType() == DOMNodeType::kElement; } @@ -919,11 +915,12 @@ void Trace(Visitor*) override; private: - enum NodeFlags { + enum NodeFlags : uint32_t { kHasRareDataFlag = 1, // Node type flags. These never change once created. - kDOMNodeTypeMask = 0x7 << kDOMNodeTypeShift, + kIsContainerFlag = 1 << 1, + kDOMNodeTypeMask = 0x3 << kDOMNodeTypeShift, kElementNamespaceTypeMask = 0x3 << kElementNamespaceTypeShift, kIsV0InsertionPointFlag = 1 << 6, @@ -977,18 +974,17 @@ void SetFlag(NodeFlags mask) { node_flags_ |= mask; } void ClearFlag(NodeFlags mask) { node_flags_ &= ~mask; } - enum class DOMNodeType { + enum class DOMNodeType : uint32_t { kOther = 0, kText = 1 << kDOMNodeTypeShift, - kContainer = 2 << kDOMNodeTypeShift, - kElement = 3 << kDOMNodeTypeShift, - kDocumentFragment = 4 << kDOMNodeTypeShift, + kElement = 2 << kDOMNodeTypeShift, + kDocumentFragment = 3 << kDOMNodeTypeShift, }; DOMNodeType GetDOMNodeType() const { return static_cast<DOMNodeType>(node_flags_ & kDOMNodeTypeMask); } - enum class ElementNamespaceType { + enum class ElementNamespaceType : uint32_t { kOther = 0, kHTML = 1 << kElementNamespaceTypeShift, kMathML = 2 << kElementNamespaceTypeShift, @@ -1005,12 +1001,11 @@ kDefaultNodeFlags | static_cast<NodeFlags>(DOMNodeType::kOther), kCreateText = kDefaultNodeFlags | static_cast<NodeFlags>(DOMNodeType::kText), - kCreateContainer = - kDefaultNodeFlags | static_cast<NodeFlags>(DOMNodeType::kContainer), + kCreateContainer = kDefaultNodeFlags | kIsContainerFlag, kCreateElement = - kDefaultNodeFlags | static_cast<NodeFlags>(DOMNodeType::kElement), + kCreateContainer | static_cast<NodeFlags>(DOMNodeType::kElement), kCreateDocumentFragment = - kDefaultNodeFlags | + kCreateContainer | static_cast<NodeFlags>(DOMNodeType::kDocumentFragment), kCreateShadowRoot = kCreateDocumentFragment | kIsInShadowTreeFlag, kCreateHTMLElement =
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 11c628f..b97a2eb 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -458,13 +458,6 @@ if (frame_->IsMainFrame()) frame_->GetPage()->GetVisualViewport().MainFrameDidChangeSize(); GetFrame().Loader().RestoreScrollPositionAndViewState(); - if (GetScrollableArea()) { - if (GetScrollableArea()->ApplyPendingHistoryRestoreScrollOffset()) { - if (ScrollingCoordinator* scrolling_coordinator = - GetFrame().GetPage()->GetScrollingCoordinator()) - scrolling_coordinator->FrameViewRootLayerDidChange(this); - } - } } }
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/third_party/blink/renderer/core/frame/root_frame_viewport.cc index 7102bef..1efda8d 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.cc +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
@@ -241,9 +241,9 @@ return LayoutViewport().ScrollCornerRect(); } -bool RootFrameViewport::ApplyPendingHistoryRestoreScrollOffset() { +void RootFrameViewport::ApplyPendingHistoryRestoreScrollOffset() { if (!pending_view_state_) - return false; + return; bool should_restore_scale = pending_view_state_->page_scale_factor_; @@ -289,7 +289,6 @@ should_restore_scroll_ = false; pending_view_state_.reset(); - return true; } void RootFrameViewport::SetScrollOffset(const ScrollOffset& offset,
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.h b/third_party/blink/renderer/core/frame/root_frame_viewport.h index 30ade1b..f9a4456 100644 --- a/third_party/blink/renderer/core/frame/root_frame_viewport.h +++ b/third_party/blink/renderer/core/frame/root_frame_viewport.h
@@ -135,7 +135,7 @@ should_restore_scroll_ = should_restore_scroll; } - bool ApplyPendingHistoryRestoreScrollOffset() override; + void ApplyPendingHistoryRestoreScrollOffset() override; private: FRIEND_TEST_ALL_PREFIXES(RootFrameViewportTest, DistributeScrollOrder);
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc index 4263efb6..2892126 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -190,11 +190,8 @@ // As an optimization, attempt to directly update the compositor // scale translation node and return kChangedOnlyCompositedValues which // avoids an expensive PaintArtifactCompositor update. - // TODO(crbug.com/953322): We need to implement this optimization for - // CompositeAfterPaint as well. - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && - effective_change_type == - PaintPropertyChangeType::kChangedOnlySimpleValues) { + if (effective_change_type == + PaintPropertyChangeType::kChangedOnlySimpleValues) { if (auto* paint_artifact_compositor = GetPaintArtifactCompositor()) { bool updated = paint_artifact_compositor->DirectlyUpdatePageScaleTransform( @@ -273,11 +270,8 @@ // As an optimization, attempt to directly update the compositor // translation node and return kChangedOnlyCompositedValues which avoids // an expensive PaintArtifactCompositor update. - // TODO(crbug.com/953322): We need to implement this optimization for - // CompositeAfterPaint as well. - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && - effective_change_type == - PaintPropertyChangeType::kChangedOnlySimpleValues) { + if (effective_change_type == + PaintPropertyChangeType::kChangedOnlySimpleValues) { if (auto* paint_artifact_compositor = GetPaintArtifactCompositor()) { bool updated = paint_artifact_compositor->DirectlyUpdateScrollOffsetTransform(
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc index c5c73eb9..4832d69 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -2688,11 +2688,6 @@ // When a pinch-zoom occurs, the viewport scale and translation nodes can be // directly updated without a PaintArtifactCompositor update. TEST_P(VisualViewportTest, DirectPinchZoomPropertyUpdate) { - // TODO(crbug.com/953322): Implement this optimization for - // CompositeAfterPaint. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - InitializeWithAndroidSettings(); RegisterMockedHttpURLLoad("200-by-800-viewport.html");
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc index 7458ce2..d5c7c66 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -1390,11 +1390,8 @@ page->GetVisualViewport().SetLocation(FloatPoint(10, 20)); ForceFullCompositingUpdate(); - // TODO(crbug.com/953322): Make this work for CAP. - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { - EXPECT_EQ(gfx::ScrollOffset(10, 20), - CurrentScrollOffset(inner_viewport_scroll_node)); - } + EXPECT_EQ(gfx::ScrollOffset(10, 20), + CurrentScrollOffset(inner_viewport_scroll_node)); } TEST_P(ScrollingTest, UpdateUMAMetricUpdated) {
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc index 7644d57..2c2df57 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
@@ -262,12 +262,6 @@ INSTANTIATE_LAYER_LIST_TEST_SUITE_P(CompositingSimTest); TEST_P(CompositingSimTest, LayerUpdatesDoNotInvalidateEarlierLayers) { - // TODO(crbug.com/765003): CAP may make different layerization decisions and - // we cannot guarantee that both divs will be composited in this test. When - // CAP gets closer to launch, this test should be updated to pass. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - InitializeWithHTML(R"HTML( <!DOCTYPE html> <style> @@ -276,6 +270,7 @@ width: 100px; height: 100px; will-change: transform; + background: lightblue; } </style> <div id='a'></div> @@ -284,16 +279,9 @@ Compositor().BeginFrame(); - auto* a_element = GetElementById("a"); auto* a_layer = CcLayerByDOMElementId("a"); - DCHECK_EQ(a_layer->element_id(), CompositorElementIdFromUniqueObjectId( - a_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); auto* b_element = GetElementById("b"); auto* b_layer = CcLayerByDOMElementId("b"); - DCHECK_EQ(b_layer->element_id(), CompositorElementIdFromUniqueObjectId( - b_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); // Initially, neither a nor b should have a layer that should push properties. cc::LayerTreeHost& host = Compositor().layer_tree_host(); @@ -313,12 +301,6 @@ } TEST_P(CompositingSimTest, LayerUpdatesDoNotInvalidateLaterLayers) { - // TODO(crbug.com/765003): CAP may make different layerization decisions and - // we cannot guarantee that both divs will be composited in this test. When - // CAP gets closer to launch, this test should be updated to pass. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - InitializeWithHTML(R"HTML( <!DOCTYPE html> <style> @@ -327,6 +309,7 @@ width: 100px; height: 100px; will-change: transform; + background: lightblue; } </style> <div id='a'></div> @@ -338,19 +321,9 @@ auto* a_element = GetElementById("a"); auto* a_layer = CcLayerByDOMElementId("a"); - DCHECK_EQ(a_layer->element_id(), CompositorElementIdFromUniqueObjectId( - a_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); auto* b_element = GetElementById("b"); auto* b_layer = CcLayerByDOMElementId("b"); - DCHECK_EQ(b_layer->element_id(), CompositorElementIdFromUniqueObjectId( - b_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); - auto* c_element = GetElementById("c"); auto* c_layer = CcLayerByDOMElementId("c"); - DCHECK_EQ(c_layer->element_id(), CompositorElementIdFromUniqueObjectId( - c_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); // Initially, no layer should need to push properties. cc::LayerTreeHost& host = Compositor().layer_tree_host(); @@ -411,12 +384,6 @@ // non-layer-list mode, this occurs in BuildPropertyTreesInternal (see: // SetLayerPropertyChangedForChild). TEST_P(CompositingSimTest, LayerSubtreeTransformPropertyChanged) { - // TODO(crbug.com/765003): CAP may make different layerization decisions and - // we cannot guarantee that both divs will be composited in this test. When - // CAP gets closer to launch, this test should be updated to pass. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - InitializeWithHTML(R"HTML( <!DOCTYPE html> <style> @@ -426,6 +393,7 @@ height: 100px; will-change: transform; transform: translate(10px, 10px); + background: lightgreen; } #inner { width: 100px; @@ -443,16 +411,7 @@ auto* outer_element = GetElementById("outer"); auto* outer_element_layer = CcLayerByDOMElementId("outer"); - DCHECK_EQ(outer_element_layer->element_id(), - CompositorElementIdFromUniqueObjectId( - outer_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); - auto* inner_element = GetElementById("inner"); auto* inner_element_layer = CcLayerByDOMElementId("inner"); - DCHECK_EQ(inner_element_layer->element_id(), - CompositorElementIdFromUniqueObjectId( - inner_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); // Initially, no layer should have |subtree_property_changed| set. EXPECT_FALSE(outer_element_layer->subtree_property_changed()); @@ -488,12 +447,6 @@ // |transform_changed| set. In non-layer-list mode, this occurs in // cc::TransformTree::OnTransformAnimated and cc::Layer::SetTransform. TEST_P(CompositingSimTest, DirectTransformPropertyUpdate) { - // TODO(crbug.com/765003): CAP may make different layerization decisions and - // we cannot guarantee that both divs will be composited in this test. When - // CAP gets closer to launch, this test should be updated to pass. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - InitializeWithHTML(R"HTML( <!DOCTYPE html> <style> @@ -503,6 +456,7 @@ height: 100px; will-change: transform; transform: translate(10px, 10px) scale(1, 2); + background: lightgreen; } #inner { width: 100px; @@ -520,10 +474,6 @@ auto* outer_element = GetElementById("outer"); auto* outer_element_layer = CcLayerByDOMElementId("outer"); - DCHECK_EQ(outer_element_layer->element_id(), - CompositorElementIdFromUniqueObjectId( - outer_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); auto transform_tree_index = outer_element_layer->transform_tree_index(); auto* transform_node = GetPropertyTrees()->transform_tree.Node(transform_tree_index); @@ -548,12 +498,6 @@ // the changed value of a directly updated transform is still set if some other // change causes PaintArtifactCompositor to run and do non-direct updates. TEST_P(CompositingSimTest, DirectTransformPropertyUpdateCausesChange) { - // TODO(crbug.com/765003): CAP may make different layerization decisions and - // we cannot guarantee that both divs will be composited in this test. When - // CAP gets closer to launch, this test should be updated to pass. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - InitializeWithHTML(R"HTML( <!DOCTYPE html> <style> @@ -563,6 +507,7 @@ height: 100px; will-change: transform; transform: translate(1px, 2px); + background: lightgreen; } #inner { width: 100px; @@ -581,20 +526,12 @@ auto* outer_element = GetElementById("outer"); auto* outer_element_layer = CcLayerByDOMElementId("outer"); - DCHECK_EQ(outer_element_layer->element_id(), - CompositorElementIdFromUniqueObjectId( - outer_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); auto outer_transform_tree_index = outer_element_layer->transform_tree_index(); auto* outer_transform_node = GetPropertyTrees()->transform_tree.Node(outer_transform_tree_index); auto* inner_element = GetElementById("inner"); auto* inner_element_layer = CcLayerByDOMElementId("inner"); - DCHECK_EQ(inner_element_layer->element_id(), - CompositorElementIdFromUniqueObjectId( - inner_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); auto inner_transform_tree_index = inner_element_layer->transform_tree_index(); auto* inner_transform_node = GetPropertyTrees()->transform_tree.Node(inner_transform_tree_index); @@ -697,12 +634,6 @@ // |transform_changed| set. In non-layer-list mode, this occurs in // cc::Layer::SetTransformOrigin. TEST_P(CompositingSimTest, DirectTransformOriginPropertyUpdate) { - // TODO(crbug.com/765003): CAP may make different layerization decisions and - // we cannot guarantee that both divs will be composited in this test. When - // CAP gets closer to launch, this test should be updated to pass. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - InitializeWithHTML(R"HTML( <!DOCTYPE html> <style> @@ -712,6 +643,7 @@ height: 100px; transform: rotate3d(3, 2, 1, 45deg); transform-origin: 10px 10px 100px; + background: lightblue; } </style> <div id='box'></div> @@ -721,10 +653,6 @@ auto* box_element = GetElementById("box"); auto* box_element_layer = CcLayerByDOMElementId("box"); - DCHECK_EQ(box_element_layer->element_id(), - CompositorElementIdFromUniqueObjectId( - box_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); auto transform_tree_index = box_element_layer->transform_tree_index(); auto* transform_node = GetPropertyTrees()->transform_tree.Node(transform_tree_index); @@ -820,12 +748,6 @@ // This test is similar to |LayerSubtreeTransformPropertyChanged| but for // clip property node changes. TEST_P(CompositingSimTest, LayerSubtreeClipPropertyChanged) { - // TODO(crbug.com/765003): CAP may make different layerization decisions and - // we cannot guarantee that both divs will be composited in this test. When - // CAP gets closer to launch, this test should be updated to pass. - if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) - return; - InitializeWithHTML(R"HTML( <!DOCTYPE html> <style> @@ -836,6 +758,7 @@ will-change: transform; position: absolute; clip: rect(10px, 80px, 70px, 40px); + background: lightgreen; } #inner { width: 100px; @@ -853,12 +776,7 @@ auto* outer_element = GetElementById("outer"); auto* outer_element_layer = CcLayerByDOMElementId("outer"); - auto* inner_element = GetElementById("inner"); auto* inner_element_layer = CcLayerByDOMElementId("inner"); - DCHECK_EQ(inner_element_layer->element_id(), - CompositorElementIdFromUniqueObjectId( - inner_element->GetLayoutObject()->UniqueId(), - CompositorElementIdNamespace::kPrimary)); // Initially, no layer should have |subtree_property_changed| set. EXPECT_FALSE(outer_element_layer->subtree_property_changed());
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 8d186b6..bd2094b 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -230,9 +230,9 @@ layer_ = nullptr; } -bool PaintLayerScrollableArea::ApplyPendingHistoryRestoreScrollOffset() { +void PaintLayerScrollableArea::ApplyPendingHistoryRestoreScrollOffset() { if (!pending_view_state_) - return false; + return; // TODO(pnoland): attempt to restore the anchor in more places than this. // Anchor-based restore should allow for earlier restoration. @@ -246,7 +246,6 @@ } pending_view_state_.reset(); - return true; } void PaintLayerScrollableArea::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h index b9a88b9f1..82490ed 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -584,7 +584,7 @@ pending_view_state_ = view_state; } - bool ApplyPendingHistoryRestoreScrollOffset() override; + void ApplyPendingHistoryRestoreScrollOffset() override; private: bool NeedsScrollbarReconstruction() const;
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 4919cede0..2a4e27a 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -776,9 +776,7 @@ style.IsRunningTransformAnimationOnCompositor(); auto effective_change_type = properties_->UpdateTransform( *context_.current.transform, std::move(state), animation_state); - // TODO(crbug.com/953322): We need to fix this to work with CAP as well. - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && - effective_change_type == + if (effective_change_type == PaintPropertyChangeType::kChangedOnlySimpleValues && properties_->Transform()->HasDirectCompositingReasons()) { if (auto* paint_artifact_compositor = @@ -1077,9 +1075,7 @@ // If we have simple value change, which means opacity, we should try to // directly update it on the PaintArtifactCompositor in order to avoid // doing a full rebuild. - // TODO(crbug.com/953322): We need to fix this to work with CAP as well. - if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && - effective_change_type == + if (effective_change_type == PaintPropertyChangeType::kChangedOnlySimpleValues && properties_->Effect()->HasDirectCompositingReasons()) { if (auto* paint_artifact_compositor =
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.h b/third_party/blink/renderer/core/scroll/scrollable_area.h index 480285b..e34eecd 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.h +++ b/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -118,8 +118,7 @@ virtual void SetPendingHistoryRestoreScrollOffset( const HistoryItem::ViewState& view_state, bool should_restore_scroll) {} - // Returns true if it applied anything. - virtual bool ApplyPendingHistoryRestoreScrollOffset() { return false; } + virtual void ApplyPendingHistoryRestoreScrollOffset() {} // Scrolls the area so that the given rect, given in absolute coordinates, // such that it's visible in the area. Returns the new location of the input
diff --git a/third_party/blink/web_tests/LeakExpectations b/third_party/blink/web_tests/LeakExpectations index 19abf9f..ac27dcc 100644 --- a/third_party/blink/web_tests/LeakExpectations +++ b/third_party/blink/web_tests/LeakExpectations
@@ -115,6 +115,9 @@ # Sheriff 2019-11-29 crbug.com/1029417 [ Linux ] external/wpt/web-nfc/NDEFReader_scan_filter.https.html [ Failure ] +# Sheriff 2019-12-30 +crbug.com/1038388 [ Linux ] http/tests/devtools/tracing/timeline-time/timeline-time.js [ Pass Failure ] + ########################################################################### # WARNING: Memory leaks must be fixed asap. Sheriff is expected to revert # # culprit CLs instead of suppressing the leaks. If you have any question, #
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 4a6f1ddd..4701bde 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2543,8 +2543,6 @@ # 1px scroll offset difference for compositor threaded scrollbar scrolling on Linux. crbug.com/1009892 [ Mac ] virtual/compositor_threaded_scrollbar_scrolling_hidpi/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html [ Failure Timeout ] -# FAIL Test mouse drags on non-custom composited div scrollbar thumb. assert_equals: Vertical thumb drag downwards did not scroll as expected. expected 46 but got 0 -crbug.com/1009892 [ Mac ] virtual/compositor_threaded_scrollbar_scrolling/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html [ Failure ] # Some control characters still not visible crbug.com/893490 [ Mac ] external/wpt/css/css-text/white-space/control-chars-001.html [ Failure ] @@ -5016,6 +5014,7 @@ # Flaky timeout only on Mac 10.13. crbug.com/853360 [ Mac10.13 ] http/tests/misc/slow-loading-image-in-pattern.html [ Timeout Pass ] +crbug.com/853360 [ Retina ] http/tests/misc/slow-loading-image-in-pattern.html [ Timeout Pass ] # Origin Policy: Skip tests that rely on --feature-enabled=OriginPolicy, so # they can be run via virtual/origin-policy instead. @@ -6153,3 +6152,7 @@ crbug.com/1037798 [ Win ] virtual/gpu-rasterization/images/exif-orientation-image-document.html [ Pass Failure ] crbug.com/1038091 [ Win ] virtual/gpu-rasterization/images/jpeg-yuv-image-decoding.html [ Pass Failure ] crbug.com/1038139 [ Win ] virtual/gpu-rasterization/images/2-comp.html [ Pass Failure ] + +# Sheriff 2019-12-30 +crbug.com/1037798 [ Mac ] virtual/gpu-rasterization/images/exif-orientation-image-document.html [ Pass Failure ] +crbug.com/1038354 fast/scroll-snap/snaps-after-scrollbar-scrolling.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/animations/composition/border-bottom-left-radius-composition.html b/third_party/blink/web_tests/animations/composition/border-bottom-left-radius-composition.html deleted file mode 100644 index 57a9ecc9..0000000 --- a/third_party/blink/web_tests/animations/composition/border-bottom-left-radius-composition.html +++ /dev/null
@@ -1,50 +0,0 @@ -<!DOCTYPE html> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-bottom-left-radius', - underlying: '40px 40px', - addFrom: '60px 60px', - addTo: '160px 160px', -}, [ - {at: -0.25, is: '75px'}, - {at: 0, is: '100px'}, - {at: 0.25, is: '125px'}, - {at: 0.5, is: '150px'}, - {at: 0.75, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.25, is: '225px'}, -]); - -assertComposition({ - property: 'border-bottom-left-radius', - underlying: '40px 140px', - replaceFrom: '100px 120px', - addTo: '160px 60px', -}, [ - {at: -0.25, is: '75px 100px'}, - {at: 0, is: '100px 120px'}, - {at: 0.25, is: '125px 140px'}, - {at: 0.5, is: '150px 160px'}, - {at: 0.75, is: '175px 180px'}, - {at: 1, is: '200px'}, - {at: 1.25, is: '225px 220px'}, -]); - -assertComposition({ - property: 'border-bottom-left-radius', - underlying: '40px 60px', - addFrom: '60px 140px', - replaceTo: '200px 120px', -}, [ - {at: -0.25, is: '75px 220px'}, - {at: 0, is: '100px 200px'}, - {at: 0.25, is: '125px 180px'}, - {at: 0.5, is: '150px 160px'}, - {at: 0.75, is: '175px 140px'}, - {at: 1, is: '200px 120px'}, - {at: 1.25, is: '225px 100px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-bottom-right-radius-composition.html b/third_party/blink/web_tests/animations/composition/border-bottom-right-radius-composition.html deleted file mode 100644 index cee2e8e..0000000 --- a/third_party/blink/web_tests/animations/composition/border-bottom-right-radius-composition.html +++ /dev/null
@@ -1,50 +0,0 @@ -<!DOCTYPE html> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-bottom-right-radius', - underlying: '40px 40px', - addFrom: '60px 60px', - addTo: '160px 160px', -}, [ - {at: -0.25, is: '75px'}, - {at: 0, is: '100px'}, - {at: 0.25, is: '125px'}, - {at: 0.5, is: '150px'}, - {at: 0.75, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.25, is: '225px'}, -]); - -assertComposition({ - property: 'border-bottom-right-radius', - underlying: '40px 140px', - replaceFrom: '100px 120px', - addTo: '160px 60px', -}, [ - {at: -0.25, is: '75px 100px'}, - {at: 0, is: '100px 120px'}, - {at: 0.25, is: '125px 140px'}, - {at: 0.5, is: '150px 160px'}, - {at: 0.75, is: '175px 180px'}, - {at: 1, is: '200px'}, - {at: 1.25, is: '225px 220px'}, -]); - -assertComposition({ - property: 'border-bottom-right-radius', - underlying: '40px 60px', - addFrom: '60px 140px', - replaceTo: '200px 120px', -}, [ - {at: -0.25, is: '75px 220px'}, - {at: 0, is: '100px 200px'}, - {at: 0.25, is: '125px 180px'}, - {at: 0.5, is: '150px 160px'}, - {at: 0.75, is: '175px 140px'}, - {at: 1, is: '200px 120px'}, - {at: 1.25, is: '225px 100px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-bottom-width-composition.html b/third_party/blink/web_tests/animations/composition/border-bottom-width-composition.html deleted file mode 100644 index b8375555..0000000 --- a/third_party/blink/web_tests/animations/composition/border-bottom-width-composition.html +++ /dev/null
@@ -1,58 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-bottom-width', - underlying: '50px', - addFrom: '100px', - addTo: '200px', -}, [ - {at: -0.3, is: '120px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '200px'}, - {at: 1, is: '250px'}, - {at: 1.5, is: '300px'}, -]); - -assertComposition({ - property: 'border-bottom-width', - underlying: '100px', - addFrom: '10px', - addTo: '2px', -}, [ - {at: -0.5, is: '114px'}, - {at: 0, is: '110px'}, - {at: 0.5, is: '106px'}, - {at: 1, is: '102px'}, - {at: 1.5, is: '98px'}, // Value clamping should happen after composition. -]); - -assertComposition({ - property: 'border-bottom-width', - underlying: '10em', - addFrom: '100px', - addTo: '20em', -}, [ - {at: -0.3, is: 'calc(130px + 4em)'}, - {at: 0, is: 'calc(100px + 10em)'}, - {at: 0.5, is: 'calc(50px + 20em)'}, - {at: 1, is: '30em'}, - {at: 1.5, is: 'calc(-50px + 40em)'}, -]); - -assertComposition({ - property: 'border-bottom-width', - underlying: '50px', - addFrom: '100px', - replaceTo: '200px', -}, [ - {at: -0.3, is: '135px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.5, is: '225px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-image-outset-composition.html b/third_party/blink/web_tests/animations/composition/border-image-outset-composition.html deleted file mode 100644 index 51cbeee67..0000000 --- a/third_party/blink/web_tests/animations/composition/border-image-outset-composition.html +++ /dev/null
@@ -1,126 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-image-outset', - underlying: '1 2 3 4', - addFrom: '1 2 3 4', - addTo: '101 102 103 104', -}, [ - {at: -0.25, is: '0'}, // Non-negative. - {at: 0, is: '2 4 6 8'}, - {at: 0.25, is: '27 29 31 33'}, - {at: 0.5, is: '52 54 56 58'}, - {at: 0.75, is: '77 79 81 83'}, - {at: 1, is: '102 104 106 108'}, - {at: 1.25, is: '127 129 131 133'}, -]); - -assertComposition({ - property: 'border-image-outset', - underlying: '100 200 300 400', - addFrom: '100', - addTo: '200 300 500', -}, [ - {at: -0.25, is: '175 250 300 450'}, - {at: 0, is: '200 300 400 500'}, - {at: 0.25, is: '225 350 500 550'}, - {at: 0.5, is: '250 400 600 600'}, - {at: 0.75, is: '275 450 700 650'}, - {at: 1, is: '300 500 800 700'}, - {at: 1.25, is: '325 550 900 750'}, -]); - -assertComposition({ - property: 'border-image-outset', - underlying: '1 2 3px 4px', - addFrom: '1 2 3px 4px', - addTo: '101 102 103px 104px', -}, [ - {at: -0.25, is: '0 0 0px 0px'}, // Non-negative. - {at: 0, is: '2 4 6px 8px'}, - {at: 0.25, is: '27 29 31px 33px'}, - {at: 0.5, is: '52 54 56px 58px'}, - {at: 0.75, is: '77 79 81px 83px'}, - {at: 1, is: '102 104 106px 108px'}, - {at: 1.25, is: '127 129 131px 133px'}, -]); - -assertComposition({ - property: 'border-image-outset', - underlying: '10px 20px', - addFrom: '190px 180px 290px 280px', - addTo: '90px 80px', -}, [ - {at: -0.25, is: '225px 225px 350px 350px'}, - {at: 0, is: '200px 200px 300px 300px'}, - {at: 0.25, is: '175px 175px 250px 250px'}, - {at: 0.5, is: '150px 150px 200px 200px'}, - {at: 0.75, is: '125px 125px 150px 150px'}, - {at: 1, is: '100px'}, - {at: 1.25, is: '75px 75px 50px 50px'}, -]); - -assertComposition({ - property: 'border-image-outset', - underlying: '10 20px', - replaceFrom: '100 100px', - addTo: '190 180px', -}, [ - {at: -0.25, is: '75 75px'}, - {at: 0, is: '100 100px'}, - {at: 0.25, is: '125 125px'}, - {at: 0.5, is: '150 150px'}, - {at: 0.75, is: '175 175px'}, - {at: 1, is: '200 200px'}, - {at: 1.25, is: '225 225px'}, -]); - -assertComposition({ - property: 'border-image-outset', - underlying: '10px 20', - addFrom: '90px 80', - replaceTo: '0px 0 0px 0', -}, [ - {at: -0.25, is: '125px 125'}, - {at: 0, is: '100px 100'}, - {at: 0.25, is: '75px 75'}, - {at: 0.5, is: '50px 50'}, - {at: 0.75, is: '25px 25'}, - {at: 1, is: '0px 0'}, - {at: 1.25, is: '0px 0'}, // Non-negative. -]); - -assertComposition({ - property: 'border-image-outset', - underlying: '10 20', - addFrom: '100px 150px', - addTo: '200px 250px', -}, [ - {at: -0.25, is: '75px 125px'}, - {at: 0, is: '100px 150px'}, - {at: 0.25, is: '125px 175px'}, - {at: 0.5, is: '150px 200px'}, - {at: 0.75, is: '175px 225px'}, - {at: 1, is: '200px 250px'}, - {at: 1.25, is: '225px 275px'}, -]); - -assertComposition({ - property: 'border-image-outset', - underlying: '10 20', - addFrom: '100 150px', - addTo: '200px 250', -}, [ - {at: -0.25, is: '100 150px'}, - {at: 0, is: '100 150px'}, - {at: 0.25, is: '100 150px'}, - {at: 0.5, is: '200px 250'}, - {at: 0.75, is: '200px 250'}, - {at: 1, is: '200px 250'}, - {at: 1.25, is: '200px 250'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-image-slice-composition.html b/third_party/blink/web_tests/animations/composition/border-image-slice-composition.html deleted file mode 100644 index df7489a..0000000 --- a/third_party/blink/web_tests/animations/composition/border-image-slice-composition.html +++ /dev/null
@@ -1,126 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-image-slice', - underlying: '1 2 3 4', - addFrom: '1 2 3 4', - addTo: '101 102 103 104', -}, [ - {at: -0.25, is: '0'}, // Non-negative. - {at: 0, is: '2 4 6 8'}, - {at: 0.25, is: '27 29 31 33'}, - {at: 0.5, is: '52 54 56 58'}, - {at: 0.75, is: '77 79 81 83'}, - {at: 1, is: '102 104 106 108'}, - {at: 1.25, is: '127 129 131 133'}, -]); - -assertComposition({ - property: 'border-image-slice', - underlying: '100 200 300 400 fill', - addFrom: '100 fill', - addTo: '200 300 500 fill', -}, [ - {at: -0.25, is: '175 250 300 450 fill'}, - {at: 0, is: '200 300 400 500 fill'}, - {at: 0.25, is: '225 350 500 550 fill'}, - {at: 0.5, is: '250 400 600 600 fill'}, - {at: 0.75, is: '275 450 700 650 fill'}, - {at: 1, is: '300 500 800 700 fill'}, - {at: 1.25, is: '325 550 900 750 fill'}, -]); - -assertComposition({ - property: 'border-image-slice', - underlying: '1 2 3% 4%', - addFrom: '1 2 3% 4%', - addTo: '101 102 103% 104%', -}, [ - {at: -0.25, is: '0 0 0% 0%'}, // Non-negative. - {at: 0, is: '2 4 6% 8%'}, - {at: 0.25, is: '27 29 31% 33%'}, - {at: 0.5, is: '52 54 56% 58%'}, - {at: 0.75, is: '77 79 81% 83%'}, - {at: 1, is: '102 104 106% 108%'}, - {at: 1.25, is: '127 129 131% 133%'}, -]); - -assertComposition({ - property: 'border-image-slice', - underlying: '10% 20%', - addFrom: '190% 180% 290% 280%', - addTo: '90% 80%', -}, [ - {at: -0.25, is: '225% 225% 350% 350%'}, - {at: 0, is: '200% 200% 300% 300%'}, - {at: 0.25, is: '175% 175% 250% 250%'}, - {at: 0.5, is: '150% 150% 200% 200%'}, - {at: 0.75, is: '125% 125% 150% 150%'}, - {at: 1, is: '100%'}, - {at: 1.25, is: '75% 75% 50% 50%'}, -]); - -assertComposition({ - property: 'border-image-slice', - underlying: '10 20%', - replaceFrom: '100 100%', - addTo: '190 180%', -}, [ - {at: -0.25, is: '75 75%'}, - {at: 0, is: '100 100%'}, - {at: 0.25, is: '125 125%'}, - {at: 0.5, is: '150 150%'}, - {at: 0.75, is: '175 175%'}, - {at: 1, is: '200 200%'}, - {at: 1.25, is: '225 225%'}, -]); - -assertComposition({ - property: 'border-image-slice', - underlying: '10% 20', - addFrom: '90% 80', - replaceTo: '0% 0 0% 0', -}, [ - {at: -0.25, is: '125% 125'}, - {at: 0, is: '100% 100'}, - {at: 0.25, is: '75% 75'}, - {at: 0.5, is: '50% 50'}, - {at: 0.75, is: '25% 25'}, - {at: 1, is: '0% 0'}, - {at: 1.25, is: '0% 0'}, // Non-negative. -]); - -assertComposition({ - property: 'border-image-slice', - underlying: '10 20', - addFrom: '100% 150%', - addTo: '200% 250% fill', -}, [ - {at: -0.25, is: '100% 150%'}, - {at: 0, is: '100% 150%'}, - {at: 0.25, is: '100% 150%'}, - {at: 0.5, is: '200% 250% fill'}, - {at: 0.75, is: '200% 250% fill'}, - {at: 1, is: '200% 250% fill'}, - {at: 1.25, is: '200% 250% fill'}, -]); - -assertComposition({ - property: 'border-image-slice', - underlying: '10 20', - addFrom: '100 150%', - addTo: '200% 250', -}, [ - {at: -0.25, is: '100 150%'}, - {at: 0, is: '100 150%'}, - {at: 0.25, is: '100 150%'}, - {at: 0.5, is: '200% 250'}, - {at: 0.75, is: '200% 250'}, - {at: 1, is: '200% 250'}, - {at: 1.25, is: '200% 250'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-image-width-composition.html b/third_party/blink/web_tests/animations/composition/border-image-width-composition.html deleted file mode 100644 index 9fecb4a..0000000 --- a/third_party/blink/web_tests/animations/composition/border-image-width-composition.html +++ /dev/null
@@ -1,126 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-image-width', - underlying: '1 2 3 4', - addFrom: '1 2 3 4', - addTo: '101 102 103 104', -}, [ - {at: -0.25, is: '0'}, // Non-negative. - {at: 0, is: '2 4 6 8'}, - {at: 0.25, is: '27 29 31 33'}, - {at: 0.5, is: '52 54 56 58'}, - {at: 0.75, is: '77 79 81 83'}, - {at: 1, is: '102 104 106 108'}, - {at: 1.25, is: '127 129 131 133'}, -]); - -assertComposition({ - property: 'border-image-width', - underlying: '100 200 300 400', - addFrom: '100', - addTo: '200 300 500', -}, [ - {at: -0.25, is: '175 250 300 450'}, - {at: 0, is: '200 300 400 500'}, - {at: 0.25, is: '225 350 500 550'}, - {at: 0.5, is: '250 400 600 600'}, - {at: 0.75, is: '275 450 700 650'}, - {at: 1, is: '300 500 800 700'}, - {at: 1.25, is: '325 550 900 750'}, -]); - -assertComposition({ - property: 'border-image-width', - underlying: '1 2 3px 4%', - addFrom: '1 2 3px 4%', - addTo: '101 102 103px 104%', -}, [ - {at: -0.25, is: '0 0 0px 0%'}, // Non-negative. - {at: 0, is: '2 4 6px 8%'}, - {at: 0.25, is: '27 29 31px 33%'}, - {at: 0.5, is: '52 54 56px 58%'}, - {at: 0.75, is: '77 79 81px 83%'}, - {at: 1, is: '102 104 106px 108%'}, - {at: 1.25, is: '127 129 131px 133%'}, -]); - -assertComposition({ - property: 'border-image-width', - underlying: '10px 20px', - addFrom: '190px 180px 290px 280px', - addTo: '90px 80px', -}, [ - {at: -0.25, is: '225px 225px 350px 350px'}, - {at: 0, is: '200px 200px 300px 300px'}, - {at: 0.25, is: '175px 175px 250px 250px'}, - {at: 0.5, is: '150px 150px 200px 200px'}, - {at: 0.75, is: '125px 125px 150px 150px'}, - {at: 1, is: '100px'}, - {at: 1.25, is: '75px 75px 50px 50px'}, -]); - -assertComposition({ - property: 'border-image-width', - underlying: '10 20px', - replaceFrom: '100 100px', - addTo: '190 180px', -}, [ - {at: -0.25, is: '75 75px'}, - {at: 0, is: '100 100px'}, - {at: 0.25, is: '125 125px'}, - {at: 0.5, is: '150 150px'}, - {at: 0.75, is: '175 175px'}, - {at: 1, is: '200 200px'}, - {at: 1.25, is: '225 225px'}, -]); - -assertComposition({ - property: 'border-image-width', - underlying: '10px 20', - addFrom: '90px 80', - replaceTo: '0px 0 0px 0', -}, [ - {at: -0.25, is: '125px 125'}, - {at: 0, is: '100px 100'}, - {at: 0.25, is: '75px 75'}, - {at: 0.5, is: '50px 50'}, - {at: 0.75, is: '25px 25'}, - {at: 1, is: '0px 0'}, - {at: 1.25, is: '0px 0'}, // Non-negative. -]); - -assertComposition({ - property: 'border-image-width', - underlying: '10 20', - addFrom: '100px 150px', - addTo: '200px 250px', -}, [ - {at: -0.25, is: '75px 125px'}, - {at: 0, is: '100px 150px'}, - {at: 0.25, is: '125px 175px'}, - {at: 0.5, is: '150px 200px'}, - {at: 0.75, is: '175px 225px'}, - {at: 1, is: '200px 250px'}, - {at: 1.25, is: '225px 275px'}, -]); - -assertComposition({ - property: 'border-image-width', - underlying: '10 20', - addFrom: '100 150px', - addTo: '200% 250', -}, [ - {at: -0.25, is: '100 150px'}, - {at: 0, is: '100 150px'}, - {at: 0.25, is: '100 150px'}, - {at: 0.5, is: '200% 250'}, - {at: 0.75, is: '200% 250'}, - {at: 1, is: '200% 250'}, - {at: 1.25, is: '200% 250'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-left-width-composition.html b/third_party/blink/web_tests/animations/composition/border-left-width-composition.html deleted file mode 100644 index 450d5a9f..0000000 --- a/third_party/blink/web_tests/animations/composition/border-left-width-composition.html +++ /dev/null
@@ -1,58 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-left-width', - underlying: '50px', - addFrom: '100px', - addTo: '200px', -}, [ - {at: -0.3, is: '120px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '200px'}, - {at: 1, is: '250px'}, - {at: 1.5, is: '300px'}, -]); - -assertComposition({ - property: 'border-left-width', - underlying: '100px', - addFrom: '10px', - addTo: '2px', -}, [ - {at: -0.5, is: '114px'}, - {at: 0, is: '110px'}, - {at: 0.5, is: '106px'}, - {at: 1, is: '102px'}, - {at: 1.5, is: '98px'}, // Value clamping should happen after composition. -]); - -assertComposition({ - property: 'border-left-width', - underlying: '10em', - addFrom: '100px', - addTo: '20em', -}, [ - {at: -0.3, is: 'calc(130px + 4em)'}, - {at: 0, is: 'calc(100px + 10em)'}, - {at: 0.5, is: 'calc(50px + 20em)'}, - {at: 1, is: '30em'}, - {at: 1.5, is: 'calc(-50px + 40em)'}, -]); - -assertComposition({ - property: 'border-left-width', - underlying: '50px', - addFrom: '100px', - replaceTo: '200px', -}, [ - {at: -0.3, is: '135px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.5, is: '225px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-right-width-composition.html b/third_party/blink/web_tests/animations/composition/border-right-width-composition.html deleted file mode 100644 index a41cfc1..0000000 --- a/third_party/blink/web_tests/animations/composition/border-right-width-composition.html +++ /dev/null
@@ -1,58 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-right-width', - underlying: '50px', - addFrom: '100px', - addTo: '200px', -}, [ - {at: -0.3, is: '120px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '200px'}, - {at: 1, is: '250px'}, - {at: 1.5, is: '300px'}, -]); - -assertComposition({ - property: 'border-right-width', - underlying: '100px', - addFrom: '10px', - addTo: '2px', -}, [ - {at: -0.5, is: '114px'}, - {at: 0, is: '110px'}, - {at: 0.5, is: '106px'}, - {at: 1, is: '102px'}, - {at: 1.5, is: '98px'}, // Value clamping should happen after composition. -]); - -assertComposition({ - property: 'border-right-width', - underlying: '10em', - addFrom: '100px', - addTo: '20em', -}, [ - {at: -0.3, is: 'calc(130px + 4em)'}, - {at: 0, is: 'calc(100px + 10em)'}, - {at: 0.5, is: 'calc(50px + 20em)'}, - {at: 1, is: '30em'}, - {at: 1.5, is: 'calc(-50px + 40em)'}, -]); - -assertComposition({ - property: 'border-right-width', - underlying: '50px', - addFrom: '100px', - replaceTo: '200px', -}, [ - {at: -0.3, is: '135px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.5, is: '225px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-top-left-radius-composition.html b/third_party/blink/web_tests/animations/composition/border-top-left-radius-composition.html deleted file mode 100644 index faf5aca..0000000 --- a/third_party/blink/web_tests/animations/composition/border-top-left-radius-composition.html +++ /dev/null
@@ -1,50 +0,0 @@ -<!DOCTYPE html> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-top-left-radius', - underlying: '40px 40px', - addFrom: '60px 60px', - addTo: '160px 160px', -}, [ - {at: -0.25, is: '75px'}, - {at: 0, is: '100px'}, - {at: 0.25, is: '125px'}, - {at: 0.5, is: '150px'}, - {at: 0.75, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.25, is: '225px'}, -]); - -assertComposition({ - property: 'border-top-left-radius', - underlying: '40px 140px', - replaceFrom: '100px 120px', - addTo: '160px 60px', -}, [ - {at: -0.25, is: '75px 100px'}, - {at: 0, is: '100px 120px'}, - {at: 0.25, is: '125px 140px'}, - {at: 0.5, is: '150px 160px'}, - {at: 0.75, is: '175px 180px'}, - {at: 1, is: '200px'}, - {at: 1.25, is: '225px 220px'}, -]); - -assertComposition({ - property: 'border-top-left-radius', - underlying: '40px 60px', - addFrom: '60px 140px', - replaceTo: '200px 120px', -}, [ - {at: -0.25, is: '75px 220px'}, - {at: 0, is: '100px 200px'}, - {at: 0.25, is: '125px 180px'}, - {at: 0.5, is: '150px 160px'}, - {at: 0.75, is: '175px 140px'}, - {at: 1, is: '200px 120px'}, - {at: 1.25, is: '225px 100px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-top-right-radius-composition.html b/third_party/blink/web_tests/animations/composition/border-top-right-radius-composition.html deleted file mode 100644 index ca246200..0000000 --- a/third_party/blink/web_tests/animations/composition/border-top-right-radius-composition.html +++ /dev/null
@@ -1,50 +0,0 @@ -<!DOCTYPE html> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-top-right-radius', - underlying: '40px 40px', - addFrom: '60px 60px', - addTo: '160px 160px', -}, [ - {at: -0.25, is: '75px'}, - {at: 0, is: '100px'}, - {at: 0.25, is: '125px'}, - {at: 0.5, is: '150px'}, - {at: 0.75, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.25, is: '225px'}, -]); - -assertComposition({ - property: 'border-top-right-radius', - underlying: '40px 140px', - replaceFrom: '100px 120px', - addTo: '160px 60px', -}, [ - {at: -0.25, is: '75px 100px'}, - {at: 0, is: '100px 120px'}, - {at: 0.25, is: '125px 140px'}, - {at: 0.5, is: '150px 160px'}, - {at: 0.75, is: '175px 180px'}, - {at: 1, is: '200px'}, - {at: 1.25, is: '225px 220px'}, -]); - -assertComposition({ - property: 'border-top-right-radius', - underlying: '40px 60px', - addFrom: '60px 140px', - replaceTo: '200px 120px', -}, [ - {at: -0.25, is: '75px 220px'}, - {at: 0, is: '100px 200px'}, - {at: 0.25, is: '125px 180px'}, - {at: 0.5, is: '150px 160px'}, - {at: 0.75, is: '175px 140px'}, - {at: 1, is: '200px 120px'}, - {at: 1.25, is: '225px 100px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/border-top-width-composition.html b/third_party/blink/web_tests/animations/composition/border-top-width-composition.html deleted file mode 100644 index 9ce9de2..0000000 --- a/third_party/blink/web_tests/animations/composition/border-top-width-composition.html +++ /dev/null
@@ -1,58 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'border-top-width', - underlying: '50px', - addFrom: '100px', - addTo: '200px', -}, [ - {at: -0.3, is: '120px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '200px'}, - {at: 1, is: '250px'}, - {at: 1.5, is: '300px'}, -]); - -assertComposition({ - property: 'border-top-width', - underlying: '100px', - addFrom: '10px', - addTo: '2px', -}, [ - {at: -0.5, is: '114px'}, - {at: 0, is: '110px'}, - {at: 0.5, is: '106px'}, - {at: 1, is: '102px'}, - {at: 1.5, is: '98px'}, // Value clamping should happen after composition. -]); - -assertComposition({ - property: 'border-top-width', - underlying: '10em', - addFrom: '100px', - addTo: '20em', -}, [ - {at: -0.3, is: 'calc(130px + 4em)'}, - {at: 0, is: 'calc(100px + 10em)'}, - {at: 0.5, is: 'calc(50px + 20em)'}, - {at: 1, is: '30em'}, - {at: 1.5, is: 'calc(-50px + 40em)'}, -]); - -assertComposition({ - property: 'border-top-width', - underlying: '50px', - addFrom: '100px', - replaceTo: '200px', -}, [ - {at: -0.3, is: '135px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.5, is: '225px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/letter-spacing-composition.html b/third_party/blink/web_tests/animations/composition/letter-spacing-composition.html deleted file mode 100644 index becabf70..0000000 --- a/third_party/blink/web_tests/animations/composition/letter-spacing-composition.html +++ /dev/null
@@ -1,45 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'letter-spacing', - underlying: '50px', - addFrom: '100px', - addTo: '200px', -}, [ - {at: -0.3, is: '120px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '200px'}, - {at: 1, is: '250px'}, - {at: 1.5, is: '300px'}, -]); - -assertComposition({ - property: 'letter-spacing', - underlying: '100px', - addFrom: '10px', - addTo: '2px', -}, [ - {at: -0.5, is: '114px'}, - {at: 0, is: '110px'}, - {at: 0.5, is: '106px'}, - {at: 1, is: '102px'}, - {at: 1.5, is: '98px'}, -]); - -assertComposition({ - property: 'letter-spacing', - underlying: '50px', - addFrom: '100px', - replaceTo: '200px', -}, [ - {at: -0.3, is: '135px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.5, is: '225px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/offset-anchor-composition.html b/third_party/blink/web_tests/animations/composition/offset-anchor-composition.html deleted file mode 100644 index 865d81b3..0000000 --- a/third_party/blink/web_tests/animations/composition/offset-anchor-composition.html +++ /dev/null
@@ -1,71 +0,0 @@ -<!DOCTYPE html> -<style> -.target { - width: 200px; - height: 200px; -} -</style> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'offset-anchor', - underlying: '40px 60px', - addFrom: '60px 40px', - addTo: '160px 140px', -}, [ - {at: -0.25, is: '75px 75px'}, - {at: 0, is: '100px 100px'}, - {at: 0.25, is: '125px 125px'}, - {at: 0.5, is: '150px 150px'}, - {at: 0.75, is: '175px 175px'}, - {at: 1, is: '200px 200px'}, - {at: 1.25, is: '225px 225px'}, -]); - -assertComposition({ - property: 'offset-anchor', - underlying: 'top 20% left 40%', - addFrom: 'left 60% top 80%', - addTo: 'right 80% bottom 40%', -}, [ - {at: -0.25, is: '110% 105%'}, - {at: 0, is: '100% 100%'}, - {at: 0.25, is: '90% 95%'}, - {at: 0.5, is: '80% 90%'}, - {at: 0.75, is: '70% 85%'}, - {at: 1, is: '60% 80%'}, - {at: 1.25, is: '50% 75%'}, -]); - -assertComposition({ - property: 'offset-anchor', - underlying: '40px 60px', - replaceFrom: '100px 200px', - addTo: '160px 40px', -}, [ - {at: -0.25, is: '75px 225px'}, - {at: 0, is: '100px 200px'}, - {at: 0.25, is: '125px 175px'}, - {at: 0.5, is: '150px 150px'}, - {at: 0.75, is: '175px 125px'}, - {at: 1, is: '200px 100px'}, - {at: 1.25, is: '225px 75px'}, -]); - -assertComposition({ - property: 'offset-anchor', - underlying: '40px 60px', - addFrom: '60px 140px', - replaceTo: '200px 100px', -}, [ - {at: -0.25, is: '75px 225px'}, - {at: 0, is: '100px 200px'}, - {at: 0.25, is: '125px 175px'}, - {at: 0.5, is: '150px 150px'}, - {at: 0.75, is: '175px 125px'}, - {at: 1, is: '200px 100px'}, - {at: 1.25, is: '225px 75px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/offset-distance-composition.html b/third_party/blink/web_tests/animations/composition/offset-distance-composition.html deleted file mode 100644 index 6a595895..0000000 --- a/third_party/blink/web_tests/animations/composition/offset-distance-composition.html +++ /dev/null
@@ -1,58 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'offset-distance', - underlying: '50px', - addFrom: '100px', - addTo: '200px', -}, [ - {at: -0.3, is: '120px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '200px'}, - {at: 1, is: '250px'}, - {at: 1.5, is: '300px'}, -]); - -assertComposition({ - property: 'offset-distance', - underlying: '100px', - addFrom: '10px', - addTo: '2px', -}, [ - {at: -0.5, is: '114px'}, - {at: 0, is: '110px'}, - {at: 0.5, is: '106px'}, - {at: 1, is: '102px'}, - {at: 1.5, is: '98px'}, -]); - -assertComposition({ - property: 'offset-distance', - underlying: '10%', - addFrom: '100px', - addTo: '20%', -}, [ - {at: -0.3, is: 'calc(130px + 4%)'}, - {at: 0, is: 'calc(100px + 10%)'}, - {at: 0.5, is: 'calc(50px + 20%)'}, - {at: 1, is: '30%'}, - {at: 1.5, is: 'calc(-50px + 40%)'}, -]); - -assertComposition({ - property: 'offset-distance', - underlying: '50px', - addFrom: '100px', - replaceTo: '200px', -}, [ - {at: -0.3, is: '135px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.5, is: '225px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/offset-path-composition.html b/third_party/blink/web_tests/animations/composition/offset-path-composition.html deleted file mode 100644 index 8d9e6c444..0000000 --- a/third_party/blink/web_tests/animations/composition/offset-path-composition.html +++ /dev/null
@@ -1,112 +0,0 @@ -<!DOCTYPE html> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> - -// TODO(ericwilligers) Support additive animation for path strings crbug.com/699308 - -// Ray paths compose. -assertComposition({ - property: 'offset-path', - underlying: 'ray(20deg sides)', - addFrom: 'ray(10deg sides)', - addTo: 'ray(20deg sides)', -}, [ - {at: -0.3, is: 'ray(27deg sides)'}, - {at: 0, is: 'ray(30deg sides)'}, - {at: 0.3, is: 'ray(33deg sides)'}, - {at: 0.6, is: 'ray(36deg sides)'}, - {at: 1, is: 'ray(40deg sides)'}, - {at: 1.5, is: 'ray(45deg sides)'}, -]); - -// Ray paths without contain don't compose with underlying contain. -assertComposition({ - property: 'offset-path', - underlying: 'ray(20deg closest-corner contain)', - addFrom: 'ray(10deg closest-corner)', - addTo: 'ray(20deg closest-corner)', -}, [ - {at: -0.3, is: 'ray(7deg closest-corner)'}, - {at: 0, is: 'ray(10deg closest-corner)'}, - {at: 0.3, is: 'ray(13deg closest-corner)'}, - {at: 0.6, is: 'ray(16deg closest-corner)'}, - {at: 1, is: 'ray(20deg closest-corner)'}, - {at: 1.5, is: 'ray(25deg closest-corner)'}, -]); - -// Ray paths don't compose when underlying has different size. -assertComposition({ - property: 'offset-path', - underlying: 'ray(20deg closest-side)', - addFrom: 'ray(10deg closest-corner)', - addTo: 'ray(20deg closest-corner)', -}, [ - {at: -0.3, is: 'ray(7deg closest-corner)'}, - {at: 0, is: 'ray(10deg closest-corner)'}, - {at: 0.3, is: 'ray(13deg closest-corner)'}, - {at: 0.6, is: 'ray(16deg closest-corner)'}, - {at: 1, is: 'ray(20deg closest-corner)'}, - {at: 1.5, is: 'ray(25deg closest-corner)'}, -]); - -// Ray contain paths compose with underlying contain. -assertComposition({ - property: 'offset-path', - underlying: 'ray(20deg farthest-side contain)', - addFrom: 'ray(190deg farthest-side contain)', - addTo: 'ray(20deg farthest-side contain)', -}, [ - {at: -0.3, is: 'ray(261deg farthest-side contain)'}, - {at: 0, is: 'ray(210deg farthest-side contain)'}, - {at: 0.3, is: 'ray(159deg farthest-side contain)'}, - {at: 0.6, is: 'ray(108deg farthest-side contain)'}, - {at: 1, is: 'ray(40deg farthest-side contain)'}, - {at: 1.5, is: 'ray(-45deg farthest-side contain)'}, -]); - -// When we can't interpolate, we can't compose. -assertComposition({ - property: 'offset-path', - underlying: 'ray(20deg farthest-corner)', - addFrom: 'ray(190deg farthest-corner contain)', - addTo: 'ray(20deg farthest-corner)', -}, [ - {at: -0.3, is: 'ray(190deg farthest-corner contain)'}, - {at: 0, is: 'ray(190deg farthest-corner contain)'}, - {at: 0.3, is: 'ray(190deg farthest-corner contain)'}, - {at: 0.6, is: 'ray(40deg farthest-corner)'}, - {at: 1, is: 'ray(40deg farthest-corner)'}, - {at: 1.5, is: 'ray(40deg farthest-corner)'}, -]); - -assertComposition({ - property: 'offset-path', - underlying: 'ray(20deg sides)', - replaceFrom: 'ray(190deg sides contain)', - addTo: 'ray(20deg sides)', -}, [ - {at: -0.3, is: 'ray(190deg sides contain)'}, - {at: 0, is: 'ray(190deg sides contain)'}, - {at: 0.3, is: 'ray(190deg sides contain)'}, - {at: 0.6, is: 'ray(40deg sides)'}, - {at: 1, is: 'ray(40deg sides)'}, - {at: 1.5, is: 'ray(40deg sides)'}, -]); - -// Ray paths compose with underlying. -assertComposition({ - property: 'offset-path', - underlying: 'ray(20deg closest-side)', - addFrom: 'ray(10deg closest-side)', - replaceTo: 'ray(10deg closest-side)', -}, [ - {at: -0.3, is: 'ray(36deg closest-side)'}, - {at: 0, is: 'ray(30deg closest-side)'}, - {at: 0.3, is: 'ray(24deg closest-side)'}, - {at: 0.6, is: 'ray(18deg closest-side)'}, - {at: 1, is: 'ray(10deg closest-side)'}, - {at: 1.5, is: 'ray(0deg closest-side)'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/offset-position-composition.html b/third_party/blink/web_tests/animations/composition/offset-position-composition.html deleted file mode 100644 index a724978..0000000 --- a/third_party/blink/web_tests/animations/composition/offset-position-composition.html +++ /dev/null
@@ -1,71 +0,0 @@ -<!DOCTYPE html> -<style> -.target { - width: 200px; - height: 200px; -} -</style> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'offset-position', - underlying: '40px 60px', - addFrom: '60px 40px', - addTo: '160px 140px', -}, [ - {at: -0.25, is: '75px 75px'}, - {at: 0, is: '100px 100px'}, - {at: 0.25, is: '125px 125px'}, - {at: 0.5, is: '150px 150px'}, - {at: 0.75, is: '175px 175px'}, - {at: 1, is: '200px 200px'}, - {at: 1.25, is: '225px 225px'}, -]); - -assertComposition({ - property: 'offset-position', - underlying: 'top 20% left 40%', - addFrom: 'left 60% top 80%', - addTo: 'right 80% bottom 40%', -}, [ - {at: -0.25, is: '110% 105%'}, - {at: 0, is: '100% 100%'}, - {at: 0.25, is: '90% 95%'}, - {at: 0.5, is: '80% 90%'}, - {at: 0.75, is: '70% 85%'}, - {at: 1, is: '60% 80%'}, - {at: 1.25, is: '50% 75%'}, -]); - -assertComposition({ - property: 'offset-position', - underlying: '40px 60px', - replaceFrom: '100px 200px', - addTo: '160px 40px', -}, [ - {at: -0.25, is: '75px 225px'}, - {at: 0, is: '100px 200px'}, - {at: 0.25, is: '125px 175px'}, - {at: 0.5, is: '150px 150px'}, - {at: 0.75, is: '175px 125px'}, - {at: 1, is: '200px 100px'}, - {at: 1.25, is: '225px 75px'}, -]); - -assertComposition({ - property: 'offset-position', - underlying: '40px 60px', - addFrom: '60px 140px', - replaceTo: '200px 100px', -}, [ - {at: -0.25, is: '75px 225px'}, - {at: 0, is: '100px 200px'}, - {at: 0.25, is: '125px 175px'}, - {at: 0.5, is: '150px 150px'}, - {at: 0.75, is: '175px 125px'}, - {at: 1, is: '200px 100px'}, - {at: 1.25, is: '225px 75px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/offset-rotate-composition.html b/third_party/blink/web_tests/animations/composition/offset-rotate-composition.html deleted file mode 100644 index 2f566546..0000000 --- a/third_party/blink/web_tests/animations/composition/offset-rotate-composition.html +++ /dev/null
@@ -1,94 +0,0 @@ -<!DOCTYPE html> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -// Angle rotations compose. -assertComposition({ - property: 'offset-rotate', - underlying: '20deg', - addFrom: '10deg', - addTo: '20deg', -}, [ - {at: -0.3, is: '27deg'}, - {at: 0, is: '30deg'}, - {at: 0.3, is: '33deg'}, - {at: 0.6, is: '36deg'}, - {at: 1, is: '40deg'}, - {at: 1.5, is: '45deg'}, -]); - -// Angle rotations don't compose with underlying 'auto'. -assertComposition({ - property: 'offset-rotate', - underlying: 'auto 20deg', - addFrom: '10deg', - addTo: '20deg', -}, [ - {at: -0.3, is: '7deg'}, - {at: 0, is: '10deg'}, - {at: 0.3, is: '13deg'}, - {at: 0.6, is: '16deg'}, - {at: 1, is: '20deg'}, - {at: 1.5, is: '25deg'}, -]); - -// Auto rotations compose with underlying 'auto'. -assertComposition({ - property: 'offset-rotate', - underlying: 'auto 20deg', - addFrom: 'reverse 10deg', - addTo: 'auto 20deg', -}, [ - {at: -0.3, is: 'auto 261deg'}, - {at: 0, is: 'auto 210deg'}, - {at: 0.3, is: 'auto 159deg'}, - {at: 0.6, is: 'auto 108deg'}, - {at: 1, is: 'auto 40deg'}, - {at: 1.5, is: 'auto -45deg'}, -]); - -// When we can't interpolate, we can't compose. -assertComposition({ - property: 'offset-rotate', - underlying: '20deg', - addFrom: 'reverse 10deg', - addTo: '20deg', -}, [ - {at: -0.3, is: 'auto 190deg'}, - {at: 0, is: 'auto 190deg'}, - {at: 0.3, is: 'auto 190deg'}, - {at: 0.6, is: '40deg'}, - {at: 1, is: '40deg'}, - {at: 1.5, is: '40deg'}, -]); - -assertComposition({ - property: 'offset-rotate', - underlying: '20deg', - replaceFrom: 'reverse 10deg', - addTo: '20deg', -}, [ - {at: -0.3, is: 'auto 190deg'}, - {at: 0, is: 'auto 190deg'}, - {at: 0.3, is: 'auto 190deg'}, - {at: 0.6, is: '40deg'}, - {at: 1, is: '40deg'}, - {at: 1.5, is: '40deg'}, -]); - -// Angle rotations compose with underlying angle. -assertComposition({ - property: 'offset-rotate', - underlying: '20deg', - addFrom: '10deg', - replaceTo: '10deg', -}, [ - {at: -0.3, is: '36deg'}, - {at: 0, is: '30deg'}, - {at: 0.3, is: '24deg'}, - {at: 0.6, is: '18deg'}, - {at: 1, is: '10deg'}, - {at: 1.5, is: '0deg'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/text-indent-composition.html b/third_party/blink/web_tests/animations/composition/text-indent-composition.html deleted file mode 100644 index 1fe8c9a..0000000 --- a/third_party/blink/web_tests/animations/composition/text-indent-composition.html +++ /dev/null
@@ -1,77 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body></body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'text-indent', - underlying: '100%', - addFrom: '50px', - addTo: '150px', -}, [ - {at: -0.3, is: 'calc(100% + 20px)'}, - {at: 0, is: 'calc(100% + 50px)'}, - {at: 0.3, is: 'calc(100% + 80px)'}, - {at: 0.6, is: 'calc(100% + 110px)'}, - {at: 1, is: 'calc(100% + 150px)'}, - {at: 1.5, is: 'calc(100% + 200px)'}, -]); - -assertComposition({ - property: 'text-indent', - underlying: '250px', - addFrom: '50px', - replaceTo: '100px', -}, [ - {at: -0.3, is: '360px'}, - {at: 0, is: '300px'}, - {at: 0.3, is: '240px'}, - {at: 0.6, is: '180px'}, - {at: 1, is: '100px'}, - {at: 1.5, is: '0px'}, -]); - -assertComposition({ - property: 'text-indent', - underlying: '50%', - replaceFrom: '-100%', - addTo: '50%', -}, [ - {at: -0.3, is: '-160%'}, - {at: 0, is: '-100%'}, - {at: 0.3, is: '-40%'}, - {at: 0.5, is: '0%'}, - {at: 0.6, is: '20%'}, - {at: 1, is: '100%'}, - {at: 1.5, is: '200%'}, -]); - -assertComposition({ - property: 'text-indent', - underlying: '250px', - addFrom: '50px each-line hanging', - replaceTo: '150px hanging each-line', -}, [ - {at: -0.3, is: '20px hanging each-line'}, - {at: 0, is: '50px hanging each-line'}, - {at: 0.3, is: '80px hanging each-line'}, - {at: 0.6, is: '110px hanging each-line'}, - {at: 1, is: '150px hanging each-line'}, - {at: 1.5, is: '200px hanging each-line'}, -]); - -assertComposition({ - property: 'text-indent', - underlying: '250px each-line', - addFrom: '50px each-line', - replaceTo: '150px hanging', -}, [ - {at: -0.3, is: '300px each-line'}, - {at: 0, is: '300px each-line'}, - {at: 0.3, is: '300px each-line'}, - {at: 0.6, is: '150px hanging'}, - {at: 1, is: '150px hanging'}, - {at: 1.5, is: '150px hanging'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/animations/composition/word-spacing-composition.html b/third_party/blink/web_tests/animations/composition/word-spacing-composition.html deleted file mode 100644 index 7bcb3a9..0000000 --- a/third_party/blink/web_tests/animations/composition/word-spacing-composition.html +++ /dev/null
@@ -1,45 +0,0 @@ -<!DOCTYPE html> -<meta charset="UTF-8"> -<body> -<script src="../interpolation/resources/interpolation-test.js"></script> -<script> -assertComposition({ - property: 'word-spacing', - underlying: '50px', - addFrom: '100px', - addTo: '200px', -}, [ - {at: -0.3, is: '120px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '200px'}, - {at: 1, is: '250px'}, - {at: 1.5, is: '300px'}, -]); - -assertComposition({ - property: 'word-spacing', - underlying: '100px', - addFrom: '10px', - addTo: '2px', -}, [ - {at: -0.5, is: '114px'}, - {at: 0, is: '110px'}, - {at: 0.5, is: '106px'}, - {at: 1, is: '102px'}, - {at: 1.5, is: '98px'}, -]); - -assertComposition({ - property: 'word-spacing', - underlying: '50px', - addFrom: '100px', - replaceTo: '200px', -}, [ - {at: -0.3, is: '135px'}, - {at: 0, is: '150px'}, - {at: 0.5, is: '175px'}, - {at: 1, is: '200px'}, - {at: 1.5, is: '225px'}, -]); -</script> -</body>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index 15eba57..0f3b0d8 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -209888,12 +209888,24 @@ {} ] ], + "css/css-align/animation/column-gap-composition.html": [ + [ + "css/css-align/animation/column-gap-composition.html", + {} + ] + ], "css/css-align/animation/column-gap-interpolation.html": [ [ "css/css-align/animation/column-gap-interpolation.html", {} ] ], + "css/css-align/animation/row-gap-composition.html": [ + [ + "css/css-align/animation/row-gap-composition.html", + {} + ] + ], "css/css-align/animation/row-gap-interpolation.html": [ [ "css/css-align/animation/row-gap-interpolation.html", @@ -210980,18 +210992,48 @@ {} ] ], + "css/css-backgrounds/animations/border-bottom-left-radius-composition.html": [ + [ + "css/css-backgrounds/animations/border-bottom-left-radius-composition.html", + {} + ] + ], + "css/css-backgrounds/animations/border-bottom-right-radius-composition.html": [ + [ + "css/css-backgrounds/animations/border-bottom-right-radius-composition.html", + {} + ] + ], + "css/css-backgrounds/animations/border-bottom-width-composition.html": [ + [ + "css/css-backgrounds/animations/border-bottom-width-composition.html", + {} + ] + ], "css/css-backgrounds/animations/border-color-interpolation.html": [ [ "css/css-backgrounds/animations/border-color-interpolation.html", {} ] ], + "css/css-backgrounds/animations/border-image-outset-composition.html": [ + [ + "css/css-backgrounds/animations/border-image-outset-composition.html", + {} + ] + ], "css/css-backgrounds/animations/border-image-outset-interpolation.html": [ [ "css/css-backgrounds/animations/border-image-outset-interpolation.html", {} ] ], + "css/css-backgrounds/animations/border-image-slice-composition.html": [ + [ + "css/css-backgrounds/animations/border-image-slice-composition.html", + {} + ] + ], "css/css-backgrounds/animations/border-image-slice-interpolation-stability.html": [ [ "css/css-backgrounds/animations/border-image-slice-interpolation-stability.html", @@ -211010,18 +211052,54 @@ {} ] ], + "css/css-backgrounds/animations/border-image-width-composition.html": [ + [ + "css/css-backgrounds/animations/border-image-width-composition.html", + {} + ] + ], "css/css-backgrounds/animations/border-image-width-interpolation.html": [ [ "css/css-backgrounds/animations/border-image-width-interpolation.html", {} ] ], + "css/css-backgrounds/animations/border-left-width-composition.html": [ + [ + "css/css-backgrounds/animations/border-left-width-composition.html", + {} + ] + ], "css/css-backgrounds/animations/border-radius-interpolation.html": [ [ "css/css-backgrounds/animations/border-radius-interpolation.html", {} ] ], + "css/css-backgrounds/animations/border-right-width-composition.html": [ + [ + "css/css-backgrounds/animations/border-right-width-composition.html", + {} + ] + ], + "css/css-backgrounds/animations/border-top-left-radius-composition.html": [ + [ + "css/css-backgrounds/animations/border-top-left-radius-composition.html", + {} + ] + ], + "css/css-backgrounds/animations/border-top-right-radius-composition.html": [ + [ + "css/css-backgrounds/animations/border-top-right-radius-composition.html", + {} + ] + ], + "css/css-backgrounds/animations/border-top-width-composition.html": [ + [ + "css/css-backgrounds/animations/border-top-width-composition.html", + {} + ] + ], "css/css-backgrounds/animations/border-width-interpolation.html": [ [ "css/css-backgrounds/animations/border-width-interpolation.html", @@ -211532,18 +211610,66 @@ {} ] ], + "css/css-box/animation/margin-bottom-composition.html": [ + [ + "css/css-box/animation/margin-bottom-composition.html", + {} + ] + ], "css/css-box/animation/margin-interpolation.html": [ [ "css/css-box/animation/margin-interpolation.html", {} ] ], + "css/css-box/animation/margin-left-composition.html": [ + [ + "css/css-box/animation/margin-left-composition.html", + {} + ] + ], + "css/css-box/animation/margin-right-composition.html": [ + [ + "css/css-box/animation/margin-right-composition.html", + {} + ] + ], + "css/css-box/animation/margin-top-composition.html": [ + [ + "css/css-box/animation/margin-top-composition.html", + {} + ] + ], + "css/css-box/animation/padding-bottom-composition.html": [ + [ + "css/css-box/animation/padding-bottom-composition.html", + {} + ] + ], "css/css-box/animation/padding-interpolation.html": [ [ "css/css-box/animation/padding-interpolation.html", {} ] ], + "css/css-box/animation/padding-left-composition.html": [ + [ + "css/css-box/animation/padding-left-composition.html", + {} + ] + ], + "css/css-box/animation/padding-right-composition.html": [ + [ + "css/css-box/animation/padding-right-composition.html", + {} + ] + ], + "css/css-box/animation/padding-top-composition.html": [ + [ + "css/css-box/animation/padding-top-composition.html", + {} + ] + ], "css/css-box/box-chrome-crash-001.html": [ [ "css/css-box/box-chrome-crash-001.html", @@ -218992,12 +219118,24 @@ {} ] ], + "css/css-shapes/animation/shape-margin-composition.html": [ + [ + "css/css-shapes/animation/shape-margin-composition.html", + {} + ] + ], "css/css-shapes/animation/shape-margin-interpolation.html": [ [ "css/css-shapes/animation/shape-margin-interpolation.html", {} ] ], + "css/css-shapes/animation/shape-outside-composition.html": [ + [ + "css/css-shapes/animation/shape-outside-composition.html", + {} + ] + ], "css/css-shapes/animation/shape-outside-interpolation.html": [ [ "css/css-shapes/animation/shape-outside-interpolation.html", @@ -219664,36 +219802,72 @@ {} ] ], + "css/css-sizing/animation/height-composition.html": [ + [ + "css/css-sizing/animation/height-composition.html", + {} + ] + ], "css/css-sizing/animation/height-interpolation.html": [ [ "css/css-sizing/animation/height-interpolation.html", {} ] ], + "css/css-sizing/animation/max-height-composition.html": [ + [ + "css/css-sizing/animation/max-height-composition.html", + {} + ] + ], "css/css-sizing/animation/max-height-interpolation.html": [ [ "css/css-sizing/animation/max-height-interpolation.html", {} ] ], + "css/css-sizing/animation/max-width-composition.html": [ + [ + "css/css-sizing/animation/max-width-composition.html", + {} + ] + ], "css/css-sizing/animation/max-width-interpolation.html": [ [ "css/css-sizing/animation/max-width-interpolation.html", {} ] ], + "css/css-sizing/animation/min-height-composition.html": [ + [ + "css/css-sizing/animation/min-height-composition.html", + {} + ] + ], "css/css-sizing/animation/min-height-interpolation.html": [ [ "css/css-sizing/animation/min-height-interpolation.html", {} ] ], + "css/css-sizing/animation/min-width-composition.html": [ + [ + "css/css-sizing/animation/min-width-composition.html", + {} + ] + ], "css/css-sizing/animation/min-width-interpolation.html": [ [ "css/css-sizing/animation/min-width-interpolation.html", {} ] ], + "css/css-sizing/animation/width-composition.html": [ + [ + "css/css-sizing/animation/width-composition.html", + {} + ] + ], "css/css-sizing/animation/width-interpolation.html": [ [ "css/css-sizing/animation/width-interpolation.html", @@ -220864,18 +221038,36 @@ {} ] ], + "css/css-text/animations/letter-spacing-composition.html": [ + [ + "css/css-text/animations/letter-spacing-composition.html", + {} + ] + ], "css/css-text/animations/letter-spacing-interpolation.html": [ [ "css/css-text/animations/letter-spacing-interpolation.html", {} ] ], + "css/css-text/animations/text-indent-composition.html": [ + [ + "css/css-text/animations/text-indent-composition.html", + {} + ] + ], "css/css-text/animations/text-indent-interpolation.html": [ [ "css/css-text/animations/text-indent-interpolation.html", {} ] ], + "css/css-text/animations/word-spacing-composition.html": [ + [ + "css/css-text/animations/word-spacing-composition.html", + {} + ] + ], "css/css-text/animations/word-spacing-interpolation.html": [ [ "css/css-text/animations/word-spacing-interpolation.html", @@ -225384,6 +225576,12 @@ {} ] ], + "css/css-ui/animation/caret-color-composition.html": [ + [ + "css/css-ui/animation/caret-color-composition.html", + {} + ] + ], "css/css-ui/animation/caret-color-interpolation.html": [ [ "css/css-ui/animation/caret-color-interpolation.html", @@ -225396,12 +225594,24 @@ {} ] ], + "css/css-ui/animation/outline-offset-composition.html": [ + [ + "css/css-ui/animation/outline-offset-composition.html", + {} + ] + ], "css/css-ui/animation/outline-offset-interpolation.html": [ [ "css/css-ui/animation/outline-offset-interpolation.html", {} ] ], + "css/css-ui/animation/outline-width-composition.html": [ + [ + "css/css-ui/animation/outline-width-composition.html", + {} + ] + ], "css/css-ui/animation/outline-width-interpolation.html": [ [ "css/css-ui/animation/outline-width-interpolation.html", @@ -228478,12 +228688,24 @@ {} ] ], + "css/motion/animation/offset-anchor-composition.html": [ + [ + "css/motion/animation/offset-anchor-composition.html", + {} + ] + ], "css/motion/animation/offset-anchor-interpolation.html": [ [ "css/motion/animation/offset-anchor-interpolation.html", {} ] ], + "css/motion/animation/offset-distance-composition.html": [ + [ + "css/motion/animation/offset-distance-composition.html", + {} + ] + ], "css/motion/animation/offset-distance-interpolation.html": [ [ "css/motion/animation/offset-distance-interpolation.html", @@ -228496,6 +228718,12 @@ {} ] ], + "css/motion/animation/offset-path-composition.html": [ + [ + "css/motion/animation/offset-path-composition.html", + {} + ] + ], "css/motion/animation/offset-path-interpolation-001.html": [ [ "css/motion/animation/offset-path-interpolation-001.html", @@ -228526,12 +228754,24 @@ {} ] ], + "css/motion/animation/offset-position-composition.html": [ + [ + "css/motion/animation/offset-position-composition.html", + {} + ] + ], "css/motion/animation/offset-position-interpolation.html": [ [ "css/motion/animation/offset-position-interpolation.html", {} ] ], + "css/motion/animation/offset-rotate-composition.html": [ + [ + "css/motion/animation/offset-rotate-composition.html", + {} + ] + ], "css/motion/animation/offset-rotate-interpolation.html": [ [ "css/motion/animation/offset-rotate-interpolation.html", @@ -264350,14 +264590,6 @@ {} ] ], - "layout-instability/observe-layout-shift.html": [ - [ - "layout-instability/observe-layout-shift.html", - { - "testdriver": true - } - ] - ], "layout-instability/partially-clipped-visual-rect.html": [ [ "layout-instability/partially-clipped-visual-rect.html", @@ -264380,6 +264612,14 @@ } ] ], + "layout-instability/recent-input.html": [ + [ + "layout-instability/recent-input.html", + { + "testdriver": true + } + ] + ], "layout-instability/rtl-distance.html": [ [ "layout-instability/rtl-distance.html", @@ -369247,10 +369487,18 @@ "01fa028a7d933a5a7480efb28cf565e7b7de845c", "support" ], + "css/css-align/animation/column-gap-composition.html": [ + "0054206cca8b3448ad5d19e055e9f435a6e123b1", + "testharness" + ], "css/css-align/animation/column-gap-interpolation.html": [ "c2f02d3ba87f4dee555be80caa45d6909e2495ae", "testharness" ], + "css/css-align/animation/row-gap-composition.html": [ + "238253adf0cda81aca80d9345219ac8cd8e0df50", + "testharness" + ], "css/css-align/animation/row-gap-interpolation.html": [ "1d85ffa3b07e8695e7b3a6ad82c02ae4da8d7b21", "testharness" @@ -370419,10 +370667,26 @@ "f6a480c7bd2ccc4a6c46fa2eade5e7231fab4938", "testharness" ], + "css/css-backgrounds/animations/border-bottom-left-radius-composition.html": [ + "87042d1969d59b6865761c60beaeba5219c6148c", + "testharness" + ], + "css/css-backgrounds/animations/border-bottom-right-radius-composition.html": [ + "2b5a72df6914f571ca00418484d9f782cd46aa63", + "testharness" + ], + "css/css-backgrounds/animations/border-bottom-width-composition.html": [ + "5377c0ab42b44623c1d7e0aa81344345db795f68", + "testharness" + ], "css/css-backgrounds/animations/border-color-interpolation.html": [ "3e7843b8a07577970279ef9a4e14bfb83c1816f0", "testharness" ], + "css/css-backgrounds/animations/border-image-outset-composition.html": [ + "e3311711753e34295eb3c7c83d5aee3d4cd684aa", + "testharness" + ], "css/css-backgrounds/animations/border-image-outset-interpolation-expected.txt": [ "6ca6cb7701110980a1adbf8f5e1cde9edda2cba6", "support" @@ -370431,6 +370695,10 @@ "aebadbbafb236a090aa543ecf82e5661bee7de74", "testharness" ], + "css/css-backgrounds/animations/border-image-slice-composition.html": [ + "d0ccb1a3a64f2b3fe75b4957dc0a75036c3cd392", + "testharness" + ], "css/css-backgrounds/animations/border-image-slice-interpolation-stability.html": [ "26431334e4acf13f6c095868a0e9cee6926a9ef1", "testharness" @@ -370447,14 +370715,38 @@ "60dcfceddc791737487fab07ea7035fac40856d6", "testharness" ], + "css/css-backgrounds/animations/border-image-width-composition.html": [ + "0d0a1dc4ed263c80b472e3ba241fffeaf771d6aa", + "testharness" + ], "css/css-backgrounds/animations/border-image-width-interpolation.html": [ "ea138201b15805cd86d8a63ed37b401b103bfee2", "testharness" ], + "css/css-backgrounds/animations/border-left-width-composition.html": [ + "1b90effbc32cd56e9120fec92158f518a67d6ae8", + "testharness" + ], "css/css-backgrounds/animations/border-radius-interpolation.html": [ "195469e83164c965ee33b6277983870100bda111", "testharness" ], + "css/css-backgrounds/animations/border-right-width-composition.html": [ + "aa9e1dcc66764c2ec8c072cbf9365529e3729d88", + "testharness" + ], + "css/css-backgrounds/animations/border-top-left-radius-composition.html": [ + "1c2056bc010a82228416983897c63676ac3aeb0f", + "testharness" + ], + "css/css-backgrounds/animations/border-top-right-radius-composition.html": [ + "9a26d51375e78bfe54ba7a3689f6b72fe6c36417", + "testharness" + ], + "css/css-backgrounds/animations/border-top-width-composition.html": [ + "475c3930b9d1704267267ff30d747b266ea3d851", + "testharness" + ], "css/css-backgrounds/animations/border-width-interpolation.html": [ "11f92f41652a9f1b167c5a399849d1e1e61c4df7", "testharness" @@ -374215,14 +374507,46 @@ "dde409360faf79a301c3ae3ea34a995d154d7bb4", "support" ], + "css/css-box/animation/margin-bottom-composition.html": [ + "c95f8de23efe6e853dd4b05eed07af01c1d02af7", + "testharness" + ], "css/css-box/animation/margin-interpolation.html": [ "088836cbbd18d0daf203de7dbacfb65733e35813", "testharness" ], + "css/css-box/animation/margin-left-composition.html": [ + "8f3c646dfec219d30d2fefafdcb89c9e7cabb2b5", + "testharness" + ], + "css/css-box/animation/margin-right-composition.html": [ + "c903303313bcc06ecf67f86efc55b21537e4af4c", + "testharness" + ], + "css/css-box/animation/margin-top-composition.html": [ + "5f050bd6c7d9663025d53a04ecd2ec6352275fba", + "testharness" + ], + "css/css-box/animation/padding-bottom-composition.html": [ + "855b5d3dc2948a9dc4ae391aaaa5caee06f88665", + "testharness" + ], "css/css-box/animation/padding-interpolation.html": [ "3bf284117960fe78300e95140244d309f8f439a4", "testharness" ], + "css/css-box/animation/padding-left-composition.html": [ + "417777ae253428cf6c852e6846960494a8ea53f7", + "testharness" + ], + "css/css-box/animation/padding-right-composition.html": [ + "3c80849bb2bc68a68c098f42a1a29b9247e6a224", + "testharness" + ], + "css/css-box/animation/padding-top-composition.html": [ + "b5083ae79b3db8a55f7af45373804d223cbbbc47", + "testharness" + ], "css/css-box/box-chrome-crash-001.html": [ "351df37f1550ab40818b7f7f1c51191cfae5583e", "testharness" @@ -402151,10 +402475,18 @@ "edac744592f76704ba82b0c4a7e5a53c7db6ba79", "testharness" ], + "css/css-shapes/animation/shape-margin-composition.html": [ + "395bad063f4c1bfb036d650d6b0319cd3d572fe2", + "testharness" + ], "css/css-shapes/animation/shape-margin-interpolation.html": [ "48b3d0c460794b18261ce7a6beedf980d8335d36", "testharness" ], + "css/css-shapes/animation/shape-outside-composition.html": [ + "0115148ec1adde1a32b1c1fb4b3c33ea8b56ece0", + "testharness" + ], "css/css-shapes/animation/shape-outside-interpolation.html": [ "3380acdba00db8e9440b33c60275f6fd6340d345", "testharness" @@ -403471,26 +403803,50 @@ "086e654a8e039f259b5e828d024f808c2e95016b", "support" ], + "css/css-sizing/animation/height-composition.html": [ + "094e247dcf22d9bd665b244993b6239265ee73bb", + "testharness" + ], "css/css-sizing/animation/height-interpolation.html": [ "10ceed5b2cc0d5511b8020aeaced36be39834c3a", "testharness" ], + "css/css-sizing/animation/max-height-composition.html": [ + "fb5b241d00865fe68c198a9fee88d932a8977f7e", + "testharness" + ], "css/css-sizing/animation/max-height-interpolation.html": [ "c4cab0e1cf4534d3705801f3159b6b8724977b66", "testharness" ], + "css/css-sizing/animation/max-width-composition.html": [ + "8b6d8b704c8771491419db0aa2a3c783a1dea2b3", + "testharness" + ], "css/css-sizing/animation/max-width-interpolation.html": [ "111199baa7ed89c6023d43b56313413cc5aeeeeb", "testharness" ], + "css/css-sizing/animation/min-height-composition.html": [ + "1e92b0ec2fd664e7b3dd6dc1cd8310c7b9526e7c", + "testharness" + ], "css/css-sizing/animation/min-height-interpolation.html": [ "6fd5b4e2f5366f6b18678f60b982e82905558e51", "testharness" ], + "css/css-sizing/animation/min-width-composition.html": [ + "e8bd41030bbd8a273f7e7c45f5f445d706d044eb", + "testharness" + ], "css/css-sizing/animation/min-width-interpolation.html": [ "d11fb3d5cb139f870d1eb40618bf547176f109b1", "testharness" ], + "css/css-sizing/animation/width-composition.html": [ + "bfe45cb31471d0c8623dbb9e84000bc1208bb76f", + "testharness" + ], "css/css-sizing/animation/width-interpolation.html": [ "d165c994b5de6fe1561498aa04c075196357f5f6", "testharness" @@ -406159,14 +406515,26 @@ "9b2e5be0a19c48f73b57fe0ad8bbeea81238a1d1", "support" ], + "css/css-text/animations/letter-spacing-composition.html": [ + "c1b614b5ebaa5bc190a080bd8da5694096a2be20", + "testharness" + ], "css/css-text/animations/letter-spacing-interpolation.html": [ "7d4958113915913bb8a3a5af13f5cee90b080825", "testharness" ], + "css/css-text/animations/text-indent-composition.html": [ + "57c528ca271646a284048bb49e11025ac25469da", + "testharness" + ], "css/css-text/animations/text-indent-interpolation.html": [ "2269fdfa5b60f6f4a8d63a7f777e6abbf499c4b7", "testharness" ], + "css/css-text/animations/word-spacing-composition.html": [ + "17aacaef1506eddbc8ef40ade114a856310a508e", + "testharness" + ], "css/css-text/animations/word-spacing-interpolation.html": [ "ffd6bb476ad87976a1183cde70a10892bab77982", "testharness" @@ -420583,6 +420951,10 @@ "5f43f9116bc8073cfadd3bf840519a3ad96c296f", "support" ], + "css/css-ui/animation/caret-color-composition.html": [ + "6c69578677896e2463331deba85731e13fd94a25", + "testharness" + ], "css/css-ui/animation/caret-color-interpolation.html": [ "b3a4e30130843163d76a0a24196c66853bd4160a", "testharness" @@ -420591,10 +420963,18 @@ "f49aa79a382c8e5a8f4c9d834f5f12aea551818f", "testharness" ], + "css/css-ui/animation/outline-offset-composition.html": [ + "984a63fdc34274fab133308dbb0b9a5c2eca03b9", + "testharness" + ], "css/css-ui/animation/outline-offset-interpolation.html": [ "46c1c51c6eefaa490fc9d55e4cadfb0cb7804337", "testharness" ], + "css/css-ui/animation/outline-width-composition.html": [ + "b770feda61ca6c74467c597749a053d3569af012", + "testharness" + ], "css/css-ui/animation/outline-width-interpolation.html": [ "c024c7cf6a08e0f6e02ccb451ca04d0b4a8c9251", "testharness" @@ -434195,10 +434575,18 @@ "d10225e4dc5237552bb74812dc35edb193a481de", "support" ], + "css/motion/animation/offset-anchor-composition.html": [ + "53210fdf38a86ec9f4e852a33527fc88b1eb9fe3", + "testharness" + ], "css/motion/animation/offset-anchor-interpolation.html": [ "9c69c0f0bed2b14c02091ccf63f50ace61f2eb2a", "testharness" ], + "css/motion/animation/offset-distance-composition.html": [ + "4ff6e95b05792505b2f98c511f5a80d64e86624d", + "testharness" + ], "css/motion/animation/offset-distance-interpolation.html": [ "bc0c094a8e5305c970f0a4d44ee8a3726d2965a1", "testharness" @@ -434207,6 +434595,10 @@ "2ee011bd77a975e9b566d24658995693c574f620", "testharness" ], + "css/motion/animation/offset-path-composition.html": [ + "eedd363efafe05b870314ad797d9dc63f2c7409c", + "testharness" + ], "css/motion/animation/offset-path-interpolation-001.html": [ "5b90813bb591d0aa7e17eeddcb1a9e3a908670f0", "testharness" @@ -434227,10 +434619,18 @@ "9924106f4b75ede89e5270a76fe217f85ef20050", "testharness" ], + "css/motion/animation/offset-position-composition.html": [ + "0ee517a73a8e9e673a83a0f81bbdea98d6a3d808", + "testharness" + ], "css/motion/animation/offset-position-interpolation.html": [ "9faaf9487afb20059046e95a8cd5b3a796e8fd42", "testharness" ], + "css/motion/animation/offset-rotate-composition.html": [ + "bf60c19abeffafa36c50f1d1da0e9f9d64b1a151", + "testharness" + ], "css/motion/animation/offset-rotate-interpolation.html": [ "55845108ebf5f3c42a8b0532121199136160d695", "testharness" @@ -475236,7 +475636,7 @@ "support" ], "interfaces/webaudio.idl": [ - "674673d90b1e8fd3e6d182f25289948fc0290cac", + "9491090337c342fc06a35a97ee6dc6887829c1bc", "support" ], "interfaces/webauthn.idl": [ @@ -475272,7 +475672,7 @@ "support" ], "interfaces/webrtc.idl": [ - "e30fc38fd003a283ebb4184786d181c5b4293dc4", + "49ed6bb0333020a6eee8d5411ae88a4e3a7dbd9a", "support" ], "interfaces/webusb.idl": [ @@ -475860,11 +476260,11 @@ "testharness" ], "layout-instability/buffer-layout-shift.html": [ - "0cfce2f7124226cf4256284c1238ba1ef024c42b", + "b6a33f579b4009d1497fdc104c07633793d53f01", "testharness" ], "layout-instability/buffered-flag.html": [ - "dabc8068931ff3b15eb4b80481ed2102a7725a62", + "cd1260e3613f58c191688ab2f492647b0cc72c0c", "testharness" ], "layout-instability/clip-negative-bottom-margin.html": [ @@ -475895,10 +476295,6 @@ "36475d4c826c11807e9c0a7fbf4457c33c92c2c0", "testharness" ], - "layout-instability/observe-layout-shift.html": [ - "1c35fe2aa234c96fce8798e6a1c35362f418e6f1", - "testharness" - ], "layout-instability/partially-clipped-visual-rect.html": [ "3b18b98dd93312c37b9e2f25918df50266a09243", "testharness" @@ -475911,6 +476307,10 @@ "e2e7a911dc043bb21cebfd4a5b625795f3523a14", "testharness" ], + "layout-instability/recent-input.html": [ + "a4fa0d8b0d92a83984034926de30958b840c1028", + "testharness" + ], "layout-instability/resources/slow-image.py": [ "ee7988c551f6429eea2b929af083ad30cbd5c73d", "support" @@ -475948,7 +476348,7 @@ "testharness" ], "layout-instability/toJSON.html": [ - "3d39d623e13314b183463fa1c365df3a7b725243", + "374a7de0cd1c4d5d5b089b7d026c8eb5709e91f1", "testharness" ], "layout-instability/transform.html": [ @@ -525204,7 +525604,7 @@ "testharness" ], "web-animations/timing-model/animations/setting-the-playback-rate-of-an-animation.html": [ - "0522c43b16a881a14b339294e5ed56b8ae064f92", + "a1f9e4f3acea04337dd0147fbfa373f950a67409", "testharness" ], "web-animations/timing-model/animations/setting-the-start-time-of-an-animation.html": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-bottom-left-radius-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-bottom-left-radius-composition.html new file mode 100644 index 0000000..87042d19 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-bottom-left-radius-composition.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-bottom-left-radius composition</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#the-border-radius"> +<meta name="assert" content="border-bottom-left-radius supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-bottom-left-radius', + underlying: '40px 40px', + addFrom: '60px 60px', + addTo: '160px 160px', +}, [ + {at: -0.25, expect: '75px'}, + {at: 0, expect: '100px'}, + {at: 0.25, expect: '125px'}, + {at: 0.5, expect: '150px'}, + {at: 0.75, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.25, expect: '225px'}, +]); + +test_composition({ + property: 'border-bottom-left-radius', + underlying: '40px 140px', + replaceFrom: '100px 120px', + addTo: '160px 60px', +}, [ + {at: -0.25, expect: '75px 100px'}, + {at: 0, expect: '100px 120px'}, + {at: 0.25, expect: '125px 140px'}, + {at: 0.5, expect: '150px 160px'}, + {at: 0.75, expect: '175px 180px'}, + {at: 1, expect: '200px'}, + {at: 1.25, expect: '225px 220px'}, +]); + +test_composition({ + property: 'border-bottom-left-radius', + underlying: '40px 60px', + addFrom: '60px 140px', + replaceTo: '200px 120px', +}, [ + {at: -0.25, expect: '75px 220px'}, + {at: 0, expect: '100px 200px'}, + {at: 0.25, expect: '125px 180px'}, + {at: 0.5, expect: '150px 160px'}, + {at: 0.75, expect: '175px 140px'}, + {at: 1, expect: '200px 120px'}, + {at: 1.25, expect: '225px 100px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-bottom-right-radius-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-bottom-right-radius-composition.html new file mode 100644 index 0000000..2b5a72d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-bottom-right-radius-composition.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-bottom-right-radius composition</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#the-border-radius"> +<meta name="assert" content="border-bottom-right-radius supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-bottom-right-radius', + underlying: '40px 40px', + addFrom: '60px 60px', + addTo: '160px 160px', +}, [ + {at: -0.25, expect: '75px'}, + {at: 0, expect: '100px'}, + {at: 0.25, expect: '125px'}, + {at: 0.5, expect: '150px'}, + {at: 0.75, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.25, expect: '225px'}, +]); + +test_composition({ + property: 'border-bottom-right-radius', + underlying: '40px 140px', + replaceFrom: '100px 120px', + addTo: '160px 60px', +}, [ + {at: -0.25, expect: '75px 100px'}, + {at: 0, expect: '100px 120px'}, + {at: 0.25, expect: '125px 140px'}, + {at: 0.5, expect: '150px 160px'}, + {at: 0.75, expect: '175px 180px'}, + {at: 1, expect: '200px'}, + {at: 1.25, expect: '225px 220px'}, +]); + +test_composition({ + property: 'border-bottom-right-radius', + underlying: '40px 60px', + addFrom: '60px 140px', + replaceTo: '200px 120px', +}, [ + {at: -0.25, expect: '75px 220px'}, + {at: 0, expect: '100px 200px'}, + {at: 0.25, expect: '125px 180px'}, + {at: 0.5, expect: '150px 160px'}, + {at: 0.75, expect: '175px 140px'}, + {at: 1, expect: '200px 120px'}, + {at: 1.25, expect: '225px 100px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-bottom-width-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-bottom-width-composition.html new file mode 100644 index 0000000..5377c0a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-bottom-width-composition.html
@@ -0,0 +1,65 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-bottom-width composition</title> +<link rel="help" href="https://www.w3.org/TR/CSS2/box.html#border-width-properties"> +<meta name="assert" content="border-bottom-width supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-bottom-width', + underlying: '50px', + addFrom: '100px', + addTo: '200px', +}, [ + {at: -0.3, expect: '120px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '200px'}, + {at: 1, expect: '250px'}, + {at: 1.5, expect: '300px'}, +]); + +test_composition({ + property: 'border-bottom-width', + underlying: '100px', + addFrom: '10px', + addTo: '2px', +}, [ + {at: -0.5, expect: '114px'}, + {at: 0, expect: '110px'}, + {at: 0.5, expect: '106px'}, + {at: 1, expect: '102px'}, + {at: 1.5, expect: '98px'}, // Value clamping should happen after composition. +]); + +test_composition({ + property: 'border-bottom-width', + underlying: '10em', + addFrom: '100px', + addTo: '20em', +}, [ + {at: -0.3, expect: 'calc(130px + 4em)'}, + {at: 0, expect: 'calc(100px + 10em)'}, + {at: 0.5, expect: 'calc(50px + 20em)'}, + {at: 1, expect: '30em'}, + {at: 1.5, expect: 'calc(-50px + 40em)'}, +]); + +test_composition({ + property: 'border-bottom-width', + underlying: '50px', + addFrom: '100px', + replaceTo: '200px', +}, [ + {at: -0.3, expect: '135px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.5, expect: '225px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-composition.html new file mode 100644 index 0000000..e331171 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-composition.html
@@ -0,0 +1,133 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-image-outset composition</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#border-image-outset"> +<meta name="assert" content="border-image-outset supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-image-outset', + underlying: '1 2 3 4', + addFrom: '1 2 3 4', + addTo: '101 102 103 104', +}, [ + {at: -0.25, expect: '0'}, // Non-negative. + {at: 0, expect: '2 4 6 8'}, + {at: 0.25, expect: '27 29 31 33'}, + {at: 0.5, expect: '52 54 56 58'}, + {at: 0.75, expect: '77 79 81 83'}, + {at: 1, expect: '102 104 106 108'}, + {at: 1.25, expect: '127 129 131 133'}, +]); + +test_composition({ + property: 'border-image-outset', + underlying: '100 200 300 400', + addFrom: '100', + addTo: '200 300 500', +}, [ + {at: -0.25, expect: '175 250 300 450'}, + {at: 0, expect: '200 300 400 500'}, + {at: 0.25, expect: '225 350 500 550'}, + {at: 0.5, expect: '250 400 600 600'}, + {at: 0.75, expect: '275 450 700 650'}, + {at: 1, expect: '300 500 800 700'}, + {at: 1.25, expect: '325 550 900 750'}, +]); + +test_composition({ + property: 'border-image-outset', + underlying: '1 2 3px 4px', + addFrom: '1 2 3px 4px', + addTo: '101 102 103px 104px', +}, [ + {at: -0.25, expect: '0 0 0px 0px'}, // Non-negative. + {at: 0, expect: '2 4 6px 8px'}, + {at: 0.25, expect: '27 29 31px 33px'}, + {at: 0.5, expect: '52 54 56px 58px'}, + {at: 0.75, expect: '77 79 81px 83px'}, + {at: 1, expect: '102 104 106px 108px'}, + {at: 1.25, expect: '127 129 131px 133px'}, +]); + +test_composition({ + property: 'border-image-outset', + underlying: '10px 20px', + addFrom: '190px 180px 290px 280px', + addTo: '90px 80px', +}, [ + {at: -0.25, expect: '225px 225px 350px 350px'}, + {at: 0, expect: '200px 200px 300px 300px'}, + {at: 0.25, expect: '175px 175px 250px 250px'}, + {at: 0.5, expect: '150px 150px 200px 200px'}, + {at: 0.75, expect: '125px 125px 150px 150px'}, + {at: 1, expect: '100px'}, + {at: 1.25, expect: '75px 75px 50px 50px'}, +]); + +test_composition({ + property: 'border-image-outset', + underlying: '10 20px', + replaceFrom: '100 100px', + addTo: '190 180px', +}, [ + {at: -0.25, expect: '75 75px'}, + {at: 0, expect: '100 100px'}, + {at: 0.25, expect: '125 125px'}, + {at: 0.5, expect: '150 150px'}, + {at: 0.75, expect: '175 175px'}, + {at: 1, expect: '200 200px'}, + {at: 1.25, expect: '225 225px'}, +]); + +test_composition({ + property: 'border-image-outset', + underlying: '10px 20', + addFrom: '90px 80', + replaceTo: '0px 0 0px 0', +}, [ + {at: -0.25, expect: '125px 125'}, + {at: 0, expect: '100px 100'}, + {at: 0.25, expect: '75px 75'}, + {at: 0.5, expect: '50px 50'}, + {at: 0.75, expect: '25px 25'}, + {at: 1, expect: '0px 0'}, + {at: 1.25, expect: '0px 0'}, // Non-negative. +]); + +test_composition({ + property: 'border-image-outset', + underlying: '10 20', + addFrom: '100px 150px', + addTo: '200px 250px', +}, [ + {at: -0.25, expect: '75px 125px'}, + {at: 0, expect: '100px 150px'}, + {at: 0.25, expect: '125px 175px'}, + {at: 0.5, expect: '150px 200px'}, + {at: 0.75, expect: '175px 225px'}, + {at: 1, expect: '200px 250px'}, + {at: 1.25, expect: '225px 275px'}, +]); + +test_composition({ + property: 'border-image-outset', + underlying: '10 20', + addFrom: '100 150px', + addTo: '200px 250', +}, [ + {at: -0.25, expect: '100 150px'}, + {at: 0, expect: '100 150px'}, + {at: 0.25, expect: '100 150px'}, + {at: 0.5, expect: '200px 250'}, + {at: 0.75, expect: '200px 250'}, + {at: 1, expect: '200px 250'}, + {at: 1.25, expect: '200px 250'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-slice-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-slice-composition.html new file mode 100644 index 0000000..d0ccb1a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-slice-composition.html
@@ -0,0 +1,133 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-image-slice composition</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#border-image-slice"> +<meta name="assert" content="border-image-slice supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-image-slice', + underlying: '1 2 3 4', + addFrom: '1 2 3 4', + addTo: '101 102 103 104', +}, [ + {at: -0.25, expect: '0'}, // Non-negative. + {at: 0, expect: '2 4 6 8'}, + {at: 0.25, expect: '27 29 31 33'}, + {at: 0.5, expect: '52 54 56 58'}, + {at: 0.75, expect: '77 79 81 83'}, + {at: 1, expect: '102 104 106 108'}, + {at: 1.25, expect: '127 129 131 133'}, +]); + +test_composition({ + property: 'border-image-slice', + underlying: '100 200 300 400 fill', + addFrom: '100 fill', + addTo: '200 300 500 fill', +}, [ + {at: -0.25, expect: '175 250 300 450 fill'}, + {at: 0, expect: '200 300 400 500 fill'}, + {at: 0.25, expect: '225 350 500 550 fill'}, + {at: 0.5, expect: '250 400 600 600 fill'}, + {at: 0.75, expect: '275 450 700 650 fill'}, + {at: 1, expect: '300 500 800 700 fill'}, + {at: 1.25, expect: '325 550 900 750 fill'}, +]); + +test_composition({ + property: 'border-image-slice', + underlying: '1 2 3% 4%', + addFrom: '1 2 3% 4%', + addTo: '101 102 103% 104%', +}, [ + {at: -0.25, expect: '0 0 0% 0%'}, // Non-negative. + {at: 0, expect: '2 4 6% 8%'}, + {at: 0.25, expect: '27 29 31% 33%'}, + {at: 0.5, expect: '52 54 56% 58%'}, + {at: 0.75, expect: '77 79 81% 83%'}, + {at: 1, expect: '102 104 106% 108%'}, + {at: 1.25, expect: '127 129 131% 133%'}, +]); + +test_composition({ + property: 'border-image-slice', + underlying: '10% 20%', + addFrom: '190% 180% 290% 280%', + addTo: '90% 80%', +}, [ + {at: -0.25, expect: '225% 225% 350% 350%'}, + {at: 0, expect: '200% 200% 300% 300%'}, + {at: 0.25, expect: '175% 175% 250% 250%'}, + {at: 0.5, expect: '150% 150% 200% 200%'}, + {at: 0.75, expect: '125% 125% 150% 150%'}, + {at: 1, expect: '100%'}, + {at: 1.25, expect: '75% 75% 50% 50%'}, +]); + +test_composition({ + property: 'border-image-slice', + underlying: '10 20%', + replaceFrom: '100 100%', + addTo: '190 180%', +}, [ + {at: -0.25, expect: '75 75%'}, + {at: 0, expect: '100 100%'}, + {at: 0.25, expect: '125 125%'}, + {at: 0.5, expect: '150 150%'}, + {at: 0.75, expect: '175 175%'}, + {at: 1, expect: '200 200%'}, + {at: 1.25, expect: '225 225%'}, +]); + +test_composition({ + property: 'border-image-slice', + underlying: '10% 20', + addFrom: '90% 80', + replaceTo: '0% 0 0% 0', +}, [ + {at: -0.25, expect: '125% 125'}, + {at: 0, expect: '100% 100'}, + {at: 0.25, expect: '75% 75'}, + {at: 0.5, expect: '50% 50'}, + {at: 0.75, expect: '25% 25'}, + {at: 1, expect: '0% 0'}, + {at: 1.25, expect: '0% 0'}, // Non-negative. +]); + +test_composition({ + property: 'border-image-slice', + underlying: '10 20', + addFrom: '100% 150%', + addTo: '200% 250% fill', +}, [ + {at: -0.25, expect: '100% 150%'}, + {at: 0, expect: '100% 150%'}, + {at: 0.25, expect: '100% 150%'}, + {at: 0.5, expect: '200% 250% fill'}, + {at: 0.75, expect: '200% 250% fill'}, + {at: 1, expect: '200% 250% fill'}, + {at: 1.25, expect: '200% 250% fill'}, +]); + +test_composition({ + property: 'border-image-slice', + underlying: '10 20', + addFrom: '100 150%', + addTo: '200% 250', +}, [ + {at: -0.25, expect: '100 150%'}, + {at: 0, expect: '100 150%'}, + {at: 0.25, expect: '100 150%'}, + {at: 0.5, expect: '200% 250'}, + {at: 0.75, expect: '200% 250'}, + {at: 1, expect: '200% 250'}, + {at: 1.25, expect: '200% 250'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-width-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-width-composition.html new file mode 100644 index 0000000..0d0a1dc4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-width-composition.html
@@ -0,0 +1,133 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-image-width composition</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#border-image-width"> +<meta name="assert" content="border-image-width supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-image-width', + underlying: '1 2 3 4', + addFrom: '1 2 3 4', + addTo: '101 102 103 104', +}, [ + {at: -0.25, expect: '0'}, // Non-negative. + {at: 0, expect: '2 4 6 8'}, + {at: 0.25, expect: '27 29 31 33'}, + {at: 0.5, expect: '52 54 56 58'}, + {at: 0.75, expect: '77 79 81 83'}, + {at: 1, expect: '102 104 106 108'}, + {at: 1.25, expect: '127 129 131 133'}, +]); + +test_composition({ + property: 'border-image-width', + underlying: '100 200 300 400', + addFrom: '100', + addTo: '200 300 500', +}, [ + {at: -0.25, expect: '175 250 300 450'}, + {at: 0, expect: '200 300 400 500'}, + {at: 0.25, expect: '225 350 500 550'}, + {at: 0.5, expect: '250 400 600 600'}, + {at: 0.75, expect: '275 450 700 650'}, + {at: 1, expect: '300 500 800 700'}, + {at: 1.25, expect: '325 550 900 750'}, +]); + +test_composition({ + property: 'border-image-width', + underlying: '1 2 3px 4%', + addFrom: '1 2 3px 4%', + addTo: '101 102 103px 104%', +}, [ + {at: -0.25, expect: '0 0 0px 0%'}, // Non-negative. + {at: 0, expect: '2 4 6px 8%'}, + {at: 0.25, expect: '27 29 31px 33%'}, + {at: 0.5, expect: '52 54 56px 58%'}, + {at: 0.75, expect: '77 79 81px 83%'}, + {at: 1, expect: '102 104 106px 108%'}, + {at: 1.25, expect: '127 129 131px 133%'}, +]); + +test_composition({ + property: 'border-image-width', + underlying: '10px 20px', + addFrom: '190px 180px 290px 280px', + addTo: '90px 80px', +}, [ + {at: -0.25, expect: '225px 225px 350px 350px'}, + {at: 0, expect: '200px 200px 300px 300px'}, + {at: 0.25, expect: '175px 175px 250px 250px'}, + {at: 0.5, expect: '150px 150px 200px 200px'}, + {at: 0.75, expect: '125px 125px 150px 150px'}, + {at: 1, expect: '100px'}, + {at: 1.25, expect: '75px 75px 50px 50px'}, +]); + +test_composition({ + property: 'border-image-width', + underlying: '10 20px', + replaceFrom: '100 100px', + addTo: '190 180px', +}, [ + {at: -0.25, expect: '75 75px'}, + {at: 0, expect: '100 100px'}, + {at: 0.25, expect: '125 125px'}, + {at: 0.5, expect: '150 150px'}, + {at: 0.75, expect: '175 175px'}, + {at: 1, expect: '200 200px'}, + {at: 1.25, expect: '225 225px'}, +]); + +test_composition({ + property: 'border-image-width', + underlying: '10px 20', + addFrom: '90px 80', + replaceTo: '0px 0 0px 0', +}, [ + {at: -0.25, expect: '125px 125'}, + {at: 0, expect: '100px 100'}, + {at: 0.25, expect: '75px 75'}, + {at: 0.5, expect: '50px 50'}, + {at: 0.75, expect: '25px 25'}, + {at: 1, expect: '0px 0'}, + {at: 1.25, expect: '0px 0'}, // Non-negative. +]); + +test_composition({ + property: 'border-image-width', + underlying: '10 20', + addFrom: '100px 150px', + addTo: '200px 250px', +}, [ + {at: -0.25, expect: '75px 125px'}, + {at: 0, expect: '100px 150px'}, + {at: 0.25, expect: '125px 175px'}, + {at: 0.5, expect: '150px 200px'}, + {at: 0.75, expect: '175px 225px'}, + {at: 1, expect: '200px 250px'}, + {at: 1.25, expect: '225px 275px'}, +]); + +test_composition({ + property: 'border-image-width', + underlying: '10 20', + addFrom: '100 150px', + addTo: '200% 250', +}, [ + {at: -0.25, expect: '100 150px'}, + {at: 0, expect: '100 150px'}, + {at: 0.25, expect: '100 150px'}, + {at: 0.5, expect: '200% 250'}, + {at: 0.75, expect: '200% 250'}, + {at: 1, expect: '200% 250'}, + {at: 1.25, expect: '200% 250'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-left-width-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-left-width-composition.html new file mode 100644 index 0000000..1b90eff --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-left-width-composition.html
@@ -0,0 +1,65 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-left-width composition</title> +<link rel="help" href="https://www.w3.org/TR/CSS2/box.html#border-width-properties"> +<meta name="assert" content="border-left-width supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-left-width', + underlying: '50px', + addFrom: '100px', + addTo: '200px', +}, [ + {at: -0.3, expect: '120px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '200px'}, + {at: 1, expect: '250px'}, + {at: 1.5, expect: '300px'}, +]); + +test_composition({ + property: 'border-left-width', + underlying: '100px', + addFrom: '10px', + addTo: '2px', +}, [ + {at: -0.5, expect: '114px'}, + {at: 0, expect: '110px'}, + {at: 0.5, expect: '106px'}, + {at: 1, expect: '102px'}, + {at: 1.5, expect: '98px'}, // Value clamping should happen after composition. +]); + +test_composition({ + property: 'border-left-width', + underlying: '10em', + addFrom: '100px', + addTo: '20em', +}, [ + {at: -0.3, expect: 'calc(130px + 4em)'}, + {at: 0, expect: 'calc(100px + 10em)'}, + {at: 0.5, expect: 'calc(50px + 20em)'}, + {at: 1, expect: '30em'}, + {at: 1.5, expect: 'calc(-50px + 40em)'}, +]); + +test_composition({ + property: 'border-left-width', + underlying: '50px', + addFrom: '100px', + replaceTo: '200px', +}, [ + {at: -0.3, expect: '135px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.5, expect: '225px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-right-width-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-right-width-composition.html new file mode 100644 index 0000000..aa9e1dcc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-right-width-composition.html
@@ -0,0 +1,65 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-right-width composition</title> +<link rel="help" href="https://www.w3.org/TR/CSS2/box.html#border-width-properties"> +<meta name="assert" content="border-right-width supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-right-width', + underlying: '50px', + addFrom: '100px', + addTo: '200px', +}, [ + {at: -0.3, expect: '120px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '200px'}, + {at: 1, expect: '250px'}, + {at: 1.5, expect: '300px'}, +]); + +test_composition({ + property: 'border-right-width', + underlying: '100px', + addFrom: '10px', + addTo: '2px', +}, [ + {at: -0.5, expect: '114px'}, + {at: 0, expect: '110px'}, + {at: 0.5, expect: '106px'}, + {at: 1, expect: '102px'}, + {at: 1.5, expect: '98px'}, // Value clamping should happen after composition. +]); + +test_composition({ + property: 'border-right-width', + underlying: '10em', + addFrom: '100px', + addTo: '20em', +}, [ + {at: -0.3, expect: 'calc(130px + 4em)'}, + {at: 0, expect: 'calc(100px + 10em)'}, + {at: 0.5, expect: 'calc(50px + 20em)'}, + {at: 1, expect: '30em'}, + {at: 1.5, expect: 'calc(-50px + 40em)'}, +]); + +test_composition({ + property: 'border-right-width', + underlying: '50px', + addFrom: '100px', + replaceTo: '200px', +}, [ + {at: -0.3, expect: '135px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.5, expect: '225px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-top-left-radius-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-top-left-radius-composition.html new file mode 100644 index 0000000..1c2056b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-top-left-radius-composition.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-top-left-radius composition</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#the-border-radius"> +<meta name="assert" content="border-top-left-radius supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-top-left-radius', + underlying: '40px 40px', + addFrom: '60px 60px', + addTo: '160px 160px', +}, [ + {at: -0.25, expect: '75px'}, + {at: 0, expect: '100px'}, + {at: 0.25, expect: '125px'}, + {at: 0.5, expect: '150px'}, + {at: 0.75, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.25, expect: '225px'}, +]); + +test_composition({ + property: 'border-top-left-radius', + underlying: '40px 140px', + replaceFrom: '100px 120px', + addTo: '160px 60px', +}, [ + {at: -0.25, expect: '75px 100px'}, + {at: 0, expect: '100px 120px'}, + {at: 0.25, expect: '125px 140px'}, + {at: 0.5, expect: '150px 160px'}, + {at: 0.75, expect: '175px 180px'}, + {at: 1, expect: '200px'}, + {at: 1.25, expect: '225px 220px'}, +]); + +test_composition({ + property: 'border-top-left-radius', + underlying: '40px 60px', + addFrom: '60px 140px', + replaceTo: '200px 120px', +}, [ + {at: -0.25, expect: '75px 220px'}, + {at: 0, expect: '100px 200px'}, + {at: 0.25, expect: '125px 180px'}, + {at: 0.5, expect: '150px 160px'}, + {at: 0.75, expect: '175px 140px'}, + {at: 1, expect: '200px 120px'}, + {at: 1.25, expect: '225px 100px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-top-right-radius-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-top-right-radius-composition.html new file mode 100644 index 0000000..9a26d513 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-top-right-radius-composition.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-top-right-radius composition</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#the-border-radius"> +<meta name="assert" content="border-top-right-radius supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-top-right-radius', + underlying: '40px 40px', + addFrom: '60px 60px', + addTo: '160px 160px', +}, [ + {at: -0.25, expect: '75px'}, + {at: 0, expect: '100px'}, + {at: 0.25, expect: '125px'}, + {at: 0.5, expect: '150px'}, + {at: 0.75, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.25, expect: '225px'}, +]); + +test_composition({ + property: 'border-top-right-radius', + underlying: '40px 140px', + replaceFrom: '100px 120px', + addTo: '160px 60px', +}, [ + {at: -0.25, expect: '75px 100px'}, + {at: 0, expect: '100px 120px'}, + {at: 0.25, expect: '125px 140px'}, + {at: 0.5, expect: '150px 160px'}, + {at: 0.75, expect: '175px 180px'}, + {at: 1, expect: '200px'}, + {at: 1.25, expect: '225px 220px'}, +]); + +test_composition({ + property: 'border-top-right-radius', + underlying: '40px 60px', + addFrom: '60px 140px', + replaceTo: '200px 120px', +}, [ + {at: -0.25, expect: '75px 220px'}, + {at: 0, expect: '100px 200px'}, + {at: 0.25, expect: '125px 180px'}, + {at: 0.5, expect: '150px 160px'}, + {at: 0.75, expect: '175px 140px'}, + {at: 1, expect: '200px 120px'}, + {at: 1.25, expect: '225px 100px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-top-width-composition.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-top-width-composition.html new file mode 100644 index 0000000..475c393 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-top-width-composition.html
@@ -0,0 +1,65 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>border-top-width composition</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#border-width"> +<meta name="assert" content="border-top-width supports animation by computed value"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'border-top-width', + underlying: '50px', + addFrom: '100px', + addTo: '200px', +}, [ + {at: -0.3, expect: '120px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '200px'}, + {at: 1, expect: '250px'}, + {at: 1.5, expect: '300px'}, +]); + +test_composition({ + property: 'border-top-width', + underlying: '100px', + addFrom: '10px', + addTo: '2px', +}, [ + {at: -0.5, expect: '114px'}, + {at: 0, expect: '110px'}, + {at: 0.5, expect: '106px'}, + {at: 1, expect: '102px'}, + {at: 1.5, expect: '98px'}, // Value clamping should happen after composition. +]); + +test_composition({ + property: 'border-top-width', + underlying: '10em', + addFrom: '100px', + addTo: '20em', +}, [ + {at: -0.3, expect: 'calc(130px + 4em)'}, + {at: 0, expect: 'calc(100px + 10em)'}, + {at: 0.5, expect: 'calc(50px + 20em)'}, + {at: 1, expect: '30em'}, + {at: 1.5, expect: 'calc(-50px + 40em)'}, +]); + +test_composition({ + property: 'border-top-width', + underlying: '50px', + addFrom: '100px', + replaceTo: '200px', +}, [ + {at: -0.3, expect: '135px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.5, expect: '225px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/animations/letter-spacing-composition.html b/third_party/blink/web_tests/external/wpt/css/css-text/animations/letter-spacing-composition.html new file mode 100644 index 0000000..c1b614b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/animations/letter-spacing-composition.html
@@ -0,0 +1,53 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>letter-spacing composition</title> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#letter-spacing-property"> +<meta name="test" content="letter-spacing supports animation by computed value type"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script src="../interpolation/resources/interpolation-test.js"></script> +<script> +test_composition({ + property: 'letter-spacing', + underlying: '50px', + addFrom: '100px', + addTo: '200px', +}, [ + {at: -0.3, expect: '120px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '200px'}, + {at: 1, expect: '250px'}, + {at: 1.5, expect: '300px'}, +]); + +test_composition({ + property: 'letter-spacing', + underlying: '100px', + addFrom: '10px', + addTo: '2px', +}, [ + {at: -0.5, expect: '114px'}, + {at: 0, expect: '110px'}, + {at: 0.5, expect: '106px'}, + {at: 1, expect: '102px'}, + {at: 1.5, expect: '98px'}, +]); + +test_composition({ + property: 'letter-spacing', + underlying: '50px', + addFrom: '100px', + replaceTo: '200px', +}, [ + {at: -0.3, expect: '135px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.5, expect: '225px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/animations/text-indent-composition.html b/third_party/blink/web_tests/external/wpt/css/css-text/animations/text-indent-composition.html new file mode 100644 index 0000000..57c528c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/animations/text-indent-composition.html
@@ -0,0 +1,84 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>letter-spacing composition</title> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#text-indent-property"> +<meta name="test" content="text-indent supports animation by computed value type"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body></body> +<script> +test_composition({ + property: 'text-indent', + underlying: '100%', + addFrom: '50px', + addTo: '150px', +}, [ + {at: -0.3, expect: 'calc(100% + 20px)'}, + {at: 0, expect: 'calc(100% + 50px)'}, + {at: 0.3, expect: 'calc(100% + 80px)'}, + {at: 0.6, expect: 'calc(100% + 110px)'}, + {at: 1, expect: 'calc(100% + 150px)'}, + {at: 1.5, expect: 'calc(100% + 200px)'}, +]); + +test_composition({ + property: 'text-indent', + underlying: '250px', + addFrom: '50px', + replaceTo: '100px', +}, [ + {at: -0.3, expect: '360px'}, + {at: 0, expect: '300px'}, + {at: 0.3, expect: '240px'}, + {at: 0.6, expect: '180px'}, + {at: 1, expect: '100px'}, + {at: 1.5, expect: '0px'}, +]); + +test_composition({ + property: 'text-indent', + underlying: '50%', + replaceFrom: '-100%', + addTo: '50%', +}, [ + {at: -0.3, expect: '-160%'}, + {at: 0, expect: '-100%'}, + {at: 0.3, expect: '-40%'}, + {at: 0.5, expect: '0%'}, + {at: 0.6, expect: '20%'}, + {at: 1, expect: '100%'}, + {at: 1.5, expect: '200%'}, +]); + +test_composition({ + property: 'text-indent', + underlying: '250px', + addFrom: '50px each-line hanging', + replaceTo: '150px hanging each-line', +}, [ + {at: -0.3, expect: '20px hanging each-line'}, + {at: 0, expect: '50px hanging each-line'}, + {at: 0.3, expect: '80px hanging each-line'}, + {at: 0.6, expect: '110px hanging each-line'}, + {at: 1, expect: '150px hanging each-line'}, + {at: 1.5, expect: '200px hanging each-line'}, +]); + +test_composition({ + property: 'text-indent', + underlying: '250px each-line', + addFrom: '50px each-line', + replaceTo: '150px hanging', +}, [ + {at: -0.3, expect: '300px each-line'}, + {at: 0, expect: '300px each-line'}, + {at: 0.3, expect: '300px each-line'}, + {at: 0.6, expect: '150px hanging'}, + {at: 1, expect: '150px hanging'}, + {at: 1.5, expect: '150px hanging'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/animations/word-spacing-composition.html b/third_party/blink/web_tests/external/wpt/css/css-text/animations/word-spacing-composition.html new file mode 100644 index 0000000..17aacae --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/animations/word-spacing-composition.html
@@ -0,0 +1,52 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>word-spacing composition</title> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#word-spacing-property"> +<meta name="test" content="word-spacing supports animation by computed value type"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'word-spacing', + underlying: '50px', + addFrom: '100px', + addTo: '200px', +}, [ + {at: -0.3, expect: '120px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '200px'}, + {at: 1, expect: '250px'}, + {at: 1.5, expect: '300px'}, +]); + +test_composition({ + property: 'word-spacing', + underlying: '100px', + addFrom: '10px', + addTo: '2px', +}, [ + {at: -0.5, expect: '114px'}, + {at: 0, expect: '110px'}, + {at: 0.5, expect: '106px'}, + {at: 1, expect: '102px'}, + {at: 1.5, expect: '98px'}, +]); + +test_composition({ + property: 'word-spacing', + underlying: '50px', + addFrom: '100px', + replaceTo: '200px', +}, [ + {at: -0.3, expect: '135px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.5, expect: '225px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-anchor-composition.html b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-anchor-composition.html new file mode 100644 index 0000000..53210fd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-anchor-composition.html
@@ -0,0 +1,80 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>offset-anchor composition</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-anchor-property"> +<meta name="assert" content="offset-anchor supports animation."> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<style> +.target { + width: 200px; + height: 200px; +} +</style> +<body> +<script> +test_composition({ + property: 'offset-anchor', + underlying: '40px 60px', + addFrom: '60px 40px', + addTo: '160px 140px', +}, [ + {at: -0.25, expect: '75px 75px'}, + {at: 0, expect: '100px 100px'}, + {at: 0.25, expect: '125px 125px'}, + {at: 0.5, expect: '150px 150px'}, + {at: 0.75, expect: '175px 175px'}, + {at: 1, expect: '200px 200px'}, + {at: 1.25, expect: '225px 225px'}, +]); + +test_composition({ + property: 'offset-anchor', + underlying: 'top 20% left 40%', + addFrom: 'left 60% top 80%', + addTo: 'right 80% bottom 40%', +}, [ + {at: -0.25, expect: '110% 105%'}, + {at: 0, expect: '100% 100%'}, + {at: 0.25, expect: '90% 95%'}, + {at: 0.5, expect: '80% 90%'}, + {at: 0.75, expect: '70% 85%'}, + {at: 1, expect: '60% 80%'}, + {at: 1.25, expect: '50% 75%'}, +]); + +test_composition({ + property: 'offset-anchor', + underlying: '40px 60px', + replaceFrom: '100px 200px', + addTo: '160px 40px', +}, [ + {at: -0.25, expect: '75px 225px'}, + {at: 0, expect: '100px 200px'}, + {at: 0.25, expect: '125px 175px'}, + {at: 0.5, expect: '150px 150px'}, + {at: 0.75, expect: '175px 125px'}, + {at: 1, expect: '200px 100px'}, + {at: 1.25, expect: '225px 75px'}, +]); + +test_composition({ + property: 'offset-anchor', + underlying: '40px 60px', + addFrom: '60px 140px', + replaceTo: '200px 100px', +}, [ + {at: -0.25, expect: '75px 225px'}, + {at: 0, expect: '100px 200px'}, + {at: 0.25, expect: '125px 175px'}, + {at: 0.5, expect: '150px 150px'}, + {at: 0.75, expect: '175px 125px'}, + {at: 1, expect: '200px 100px'}, + {at: 1.25, expect: '225px 75px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-distance-composition.html b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-distance-composition.html new file mode 100644 index 0000000..4ff6e95 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-distance-composition.html
@@ -0,0 +1,66 @@ +<!DOCTYPE html> +<meta charset="UTF-8"> +<title>offset-distance composition</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-distance-property"> +<meta name="assert" content="offset-distance supports animation."> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +test_composition({ + property: 'offset-distance', + underlying: '50px', + addFrom: '100px', + addTo: '200px', +}, [ + {at: -0.3, expect: '120px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '200px'}, + {at: 1, expect: '250px'}, + {at: 1.5, expect: '300px'}, +]); + +test_composition({ + property: 'offset-distance', + underlying: '100px', + addFrom: '10px', + addTo: '2px', +}, [ + {at: -0.5, expect: '114px'}, + {at: 0, expect: '110px'}, + {at: 0.5, expect: '106px'}, + {at: 1, expect: '102px'}, + {at: 1.5, expect: '98px'}, +]); + +test_composition({ + property: 'offset-distance', + underlying: '10%', + addFrom: '100px', + addTo: '20%', +}, [ + {at: -0.3, expect: 'calc(130px + 4%)'}, + {at: 0, expect: 'calc(100px + 10%)'}, + {at: 0.5, expect: 'calc(50px + 20%)'}, + {at: 1, expect: '30%'}, + {at: 1.5, expect: 'calc(-50px + 40%)'}, +]); + +test_composition({ + property: 'offset-distance', + underlying: '50px', + addFrom: '100px', + replaceTo: '200px', +}, [ + {at: -0.3, expect: '135px'}, + {at: 0, expect: '150px'}, + {at: 0.5, expect: '175px'}, + {at: 1, expect: '200px'}, + {at: 1.5, expect: '225px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-path-composition.html b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-path-composition.html new file mode 100644 index 0000000..eedd363 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-path-composition.html
@@ -0,0 +1,120 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>offset-distance composition</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-distance-property"> +<meta name="assert" content="offset-distance supports animation."> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +// TODO(ericwilligers) Support additive animation for path strings crbug.com/699308 + +// Ray paths compose. +test_composition({ + property: 'offset-path', + underlying: 'ray(20deg sides)', + addFrom: 'ray(10deg sides)', + addTo: 'ray(20deg sides)', +}, [ + {at: -0.3, expect: 'ray(27deg sides)'}, + {at: 0, expect: 'ray(30deg sides)'}, + {at: 0.3, expect: 'ray(33deg sides)'}, + {at: 0.6, expect: 'ray(36deg sides)'}, + {at: 1, expect: 'ray(40deg sides)'}, + {at: 1.5, expect: 'ray(45deg sides)'}, +]); + +// Ray paths without contain don't compose with underlying contain. +test_composition({ + property: 'offset-path', + underlying: 'ray(20deg closest-corner contain)', + addFrom: 'ray(10deg closest-corner)', + addTo: 'ray(20deg closest-corner)', +}, [ + {at: -0.3, expect: 'ray(7deg closest-corner)'}, + {at: 0, expect: 'ray(10deg closest-corner)'}, + {at: 0.3, expect: 'ray(13deg closest-corner)'}, + {at: 0.6, expect: 'ray(16deg closest-corner)'}, + {at: 1, expect: 'ray(20deg closest-corner)'}, + {at: 1.5, expect: 'ray(25deg closest-corner)'}, +]); + +// Ray paths don't compose when underlying has different size. +test_composition({ + property: 'offset-path', + underlying: 'ray(20deg closest-side)', + addFrom: 'ray(10deg closest-corner)', + addTo: 'ray(20deg closest-corner)', +}, [ + {at: -0.3, expect: 'ray(7deg closest-corner)'}, + {at: 0, expect: 'ray(10deg closest-corner)'}, + {at: 0.3, expect: 'ray(13deg closest-corner)'}, + {at: 0.6, expect: 'ray(16deg closest-corner)'}, + {at: 1, expect: 'ray(20deg closest-corner)'}, + {at: 1.5, expect: 'ray(25deg closest-corner)'}, +]); + +// Ray contain paths compose with underlying contain. +test_composition({ + property: 'offset-path', + underlying: 'ray(20deg farthest-side contain)', + addFrom: 'ray(190deg farthest-side contain)', + addTo: 'ray(20deg farthest-side contain)', +}, [ + {at: -0.3, expect: 'ray(261deg farthest-side contain)'}, + {at: 0, expect: 'ray(210deg farthest-side contain)'}, + {at: 0.3, expect: 'ray(159deg farthest-side contain)'}, + {at: 0.6, expect: 'ray(108deg farthest-side contain)'}, + {at: 1, expect: 'ray(40deg farthest-side contain)'}, + {at: 1.5, expect: 'ray(-45deg farthest-side contain)'}, +]); + +// When we can't interpolate, we can't compose. +test_composition({ + property: 'offset-path', + underlying: 'ray(20deg farthest-corner)', + addFrom: 'ray(190deg farthest-corner contain)', + addTo: 'ray(20deg farthest-corner)', +}, [ + {at: -0.3, expect: 'ray(190deg farthest-corner contain)'}, + {at: 0, expect: 'ray(190deg farthest-corner contain)'}, + {at: 0.3, expect: 'ray(190deg farthest-corner contain)'}, + {at: 0.6, expect: 'ray(40deg farthest-corner)'}, + {at: 1, expect: 'ray(40deg farthest-corner)'}, + {at: 1.5, expect: 'ray(40deg farthest-corner)'}, +]); + +test_composition({ + property: 'offset-path', + underlying: 'ray(20deg sides)', + replaceFrom: 'ray(190deg sides contain)', + addTo: 'ray(20deg sides)', +}, [ + {at: -0.3, expect: 'ray(190deg sides contain)'}, + {at: 0, expect: 'ray(190deg sides contain)'}, + {at: 0.3, expect: 'ray(190deg sides contain)'}, + {at: 0.6, expect: 'ray(40deg sides)'}, + {at: 1, expect: 'ray(40deg sides)'}, + {at: 1.5, expect: 'ray(40deg sides)'}, +]); + +// Ray paths compose with underlying. +test_composition({ + property: 'offset-path', + underlying: 'ray(20deg closest-side)', + addFrom: 'ray(10deg closest-side)', + replaceTo: 'ray(10deg closest-side)', +}, [ + {at: -0.3, expect: 'ray(36deg closest-side)'}, + {at: 0, expect: 'ray(30deg closest-side)'}, + {at: 0.3, expect: 'ray(24deg closest-side)'}, + {at: 0.6, expect: 'ray(18deg closest-side)'}, + {at: 1, expect: 'ray(10deg closest-side)'}, + {at: 1.5, expect: 'ray(0deg closest-side)'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-position-composition.html b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-position-composition.html new file mode 100644 index 0000000..0ee517a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-position-composition.html
@@ -0,0 +1,80 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>offset-position composition</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-position-property"> +<meta name="assert" content="offset-position supports <position> animation."> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<style> +.target { + width: 200px; + height: 200px; +} +</style> +<body> +<script> +test_composition({ + property: 'offset-position', + underlying: '40px 60px', + addFrom: '60px 40px', + addTo: '160px 140px', +}, [ + {at: -0.25, expect: '75px 75px'}, + {at: 0, expect: '100px 100px'}, + {at: 0.25, expect: '125px 125px'}, + {at: 0.5, expect: '150px 150px'}, + {at: 0.75, expect: '175px 175px'}, + {at: 1, expect: '200px 200px'}, + {at: 1.25, expect: '225px 225px'}, +]); + +test_composition({ + property: 'offset-position', + underlying: 'top 20% left 40%', + addFrom: 'left 60% top 80%', + addTo: 'right 80% bottom 40%', +}, [ + {at: -0.25, expect: '110% 105%'}, + {at: 0, expect: '100% 100%'}, + {at: 0.25, expect: '90% 95%'}, + {at: 0.5, expect: '80% 90%'}, + {at: 0.75, expect: '70% 85%'}, + {at: 1, expect: '60% 80%'}, + {at: 1.25, expect: '50% 75%'}, +]); + +test_composition({ + property: 'offset-position', + underlying: '40px 60px', + replaceFrom: '100px 200px', + addTo: '160px 40px', +}, [ + {at: -0.25, expect: '75px 225px'}, + {at: 0, expect: '100px 200px'}, + {at: 0.25, expect: '125px 175px'}, + {at: 0.5, expect: '150px 150px'}, + {at: 0.75, expect: '175px 125px'}, + {at: 1, expect: '200px 100px'}, + {at: 1.25, expect: '225px 75px'}, +]); + +test_composition({ + property: 'offset-position', + underlying: '40px 60px', + addFrom: '60px 140px', + replaceTo: '200px 100px', +}, [ + {at: -0.25, expect: '75px 225px'}, + {at: 0, expect: '100px 200px'}, + {at: 0.25, expect: '125px 175px'}, + {at: 0.5, expect: '150px 150px'}, + {at: 0.75, expect: '175px 125px'}, + {at: 1, expect: '200px 100px'}, + {at: 1.25, expect: '225px 75px'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-rotate-composition.html b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-rotate-composition.html new file mode 100644 index 0000000..bf60c19a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-rotate-composition.html
@@ -0,0 +1,103 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>offset-rotate composition</title> +<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org"> +<link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-rotate-property"> +<meta name="assert" content="offset-rotate supports animation."> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/interpolation-testcommon.js"></script> + +<body> +<script> +// Angle rotations compose. +test_composition({ + property: 'offset-rotate', + underlying: '20deg', + addFrom: '10deg', + addTo: '20deg', +}, [ + {at: -0.3, expect: '27deg'}, + {at: 0, expect: '30deg'}, + {at: 0.3, expect: '33deg'}, + {at: 0.6, expect: '36deg'}, + {at: 1, expect: '40deg'}, + {at: 1.5, expect: '45deg'}, +]); + +// Angle rotations don't compose with underlying 'auto'. +test_composition({ + property: 'offset-rotate', + underlying: 'auto 20deg', + addFrom: '10deg', + addTo: '20deg', +}, [ + {at: -0.3, expect: '7deg'}, + {at: 0, expect: '10deg'}, + {at: 0.3, expect: '13deg'}, + {at: 0.6, expect: '16deg'}, + {at: 1, expect: '20deg'}, + {at: 1.5, expect: '25deg'}, +]); + +// Auto rotations compose with underlying 'auto'. +test_composition({ + property: 'offset-rotate', + underlying: 'auto 20deg', + addFrom: 'reverse 10deg', + addTo: 'auto 20deg', +}, [ + {at: -0.3, expect: 'auto 261deg'}, + {at: 0, expect: 'auto 210deg'}, + {at: 0.3, expect: 'auto 159deg'}, + {at: 0.6, expect: 'auto 108deg'}, + {at: 1, expect: 'auto 40deg'}, + {at: 1.5, expect: 'auto -45deg'}, +]); + +// When we can't interpolate, we can't compose. +test_composition({ + property: 'offset-rotate', + underlying: '20deg', + addFrom: 'reverse 10deg', + addTo: '20deg', +}, [ + {at: -0.3, expect: 'auto 190deg'}, + {at: 0, expect: 'auto 190deg'}, + {at: 0.3, expect: 'auto 190deg'}, + {at: 0.6, expect: '40deg'}, + {at: 1, expect: '40deg'}, + {at: 1.5, expect: '40deg'}, +]); + +test_composition({ + property: 'offset-rotate', + underlying: '20deg', + replaceFrom: 'reverse 10deg', + addTo: '20deg', +}, [ + {at: -0.3, expect: 'auto 190deg'}, + {at: 0, expect: 'auto 190deg'}, + {at: 0.3, expect: 'auto 190deg'}, + {at: 0.6, expect: '40deg'}, + {at: 1, expect: '40deg'}, + {at: 1.5, expect: '40deg'}, +]); + +// Angle rotations compose with underlying angle. +test_composition({ + property: 'offset-rotate', + underlying: '20deg', + addFrom: '10deg', + replaceTo: '10deg', +}, [ + {at: -0.3, expect: '36deg'}, + {at: 0, expect: '30deg'}, + {at: 0.3, expect: '24deg'}, + {at: 0.6, expect: '18deg'}, + {at: 1, expect: '10deg'}, + {at: 1.5, expect: '0deg'}, +]); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webaudio.idl b/third_party/blink/web_tests/external/wpt/interfaces/webaudio.idl index 674673d..94910903 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webaudio.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webaudio.idl
@@ -26,28 +26,36 @@ AnalyserNode createAnalyser (); BiquadFilterNode createBiquadFilter (); - AudioBuffer createBuffer (unsigned long numberOfChannels, unsigned long length, float sampleRate); + AudioBuffer createBuffer (unsigned long numberOfChannels, + unsigned long length, + float sampleRate); AudioBufferSourceNode createBufferSource (); ChannelMergerNode createChannelMerger (optional unsigned long numberOfInputs = 6); - ChannelSplitterNode createChannelSplitter (optional unsigned long numberOfOutputs = 6); + ChannelSplitterNode createChannelSplitter ( + optional unsigned long numberOfOutputs = 6); ConstantSourceNode createConstantSource (); ConvolverNode createConvolver (); DelayNode createDelay (optional double maxDelayTime = 1.0); DynamicsCompressorNode createDynamicsCompressor (); GainNode createGain (); - IIRFilterNode createIIRFilter (sequence<double> feedforward, sequence<double> feedback); + IIRFilterNode createIIRFilter (sequence<double> feedforward, + sequence<double> feedback); OscillatorNode createOscillator (); PannerNode createPanner (); - PeriodicWave createPeriodicWave (sequence<float> real, sequence<float> imag, optional PeriodicWaveConstraints constraints = {}); - ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0, - optional unsigned long numberOfInputChannels = 2, - optional unsigned long numberOfOutputChannels = 2); + PeriodicWave createPeriodicWave (sequence<float> real, + sequence<float> imag, + optional PeriodicWaveConstraints constraints = {}); + ScriptProcessorNode createScriptProcessor( + optional unsigned long bufferSize = 0, + optional unsigned long numberOfInputChannels = 2, + optional unsigned long numberOfOutputChannels = 2); StereoPannerNode createStereoPanner (); WaveShaperNode createWaveShaper (); - Promise<AudioBuffer> decodeAudioData (ArrayBuffer audioData, - optional DecodeSuccessCallback? successCallback, - optional DecodeErrorCallback? errorCallback); + Promise<AudioBuffer> decodeAudioData ( + ArrayBuffer audioData, + optional DecodeSuccessCallback? successCallback, + optional DecodeErrorCallback? errorCallback); }; enum AudioContextLatencyCategory { @@ -67,7 +75,8 @@ Promise<void> close (); MediaElementAudioSourceNode createMediaElementSource (HTMLMediaElement mediaElement); MediaStreamAudioSourceNode createMediaStreamSource (MediaStream mediaStream); - MediaStreamTrackAudioSourceNode createMediaStreamTrackSource (MediaStreamTrack mediaStreamTrack); + MediaStreamTrackAudioSourceNode createMediaStreamTrackSource ( + MediaStreamTrack mediaStreamTrack); MediaStreamAudioDestinationNode createMediaStreamDestination (); }; @@ -116,8 +125,14 @@ readonly attribute double duration; readonly attribute unsigned long numberOfChannels; Float32Array getChannelData (unsigned long channel); - void copyFromChannel (Float32Array destination, unsigned long channelNumber, optional unsigned long bufferOffset = 0); - void copyToChannel (Float32Array source, unsigned long channelNumber, optional unsigned long bufferOffset = 0); + void copyFromChannel (Float32Array destination, + unsigned long channelNumber, + optional unsigned long bufferOffset = 0); + void copyToChannel (Float32Array source, + + unsigned long channelNumber, + + optional unsigned long bufferOffset = 0); }; dictionary AudioBufferOptions { @@ -136,7 +151,9 @@ void disconnect (unsigned long output); void disconnect (AudioNode destinationNode); void disconnect (AudioNode destinationNode, unsigned long output); - void disconnect (AudioNode destinationNode, unsigned long output, unsigned long input); + void disconnect (AudioNode destinationNode, + unsigned long output, + unsigned long input); void disconnect (AudioParam destinationParam); void disconnect (AudioParam destinationParam, unsigned long output); readonly attribute BaseAudioContext context; @@ -180,7 +197,11 @@ AudioParam linearRampToValueAtTime (float value, double endTime); AudioParam exponentialRampToValueAtTime (float value, double endTime); AudioParam setTargetAtTime (float target, double startTime, float timeConstant); - AudioParam setValueCurveAtTime (sequence<float> values, double startTime, double duration); + AudioParam setValueCurveAtTime (sequence<float> values, + + double startTime, + + double duration); AudioParam cancelScheduledValues (double cancelTime); AudioParam cancelAndHoldAtTime (double cancelTime); }; @@ -215,7 +236,8 @@ [Exposed=Window] interface AudioBufferSourceNode : AudioScheduledSourceNode { - constructor (BaseAudioContext context, optional AudioBufferSourceOptions options = {}); + constructor (BaseAudioContext context, + optional AudioBufferSourceOptions options = {}); attribute AudioBuffer? buffer; readonly attribute AudioParam playbackRate; readonly attribute AudioParam detune; @@ -289,7 +311,9 @@ readonly attribute AudioParam detune; readonly attribute AudioParam Q; readonly attribute AudioParam gain; - void getFrequencyResponse (Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse); + void getFrequencyResponse (Float32Array frequencyHz, + Float32Array magResponse, + Float32Array phaseResponse); }; dictionary BiquadFilterOptions : AudioNodeOptions { @@ -353,7 +377,8 @@ [Exposed=Window] interface DynamicsCompressorNode : AudioNode { - constructor (BaseAudioContext context, optional DynamicsCompressorOptions options = {}); + constructor (BaseAudioContext context, + optional DynamicsCompressorOptions options = {}); readonly attribute AudioParam threshold; readonly attribute AudioParam knee; readonly attribute AudioParam ratio; @@ -383,7 +408,9 @@ [Exposed=Window] interface IIRFilterNode : AudioNode { constructor (BaseAudioContext context, IIRFilterOptions options); - void getFrequencyResponse (Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse); + void getFrequencyResponse (Float32Array frequencyHz, + Float32Array magResponse, + Float32Array phaseResponse); }; dictionary IIRFilterOptions : AudioNodeOptions { @@ -555,7 +582,8 @@ [Global=(Worklet, AudioWorklet), Exposed=AudioWorklet] interface AudioWorkletGlobalScope : WorkletGlobalScope { - void registerProcessor (DOMString name, AudioWorkletProcessorConstructor processorCtor); + void registerProcessor (DOMString name, + AudioWorkletProcessorConstructor processorCtor); readonly attribute unsigned long long currentFrame; readonly attribute double currentTime; readonly attribute float sampleRate;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl index e30fc38..49ed6bb 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc.idl
@@ -13,7 +13,7 @@ }; enum RTCIceCredentialType { - "password", + "password" }; dictionary RTCIceServer {
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-playback-rate-of-an-animation.html b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-playback-rate-of-an-animation.html index 0522c43..a1f9e4f 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-playback-rate-of-an-animation.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-playback-rate-of-an-animation.html
@@ -97,8 +97,8 @@ promise_test(async t => { const animation = createDiv(t).animate(null, 100 * MS_PER_SEC); - animation.currentTime = 50 * MS_PER_SEC; await animation.ready; + animation.currentTime = 50 * MS_PER_SEC; animation.playbackRate = 0; // Ensure that current time does not drift. assert_equals(animation.playState, 'running');
diff --git a/third_party/blink/web_tests/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html b/third_party/blink/web_tests/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html index 871b08b..fbe2515 100644 --- a/third_party/blink/web_tests/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html +++ b/third_party/blink/web_tests/fast/scrolling/scrollbars/dsf-ready/mouse-interactions-dsf-2.html
@@ -104,14 +104,11 @@ if (onLinuxPlatform) expected_offset = window.devicePixelRatio == 1 ? 87 : 82; else if (onMacPlatform) - expected_offset = 74; + expected_offset = 72; else expected_offset = 82; - // TODO(arakeri): crbug.com/1019076 Option + click is off by 3-4 px. - assert_approx_equals(standardDivFast.scrollTop, expected_offset, 3, - modifier + " + click forward didn't scroll."); - + assert_equals(standardDivFast.scrollTop, expected_offset, modifier + " + click forward didn't scroll."); await mouseClickOn(SCROLLBAR_BUTTON_FWD.x, standardRectFast.top + ((onMacPlatform ? 0 : BUTTON_WIDTH) + 2), /*left_click*/0, modifier); assert_equals(standardDivFast.scrollTop, 0, modifier + " + click backward didn't scroll.");
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/background/multiple-backgrounds-style-change-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/background/multiple-backgrounds-style-change-expected.txt index 313bfe96..3dfd4c10 100644 --- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/background/multiple-backgrounds-style-change-expected.txt +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/background/multiple-backgrounds-style-change-expected.txt
@@ -7,7 +7,7 @@ "backgroundColor": "#FFFFFF" }, { - "name": "LayoutNGBlockFlow DIV id='test' class='composited box changed'", + "name": "LayoutNGBlockFlow DIV id='test' class='composited box'", "bounds": [202, 202], "transform": 2 }
diff --git a/third_party/closure_compiler/compiler.py b/third_party/closure_compiler/compiler.py index c0c0bf2..f2bedcb1 100755 --- a/third_party/closure_compiler/compiler.py +++ b/third_party/closure_compiler/compiler.py
@@ -24,7 +24,7 @@ and produce minified output.""" _JAR_COMMAND = [ - "java", + os.path.join(_CURRENT_DIR, "..", "jdk", "current", "bin", "java"), "-jar", "-Xms1024m", "-client",
diff --git a/tools/binary_size/generate_milestone_reports.py b/tools/binary_size/generate_milestone_reports.py index 0322a253..c9c4acb 100755 --- a/tools/binary_size/generate_milestone_reports.py +++ b/tools/binary_size/generate_milestone_reports.py
@@ -232,7 +232,7 @@ if args.sync: subprocess.check_call(cmd) subprocess.check_call([ - 'gsutil.py', 'setmeta', '-h', 'Cache-Control:no-cache', + _GSUTIL, 'setmeta', '-h', 'Cache-Control:no-cache', _PUSH_URL + 'milestones.json' ]) else:
diff --git a/tools/binary_size/generate_official_build_report.py b/tools/binary_size/generate_official_build_report.py index b08ccce..9387260 100755 --- a/tools/binary_size/generate_official_build_report.py +++ b/tools/binary_size/generate_official_build_report.py
@@ -17,14 +17,19 @@ _REPORTS_JSON_GS_URL = os.path.join(_REPORTS_BASE_URL, 'canary_reports.json') _REPORTS_GS_URL = os.path.join(_REPORTS_BASE_URL, 'reports') +_DIR_SOURCE_ROOT = os.path.normpath( + os.path.join(os.path.dirname(__file__), '..', '..')) +_GSUTIL = os.path.join(_DIR_SOURCE_ROOT, 'third_party', 'depot_tools', + 'gsutil.py') + def _WriteReportsJson(out): - output = subprocess.check_output(['gsutil.py', 'ls', '-R', _REPORTS_GS_URL]) + output = subprocess.check_output([_GSUTIL, 'ls', '-R', _REPORTS_GS_URL]) reports = [] report_re = re.compile( re.escape(_REPORTS_GS_URL) + - r'/(?P<version>.+?)/(?P<apk>.+?)/(?P<cpu>.+?)\.size') + r'/(?P<version>.+?)/(?P<cpu>.+?)/(?P<apk>.+?)\.size') for line in output.splitlines(): m = report_re.search(line) if m: @@ -37,6 +42,30 @@ json.dump({'pushed': reports}, out) +def _UploadReportsJson(): + with tempfile.NamedTemporaryFile() as f: + _WriteReportsJson(f) + f.flush() + cmd = [ + _GSUTIL, '--', '-h', 'Cache-Control:no-cache', 'cp', '-a', + 'public-read', f.name, _REPORTS_JSON_GS_URL + ] + logging.warning(' '.join(cmd)) + subprocess.check_call(cmd) + + +def _UploadSizeFile(size_path, version, arch): + report_basename = os.path.splitext(os.path.basename(size_path))[0] + # Maintain name through transition to bundles. + report_basename = report_basename.replace('.minimal.apks', '.apk') + dst_url = os.path.join(_REPORTS_GS_URL, version, arch, + report_basename + '.size') + + cmd = [_GSUTIL, 'cp', '-a', 'public-read', size_path, dst_url] + logging.warning(' '.join(cmd)) + subprocess.check_call(cmd) + + def main(): parser = argparse.ArgumentParser() parser.add_argument( @@ -47,36 +76,16 @@ '--size-path', required=True, help='Path to .size file for the given version.') - parser.add_argument('--gs-size-url', help='Unused') - parser.add_argument('--gs-size-path', help='Unused') parser.add_argument( '--arch', required=True, help='Compiler architecture of build.') - parser.add_argument( - '--platform', - required=True, - help='OS corresponding to those used by omahaproxy.', - choices=['android', 'webview']) + parser.add_argument('--gs-size-url', help='Unused') + parser.add_argument('--gs-size-path', help='Unused') + parser.add_argument('--platform', help='Unused') args = parser.parse_args() - report_basename = os.path.splitext(os.path.basename(args.size_path))[0] - # Maintain name through transition to bundles. - report_basename = report_basename.replace('.minimal.apks', '.apk') - dst_url = os.path.join(_REPORTS_GS_URL, args.version, args.arch, - report_basename + '.size') - - cmd = ['gsutil.py', 'cp', '-a', 'public-read', args.size_path, dst_url] - logging.warning(' '.join(cmd)) - subprocess.check_call(cmd) - - with tempfile.NamedTemporaryFile() as f: - _WriteReportsJson(f) - cmd = [ - 'gsutil.py', '--', '-h', 'Cache-Control:no-cache', 'cp', '-a', - 'public-read', f.name, _REPORTS_JSON_GS_URL - ] - logging.warning(' '.join(cmd)) - subprocess.check_call(cmd) + _UploadSizeFile(args.size_path, args.version, args.arch) + _UploadReportsJson() if __name__ == '__main__':
diff --git a/tools/binary_size/libsupersize/static/index.js b/tools/binary_size/libsupersize/static/index.js index e6611fc..2a510ff 100644 --- a/tools/binary_size/libsupersize/static/index.js +++ b/tools/binary_size/libsupersize/static/index.js
@@ -116,7 +116,7 @@ mainVersions.filter(v2 => compareVersions(v2, '71.0.0.0') > 0); } - if (showAll.value) { + if (showAll.checked) { activeVersions = [...mainVersions, ...canaryVersions]; activeVersions.sort(compareVersions); } else {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 9a58d9f5..f84ff66 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -41517,16 +41517,16 @@ <int value="7" label="Ephemeral icon and local file"/> <int value="8" label="Context menu and presentation"/> <int value="9" label="Context menu and tab mirroring"/> - <int value="11" label="Context menu and desktop mirroring"/> - <int value="12" label="Context menu and local file"/> - <int value="13" label="Page and presentation"/> - <int value="14" label="Page and tab mirroring"/> - <int value="15" label="Page and desktop mirroring"/> - <int value="16" label="Page and local file"/> - <int value="17" label="App menu and presentation"/> - <int value="18" label="App menu and tab mirroring"/> - <int value="19" label="App menu and desktop mirroring"/> - <int value="20" label="App menu and local file"/> + <int value="10" label="Context menu and desktop mirroring"/> + <int value="11" label="Context menu and local file"/> + <int value="12" label="Page and presentation"/> + <int value="13" label="Page and tab mirroring"/> + <int value="14" label="Page and desktop mirroring"/> + <int value="15" label="Page and local file"/> + <int value="16" label="App menu and presentation"/> + <int value="17" label="App menu and tab mirroring"/> + <int value="18" label="App menu and desktop mirroring"/> + <int value="19" label="App menu and local file"/> </enum> <enum name="MediaRouterDialogOpenOrigin"> @@ -51032,10 +51032,10 @@ <int value="41" label="WOULD_HAVE_BEEN_USED (Obsolete)"/> <int value="42" label="REGISTER_PROTOCOL_HANDLER"/> <int value="43" label="CREATING_AUDIO_STREAM"/> - <int value="44" label="PAGE_BEING_CAPTURED"/> + <int value="44" label="PAGE_BEING_CAPTURED (Obsolete)"/> <int value="45" label="BAD_DEFERRED_REDIRECT"/> <int value="46" label="NAVIGATION_UNCOMMITTED"/> - <int value="47" label="NEW_NAVIGATION_ENTRY"/> + <int value="47" label="NEW_NAVIGATION_ENTRY (Obsolete)"/> <int value="48" label="COOKIE_STORE_NOT_LOADED (Obsolete)"/> <int value="49" label="COOKIE_CONFLICT (Obsolete)"/> <int value="50" label="NON_EMPTY_BROWSING_INSTANCE"/> @@ -62967,6 +62967,7 @@ <int value="1941011596" label="IFX 9655 rev 35 fw 4.34 build 03f2"/> <int value="1953654937" label="IFX 9645 rev 45 fw 133.33 build 00e3"/> <int value="2024714959" label="IFX 9655 rev 32 fw 4.34 build 03f2"/> + <int value="2036182876" label="CROS Cr50 0.3.24"/> <int value="2061474747" label="CROS Cr50 0.2.2 aka 0.4.4 Flags 0x10(pre-pvt)"/> <int value="2104725364" label="CROS Cr50 0.3.20"/>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index 2519a9e2..cbe58186 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -18,6 +18,7 @@ blink_perf.shadow_dom,masonfreed@chromium.org,Blink>DOM>ShadowDOM,https://bit.ly/blink-perf-benchmarks, blink_perf.svg,"fs@opera.com, pdr@chromium.org",Blink>SVG,https://bit.ly/blink-perf-benchmarks, components_perftests,csharrison@chromium.org,,, +dawn_perf_tests,"enga@chromium.org, chrome-gpu-perf-owners@chromium.org",Internals>GPU>Dawn,https://dawn.googlesource.com/dawn/+/HEAD/src/tests/perf_tests/README.md, dromaeo,"jbroman@chromium.org, yukishiino@chromium.org, haraken@chromium.org",Blink>Bindings,, dummy_benchmark.noisy_benchmark_1,crouleau@chromium.org,Test>Telemetry,, dummy_benchmark.stable_benchmark_1,crouleau@chromium.org,Test>Telemetry,,
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py index b1fc7d5..74f94c8 100644 --- a/tools/perf/core/bot_platforms.py +++ b/tools/perf/core/bot_platforms.py
@@ -33,6 +33,7 @@ def __init__(self, name, description, benchmark_configs, num_shards, platform_os, is_fyi=False, run_reference_build=True, executables=None): + benchmark_configs = benchmark_configs.Frozenset() self._name = name self._description = description self._platform_os = platform_os @@ -159,6 +160,39 @@ self.repeat = 1 +class PerfSuite(object): + def __init__(self, configs): + self._configs = dict() + self.Add(configs) + + def Frozenset(self): + return frozenset(self._configs.values()) + + def Add(self, configs): + if isinstance(configs, PerfSuite): + configs = configs.Frozenset() + for config in configs: + if config.name in self._configs: + raise ValueError('Cannot have duplicate benchmarks/executables.') + self._configs[config.name] = config + return self + + def Remove(self, configs): + for config in configs: + name = config + if isinstance(config, PerfSuite): + name = config.name + del self._configs[name] + return self + + def Abridge(self, config_names): + for name in config_names: + del self._configs[name] + self._configs[name] = _GetBenchmarkConfig( + name, abridged=True) + return self + + # Global |benchmarks| is convenient way to keep BenchmarkConfig objects # unique, which allows us to use set subtraction below. benchmarks = {b.Name(): {True: BenchmarkConfig(b, abridged=True), @@ -168,22 +202,20 @@ def _GetBenchmarkConfig(benchmark_name, abridged=False): return benchmarks[benchmark_name][abridged] -OFFICIAL_BENCHMARK_CONFIGS = frozenset( - _GetBenchmarkConfig(b.Name()) for b in OFFICIAL_BENCHMARKS) +OFFICIAL_BENCHMARK_CONFIGS = PerfSuite( + [_GetBenchmarkConfig(b.Name()) for b in OFFICIAL_BENCHMARKS]) # TODO(crbug.com/965158): Remove OFFICIAL_BENCHMARK_NAMES once sharding # scripts are no longer using it. OFFICIAL_BENCHMARK_NAMES = frozenset( - b.name for b in OFFICIAL_BENCHMARK_CONFIGS) -_DL_BENCHMARK_CONFIGS = frozenset([_GetBenchmarkConfig( - 'blink_perf.display_locking')]) -_JETSTREAM2 = frozenset([_GetBenchmarkConfig('jetstream2')]) + b.name for b in OFFICIAL_BENCHMARK_CONFIGS.Frozenset()) -_OFFICIAL_EXCEPT_DISPLAY_LOCKING = ( - OFFICIAL_BENCHMARK_CONFIGS - _DL_BENCHMARK_CONFIGS) -_OFFICIAL_EXCEPT_JETSTREAM2 = ( - OFFICIAL_BENCHMARK_CONFIGS - _JETSTREAM2) -_OFFICIAL_EXCEPT_DISPLAY_LOCKING_JETSTREAM2 = ( - OFFICIAL_BENCHMARK_CONFIGS - _DL_BENCHMARK_CONFIGS - _JETSTREAM2) +_OFFICIAL_EXCEPT_DISPLAY_LOCKING = PerfSuite(OFFICIAL_BENCHMARK_CONFIGS).Remove( + ['blink_perf.display_locking']) +_OFFICIAL_EXCEPT_JETSTREAM2 = PerfSuite(OFFICIAL_BENCHMARK_CONFIGS).Remove( + ['jetstream2']) +_OFFICIAL_EXCEPT_DISPLAY_LOCKING_JETSTREAM2 = PerfSuite( + OFFICIAL_BENCHMARK_CONFIGS).Remove( + ['blink_perf.display_locking', 'jetstream2']) _TRACING_PERFTESTS = ExecutableConfig('tracing_perftests', estimated_runtime=50) _COMPONENTS_PERFTESTS = ExecutableConfig('components_perftests', @@ -195,12 +227,12 @@ _MAC_LOW_END_BENCHMARK_CONFIGS = _OFFICIAL_EXCEPT_JETSTREAM2 _WIN_10_BENCHMARK_CONFIGS = _OFFICIAL_EXCEPT_DISPLAY_LOCKING _WIN_10_LOW_END_BENCHMARK_CONFIGS = _OFFICIAL_EXCEPT_DISPLAY_LOCKING -_WIN_10_LOW_END_HP_CANDIDATE_BENCHMARK_CONFIGS = frozenset([ - _GetBenchmarkConfig('v8.browsing_desktop')]) -_WIN_7_BENCHMARK_CONFIGS = (_OFFICIAL_EXCEPT_DISPLAY_LOCKING_JETSTREAM2 - - frozenset([_GetBenchmarkConfig('rendering.desktop')])) +_WIN_10_LOW_END_HP_CANDIDATE_BENCHMARK_CONFIGS = PerfSuite( + [_GetBenchmarkConfig('v8.browsing_desktop')]) +_WIN_7_BENCHMARK_CONFIGS = PerfSuite( + _OFFICIAL_EXCEPT_DISPLAY_LOCKING_JETSTREAM2).Remove(['rendering.desktop']) _WIN_7_GPU_BENCHMARK_CONFIGS = _OFFICIAL_EXCEPT_DISPLAY_LOCKING_JETSTREAM2 -_ANDROID_GO_BENCHMARK_CONFIGS = frozenset([ +_ANDROID_GO_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('system_health.memory_mobile'), _GetBenchmarkConfig('system_health.common_mobile'), _GetBenchmarkConfig('startup.mobile'), @@ -212,15 +244,9 @@ _ANDROID_NEXUS_5_BENCHMARK_CONFIGS = _OFFICIAL_EXCEPT_DISPLAY_LOCKING_JETSTREAM2 _ANDROID_NEXUS_5_EXECUTABLE_CONFIGS = frozenset([ _TRACING_PERFTESTS, _COMPONENTS_PERFTESTS, _GPU_PERFTESTS]) -_ANDROID_NEXUS_5X_BENCHMARK_CONFIGS = ( - (((_OFFICIAL_EXCEPT_JETSTREAM2 - # Remove unabridged rendering benchmark and replace with abridged benchmark. - - frozenset([_GetBenchmarkConfig('rendering.mobile')])) - | frozenset([_GetBenchmarkConfig('rendering.mobile', True)])) - # Remove unabridged system health memory benchmark and replace with abridged - # benchmark: crbug.com/1030788 - - frozenset([_GetBenchmarkConfig('system_health.memory_mobile')])) - | frozenset([_GetBenchmarkConfig('system_health.memory_mobile', True)])) +_ANDROID_NEXUS_5X_BENCHMARK_CONFIGS = PerfSuite( + _OFFICIAL_EXCEPT_JETSTREAM2).Abridge( + ['rendering.mobile', 'system_health.memory_mobile']) _ANDROID_NEXUS_5X_WEBVIEW_BENCHMARK_CONFIGS = ( _OFFICIAL_EXCEPT_DISPLAY_LOCKING_JETSTREAM2) _ANDROID_NEXUS_6_WEBVIEW_BENCHMARK_CONFIGS = ( @@ -228,17 +254,17 @@ _ANDROID_PIXEL2_BENCHMARK_CONFIGS = _OFFICIAL_EXCEPT_DISPLAY_LOCKING _ANDROID_PIXEL2_WEBVIEW_BENCHMARK_CONFIGS = ( _OFFICIAL_EXCEPT_DISPLAY_LOCKING_JETSTREAM2) -_ANDROID_PIXEL2_WEBLAYER_BENCHMARK_CONFIGS = frozenset([ +_ANDROID_PIXEL2_WEBLAYER_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('system_health.common_mobile', True), _GetBenchmarkConfig('system_health.memory_mobile', True), _GetBenchmarkConfig('startup.mobile')]) -_ANDROID_NEXUS5X_FYI_BENCHMARK_CONFIGS = frozenset([ +_ANDROID_NEXUS5X_FYI_BENCHMARK_CONFIGS = PerfSuite([ # Running a sample benchmark to help testing out the work on # trace_processor_shell: crbug.com/1028612 _GetBenchmarkConfig('tracing.tracing_with_background_memory_infra')]) -_ANDROID_PIXEL2_AAB_FYI_BENCHMARK_CONFIGS = frozenset([ +_ANDROID_PIXEL2_AAB_FYI_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('rendering.mobile', True)]) -_ANDROID_PIXEL2_FYI_BENCHMARK_CONFIGS = frozenset([ +_ANDROID_PIXEL2_FYI_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('v8.browsing_mobile'), _GetBenchmarkConfig('system_health.memory_mobile'), _GetBenchmarkConfig('system_health.common_mobile'), @@ -246,9 +272,9 @@ _GetBenchmarkConfig('speedometer2'), _GetBenchmarkConfig('octane'), _GetBenchmarkConfig('jetstream')]) -_CHROMEOS_KEVIN_FYI_BENCHMARK_CONFIGS = frozenset([ +_CHROMEOS_KEVIN_FYI_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('rendering.desktop')]) -_LINUX_PERF_FYI_BENCHMARK_CONFIGS = frozenset([ +_LINUX_PERF_FYI_BENCHMARK_CONFIGS = PerfSuite([ _GetBenchmarkConfig('power.desktop')])
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 6c2dae8..4f2afc80 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -131,6 +131,9 @@ 'tests': [ { 'isolate': 'performance_test_suite', + 'extra_args': [ + '--run-ref-build', + ], } ], 'platform': 'android-chrome-bundle', @@ -570,6 +573,14 @@ 'num_shards': 1, 'type': TEST_TYPES.GTEST, }, + { + 'isolate': 'dawn_perf_tests', + 'num_shards': 1, + 'type': TEST_TYPES.GTEST, + 'extra_args': [ + '--shard-timeout=300' + ], + }, ], 'platform': 'win', 'target_bits': 64, @@ -881,6 +892,10 @@ 'views_perftests': BenchmarkMetadata( 'tapted@chromium.org', 'Internals>Views'), 'components_perftests': BenchmarkMetadata('csharrison@chromium.org'), + 'dawn_perf_tests': BenchmarkMetadata( + 'enga@chromium.org, chrome-gpu-perf-owners@chromium.org', + 'Internals>GPU>Dawn', + 'https://dawn.googlesource.com/dawn/+/HEAD/src/tests/perf_tests/README.md'), }
diff --git a/tools/perf/core/results_processor/command_line.py b/tools/perf/core/results_processor/command_line.py index c1b7f87..dfa838cd 100644 --- a/tools/perf/core/results_processor/command_line.py +++ b/tools/perf/core/results_processor/command_line.py
@@ -184,10 +184,17 @@ the path to trace processor binary located in that directory. Otherwise we don't guess, but leave it to the user to supply a path. """ - build_dirs = ['build', 'out', 'xcodebuild'] - build_types = ['Debug', 'Debug_x64', 'Release', 'Release_x64', 'Default'] executable_names = [trace_processor.TP_BINARY_NAME, trace_processor.TP_BINARY_NAME + '.exe'] + chromium_output_dir = os.environ.get('CHROMIUM_OUTPUT_DIR') + if chromium_output_dir: + for executable_name in executable_names: + candidate_path = os.path.join(chromium_output_dir, executable_name) + if os.path.isfile(candidate_path): + return candidate_path + + build_dirs = ['build', 'out', 'xcodebuild'] + build_types = ['Debug', 'Debug_x64', 'Release', 'Release_x64', 'Default'] candidate_paths = [] for build_dir in build_dirs: for build_type in build_types:
diff --git a/tools/perf/core/results_processor/command_line_unittest.py b/tools/perf/core/results_processor/command_line_unittest.py index fc531bb..5dd1f9ab 100644 --- a/tools/perf/core/results_processor/command_line_unittest.py +++ b/tools/perf/core/results_processor/command_line_unittest.py
@@ -137,9 +137,26 @@ self.assertEqual(options.output_formats, ['csv', 'html']) def testTraceProcessorPath_noBuildDir(self): - options = self.ParseArgs([]) + with mock.patch(module('os.environ.get'), return_value=None): + options = self.ParseArgs([]) self.assertIsNone(options.trace_processor_path) + def testTraceProcessorPath_chromiumOutputDir(self): + def isfile(path): + return path == '/path/to/chromium/out_test/Debug/trace_processor_shell' + + def env_get(name): + if name == 'CHROMIUM_OUTPUT_DIR': + return '/path/to/chromium/out_test/Debug' + + with mock.patch(module('os.path.isfile')) as isfile_patch: + with mock.patch(module('os.environ.get')) as env_patch: + isfile_patch.side_effect = isfile + env_patch.side_effect = env_get + options = self.ParseArgs([]) + self.assertEqual(options.trace_processor_path, + '/path/to/chromium/out_test/Debug/trace_processor_shell') + def testTraceProcessorPath_oneBuildDir(self): def isfile(path): return path == '/path/to/chromium/out/Release/trace_processor_shell'
diff --git a/tools/perf/core/shard_maps/smoke_test_benchmark_shard_map.json b/tools/perf/core/shard_maps/smoke_test_benchmark_shard_map.json index 992dd83..1524b68 100644 --- a/tools/perf/core/shard_maps/smoke_test_benchmark_shard_map.json +++ b/tools/perf/core/shard_maps/smoke_test_benchmark_shard_map.json
@@ -4,14 +4,6 @@ "dummy_benchmark.stable_benchmark_1": { "abridged": false } - }, - "executables": { - "dummy_gtest": { - "path": "../../tools/perf/testdata/dummy_gtest", - "arguments": [ - "--argument-to-check-that-arguments-work" - ] - } } }, "1": {
diff --git a/tools/perf/scripts_smoke_unittest.py b/tools/perf/scripts_smoke_unittest.py index 968b7b90..007311aa 100644 --- a/tools/perf/scripts_smoke_unittest.py +++ b/tools/perf/scripts_smoke_unittest.py
@@ -163,7 +163,10 @@ # Android: crbug.com/932301 # ChromeOS: crbug.com/754913 # Windows: crbug.com/1024767 - @decorators.Disabled('chromeos', 'android', 'win') + # Linux: crbug.com/1024767 + # all: Disabled everywhere because the smoke test shard map + # needed to be changed to fix crbug.com/1024767. + @decorators.Disabled('all') def testRunPerformanceTestsTelemetrySharded_end2end(self): tempdir = tempfile.mkdtemp() env = os.environ.copy()
diff --git a/ui/color/BUILD.gn b/ui/color/BUILD.gn index 347b2847..12d0512 100644 --- a/ui/color/BUILD.gn +++ b/ui/color/BUILD.gn
@@ -13,76 +13,104 @@ flags = [ "USE_COLOR_PIPELINE=$use_color_pipeline" ] } -jumbo_component("color") { +source_set("color_headers") { sources = [ "color_id.h", - "color_mixer.cc", - "color_mixer.h", - "color_provider.cc", + "color_id_macros.inc", "color_provider.h", - "color_recipe.cc", - "color_recipe.h", - "color_set.cc", - "color_set.h", - "color_transform.cc", - "color_transform.h", ] - defines = [ "IS_COLOR_IMPL" ] - public_deps = [ ":color_buildflags", - "//base", - "//skia", - "//ui/gfx:color_utils", ] + + if (use_color_pipeline) { + sources += [ + "color_mixer.h", + "color_set.h", + ] + + public_deps += [ + "//base:base", + "//skia:skia", + ] + } else { + public_deps += [ + "//ui/base:base", + "//ui/native_theme:native_theme", + ] + } } -test("color_unittests") { - testonly = true +if (use_color_pipeline) { + jumbo_component("color") { + sources = [ + "color_mixer.cc", + "color_provider.cc", + "color_recipe.cc", + "color_recipe.h", + "color_set.cc", + "color_transform.cc", + "color_transform.h", + ] - sources = [ - "color_mixer_unittest.cc", - "color_provider_unittest.cc", - "color_recipe_unittest.cc", - "color_test_ids.h", - "color_transform_unittest.cc", - "run_all_unittests.cc", - ] + defines = [ "IS_COLOR_IMPL" ] - deps = [ - ":color", - "//base/test:test_support", - "//testing/gtest", - ] -} + public_deps = [ + ":color_headers", + "//base:base", + "//skia:skia", + "//ui/gfx:color_utils", + ] + } -jumbo_component("mixers") { - sources = [ - "color_mixers.h", - "core_default_color_mixer.cc", - "ui_color_mixer.cc", - ] + test("color_unittests") { + testonly = true - defines = [ "IS_COLOR_IMPL" ] + sources = [ + "color_mixer_unittest.cc", + "color_provider_unittest.cc", + "color_recipe_unittest.cc", + "color_test_ids.h", + "color_transform_unittest.cc", + "run_all_unittests.cc", + ] - deps = [ - ":color", - "//skia", - "//ui/gfx:color_utils", - ] + deps = [ + ":color", + "//base/test:test_support", + "//testing/gtest", + ] + } - public_deps = [ - "//base", - ] + jumbo_component("mixers") { + sources = [ + "color_mixers.h", + "core_default_color_mixer.cc", + "ui_color_mixer.cc", + ] - if (is_chromeos) { - sources += [ "cros/native_color_mixer.cc" ] - } else if (is_linux) { - sources += [ "linux/native_color_mixer.cc" ] - } else if (is_mac) { - sources += [ "mac/native_color_mixer.cc" ] - } else if (is_win) { - sources += [ "win/native_color_mixer.cc" ] + defines = [ "IS_COLOR_IMPL" ] + + deps = [ + ":color", + ":color_headers", + "//skia", + "//ui/gfx:color_utils", + ] + + public_deps = [ + "//base", + ] + + if (is_chromeos) { + sources += [ "cros/native_color_mixer.cc" ] + } else if (is_linux) { + sources += [ "linux/native_color_mixer.cc" ] + } else if (is_mac) { + sources += [ "mac/native_color_mixer.cc" ] + } else if (is_win) { + sources += [ "win/native_color_mixer.cc" ] + } } }
diff --git a/ui/color/DEPS b/ui/color/DEPS index 41134f5..c5a8c5f9 100644 --- a/ui/color/DEPS +++ b/ui/color/DEPS
@@ -1,4 +1,6 @@ include_rules = [ "+third_party/skia/include", + "+ui/base/theme_provider.h", # used by color_provider.h when !USE_COLOR_PIPELINE. "+ui/gfx", + "+ui/native_theme/native_theme.h", # used by color_id.h when !USE_COLOR_PIPELINE. ]
diff --git a/ui/color/color_id.h b/ui/color/color_id.h index 29ecf72..e5b2d49d 100644 --- a/ui/color/color_id.h +++ b/ui/color/color_id.h
@@ -6,128 +6,171 @@ #define UI_COLOR_COLOR_ID_H_ #include "build/build_config.h" +#include "build/buildflag.h" +#include "ui/color/color_buildflags.h" + +#if !BUILDFLAG(USE_COLOR_PIPELINE) +#include "ui/native_theme/native_theme.h" // nogncheck + +#if defined(OS_WIN) +#include <windows.h> +#endif +#endif // clang-format off #define CROSS_PLATFORM_COLOR_IDS \ /* Core color concepts */ \ - E(kColorAccent, kUiColorsStart), \ - E(kColorAlertHighSeverity), \ - E(kColorAlertLowSeverity), \ - E(kColorAlertMediumSeverity), \ - E(kColorBorderAndSeparatorForeground), \ - E(kColorDisabledForeground), \ - E(kColorItemSelectionBackground), \ - E(kColorPrimaryBackground), \ - E(kColorPrimaryForeground), \ - E(kColorSecondaryForeground), \ - E(kColorSubtleEmphasisBackground), \ - E(kColorTextSelectionBackground), \ + E_CPONLY(kColorAccent, kUiColorsStart) \ + E(kColorAlertHighSeverity, NativeTheme::kColorId_AlertSeverityHigh) \ + E(kColorAlertLowSeverity, NativeTheme::kColorId_AlertSeverityLow) \ + E(kColorAlertMediumSeverity, NativeTheme::kColorId_AlertSeverityMedium) \ + E_CPONLY(kColorBorderAndSeparatorForeground) \ + E_CPONLY(kColorDisabledForeground) \ + E_CPONLY(kColorItemSelectionBackground) \ + E_CPONLY(kColorPrimaryBackground) \ + E_CPONLY(kColorPrimaryForeground) \ + E_CPONLY(kColorSecondaryForeground) \ + E_CPONLY(kColorSubtleEmphasisBackground) \ + E_CPONLY(kColorTextSelectionBackground) \ \ /* Further UI element colors */ \ - E(kColorBubbleBackground), \ - E(kColorBubbleFooterBackground), \ - E(kColorButtonBackground), \ - E(kColorButtonBorder), \ - E(kColorButtonDisabledForeground), \ - E(kColorButtonForeground), \ - E(kColorButtonPressedBackground), \ - E(kColorButtonProminentBackground), \ - E(kColorButtonProminentDisabledBackground), \ - E(kColorButtonProminentFocusedBackground), \ - E(kColorButtonProminentForeground), \ - E(kColorButtonUncheckedForeground), \ - E(kColorDialogBackground), \ - E(kColorDialogForeground), \ - E(kColorFocusableBorderFocused), \ - E(kColorFocusableBorderUnfocused), \ - E(kColorIcon), \ - E(kColorLabelDisabledForeground), \ - E(kColorLabelForeground), \ - E(kColorLabelSecondaryForeground), \ - E(kColorLabelSelectionBackground), \ - E(kColorLabelSelectionForeground), \ - E(kColorLinkDisabledForeground), \ - E(kColorLinkForeground), \ - E(kColorLinkPressedForeground), \ - E(kColorMenuBackground), \ - E(kColorMenuBorder), \ - E(kColorMenuItemAlertedBackground), \ - E(kColorMenuItemDisabledForeground), \ - E(kColorMenuItemForeground), \ - E(kColorMenuItemHighlightedBackground), \ - E(kColorMenuItemHighlightedForeground), \ - E(kColorMenuItemSecondaryForeground), \ - E(kColorMenuItemSelectedBackground), \ - E(kColorMenuItemSelectedForeground), \ - E(kColorMenuSeparator), \ - E(kColorTabContentSeparator), \ - E(kColorTabForeground), \ - E(kColorTabSelectedForeground), \ - E(kColorTableBackground), \ - E(kColorTableForeground), \ - E(kColorTableGroupingIndicator), \ - E(kColorTableHeaderBackground), \ - E(kColorTableHeaderForeground), \ - E(kColorTableHeaderSeparator), \ - E(kColorTableSelectedFocusedBackground), \ - E(kColorTableSelectedFocusedForeground), \ - E(kColorTableSelectedUnfocusedBackground), \ - E(kColorTableSelectedUnfocusedForeground), \ - E(kColorTextfieldBackground), \ - E(kColorTextfieldDisabledBackground), \ - E(kColorTextfieldDisabledForeground), \ - E(kColorTextfieldForeground), \ - E(kColorTextfieldSelectionBackground), \ - E(kColorTextfieldSelectionForeground), \ - E(kColorThrobber), \ - E(kColorTooltipBackground), \ - E(kColorTooltipForeground), \ - E(kColorTreeBackground), \ - E(kColorTreeNodeForeground), \ - E(kColorTreeNodeSelectedFocusedBackground), \ - E(kColorTreeNodeSelectedFocusedForeground), \ - E(kColorTreeNodeSelectedUnfocusedBackground), \ - E(kColorTreeNodeSelectedUnfocusedForeground), \ - E(kColorWindowBackground) + E(kColorBubbleBackground, NativeTheme::kColorId_BubbleBackground) \ + E(kColorBubbleFooterBackground, \ + NativeTheme::kColorId_BubbleFooterBackground) \ + E(kColorButtonBackground, NativeTheme::kColorId_DialogBackground) \ + E(kColorButtonBorder, NativeTheme::kColorId_ButtonBorderColor) \ + E(kColorButtonDisabledForeground, NativeTheme::kColorId_ButtonDisabledColor) \ + E(kColorButtonForeground, NativeTheme::kColorId_ButtonEnabledColor) \ + /* TODO(https://crbug.com/1003612): Map this to old color id. */ \ + E_CPONLY(kColorButtonPressedBackground) \ + E(kColorButtonProminentBackground, \ + NativeTheme::kColorId_ProminentButtonColor) \ + E(kColorButtonProminentDisabledBackground, \ + NativeTheme::kColorId_ProminentButtonDisabledColor) \ + E(kColorButtonProminentFocusedBackground, \ + NativeTheme::kColorId_ProminentButtonFocusedColor) \ + E(kColorButtonProminentForeground, \ + NativeTheme::kColorId_TextOnProminentButtonColor) \ + E(kColorButtonUncheckedForeground, \ + NativeTheme::kColorId_ButtonUncheckedColor) \ + E(kColorDialogBackground, NativeTheme::kColorId_DialogBackground) \ + E(kColorDialogForeground, NativeTheme::kColorId_DialogForeground) \ + E(kColorFocusableBorderFocused, NativeTheme::kColorId_FocusedBorderColor) \ + E(kColorFocusableBorderUnfocused, \ + NativeTheme::kColorId_UnfocusedBorderColor) \ + E(kColorIcon, NativeTheme::kColorId_DefaultIconColor) \ + E(kColorLabelDisabledForeground, NativeTheme::kColorId_LabelDisabledColor) \ + E(kColorLabelForeground, NativeTheme::kColorId_LabelEnabledColor) \ + E(kColorLabelSecondaryForeground, NativeTheme::kColorId_LabelSecondaryColor) \ + E(kColorLabelSelectionBackground, \ + NativeTheme::kColorId_LabelTextSelectionBackgroundFocused) \ + E(kColorLabelSelectionForeground, \ + NativeTheme::kColorId_LabelTextSelectionColor) \ + E(kColorLinkDisabledForeground, NativeTheme::kColorId_LinkDisabled) \ + E(kColorLinkForeground, NativeTheme::kColorId_LinkEnabled) \ + E(kColorLinkPressedForeground, NativeTheme::kColorId_LinkPressed) \ + E(kColorMenuBackground, NativeTheme::kColorId_MenuBackgroundColor) \ + E(kColorMenuBorder, NativeTheme::kColorId_MenuBorderColor) \ + E(kColorMenuItemAlertedBackground, \ + NativeTheme::kColorId_MenuItemAlertBackgroundColor) \ + E(kColorMenuItemDisabledForeground, \ + NativeTheme::kColorId_DisabledMenuItemForegroundColor) \ + E(kColorMenuItemForeground, \ + NativeTheme::kColorId_EnabledMenuItemForegroundColor) \ + E(kColorMenuItemHighlightedBackground, \ + NativeTheme::kColorId_HighlightedMenuItemBackgroundColor) \ + E(kColorMenuItemHighlightedForeground, \ + NativeTheme::kColorId_HighlightedMenuItemForegroundColor) \ + E(kColorMenuItemSecondaryForeground, \ + NativeTheme::kColorId_MenuItemMinorTextColor) \ + E(kColorMenuItemSelectedBackground, \ + NativeTheme::kColorId_FocusedMenuItemBackgroundColor) \ + E(kColorMenuItemSelectedForeground, \ + NativeTheme::kColorId_SelectedMenuItemForegroundColor) \ + E(kColorMenuSeparator, NativeTheme::kColorId_MenuSeparatorColor) \ + E(kColorTabContentSeparator, NativeTheme::kColorId_TabBottomBorder) \ + E(kColorTabForeground, NativeTheme::kColorId_TabTitleColorInactive) \ + E(kColorTabSelectedForeground, \ + NativeTheme::kColorId_TabTitleColorActive) \ + E(kColorTableBackground, NativeTheme::kColorId_TableBackground) \ + E(kColorTableForeground, NativeTheme::kColorId_TableText) \ + E(kColorTableGroupingIndicator, \ + NativeTheme::kColorId_TableGroupingIndicatorColor) \ + E(kColorTableHeaderBackground, NativeTheme::kColorId_TableHeaderBackground) \ + E(kColorTableHeaderForeground, NativeTheme::kColorId_TableHeaderText) \ + E(kColorTableHeaderSeparator, NativeTheme::kColorId_TableHeaderSeparator) \ + E(kColorTableSelectedFocusedBackground, \ + NativeTheme::kColorId_TableSelectionBackgroundFocused) \ + E(kColorTableSelectedFocusedForeground, \ + NativeTheme::kColorId_TableSelectedText) \ + E(kColorTableSelectedUnfocusedBackground, \ + NativeTheme::kColorId_TableSelectionBackgroundUnfocused) \ + E(kColorTableSelectedUnfocusedForeground, \ + NativeTheme::kColorId_TableSelectedTextUnfocused) \ + E(kColorTextfieldBackground, \ + NativeTheme::kColorId_TextfieldDefaultBackground) \ + E(kColorTextfieldDisabledBackground, \ + NativeTheme::kColorId_TextfieldReadOnlyBackground) \ + E(kColorTextfieldDisabledForeground, \ + NativeTheme::kColorId_TextfieldReadOnlyColor) \ + E(kColorTextfieldForeground, NativeTheme::kColorId_TextfieldDefaultColor) \ + E(kColorTextfieldSelectionBackground, \ + NativeTheme::kColorId_TextfieldSelectionBackgroundFocused) \ + E(kColorTextfieldSelectionForeground, \ + NativeTheme::kColorId_TextfieldSelectionColor) \ + E(kColorThrobber, NativeTheme::kColorId_ThrobberSpinningColor) \ + E(kColorTooltipBackground, NativeTheme::kColorId_TooltipBackground) \ + E(kColorTooltipForeground, NativeTheme::kColorId_TooltipText) \ + E(kColorTreeBackground, NativeTheme::kColorId_TreeBackground) \ + E(kColorTreeNodeForeground, NativeTheme::kColorId_TreeText) \ + E(kColorTreeNodeSelectedFocusedBackground, \ + NativeTheme::kColorId_TreeSelectionBackgroundFocused) \ + E(kColorTreeNodeSelectedFocusedForeground, \ + NativeTheme::kColorId_TreeSelectedText) \ + E(kColorTreeNodeSelectedUnfocusedBackground, \ + NativeTheme::kColorId_TreeSelectionBackgroundUnfocused) \ + E(kColorTreeNodeSelectedUnfocusedForeground, \ + NativeTheme::kColorId_TreeSelectedTextUnfocused) \ + E(kColorWindowBackground, NativeTheme::kColorId_WindowBackground) #if defined(OS_WIN) #define WIN_COLOR_IDS \ /* Windows native colors */ \ - E(kColorNative3dDkShadow), \ - E(kColorNative3dLight), \ - E(kColorNativeActiveBorder), \ - E(kColorNativeActiveCaption), \ - E(kColorNativeAppWorkspace), \ - E(kColorNativeBackground), \ - E(kColorNativeBtnFace), \ - E(kColorNativeBtnHighlight), \ - E(kColorNativeBtnShadow), \ - E(kColorNativeBtnText), \ - E(kColorNativeCaptionText), \ - E(kColorNativeGradientActiveCaption), \ - E(kColorNativeGradientInactiveCaption), \ - E(kColorNativeGrayText), \ - E(kColorNativeHighlight), \ - E(kColorNativeHighlightText), \ - E(kColorNativeHotlight), \ - E(kColorNativeInactiveBorder), \ - E(kColorNativeInactiveCaption), \ - E(kColorNativeInactiveCaptionText), \ - E(kColorNativeInfoBk), \ - E(kColorNativeInfoText), \ - E(kColorNativeMenu), \ - E(kColorNativeMenuBar), \ - E(kColorNativeMenuHilight), \ - E(kColorNativeMenuText), \ - E(kColorNativeScrollbar), \ - E(kColorNativeWindow), \ - E(kColorNativeWindowFrame), \ - E(kColorNativeWindowText) + E(kColorNative3dDkShadow, COLOR_3DDKSHADOW) \ + E(kColorNative3dLight, COLOR_3DLIGHT) \ + E(kColorNativeActiveBorder, COLOR_ACTIVEBORDER) \ + E(kColorNativeActiveCaption, COLOR_ACTIVECAPTION) \ + E(kColorNativeAppWorkspace, COLOR_APPWORKSPACE) \ + E(kColorNativeBackground, COLOR_BACKGROUND) \ + E(kColorNativeBtnFace, COLOR_BTNFACE) \ + E(kColorNativeBtnHighlight, COLOR_BTNHIGHLIGHT) \ + E(kColorNativeBtnShadow, COLOR_BTNSHADOW) \ + E(kColorNativeBtnText, COLOR_BTNTEXT) \ + E(kColorNativeCaptionText, COLOR_CAPTIONTEXT) \ + E(kColorNativeGradientActiveCaption, COLOR_GRADIENTACTIVECAPTION) \ + E(kColorNativeGradientInactiveCaption, COLOR_GRADIENTINACTIVECAPTION) \ + E(kColorNativeGrayText, COLOR_GRAYTEXT) \ + E(kColorNativeHighlight, COLOR_HIGHLIGHT) \ + E(kColorNativeHighlightText, COLOR_HIGHLIGHTTEXT) \ + E(kColorNativeHotlight, COLOR_HOTLIGHT) \ + E(kColorNativeInactiveBorder, COLOR_INACTIVEBORDER) \ + E(kColorNativeInactiveCaption, COLOR_INACTIVECAPTION) \ + E(kColorNativeInactiveCaptionText, COLOR_INACTIVECAPTIONTEXT) \ + E(kColorNativeInfoBk, COLOR_INFOBK) \ + E(kColorNativeInfoText, COLOR_INFOTEXT) \ + E(kColorNativeMenu, COLOR_MENU) \ + E(kColorNativeMenuBar, COLOR_MENUBAR) \ + E(kColorNativeMenuHilight, COLOR_MENUHILIGHT) \ + E(kColorNativeMenuText, COLOR_MENUTEXT) \ + E(kColorNativeScrollbar, COLOR_SCROLLBAR) \ + E(kColorNativeWindow, COLOR_WINDOW) \ + E(kColorNativeWindowFrame, COLOR_WINDOWFRAME) \ + E(kColorNativeWindowText, COLOR_WINDOWTEXT) #endif #if defined(OS_WIN) #define COLOR_IDS \ - CROSS_PLATFORM_COLOR_IDS, \ + CROSS_PLATFORM_COLOR_IDS \ WIN_COLOR_IDS #else #define COLOR_IDS CROSS_PLATFORM_COLOR_IDS @@ -144,10 +187,11 @@ // define enum values from kUiColorsEnd. Values named beginning with "kColor" // represent the actual colors; the rest are markers. using ColorId = int; +// clang-format off enum ColorIds : ColorId { kUiColorsStart = 0, - COLOR_IDS, + COLOR_IDS // TODO(pkasting): Other native colors @@ -158,9 +202,12 @@ // verify that color IDs and color set IDs are not interchanged. kUiColorsLast = 0xffff }; +// clang-format on #include "ui/color/color_id_macros.inc" +#if BUILDFLAG(USE_COLOR_PIPELINE) + // ColorSetId contains identifiers for all distinct color sets known to the core // UI layer. As with ColorId, embedders can extend this enum with additional // values that are understood by the ColorProvider implementation. Embedders @@ -190,6 +237,8 @@ // Verifies that |id| is a color set ID, not a color ID. #define DCHECK_COLOR_SET_ID_VALID(id) DCHECK_GE(id, kUiColorSetsStart) +#endif // BUILDFLAG(USE_COLOR_PIPELINE) + } // namespace ui #endif // UI_COLOR_COLOR_ID_H_
diff --git a/ui/color/color_id_macros.inc b/ui/color/color_id_macros.inc index 97f20f9..66e4a492 100644 --- a/ui/color/color_id_macros.inc +++ b/ui/color/color_id_macros.inc
@@ -11,17 +11,39 @@ #if !defined(COLOR_ID_MACROS_DEFINED) #define COLOR_ID_MACROS_DEFINED #if defined(STRINGIZE_COLOR_IDS) -#define E1(enum_name) #enum_name -#define E2(enum_name, enum_value) #enum_name +// Convert first token to string, throw away the rest. +#define D1(enum_name) #enum_name +#define D2(enum_name, enum_value) #enum_name #else -#define E1(enum_name) enum_name -#define E2(enum_name, enum_value) enum_name = enum_value -#endif -#define GET_E(_1, _2, macro_name, ...) macro_name -#define E(...) GET_E(__VA_ARGS__, E2, E1)(__VA_ARGS__) +// Declare enum with optional assigned value. +#define D1(enum_name) enum_name +#define D2(enum_name, enum_value) enum_name = enum_value +#endif // defined(STRINGIZE_COLOR_IDS) +// Select which token in the declaration is the assigned value. +#if BUILDFLAG(USE_COLOR_PIPELINE) +// Use first and optional third token, ignore optional second. +#define E1(enum_name) D1(enum_name) +#define E2(enum_name, old_enum_name) D1(enum_name) +#define E3(enum_name, old_enum_name, enum_value) D2(enum_name, enum_value) +#define E_CPONLY(...) E(__VA_ARGS__) #else +// Use first and mandatory second token, ignore optional third. +#define E1(enum_name) \ + static_assert(false, "New-style color compiled for !USE_COLOR_PIPELINE") +#define E2(enum_name, old_enum_name) D2(enum_name, old_enum_name) +#define E3(enum_name, old_enum_name, enum_value) D2(enum_name, old_enum_name) +// Ignore any new color id defined only for color pipeline enabled. +#define E_CPONLY(...) +#endif // BUILDFLAG(USE_COLOR_PIPELINE) +#define GET_E(_1, _2, _3, macro_name, ...) macro_name +#define E(...) GET_E(__VA_ARGS__, E3, E2, E1)(__VA_ARGS__), +#else +#undef D1 +#undef D2 #undef E1 #undef E2 +#undef E3 +#undef E_CPONLY #undef GET_E #undef E #undef COLOR_ID_MACROS_DEFINED
diff --git a/ui/color/color_provider.h b/ui/color/color_provider.h index c735a5e..1c60ea9 100644 --- a/ui/color/color_provider.h +++ b/ui/color/color_provider.h
@@ -8,13 +8,21 @@ #include <forward_list> #include <map> +#include "ui/color/color_buildflags.h" + +#if BUILDFLAG(USE_COLOR_PIPELINE) #include "base/component_export.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/color/color_id.h" #include "ui/color/color_mixer.h" +#else +#include "ui/base/theme_provider.h" // nogncheck +#endif namespace ui { +#if BUILDFLAG(USE_COLOR_PIPELINE) + // A ColorProvider holds the complete pipeline of ColorMixers that compute // result colors for UI elements. ColorProvider is meant to be a long-lived // object whose internal list of mixers does not change after initial @@ -49,6 +57,12 @@ mutable std::map<ColorId, SkColor> cache_; }; +#else + +using ColorProvider = ThemeProvider; + +#endif // !BUILDFLAG(USE_COLOR_PIPELINE) + } // namespace ui #endif // UI_COLOR_COLOR_PROVIDER_H_
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index a1beb41..f34479e 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -944,11 +944,8 @@ NativeWidgetMacNSWindowHost::GetFromNativeView(native_view); if (!window_host) return nullptr; - while (window_host->parent()) { - if (window_host->native_widget_mac()->GetWidget()->is_top_level()) - break; + while (window_host->parent()) window_host = window_host->parent(); - } return window_host->native_widget_mac(); }
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index ff72483..6735f70 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -737,7 +737,6 @@ Widget* child = new Widget; Widget::InitParams init_params; init_params.parent = anchor_view.get(); - init_params.child = true; init_params.type = Widget::InitParams::TYPE_POPUP; child->Init(std::move(init_params)); return child; @@ -754,7 +753,6 @@ EXPECT_EQ(1u, children.size()); Widget* child = AttachPopupToNativeParent(native_parent); - EXPECT_FALSE(child->is_top_level()); TestWidgetObserver child_observer(child); // GetTopLevelNativeWidget() will go up through |native_parent|'s Widget.
diff --git a/ui/views_content_client/views_content_browser_client.cc b/ui/views_content_client/views_content_browser_client.cc index 35936ba..3ece6bf 100644 --- a/ui/views_content_client/views_content_browser_client.cc +++ b/ui/views_content_client/views_content_browser_client.cc
@@ -6,7 +6,6 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" -#include "storage/browser/quota/quota_settings.h" #include "ui/views_content_client/views_content_client_main_parts.h" namespace ui { @@ -24,13 +23,4 @@ return ViewsContentClientMainParts::Create(parameters, views_content_client_); } -void ViewsContentBrowserClient::GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) { - storage::GetNominalDynamicSettings( - partition->GetPath(), context->IsOffTheRecord(), - storage::GetDefaultDeviceInfoHelper(), std::move(callback)); -} - } // namespace ui
diff --git a/ui/views_content_client/views_content_browser_client.h b/ui/views_content_client/views_content_browser_client.h index 5159aa85..cea9c03c 100644 --- a/ui/views_content_client/views_content_browser_client.h +++ b/ui/views_content_client/views_content_browser_client.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "content/public/browser/content_browser_client.h" -#include "storage/browser/quota/quota_settings.h" namespace ui { @@ -24,10 +23,6 @@ // content::ContentBrowserClient: std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts( const content::MainFunctionParams& parameters) override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - storage::OptionalQuotaSettingsCallback callback) override; private: ViewsContentClient* views_content_client_;
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn index a5a13384..9bd7a857 100644 --- a/weblayer/BUILD.gn +++ b/weblayer/BUILD.gn
@@ -102,6 +102,8 @@ "app/content_main_delegate_impl.cc", "app/content_main_delegate_impl.h", "app/main.cc", + "browser/autofill_client_impl.cc", + "browser/autofill_client_impl.h", "browser/browser_context_impl.cc", "browser/browser_context_impl.h", "browser/browser_main_parts_impl.cc", @@ -158,6 +160,8 @@ "renderer/content_renderer_client_impl.h", "renderer/ssl_error_helper.cc", "renderer/ssl_error_helper.h", + "renderer/weblayer_render_frame_observer.cc", + "renderer/weblayer_render_frame_observer.h", "utility/content_utility_client_impl.cc", "utility/content_utility_client_impl.h", ] @@ -198,6 +202,9 @@ "//base:base_static", "//base/third_party/dynamic_annotations", "//cc", + "//components/autofill/content/browser", + "//components/autofill/content/renderer", + "//components/autofill/core/browser", "//components/crash/content/app", "//components/crash/content/browser", "//components/embedder_support:switches",
diff --git a/weblayer/browser/DEPS b/weblayer/browser/DEPS index cd242a9..12982e9 100644 --- a/weblayer/browser/DEPS +++ b/weblayer/browser/DEPS
@@ -5,6 +5,9 @@ # that implementation and remove the need for this dependency. "+android_webview/grit", "+cc", + "+components/autofill/content/browser", + "+components/autofill/core/browser", + "+components/autofill/core/common", "+components/crash/content/browser", "+components/embedder_support", "+components/prefs",
diff --git a/weblayer/browser/autofill_browsertest.cc b/weblayer/browser/autofill_browsertest.cc new file mode 100644 index 0000000..870b935 --- /dev/null +++ b/weblayer/browser/autofill_browsertest.cc
@@ -0,0 +1,85 @@ +// 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 "weblayer/test/weblayer_browser_test.h" + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/common/form_data.h" +#include "components/autofill/core/common/form_field_data.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "weblayer/shell/browser/shell.h" +#include "weblayer/test/weblayer_browser_test_utils.h" + +namespace weblayer { + +namespace { + +// Method that is passed to the autofill system to be invoked on detection of +// autofill forms. +// NOTE: This method can currently be invoked only once within the context of +// a given test. If that restriction ever needs to be relaxed, it could be +// done by changing |quit_closure| to a global that could be reset between +// expected invocations of the method. +void OnReceivedFormDataFromRenderer(base::OnceClosure quit_closure, + autofill::FormData* output, + const autofill::FormData& form) { + ASSERT_TRUE(quit_closure); + + *output = form; + std::move(quit_closure).Run(); +} + +} // namespace + +// Cross-platform tests of autofill parsing in the renderer and communication +// to the browser. Does not test integration with any platform's underlying +// system autofill mechanisms. +class AutofillBrowserTest : public WebLayerBrowserTest { + public: + AutofillBrowserTest() = default; + ~AutofillBrowserTest() override = default; + + private: + DISALLOW_COPY_AND_ASSIGN(AutofillBrowserTest); +}; + +// Tests that the renderer detects a password form and passes the appropriate +// data to the browser. +IN_PROC_BROWSER_TEST_F(AutofillBrowserTest, TestPasswordFormDetection) { + ASSERT_TRUE(embedded_test_server()->Start()); + + base::RunLoop run_loop; + autofill::FormData observed_form; + + InitializeAutofillWithEventForwarding( + shell(), base::BindRepeating(&OnReceivedFormDataFromRenderer, + run_loop.QuitClosure(), &observed_form)); + + GURL password_form_url = + embedded_test_server()->GetURL("/simple_password_form.html"); + NavigateAndWaitForCompletion(password_form_url, shell()); + + // Focus the username field (note that a user gesture is necessary for + // autofill to trigger) ... + ExecuteScriptWithUserGesture( + shell(), "document.getElementById('username_field').focus();"); + + // ... and wait for the parsed data to be passed to the browser. + run_loop.Run(); + + // Verify that that the form data matches that of the document. + EXPECT_EQ(base::ASCIIToUTF16("testform"), observed_form.name); + EXPECT_EQ(password_form_url.spec(), observed_form.url); + + auto fields = observed_form.fields; + EXPECT_EQ(2u, fields.size()); + autofill::FormFieldData username_field = fields[0]; + EXPECT_EQ(base::ASCIIToUTF16("username_field"), username_field.name); + autofill::FormFieldData password_field = fields[1]; + EXPECT_EQ(base::ASCIIToUTF16("password_field"), password_field.name); +} + +} // namespace weblayer
diff --git a/weblayer/browser/autofill_client_impl.cc b/weblayer/browser/autofill_client_impl.cc new file mode 100644 index 0000000..2f6db72 --- /dev/null +++ b/weblayer/browser/autofill_client_impl.cc
@@ -0,0 +1,287 @@ +// 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 "weblayer/browser/autofill_client_impl.h" + +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/ssl_status.h" +#include "content/public/browser/web_contents.h" + +namespace weblayer { + +AutofillClientImpl::~AutofillClientImpl() = default; + +autofill::PersonalDataManager* AutofillClientImpl::GetPersonalDataManager() { + NOTREACHED(); + return nullptr; +} + +autofill::AutocompleteHistoryManager* +AutofillClientImpl::GetAutocompleteHistoryManager() { + NOTREACHED(); + return nullptr; +} + +PrefService* AutofillClientImpl::GetPrefs() { + NOTREACHED(); + return nullptr; +} + +syncer::SyncService* AutofillClientImpl::GetSyncService() { + NOTREACHED(); + return nullptr; +} + +signin::IdentityManager* AutofillClientImpl::GetIdentityManager() { + NOTREACHED(); + return nullptr; +} + +autofill::FormDataImporter* AutofillClientImpl::GetFormDataImporter() { + NOTREACHED(); + return nullptr; +} + +autofill::payments::PaymentsClient* AutofillClientImpl::GetPaymentsClient() { + NOTREACHED(); + return nullptr; +} + +autofill::SmsClient* AutofillClientImpl::GetSmsClient() { + NOTREACHED(); + return nullptr; +} + +autofill::StrikeDatabase* AutofillClientImpl::GetStrikeDatabase() { + NOTREACHED(); + return nullptr; +} + +ukm::UkmRecorder* AutofillClientImpl::GetUkmRecorder() { + NOTREACHED(); + return nullptr; +} + +ukm::SourceId AutofillClientImpl::GetUkmSourceId() { + NOTREACHED(); + return ukm::kInvalidSourceId; +} + +autofill::AddressNormalizer* AutofillClientImpl::GetAddressNormalizer() { + NOTREACHED(); + return nullptr; +} + +security_state::SecurityLevel +AutofillClientImpl::GetSecurityLevelForUmaHistograms() { + NOTREACHED(); + return security_state::SecurityLevel::SECURITY_LEVEL_COUNT; +} + +void AutofillClientImpl::ShowAutofillSettings(bool show_credit_card_settings) { + NOTREACHED(); +} + +#if !defined(OS_ANDROID) +std::vector<std::string> +AutofillClientImpl::GetMerchantWhitelistForVirtualCards() { + NOTREACHED(); + return std::vector<std::string>(); +} + +std::vector<std::string> +AutofillClientImpl::GetBinRangeWhitelistForVirtualCards() { + NOTREACHED(); + return std::vector<std::string>(); +} +#endif + +void AutofillClientImpl::ShowUnmaskPrompt( + const autofill::CreditCard& card, + UnmaskCardReason reason, + base::WeakPtr<autofill::CardUnmaskDelegate> delegate) { + NOTREACHED(); +} + +void AutofillClientImpl::OnUnmaskVerificationResult(PaymentsRpcResult result) { + NOTREACHED(); +} + +void AutofillClientImpl::ShowLocalCardMigrationDialog( + base::OnceClosure show_migration_dialog_closure) { + NOTREACHED(); +} + +void AutofillClientImpl::ConfirmMigrateLocalCardToCloud( + const autofill::LegalMessageLines& legal_message_lines, + const std::string& user_email, + const std::vector<autofill::MigratableCreditCard>& migratable_credit_cards, + LocalCardMigrationCallback start_migrating_cards_callback) { + NOTREACHED(); +} + +void AutofillClientImpl::ShowLocalCardMigrationResults( + const bool has_server_error, + const base::string16& tip_message, + const std::vector<autofill::MigratableCreditCard>& migratable_credit_cards, + MigrationDeleteCardCallback delete_local_card_callback) { + NOTREACHED(); +} + +#if !defined(OS_ANDROID) +void AutofillClientImpl::ShowWebauthnOfferDialog( + WebauthnDialogCallback offer_dialog_callback) { + NOTREACHED(); +} + +void AutofillClientImpl::ShowWebauthnVerifyPendingDialog( + WebauthnDialogCallback verify_pending_dialog_callback) { + NOTREACHED(); +} + +void AutofillClientImpl::UpdateWebauthnOfferDialogWithError() { + NOTREACHED(); +} + +bool AutofillClientImpl::CloseWebauthnDialog() { + NOTREACHED(); + return false; +} + +void AutofillClientImpl::ConfirmSaveUpiIdLocally( + const std::string& upi_id, + base::OnceCallback<void(bool user_decision)> callback) { + NOTREACHED(); +} + +void AutofillClientImpl::OfferVirtualCardOptions( + const std::vector<autofill::CreditCard*>& candidates, + base::OnceCallback<void(const std::string&)> callback) { + NOTREACHED(); +} +#endif + +void AutofillClientImpl::ConfirmSaveAutofillProfile( + const autofill::AutofillProfile& profile, + base::OnceClosure callback) { + NOTREACHED(); +} + +void AutofillClientImpl::ConfirmSaveCreditCardLocally( + const autofill::CreditCard& card, + SaveCreditCardOptions options, + LocalSaveCardPromptCallback callback) { + NOTREACHED(); +} + +#if defined(OS_ANDROID) +void AutofillClientImpl::ConfirmAccountNameFixFlow( + base::OnceCallback<void(const base::string16&)> callback) { + NOTREACHED(); +} + +void AutofillClientImpl::ConfirmExpirationDateFixFlow( + const autofill::CreditCard& card, + base::OnceCallback<void(const base::string16&, const base::string16&)> + callback) { + NOTREACHED(); +} +#endif + +void AutofillClientImpl::ConfirmSaveCreditCardToCloud( + const autofill::CreditCard& card, + const autofill::LegalMessageLines& legal_message_lines, + SaveCreditCardOptions options, + UploadSaveCardPromptCallback callback) { + NOTREACHED(); +} + +void AutofillClientImpl::CreditCardUploadCompleted(bool card_saved) { + NOTREACHED(); +} + +void AutofillClientImpl::ConfirmCreditCardFillAssist( + const autofill::CreditCard& card, + base::OnceClosure callback) { + NOTREACHED(); +} + +bool AutofillClientImpl::HasCreditCardScanFeature() { + NOTREACHED(); + return false; +} + +void AutofillClientImpl::ScanCreditCard(CreditCardScanCallback callback) { + NOTREACHED(); +} + +void AutofillClientImpl::ShowAutofillPopup( + const gfx::RectF& element_bounds, + base::i18n::TextDirection text_direction, + const std::vector<autofill::Suggestion>& suggestions, + bool /*unused_autoselect_first_suggestion*/, + autofill::PopupType popup_type, + base::WeakPtr<autofill::AutofillPopupDelegate> delegate) { + NOTREACHED(); +} + +void AutofillClientImpl::UpdateAutofillPopupDataListValues( + const std::vector<base::string16>& values, + const std::vector<base::string16>& labels) { + NOTREACHED(); +} + +void AutofillClientImpl::HideAutofillPopup() { + // This is invoked on the user moving away from an autofill context (e.g., a + // navigation finishing or a tab being hidden). As all showing/hiding of + // autofill UI in WebLayer is driven by the system, there is no action to + // take. +} + +bool AutofillClientImpl::IsAutocompleteEnabled() { + NOTREACHED(); + return false; +} + +void AutofillClientImpl::PropagateAutofillPredictions( + content::RenderFrameHost* rfh, + const std::vector<autofill::FormStructure*>& forms) { + NOTREACHED(); +} + +void AutofillClientImpl::DidFillOrPreviewField( + const base::string16& autofilled_value, + const base::string16& profile_full_name) { + NOTREACHED(); +} + +bool AutofillClientImpl::IsContextSecure() { + NOTREACHED(); + return false; +} + +bool AutofillClientImpl::ShouldShowSigninPromo() { + NOTREACHED(); + return false; +} + +bool AutofillClientImpl::AreServerCardsSupported() { + NOTREACHED(); + return false; +} + +void AutofillClientImpl::ExecuteCommand(int id) { + NOTREACHED(); +} + +void AutofillClientImpl::LoadRiskData( + base::OnceCallback<void(const std::string&)> callback) { + NOTREACHED(); +} + +AutofillClientImpl::AutofillClientImpl(content::WebContents* web_contents) {} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(AutofillClientImpl) + +} // namespace weblayer
diff --git a/weblayer/browser/autofill_client_impl.h b/weblayer/browser/autofill_client_impl.h new file mode 100644 index 0000000..f522b682 --- /dev/null +++ b/weblayer/browser/autofill_client_impl.h
@@ -0,0 +1,143 @@ +// 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 WEBLAYER_BROWSER_AUTOFILL_CLIENT_IMPL_H_ +#define WEBLAYER_BROWSER_AUTOFILL_CLIENT_IMPL_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "build/build_config.h" +#include "components/autofill/core/browser/autofill_client.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace weblayer { + +// A minimal implementation of autofill::AutofillClient to satisfy the minor +// touchpoints between the autofill implementation and its client that get +// exercised within the WebLayer autofill flow. +class AutofillClientImpl + : public autofill::AutofillClient, + public content::WebContentsUserData<AutofillClientImpl> { + public: + ~AutofillClientImpl() override; + + // AutofillClient: + autofill::PersonalDataManager* GetPersonalDataManager() override; + autofill::AutocompleteHistoryManager* GetAutocompleteHistoryManager() + override; + PrefService* GetPrefs() override; + syncer::SyncService* GetSyncService() override; + signin::IdentityManager* GetIdentityManager() override; + autofill::FormDataImporter* GetFormDataImporter() override; + autofill::payments::PaymentsClient* GetPaymentsClient() override; + autofill::SmsClient* GetSmsClient() override; + autofill::StrikeDatabase* GetStrikeDatabase() override; + ukm::UkmRecorder* GetUkmRecorder() override; + ukm::SourceId GetUkmSourceId() override; + autofill::AddressNormalizer* GetAddressNormalizer() override; + security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override; + void ShowAutofillSettings(bool show_credit_card_settings) override; + +#if !defined(OS_ANDROID) + std::vector<std::string> GetMerchantWhitelistForVirtualCards() override; + std::vector<std::string> GetBinRangeWhitelistForVirtualCards() override; +#endif + + void ShowUnmaskPrompt( + const autofill::CreditCard& card, + UnmaskCardReason reason, + base::WeakPtr<autofill::CardUnmaskDelegate> delegate) override; + void OnUnmaskVerificationResult(PaymentsRpcResult result) override; + void ShowLocalCardMigrationDialog( + base::OnceClosure show_migration_dialog_closure) override; + void ConfirmMigrateLocalCardToCloud( + const autofill::LegalMessageLines& legal_message_lines, + const std::string& user_email, + const std::vector<autofill::MigratableCreditCard>& + migratable_credit_cards, + LocalCardMigrationCallback start_migrating_cards_callback) override; + void ShowLocalCardMigrationResults( + const bool has_server_error, + const base::string16& tip_message, + const std::vector<autofill::MigratableCreditCard>& + migratable_credit_cards, + MigrationDeleteCardCallback delete_local_card_callback) override; + +#if !defined(OS_ANDROID) + void ShowWebauthnOfferDialog( + WebauthnDialogCallback offer_dialog_callback) override; + void ShowWebauthnVerifyPendingDialog( + WebauthnDialogCallback verify_pending_dialog_callback) override; + void UpdateWebauthnOfferDialogWithError() override; + bool CloseWebauthnDialog() override; + void ConfirmSaveUpiIdLocally( + const std::string& upi_id, + base::OnceCallback<void(bool user_decision)> callback) override; + void OfferVirtualCardOptions( + const std::vector<autofill::CreditCard*>& candidates, + base::OnceCallback<void(const std::string&)> callback) override; +#endif + + void ConfirmSaveAutofillProfile(const autofill::AutofillProfile& profile, + base::OnceClosure callback) override; + void ConfirmSaveCreditCardLocally( + const autofill::CreditCard& card, + SaveCreditCardOptions options, + LocalSaveCardPromptCallback callback) override; +#if defined(OS_ANDROID) + void ConfirmAccountNameFixFlow( + base::OnceCallback<void(const base::string16&)> callback) override; + void ConfirmExpirationDateFixFlow( + const autofill::CreditCard& card, + base::OnceCallback<void(const base::string16&, const base::string16&)> + callback) override; +#endif + void ConfirmSaveCreditCardToCloud( + const autofill::CreditCard& card, + const autofill::LegalMessageLines& legal_message_lines, + SaveCreditCardOptions options, + UploadSaveCardPromptCallback callback) override; + void CreditCardUploadCompleted(bool card_saved) override; + void ConfirmCreditCardFillAssist(const autofill::CreditCard& card, + base::OnceClosure callback) override; + bool HasCreditCardScanFeature() override; + void ScanCreditCard(CreditCardScanCallback callback) override; + void ShowAutofillPopup( + const gfx::RectF& element_bounds, + base::i18n::TextDirection text_direction, + const std::vector<autofill::Suggestion>& suggestions, + bool /*unused_autoselect_first_suggestion*/, + autofill::PopupType popup_type, + base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override; + void UpdateAutofillPopupDataListValues( + const std::vector<base::string16>& values, + const std::vector<base::string16>& labels) override; + void HideAutofillPopup() override; + bool IsAutocompleteEnabled() override; + void PropagateAutofillPredictions( + content::RenderFrameHost* rfh, + const std::vector<autofill::FormStructure*>& forms) override; + void DidFillOrPreviewField(const base::string16& autofilled_value, + const base::string16& profile_full_name) override; + bool IsContextSecure() override; + bool ShouldShowSigninPromo() override; + bool AreServerCardsSupported() override; + void ExecuteCommand(int id) override; + + // RiskDataLoader: + void LoadRiskData( + base::OnceCallback<void(const std::string&)> callback) override; + + private: + explicit AutofillClientImpl(content::WebContents* web_contents); + friend class content::WebContentsUserData<AutofillClientImpl>; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); + + DISALLOW_COPY_AND_ASSIGN(AutofillClientImpl); +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_AUTOFILL_CLIENT_IMPL_H_
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc index 83475eac..39e88ed 100644 --- a/weblayer/browser/content_browser_client_impl.cc +++ b/weblayer/browser/content_browser_client_impl.cc
@@ -12,6 +12,7 @@ #include "base/path_service.h" #include "base/stl_util.h" #include "build/build_config.h" +#include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/embedder_support/switches.h" #include "components/security_interstitials/content/ssl_cert_reporter.h" #include "components/security_interstitials/content/ssl_error_navigation_throttle.h" @@ -33,7 +34,6 @@ #include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/service_manager/public/cpp/binder_map.h" -#include "storage/browser/quota/quota_settings.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" #include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom.h" @@ -359,6 +359,21 @@ true, 0, ProfileImpl::GetCachePath(context)); } +bool ContentBrowserClientImpl::BindAssociatedReceiverFromFrame( + content::RenderFrameHost* render_frame_host, + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) { + if (interface_name == autofill::mojom::AutofillDriver::Name_) { + autofill::ContentAutofillDriverFactory::BindAutofillDriver( + mojo::PendingAssociatedReceiver<autofill::mojom::AutofillDriver>( + std::move(*handle)), + render_frame_host); + return true; + } + + return false; +} + void ContentBrowserClientImpl::ExposeInterfacesToRenderer( service_manager::BinderRegistry* registry, blink::AssociatedInterfaceRegistry* associated_registry, @@ -390,15 +405,6 @@ #endif } -void ContentBrowserClientImpl::GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - base::OnceCallback<void(base::Optional<storage::QuotaSettings>)> callback) { - storage::GetNominalDynamicSettings( - partition->GetPath(), context->IsOffTheRecord(), - storage::GetDefaultDeviceInfoHelper(), std::move(callback)); -} - #if defined(OS_ANDROID) SafeBrowsingService* ContentBrowserClientImpl::GetSafeBrowsingService() { if (!safe_browsing_service_) {
diff --git a/weblayer/browser/content_browser_client_impl.h b/weblayer/browser/content_browser_client_impl.h index c869f91..d10624a8 100644 --- a/weblayer/browser/content_browser_client_impl.h +++ b/weblayer/browser/content_browser_client_impl.h
@@ -70,6 +70,10 @@ CreateThrottlesForNavigation(content::NavigationHandle* handle) override; content::GeneratedCodeCacheSettings GetGeneratedCodeCacheSettings( content::BrowserContext* context) override; + bool BindAssociatedReceiverFromFrame( + content::RenderFrameHost* render_frame_host, + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) override; void ExposeInterfacesToRenderer( service_manager::BinderRegistry* registry, blink::AssociatedInterfaceRegistry* associated_registry, @@ -78,11 +82,6 @@ content::RenderFrameHost* render_frame_host, service_manager::BinderMapWithContext<content::RenderFrameHost*>* map) override; - void GetQuotaSettings( - content::BrowserContext* context, - content::StoragePartition* partition, - base::OnceCallback<void(base::Optional<storage::QuotaSettings>)> callback) - override; #if defined(OS_LINUX) || defined(OS_ANDROID) void GetAdditionalMappedFilesForChildProcess(
diff --git a/weblayer/browser/ssl_browsertest.cc b/weblayer/browser/ssl_browsertest.cc index 513a10c9..6b006c5 100644 --- a/weblayer/browser/ssl_browsertest.cc +++ b/weblayer/browser/ssl_browsertest.cc
@@ -7,7 +7,9 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/optional.h" +#include "build/build_config.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "weblayer/browser/ssl_error_handler.h" #include "weblayer/shell/browser/shell.h" #include "weblayer/test/interstitial_utils.h" #include "weblayer/test/load_completion_observer.h" @@ -53,7 +55,7 @@ EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); } - void NavigateToPageWithSslErrorExpectBlocked() { + void NavigateToPageWithSslErrorExpectSSLInterstitial() { // Do a navigation that should result in an SSL error. NavigateAndWaitForFailure(bad_ssl_url(), shell()); // First check that there *is* an interstitial. @@ -67,6 +69,21 @@ // ssl_browsertest.cc's CheckAuthenticationBrokenState() function. } + void NavigateToPageWithSslErrorExpectCaptivePortalInterstitial() { + // Do a navigation that should result in an SSL error. + NavigateAndWaitForFailure(bad_ssl_url(), shell()); + // First check that there *is* an interstitial. + ASSERT_TRUE(IsShowingSecurityInterstitial(shell()->tab())); + + // Now verify that the interstitial is in fact a captive portal + // interstitial. + EXPECT_TRUE(IsShowingCaptivePortalInterstitial(shell()->tab())); + + // TODO(blundell): Check the security state once security state is available + // via the public WebLayer API, following the example of //chrome's + // ssl_browsertest.cc's CheckAuthenticationBrokenState() function. + } + void NavigateToPageWithSslErrorExpectNotBlocked() { NavigateAndWaitForCompletion(bad_ssl_url(), shell()); EXPECT_FALSE(IsShowingSecurityInterstitial(shell()->tab())); @@ -107,6 +124,21 @@ EXPECT_TRUE(IsShowingSSLInterstitial(shell()->tab())); } +#if defined(OS_ANDROID) + void SendInterstitialOpenLoginCommandAndWait() { + ASSERT_TRUE(IsShowingCaptivePortalInterstitial(shell()->tab())); + + // Note: The embedded test server cannot actually load the captive portal + // login URL, so simply detect the start of the navigation to the page. + TestNavigationObserver navigation_observer( + GetCaptivePortalLoginPageUrlForTesting(), + TestNavigationObserver::NavigationEvent::Start, shell()); + ExecuteScript(shell(), "window.certificateErrorPageController.openLogin();", + false /*use_separate_isolate*/); + navigation_observer.Wait(); + } +#endif + void NavigateToOtherOkPage() { NavigateAndWaitForCompletion(https_server_->GetURL("/simple_page2.html"), shell()); @@ -129,7 +161,7 @@ // Tests clicking "take me back" on the interstitial page. IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBack) { NavigateToOkPage(); - NavigateToPageWithSslErrorExpectBlocked(); + NavigateToPageWithSslErrorExpectSSLInterstitial(); // Click "Take me back". SendInterstitialNavigationCommandAndWait(false /*proceed*/); @@ -139,13 +171,13 @@ // Navigate to the bad SSL page again, an interstitial shows again (in // contrast to what would happen had the user chosen to proceed). - NavigateToPageWithSslErrorExpectBlocked(); + NavigateToPageWithSslErrorExpectSSLInterstitial(); } // Tests clicking "take me back" on the interstitial page when there's no // navigation history. The user should be taken to a safe page (about:blank). IN_PROC_BROWSER_TEST_F(SSLBrowserTest, TakeMeBackEmptyNavigationHistory) { - NavigateToPageWithSslErrorExpectBlocked(); + NavigateToPageWithSslErrorExpectSSLInterstitial(); // Click "Take me back". SendInterstitialNavigationCommandAndWait(false /*proceed*/, @@ -154,7 +186,7 @@ IN_PROC_BROWSER_TEST_F(SSLBrowserTest, Reload) { NavigateToOkPage(); - NavigateToPageWithSslErrorExpectBlocked(); + NavigateToPageWithSslErrorExpectSSLInterstitial(); SendInterstitialReloadCommandAndWait(); @@ -174,7 +206,7 @@ // across restarts. IN_PROC_BROWSER_TEST_F(SSLBrowserTest, PRE_Proceed) { NavigateToOkPage(); - NavigateToPageWithSslErrorExpectBlocked(); + NavigateToPageWithSslErrorExpectSSLInterstitial(); SendInterstitialNavigationCommandAndWait(true /*proceed*/); // Go back to an OK page, then try to navigate again. The "Proceed" decision @@ -187,14 +219,40 @@ // WebLayer will block again when navigating to the same bad page that was // previously proceeded through. IN_PROC_BROWSER_TEST_F(SSLBrowserTest, Proceed) { - NavigateToPageWithSslErrorExpectBlocked(); + NavigateToPageWithSslErrorExpectSSLInterstitial(); } // Tests navigating away from the interstitial page. IN_PROC_BROWSER_TEST_F(SSLBrowserTest, NavigateAway) { NavigateToOkPage(); - NavigateToPageWithSslErrorExpectBlocked(); + NavigateToPageWithSslErrorExpectSSLInterstitial(); NavigateToOtherOkPage(); } +// Tests the scenario where the OS reports that an SSL error is due to a +// captive portal. A captive portal interstitial should be displayed. The test +// then switches OS captive portal status to false and reloads the page. This +// time, a normal SSL interstitial should be displayed. +IN_PROC_BROWSER_TEST_F(SSLBrowserTest, OSReportsCaptivePortal) { + SetDiagnoseSSLErrorsAsCaptivePortalForTesting(true); + + NavigateToPageWithSslErrorExpectCaptivePortalInterstitial(); + + // Check that clearing the test setting causes behavior to revert to normal. + SetDiagnoseSSLErrorsAsCaptivePortalForTesting(false); + NavigateToPageWithSslErrorExpectSSLInterstitial(); +} + +#if defined(OS_ANDROID) +// Tests that after reaching a captive portal interstitial, clicking on the +// connect link will cause a navigation to the login page. +IN_PROC_BROWSER_TEST_F(SSLBrowserTest, CaptivePortalConnectToLoginPage) { + SetDiagnoseSSLErrorsAsCaptivePortalForTesting(true); + + NavigateToPageWithSslErrorExpectCaptivePortalInterstitial(); + + SendInterstitialOpenLoginCommandAndWait(); +} +#endif + } // namespace weblayer
diff --git a/weblayer/browser/ssl_error_handler.cc b/weblayer/browser/ssl_error_handler.cc index d053f78..2ea089a 100644 --- a/weblayer/browser/ssl_error_handler.cc +++ b/weblayer/browser/ssl_error_handler.cc
@@ -5,6 +5,8 @@ #include "weblayer/browser/ssl_error_handler.h" #include "base/threading/thread_task_runner_handle.h" +#include "build/build_config.h" +#include "components/security_interstitials/content/captive_portal_blocking_page.h" #include "components/security_interstitials/content/ssl_blocking_page.h" #include "components/security_interstitials/content/ssl_cert_reporter.h" #include "components/security_interstitials/content/ssl_error_navigation_throttle.h" @@ -14,10 +16,99 @@ #include "weblayer/browser/ssl_error_controller_client.h" #include "weblayer/browser/weblayer_content_browser_overlay_manifest.h" +#if defined(OS_ANDROID) +#include "content/public/browser/page_navigator.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/referrer.h" +#include "net/android/network_library.h" +#include "ui/base/window_open_disposition.h" +#endif + namespace weblayer { namespace { +bool g_is_behind_captive_portal_for_testing = false; + +// Returns whether the user is behind a captive portal. +bool IsBehindCaptivePortal() { + if (g_is_behind_captive_portal_for_testing) + return true; + +#if defined(OS_ANDROID) + return net::android::GetIsCaptivePortal(); +#else + // WebLayer does not currently integrate CaptivePortalService, which Chrome + // uses on non-Android platforms to detect the user being behind a captive + // portal. + return false; +#endif +} + +#if defined(OS_ANDROID) +GURL GetCaptivePortalLoginPageUrlInternal() { + // NOTE: This is taken from the default login URL in //chrome's + // CaptivePortalHelper.java, which is used in the implementation referenced + // in OpenLoginPage() below. + return GURL("http://connectivitycheck.gstatic.com/generate_204"); +} +#endif + +void OpenLoginPage(content::WebContents* web_contents) { + // TODO(https://crbug.com/1030692): Componentize and share the + // Android implementation from //chrome's + // ChromeSecurityBlockingPageFactory::OpenLoginPage(), from which this is + // adapted. +#if defined(OS_ANDROID) + // NOTE: In Chrome this opens in a new tab; however, as WebLayer doesn't have + // the ability to open new tabs it must open in the current tab. + content::OpenURLParams params( + GetCaptivePortalLoginPageUrlInternal(), content::Referrer(), + WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_LINK, false); + web_contents->OpenURL(params); +#else + NOTIMPLEMENTED(); +#endif +} + +// Constructs and shows a captive portal interstitial. Adapted from //chrome's +// SSLErrorHandlerDelegateImpl::ShowCaptivePortalInterstitial(). +void ShowCaptivePortalInterstitial( + content::WebContents* web_contents, + int cert_error, + const net::SSLInfo& ssl_info, + const GURL& request_url, + std::unique_ptr<SSLCertReporter> ssl_cert_reporter, + base::OnceCallback< + void(std::unique_ptr<security_interstitials::SecurityInterstitialPage>)> + blocking_page_ready_callback) { + security_interstitials::MetricsHelper::ReportDetails report_details; + report_details.metric_prefix = "captive_portal"; + auto metrics_helper = std::make_unique<security_interstitials::MetricsHelper>( + request_url, report_details, /*history_service=*/nullptr); + + auto controller_client = std::make_unique<SSLErrorControllerClient>( + web_contents, cert_error, ssl_info, request_url, + std::move(metrics_helper)); + + // When captive portals are detected by the underlying platform (the only + // context in which captive portals are currently detected in WebLayer), + // the login URL is not specified by the client but is determined internally. + GURL login_url; + + auto* interstitial_page = new CaptivePortalBlockingPage( + web_contents, request_url, login_url, std::move(ssl_cert_reporter), + ssl_info, std::move(controller_client), + base::BindRepeating(&OpenLoginPage)); + + // Note: |blocking_page_ready_callback| must be posted due to + // HandleSSLError()'s guarantee that it will not invoke this callback + // synchronously. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(blocking_page_ready_callback), + base::WrapUnique(interstitial_page))); +} + // Constructs and shows an SSL interstitial. Adapted from //chrome's // SSLErrorHandlerDelegateImpl::ShowSSLInterstitial(). void ShowSSLInterstitial( @@ -66,6 +157,25 @@ base::OnceCallback< void(std::unique_ptr<security_interstitials::SecurityInterstitialPage>)> blocking_page_ready_callback) { + // First check for captive portal. + + // TODO(https://crbug.com/1030692): Share the check for known captive + // portal certificates from //chrome's SSLErrorHandler:757. + if (IsBehindCaptivePortal()) { + // TODO(https://crbug.com/1030692): Share the reporting of network + // connectivity and tracking UMA from //chrome's SSLErrorHandler:743. + ShowCaptivePortalInterstitial(web_contents, cert_error, ssl_info, + request_url, std::move(ssl_cert_reporter), + std::move(blocking_page_ready_callback)); + return; + } + + // Handle all remaining errors by showing SSL interstitials. If this needs to + // get more refined in the short-term, can adapt logic from + // SSLErrorHandler::StartHandlingError() as needed (in the long-term, + // WebLayer will most likely share a componentized version of //chrome's + // SSLErrorHandler). + // NOTE: In Chrome hard overrides can be disabled for the Profile by setting // the kSSLErrorOverrideAllowed preference (which defaults to true) to false. // However, in WebLayer there is currently no way for the user to set this @@ -74,14 +184,19 @@ int options_mask = security_interstitials::CalculateSSLErrorOptionsMask( cert_error, hard_override_disabled, ssl_info.is_fatal_cert_error); - // Handle all errors by showing SSL interstitials. If this needs to get more - // refined in the short-term, can adapt logic from - // SSLErrorHandler::StartHandlingError() as needed (in the long-term, WebLayer - // will most likely share a componentized version of //chrome's - // SSLErrorHandler). ShowSSLInterstitial(web_contents, cert_error, ssl_info, request_url, std::move(ssl_cert_reporter), std::move(blocking_page_ready_callback), options_mask); } +void SetDiagnoseSSLErrorsAsCaptivePortalForTesting(bool enabled) { + g_is_behind_captive_portal_for_testing = enabled; +} + +#if defined(OS_ANDROID) +GURL GetCaptivePortalLoginPageUrlForTesting() { + return GetCaptivePortalLoginPageUrlInternal(); +} +#endif + } // namespace weblayer
diff --git a/weblayer/browser/ssl_error_handler.h b/weblayer/browser/ssl_error_handler.h index bf3124e0..0eae1de 100644 --- a/weblayer/browser/ssl_error_handler.h +++ b/weblayer/browser/ssl_error_handler.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/time/time.h" +#include "build/build_config.h" #include "components/security_interstitials/content/security_interstitial_page.h" #include "content/public/browser/certificate_request_result_type.h" #include "net/ssl/ssl_info.h" @@ -42,6 +43,17 @@ std::unique_ptr<SSLCertReporter> ssl_cert_reporter, BlockingPageReadyCallback blocking_page_ready_callback); +// Pass true to simulate the OS reporting that SSL errors are due to captive +// portals. +void SetDiagnoseSSLErrorsAsCaptivePortalForTesting(bool enabled); + +#if defined(OS_ANDROID) +// Returns the URL that will be navigated to when the user clicks on the +// "Connect" button of the captive portal interstitial. Used by tests to +// verify this flow. +GURL GetCaptivePortalLoginPageUrlForTesting(); +#endif + } // namespace weblayer #endif // WEBLAYER_BROWSER_SSL_ERROR_HANDLER_H_
diff --git a/weblayer/browser/tab_impl.cc b/weblayer/browser/tab_impl.cc index e0db45a..cdad274 100644 --- a/weblayer/browser/tab_impl.cc +++ b/weblayer/browser/tab_impl.cc
@@ -7,6 +7,9 @@ #include "base/auto_reset.h" #include "base/feature_list.h" #include "base/logging.h" +#include "components/autofill/content/browser/content_autofill_driver_factory.h" +#include "components/autofill/core/browser/autofill_manager.h" +#include "components/autofill/core/browser/autofill_provider.h" #include "content/public/browser/file_select_listener.h" #include "content/public/browser/interstitial_page.h" #include "content/public/browser/navigation_controller.h" @@ -16,7 +19,9 @@ #include "content/public/browser/web_contents.h" #include "third_party/blink/public/mojom/renderer_preferences.mojom.h" #include "ui/base/window_open_disposition.h" +#include "weblayer/browser/autofill_client_impl.h" #include "weblayer/browser/file_select_helper.h" +#include "weblayer/browser/i18n_util.h" #include "weblayer/browser/isolated_world_ids.h" #include "weblayer/browser/navigation_controller_impl.h" #include "weblayer/browser/profile_impl.h" @@ -213,6 +218,12 @@ } } +void TabImpl::ExecuteScriptWithUserGestureForTests( + const base::string16& script) { + web_contents_->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( + script); +} + #if !defined(OS_ANDROID) void TabImpl::AttachToView(views::WebView* web_view) { web_view->SetWebContents(web_contents_.get()); @@ -457,4 +468,25 @@ } #endif +void TabImpl::InitializeAutofillForTests( + std::unique_ptr<autofill::AutofillProvider> provider) { + autofill_provider_ = std::move(provider); + InitializeAutofill(); +} + +void TabImpl::InitializeAutofill() { + DCHECK(autofill_provider_); + + content::WebContents* web_contents = web_contents_.get(); + DCHECK( + !autofill::ContentAutofillDriverFactory::FromWebContents(web_contents)); + + AutofillClientImpl::CreateForWebContents(web_contents); + autofill::ContentAutofillDriverFactory::CreateForWebContentsAndDelegate( + web_contents, AutofillClientImpl::FromWebContents(web_contents), + i18n::GetApplicationLocale(), + autofill::AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER, + autofill_provider_.get()); +} + } // namespace weblayer
diff --git a/weblayer/browser/tab_impl.h b/weblayer/browser/tab_impl.h index 5b6b8a7..a10af73 100644 --- a/weblayer/browser/tab_impl.h +++ b/weblayer/browser/tab_impl.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" @@ -22,6 +23,10 @@ #include "base/android/scoped_java_ref.h" #endif +namespace autofill { +class AutofillProvider; +} // namespace autofill + namespace content { class WebContents; } @@ -92,6 +97,13 @@ void AttachToView(views::WebView* web_view) override; #endif + // Executes |script| with a user gesture. + void ExecuteScriptWithUserGestureForTests(const base::string16& script); + + // Initializes the autofill system with |provider| for tests. + void InitializeAutofillForTests( + std::unique_ptr<autofill::AutofillProvider> provider); + private: // content::WebContentsDelegate: content::WebContents* OpenURLFromTab( @@ -138,6 +150,8 @@ void UpdateRendererPrefs(bool should_sync_prefs); + void InitializeAutofill(); + #if defined(OS_ANDROID) void UpdateBrowserControlsState(content::BrowserControlsState constraints, content::BrowserControlsState current, @@ -163,6 +177,8 @@ // Set to true doing EnterFullscreenModeForTab(). bool processing_enter_fullscreen_ = false; + std::unique_ptr<autofill::AutofillProvider> autofill_provider_; + base::WeakPtrFactory<TabImpl> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(TabImpl);
diff --git a/weblayer/grit_strings_whitelist.txt b/weblayer/grit_strings_whitelist.txt index 907d69c..e6ad7d739 100644 --- a/weblayer/grit_strings_whitelist.txt +++ b/weblayer/grit_strings_whitelist.txt
@@ -1,3 +1,12 @@ +IDS_CAPTIVE_PORTAL_BUTTON_OPEN_LOGIN_PAGE +IDS_CAPTIVE_PORTAL_HEADING_WIFI +IDS_CAPTIVE_PORTAL_HEADING_WIRED +IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIFI +IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIRED +IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_NO_LOGIN_URL_WIFI_SSID +IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI +IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIRED +IDS_CAPTIVE_PORTAL_PRIMARY_PARAGRAPH_WIFI_SSID IDS_SSL_OPEN_DETAILS_BUTTON IDS_SSL_CLOSE_DETAILS_BUTTON IDS_SSL_NONOVERRIDABLE_HSTS
diff --git a/weblayer/renderer/DEPS b/weblayer/renderer/DEPS index e83c2333..b792c33 100644 --- a/weblayer/renderer/DEPS +++ b/weblayer/renderer/DEPS
@@ -4,6 +4,7 @@ # long-term, componentize these strings/resources as part of componentizing # that implementation and remove the need for this dependency. "+android_webview/grit", + "+components/autofill/content/renderer", "+components/safe_browsing/common", "+components/safe_browsing/renderer", "+components/security_interstitials/content/renderer",
diff --git a/weblayer/renderer/content_renderer_client_impl.cc b/weblayer/renderer/content_renderer_client_impl.cc index 35c2649..d56a7cf 100644 --- a/weblayer/renderer/content_renderer_client_impl.cc +++ b/weblayer/renderer/content_renderer_client_impl.cc
@@ -8,6 +8,8 @@ #include "base/i18n/rtl.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "components/autofill/content/renderer/autofill_agent.h" +#include "components/autofill/content/renderer/password_autofill_agent.h" #include "content/public/renderer/render_thread.h" #include "net/base/escape.h" #include "third_party/blink/public/platform/platform.h" @@ -15,6 +17,7 @@ #include "ui/base/resource/resource_bundle.h" #include "weblayer/common/features.h" #include "weblayer/renderer/ssl_error_helper.h" +#include "weblayer/renderer/weblayer_render_frame_observer.h" #if defined(OS_ANDROID) #include "android_webview/grit/aw_resources.h" @@ -125,8 +128,16 @@ void ContentRendererClientImpl::RenderFrameCreated( content::RenderFrame* render_frame) { + auto* render_frame_observer = new WebLayerRenderFrameObserver(render_frame); + SSLErrorHelper::Create(render_frame); + autofill::PasswordAutofillAgent* password_autofill_agent = + new autofill::PasswordAutofillAgent( + render_frame, render_frame_observer->associated_interfaces()); + new autofill::AutofillAgent(render_frame, password_autofill_agent, nullptr, + render_frame_observer->associated_interfaces()); + #if defined(OS_ANDROID) // |SpellCheckProvider| manages its own lifetime (and destroys itself when the // RenderFrame is destroyed).
diff --git a/weblayer/renderer/ssl_error_helper.cc b/weblayer/renderer/ssl_error_helper.cc index edadda2..e1c40cb 100644 --- a/weblayer/renderer/ssl_error_helper.cc +++ b/weblayer/renderer/ssl_error_helper.cc
@@ -66,9 +66,11 @@ case security_interstitials::CMD_RELOAD: interface->Reload(); break; + case security_interstitials::CMD_OPEN_LOGIN: + interface->OpenLogin(); + break; case security_interstitials::CMD_OPEN_DIAGNOSTIC: case security_interstitials::CMD_OPEN_DATE_SETTINGS: - case security_interstitials::CMD_OPEN_LOGIN: case security_interstitials::CMD_DO_REPORT: case security_interstitials::CMD_DONT_REPORT: case security_interstitials::CMD_OPEN_REPORTING_PRIVACY:
diff --git a/weblayer/renderer/weblayer_render_frame_observer.cc b/weblayer/renderer/weblayer_render_frame_observer.cc new file mode 100644 index 0000000..038d69a3 --- /dev/null +++ b/weblayer/renderer/weblayer_render_frame_observer.cc
@@ -0,0 +1,27 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "weblayer/renderer/weblayer_render_frame_observer.h" + +#include "content/public/renderer/render_frame.h" + +namespace weblayer { + +WebLayerRenderFrameObserver::WebLayerRenderFrameObserver( + content::RenderFrame* render_frame) + : content::RenderFrameObserver(render_frame) {} + +WebLayerRenderFrameObserver::~WebLayerRenderFrameObserver() = default; + +bool WebLayerRenderFrameObserver::OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) { + return associated_interfaces_.TryBindInterface(interface_name, handle); +} + +void WebLayerRenderFrameObserver::OnDestruct() { + delete this; +} + +} // namespace weblayer
diff --git a/weblayer/renderer/weblayer_render_frame_observer.h b/weblayer/renderer/weblayer_render_frame_observer.h new file mode 100644 index 0000000..d45b57f --- /dev/null +++ b/weblayer/renderer/weblayer_render_frame_observer.h
@@ -0,0 +1,40 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBLAYER_RENDERER_WEBLAYER_RENDER_FRAME_OBSERVER_H_ +#define WEBLAYER_RENDERER_WEBLAYER_RENDER_FRAME_OBSERVER_H_ + +#include "base/macros.h" +#include "content/public/renderer/render_frame_observer.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" + +namespace weblayer { + +// This class holds the WebLayer-specific parts of RenderFrame, and has the +// same lifetime. It is analogous to //chrome's ChromeRenderFrameObserver. +class WebLayerRenderFrameObserver : public content::RenderFrameObserver { + public: + explicit WebLayerRenderFrameObserver(content::RenderFrame* render_frame); + + blink::AssociatedInterfaceRegistry* associated_interfaces() { + return &associated_interfaces_; + } + + private: + ~WebLayerRenderFrameObserver() override; + + // RenderFrameObserver: + bool OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) override; + void OnDestruct() override; + + blink::AssociatedInterfaceRegistry associated_interfaces_; + + DISALLOW_COPY_AND_ASSIGN(WebLayerRenderFrameObserver); +}; + +} // namespace weblayer + +#endif // WEBLAYER_RENDERER_WEBLAYER_RENDER_FRAME_OBSERVER_H_
diff --git a/weblayer/test/BUILD.gn b/weblayer/test/BUILD.gn index 5b3cfb2..41ffbe9 100644 --- a/weblayer/test/BUILD.gn +++ b/weblayer/test/BUILD.gn
@@ -78,6 +78,9 @@ "//base", "//base", "//base/test:test_support", + "//components/autofill/core/browser", + "//components/autofill/core/browser:test_support", + "//components/autofill/core/common", "//components/security_interstitials/content:security_interstitial_page", "//content/public/browser", "//content/test:test_support", @@ -88,6 +91,7 @@ ] sources = [ + "../browser/autofill_browsertest.cc", "../browser/errorpage_browsertest.cc", "../browser/navigation_browsertest.cc", "../browser/ssl_browsertest.cc", @@ -97,6 +101,8 @@ "interstitial_utils.h", "load_completion_observer.cc", "load_completion_observer.h", + "stub_autofill_provider.cc", + "stub_autofill_provider.h", "test_launcher_delegate_impl.cc", "test_launcher_delegate_impl.h", "test_navigation_observer.cc",
diff --git a/weblayer/test/DEPS b/weblayer/test/DEPS index a861b20..9dfe23d 100644 --- a/weblayer/test/DEPS +++ b/weblayer/test/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/autofill/core/browser", "+components/security_interstitials", "+content/public/common", "+content/public/test",
diff --git a/weblayer/test/data/simple_password_form.html b/weblayer/test/data/simple_password_form.html new file mode 100644 index 0000000..7608c78 --- /dev/null +++ b/weblayer/test/data/simple_password_form.html
@@ -0,0 +1,9 @@ +<html> +<body> +<form method="POST" action="done.html" onsubmit="return true;" id="testform"> + <input type="text" id="username_field" name="username_field"> + <input type="password" id="password_field" name="password_field"> + <input type="submit" id="input_submit_button" name="input_submit_button"> +</form> +</body> +</html>
diff --git a/weblayer/test/interstitial_utils.cc b/weblayer/test/interstitial_utils.cc index 2bbfbf6..4266a77 100644 --- a/weblayer/test/interstitial_utils.cc +++ b/weblayer/test/interstitial_utils.cc
@@ -4,6 +4,7 @@ #include "weblayer/test/interstitial_utils.h" +#include "components/security_interstitials/content/captive_portal_blocking_page.h" #include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/content/ssl_blocking_page.h" #include "weblayer/browser/tab_impl.h" @@ -28,6 +29,19 @@ : nullptr; } +// Returns true if a security interstitial of type |type| is currently showing +// in |tab|. +bool IsShowingInterstitialOfType( + Tab* tab, + content::InterstitialPageDelegate::TypeID type) { + auto* blocking_page = GetCurrentlyShowingInterstitial(tab); + + if (!blocking_page) + return false; + + return blocking_page->GetTypeForTesting() == type; +} + } // namespace bool IsShowingSecurityInterstitial(Tab* tab) { @@ -35,12 +49,12 @@ } bool IsShowingSSLInterstitial(Tab* tab) { - auto* blocking_page = GetCurrentlyShowingInterstitial(tab); + return IsShowingInterstitialOfType(tab, SSLBlockingPage::kTypeForTesting); +} - if (!blocking_page) - return false; - - return blocking_page->GetTypeForTesting() == SSLBlockingPage::kTypeForTesting; +bool IsShowingCaptivePortalInterstitial(Tab* tab) { + return IsShowingInterstitialOfType( + tab, CaptivePortalBlockingPage::kTypeForTesting); } } // namespace weblayer
diff --git a/weblayer/test/interstitial_utils.h b/weblayer/test/interstitial_utils.h index 7bf546e..e8b7834 100644 --- a/weblayer/test/interstitial_utils.h +++ b/weblayer/test/interstitial_utils.h
@@ -20,6 +20,10 @@ // |tab|. bool IsShowingSSLInterstitial(Tab* tab); +// Returns true iff a captive portal interstitial is currently displaying in +// |tab|. +bool IsShowingCaptivePortalInterstitial(Tab* tab); + } // namespace weblayer #endif // WEBLAYER_TEST_INTERSTITIAL_UTILS_H_
diff --git a/weblayer/test/stub_autofill_provider.cc b/weblayer/test/stub_autofill_provider.cc new file mode 100644 index 0000000..c1c1b94a --- /dev/null +++ b/weblayer/test/stub_autofill_provider.cc
@@ -0,0 +1,26 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "weblayer/test/stub_autofill_provider.h" + +namespace weblayer { + +StubAutofillProvider::StubAutofillProvider( + const base::RepeatingCallback<void(const autofill::FormData&)>& + on_received_form_data) + : on_received_form_data_(on_received_form_data) {} + +StubAutofillProvider::~StubAutofillProvider() = default; + +void StubAutofillProvider::OnQueryFormFieldAutofill( + autofill::AutofillHandlerProxy* handler, + int32_t id, + const autofill::FormData& form, + const autofill::FormFieldData& field, + const gfx::RectF& bounding_box, + bool /*unused_autoselect_first_suggestion*/) { + on_received_form_data_.Run(form); +} + +} // namespace weblayer
diff --git a/weblayer/test/stub_autofill_provider.h b/weblayer/test/stub_autofill_provider.h new file mode 100644 index 0000000..8f648e4 --- /dev/null +++ b/weblayer/test/stub_autofill_provider.h
@@ -0,0 +1,41 @@ +// 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 WEBLAYER_TEST_STUB_AUTOFILL_PROVIDER_H_ +#define WEBLAYER_TEST_STUB_AUTOFILL_PROVIDER_H_ + +#include "base/callback_forward.h" +#include "components/autofill/core/browser/test_autofill_provider.h" + +namespace weblayer { + +// A stub AutofillProvider implementation that is used in cross-platform +// integration tests of renderer-side autofill detection and communication to +// the browser. +class StubAutofillProvider : public autofill::TestAutofillProvider { + public: + explicit StubAutofillProvider( + const base::RepeatingCallback<void(const autofill::FormData&)>& + on_received_form_data); + ~StubAutofillProvider() override; + + // AutofillProvider: + void OnQueryFormFieldAutofill( + autofill::AutofillHandlerProxy* handler, + int32_t id, + const autofill::FormData& form, + const autofill::FormFieldData& field, + const gfx::RectF& bounding_box, + bool /*unused_autoselect_first_suggestion*/) override; + + private: + DISALLOW_COPY_AND_ASSIGN(StubAutofillProvider); + + base::RepeatingCallback<void(const autofill::FormData&)> + on_received_form_data_; +}; + +} // namespace weblayer + +#endif // WEBLAYER_TEST_STUB_AUTOFILL_PROVIDER_H_
diff --git a/weblayer/test/test_navigation_observer.cc b/weblayer/test/test_navigation_observer.cc index 00de95c5..4b7b351 100644 --- a/weblayer/test/test_navigation_observer.cc +++ b/weblayer/test/test_navigation_observer.cc
@@ -24,6 +24,15 @@ tab_->GetNavigationController()->RemoveObserver(this); } +void TestNavigationObserver::NavigationStarted(Navigation* navigation) { + // Note: We don't go through CheckNavigationCompleted() here as that waits + // for the load to be complete, which isn't appropriate when just waiting for + // the navigation to be started. + if (navigation->GetURL() == url_ && target_event_ == NavigationEvent::Start) { + run_loop_.Quit(); + } +} + void TestNavigationObserver::NavigationCompleted(Navigation* navigation) { if (navigation->GetURL() == url_) observed_event_ = NavigationEvent::Completion;
diff --git a/weblayer/test/test_navigation_observer.h b/weblayer/test/test_navigation_observer.h index fbfddee8..535fa536 100644 --- a/weblayer/test/test_navigation_observer.h +++ b/weblayer/test/test_navigation_observer.h
@@ -19,10 +19,10 @@ // A helper that waits for a navigation to finish. class TestNavigationObserver : public NavigationObserver { public: - enum class NavigationEvent { Completion, Failure }; + enum class NavigationEvent { Start, Completion, Failure }; // Creates an instance that begins waiting for a Navigation within |shell| and - // to |url| to either complete or fail as per |target_event|. + // to |url| to reach the specified |target_event|. TestNavigationObserver(const GURL& url, NavigationEvent target_event, Shell* shell); @@ -33,6 +33,7 @@ private: // NavigationObserver implementation: + void NavigationStarted(Navigation* navigation) override; void NavigationCompleted(Navigation* navigation) override; void NavigationFailed(Navigation* navigation) override; void LoadStateChanged(bool is_loading, bool to_different_document) override;
diff --git a/weblayer/test/weblayer_browser_test_utils.cc b/weblayer/test/weblayer_browser_test_utils.cc index 1ba8d9a..b81f4cf 100644 --- a/weblayer/test/weblayer_browser_test_utils.cc +++ b/weblayer/test/weblayer_browser_test_utils.cc
@@ -11,6 +11,7 @@ #include "weblayer/public/navigation_controller.h" #include "weblayer/public/tab.h" #include "weblayer/shell/browser/shell.h" +#include "weblayer/test/stub_autofill_provider.h" #include "weblayer/test/test_navigation_observer.h" namespace weblayer { @@ -54,10 +55,25 @@ return final_result; } +void ExecuteScriptWithUserGesture(Shell* shell, const std::string& script) { + TabImpl* tab_impl = static_cast<TabImpl*>(shell->tab()); + tab_impl->ExecuteScriptWithUserGestureForTests(base::ASCIIToUTF16(script)); +} + const base::string16& GetTitle(Shell* shell) { TabImpl* tab_impl = static_cast<TabImpl*>(shell->tab()); return tab_impl->web_contents()->GetTitle(); } +void InitializeAutofillWithEventForwarding( + Shell* shell, + const base::RepeatingCallback<void(const autofill::FormData&)>& + on_received_form_data) { + TabImpl* tab_impl = static_cast<TabImpl*>(shell->tab()); + + tab_impl->InitializeAutofillForTests( + std::make_unique<StubAutofillProvider>(on_received_form_data)); +} + } // namespace weblayer
diff --git a/weblayer/test/weblayer_browser_test_utils.h b/weblayer/test/weblayer_browser_test_utils.h index 99c0ad6..916fc99 100644 --- a/weblayer/test/weblayer_browser_test_utils.h +++ b/weblayer/test/weblayer_browser_test_utils.h
@@ -5,11 +5,17 @@ #ifndef WEBLAYER_TEST_WEBLAYER_BROWSER_TEST_UTILS_H_ #define WEBLAYER_TEST_WEBLAYER_BROWSER_TEST_UTILS_H_ +#include "base/callback_forward.h" +#include "base/optional.h" #include "base/strings/string16.h" #include "base/values.h" class GURL; +namespace autofill { +struct FormData; +} + namespace weblayer { class Shell; @@ -24,9 +30,27 @@ const std::string& script, bool use_separate_isolate); -// Gets the title of the current webpage in |shell|. +// Executes |script| in |shell| with a user gesture. Useful for tests of +// functionality that gates action on a user gesture having occurred. +// Differs from ExecuteScript() as follows: +// - Does not notify the caller of the result as the underlying implementation +// does not. Thus, unlike the above, the caller of this function will need to +// explicitly listen *after* making this call for any expected event to +// occur. +// - Does not allow running in a separate isolate as the machinery for +// setting a user gesture works only in the main isolate. +void ExecuteScriptWithUserGesture(Shell* shell, const std::string& script); + +/// Gets the title of the current webpage in |shell|. const base::string16& GetTitle(Shell* shell); +// Sets up the autofill system to be one that simply forwards detected forms to +// the passed-in callback. +void InitializeAutofillWithEventForwarding( + Shell* shell, + const base::RepeatingCallback<void(const autofill::FormData&)>& + on_received_form_data); + } // namespace weblayer #endif // WEBLAYER_TEST_WEBLAYER_BROWSER_TEST_UTILS_H_