diff --git a/DEPS b/DEPS index 40087840..db213d3 100644 --- a/DEPS +++ b/DEPS
@@ -44,7 +44,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '4f7d985201a09efb3069343fe5c9f78c110f6160', + 'v8_revision': 'e677748719dec3f42367144bd6bd01ab701ab221', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -60,7 +60,7 @@ # 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': '30385f0f418b2c366acd7ef9bf6024b41bd4a1e1', + 'swiftshader_revision': 'dc7759ccc3151a1aefefa9f86610e66f6fe9311c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -96,7 +96,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': '24e36dadf5b1aff6cebffa55b476cd7ef64eba0a', + 'catapult_revision': '121ef2b4a8c6adbb65df758521fb4f80e78d1d2e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -196,7 +196,7 @@ Var('chromium_git') + '/external/bidichecker/lib.git' + '@' + '97f2aa645b74c28c57eca56992235c79850fa9e0', 'src/third_party/webgl/src': - Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'fd73a606f94d1837eba4d165f1f5b3afd542fc08', + Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '73fd432435e8a8563f2117737c7639331761bddd', 'src/third_party/webdriver/pylib': Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index 955d304..c17dcf1 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -30,7 +30,7 @@ #include "ash/wm/wm_event.h" #include "ash/wm_window.h" #include "base/command_line.h" -#include "base/test/user_action_tester.cc" +#include "base/test/user_action_tester.h" #include "services/ui/public/interfaces/window_manager_constants.mojom.h" #include "ui/app_list/presenter/app_list.h" #include "ui/app_list/presenter/test/test_app_list_presenter.h"
diff --git a/ash/accelerators/accelerator_interactive_uitest_chromeos.cc b/ash/accelerators/accelerator_interactive_uitest_chromeos.cc index 27a1555..0015c42f 100644 --- a/ash/accelerators/accelerator_interactive_uitest_chromeos.cc +++ b/ash/accelerators/accelerator_interactive_uitest_chromeos.cc
@@ -15,7 +15,7 @@ #include "ash/wm/window_state_aura.h" #include "ash/wm/window_util.h" #include "base/run_loop.h" -#include "base/test/user_action_tester.cc" +#include "base/test/user_action_tester.h" #include "chromeos/network/network_handler.h" #include "ui/app_list/presenter/app_list.h" #include "ui/app_list/presenter/test/test_app_list_presenter.h"
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc index 30ec63f..b24c57b 100644 --- a/ash/drag_drop/drag_drop_controller_unittest.cc +++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -17,7 +17,6 @@ #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/dragdrop/drag_drop_types.h" -#include "ui/base/dragdrop/drag_utils.h" #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/ui_base_switches.h" #include "ui/events/event.h" @@ -77,8 +76,7 @@ data->SetString(base::UTF8ToUTF16("I am being dragged")); gfx::ImageSkiaRep image_rep(gfx::Size(10, 20), 1.0f); gfx::ImageSkia image_skia(image_rep); - - drag_utils::SetDragImageOnDataObject(image_skia, gfx::Vector2d(), data); + data->provider().SetDragImage(image_skia, gfx::Vector2d()); } bool OnMousePressed(const ui::MouseEvent& event) override { return true; }
diff --git a/ash/resources/vector_icons/system_menu_accessibility_chromevox.1x.icon b/ash/resources/vector_icons/system_menu_accessibility_chromevox.1x.icon index 65307d1..97e8c052 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_chromevox.1x.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_chromevox.1x.icon
@@ -3,29 +3,40 @@ // found in the LICENSE file. CANVAS_DIMENSIONS, 20, -MOVE_TO, 7.82f, 11.11f, -R_CUBIC_TO, 1.61f, 0, 2.91f, -1.32f, 2.91f, -2.95f, -R_CUBIC_TO, 0, -1.63f, -1.3f, -2.95f, -2.91f, -2.95f, -R_CUBIC_TO, -1.61f, 0, -2.91f, 1.32f, -2.91f, 2.95f, -R_CUBIC_TO, 0, 1.63f, 1.3f, 2.95f, 2.91f, 2.95f, +MOVE_TO, 10, 18, +R_CUBIC_TO, -4.42f, 0, -8, -3.58f, -8, -8, +R_CUBIC_TO, 0, -4.42f, 3.58f, -8, 8, -8, +R_CUBIC_TO, 4.42f, 0, 8, 3.58f, 8, 8, +R_CUBIC_TO, 0, 4.42f, -3.58f, 8, -8, 8, CLOSE, -MOVE_TO, 7.75f, 12.5f, -R_CUBIC_TO, -1.92f, 0, -5.75f, 1, -5.75f, 3, -V_LINE_TO, 17, -R_H_LINE_TO, 11.5f, -R_V_LINE_TO, -1.5f, -R_CUBIC_TO, 0, -1.99f, -3.83f, -3, -5.75f, -3, +R_MOVE_TO, 1.9f, -10.76f, +R_CUBIC_TO, 0.71f, 0.79f, 1.51f, 1.66f, 1.45f, 2.78f, +R_CUBIC_TO, 0.07f, 1.13f, -0.67f, 2.05f, -1.43f, 2.81f, +R_LINE_TO, 0.66f, 0.86f, +R_CUBIC_TO, 1.26f, -0.83f, 2.04f, -2.31f, 1.94f, -3.81f, +R_CUBIC_TO, -0.02f, -1.35f, -0.8f, -2.58f, -1.84f, -3.42f, +R_CUBIC_TO, -0.26f, 0.26f, -0.51f, 0.53f, -0.76f, 0.79f, CLOSE, -R_MOVE_TO, 5.71f, -7.02f, -R_LINE_TO, -1.22f, 1.25f, -R_CUBIC_TO, 0.61f, 0.87f, 0.61f, 2, 0, 2.87f, -R_LINE_TO, 1.22f, 1.25f, -R_CUBIC_TO, 1.47f, -1.49f, 1.47f, -3.74f, 0, -5.36f, +R_MOVE_TO, 4.53f, 4.56f, +R_CUBIC_TO, 0.7f, -2.52f, -0.23f, -5.5f, -2.49f, -6.97f, +R_CUBIC_TO, -0.24f, 0.31f, -0.47f, 0.61f, -0.7f, 0.92f, +R_CUBIC_TO, 0.52f, 0.54f, 1.08f, 1.04f, 1.46f, 1.68f, +R_CUBIC_TO, 0.92f, 1.54f, 0.97f, 3.54f, 0.1f, 5.1f, +R_CUBIC_TO, -0.4f, 0.73f, -1.02f, 1.31f, -1.61f, 1.89f, +R_CUBIC_TO, 0.22f, 0.32f, 0.45f, 0.63f, 0.68f, 0.94f, +R_CUBIC_TO, 1.23f, -0.86f, 2.15f, -2.11f, 2.56f, -3.57f, CLOSE, -MOVE_TO, 15.87f, 3, -R_LINE_TO, -1.19f, 1.2f, -R_CUBIC_TO, 2.02f, 2.23f, 2.02f, 5.57f, 0, 7.92f, -R_LINE_TO, 1.19f, 1.2f, -R_CUBIC_TO, 2.84f, -2.87f, 2.84f, -7.33f, 0, -10.31f, +MOVE_TO, 8.42f, 3.67f, +R_CUBIC_TO, -2.92f, 0.7f, -5.09f, 3.28f, -5.09f, 6.36f, +R_CUBIC_TO, 0, 2.66f, 1.62f, 4.94f, 3.93f, 5.97f, +R_CUBIC_TO, 0.55f, -0.16f, 1.06f, -0.3f, 1.48f, -0.39f, +R_CUBIC_TO, 0.21f, -1.04f, 0.33f, -2.1f, 0.38f, -3.16f, +R_CUBIC_TO, -0.7f, -0.4f, -1.44f, -0.73f, -2.16f, -1.09f, +R_CUBIC_TO, 0.84f, -0.16f, 1.68f, -0.29f, 2.5f, -0.52f, +R_CUBIC_TO, 0.04f, -0.51f, 0.06f, -1.01f, 0.1f, -1.52f, +R_CUBIC_TO, 0.51f, -0.33f, 1.02f, -0.66f, 1.54f, -0.98f, +R_CUBIC_TO, -0.22f, -0.61f, -0.5f, -1.2f, -0.81f, -1.77f, +R_CUBIC_TO, -0.53f, -0.95f, -0.95f, -1.96f, -1.54f, -2.88f, +LINE_TO, 8.42f, 3.67f, CLOSE, END
diff --git a/ash/resources/vector_icons/system_menu_accessibility_chromevox.icon b/ash/resources/vector_icons/system_menu_accessibility_chromevox.icon index 38a96e8..2626248 100644 --- a/ash/resources/vector_icons/system_menu_accessibility_chromevox.icon +++ b/ash/resources/vector_icons/system_menu_accessibility_chromevox.icon
@@ -3,29 +3,40 @@ // found in the LICENSE file. CANVAS_DIMENSIONS, 40, -MOVE_TO, 15.64f, 22.21f, -R_CUBIC_TO, 3.21f, 0, 5.82f, -2.64f, 5.82f, -5.89f, -R_CUBIC_TO, 0, -3.26f, -2.61f, -5.89f, -5.82f, -5.89f, -CUBIC_TO_SHORTHAND, 9.82f, 13.06f, 9.82f, 16.32f, -R_CUBIC_TO, 0, 3.26f, 2.6f, 5.9f, 5.82f, 5.9f, +MOVE_TO, 20, 36, +R_CUBIC_TO, -8.84f, 0, -16, -7.16f, -16, -16, +CUBIC_TO, 4, 11.16, 11.16f, 4, 20, 4, +R_CUBIC_TO, 8.84f, 0, 16, 7.16f, 16, 16, +R_CUBIC_TO, 0, 8.84f, -7.16f, 16, -16, 16, CLOSE, -MOVE_TO, 15.5f, 25, -CUBIC_TO, 11.66f, 25, 4, 27.01f, 4, 31, -R_V_LINE_TO, 3, -R_H_LINE_TO, 23, -R_V_LINE_TO, -3, -R_CUBIC_TO, 0, -3.99f, -7.66f, -6, -11.5f, -6, +R_MOVE_TO, 3.81f, -21.52f, +R_CUBIC_TO, 1.41f, 1.57f, 3.01f, 3.31f, 2.9f, 5.56f, +R_CUBIC_TO, 0.14f, 2.25f, -1.34f, 4.11f, -2.86f, 5.61f, +R_CUBIC_TO, 0.43f, 0.57f, 0.87f, 1.14f, 1.31f, 1.71f, +R_CUBIC_TO, 2.52f, -1.68f, 4.08f, -4.63f, 3.88f, -7.62f, +R_CUBIC_TO, -0.04f, -2.71f, -1.6f, -5.16f, -3.69f, -6.83f, +R_CUBIC_TO, -0.51f, 0.52f, -1.02f, 1.04f, -1.52f, 1.58f, CLOSE, -R_MOVE_TO, 11.43f, -14.05f, -R_LINE_TO, -2.44f, 2.49f, -R_CUBIC_TO, 1.22f, 1.74f, 1.22f, 3.99f, 0, 5.73f, -R_LINE_TO, 2.44f, 2.49f, -R_CUBIC_TO, 2.94f, -2.98f, 2.94f, -7.47f, 0, -10.71f, +R_MOVE_TO, 9.07f, 9.12f, +R_CUBIC_TO, 1.41f, -5.05f, -0.45f, -11, -4.98f, -13.94f, +R_CUBIC_TO, -0.47f, 0.61f, -0.94f, 1.22f, -1.41f, 1.83f, +R_CUBIC_TO, 1.03f, 1.07f, 2.16f, 2.09f, 2.93f, 3.36f, +R_CUBIC_TO, 1.83f, 3.07f, 1.94f, 7.08f, 0.2f, 10.21f, +R_CUBIC_TO, -0.79f, 1.47f, -2.04f, 2.62f, -3.22f, 3.79f, +R_CUBIC_TO, 0.44f, 0.64f, 0.89f, 1.26f, 1.36f, 1.88f, +R_CUBIC_TO, 2.45f, -1.71f, 4.29f, -4.22f, 5.12f, -7.13f, CLOSE, -MOVE_TO, 31.74f, 6, -R_LINE_TO, -2.37f, 2.4f, -R_CUBIC_TO, 4.03f, 4.45f, 4.03f, 11.14f, 0, 15.83f, -R_LINE_TO, 2.37f, 2.4f, -R_CUBIC_TO, 5.67f, -5.73f, 5.69f, -14.66f, 0, -20.63f, +MOVE_TO, 16.85f, 7.33f, +R_CUBIC_TO, -5.84f, 1.4f, -10.18f, 6.56f, -10.18f, 12.72f, +R_CUBIC_TO, 0, 5.32f, 3.23f, 9.89f, 7.87f, 11.94f, +R_CUBIC_TO, 1.09f, -0.31f, 2.11f, -0.59f, 2.96f, -0.77f, +R_CUBIC_TO, 0.41f, -2.08f, 0.66f, -4.2f, 0.76f, -6.32f, +R_CUBIC_TO, -1.4f, -0.8f, -2.88f, -1.47f, -4.33f, -2.19f, +R_CUBIC_TO, 1.67f, -0.32f, 3.36f, -0.59f, 5, -1.04f, +R_CUBIC_TO, 0.08f, -1.01f, 0.13f, -2.02f, 0.21f, -3.04f, +R_CUBIC_TO, 1.03f, -0.67f, 2.06f, -1.32f, 3.1f, -1.96f, +R_CUBIC_TO, -0.43f, -1.23f, -0.99f, -2.4f, -1.62f, -3.54f, +R_CUBIC_TO, -1.05f, -1.91f, -1.89f, -3.93f, -3.07f, -5.77f, +R_CUBIC_TO, -0.22f, -0.01f, -0.45f, -0.02f, -0.69f, -0.03f, CLOSE, END
diff --git a/ash/wm/session_state_animator.h b/ash/wm/session_state_animator.h index 977e266..89b617b 100644 --- a/ash/wm/session_state_animator.h +++ b/ash/wm/session_state_animator.h
@@ -192,8 +192,8 @@ AnimationSpeed speed) = 0; // Apply animation |type| to all containers included in |container_mask| with - // specified |speed| and call a |callback| at the end of the animation, if it - // is not null. + // specified |speed| and call a |callback| once at the end of the animations, + // if it is not null. virtual void StartAnimationWithCallback(int container_mask, AnimationType type, AnimationSpeed speed,
diff --git a/ash/wm/session_state_animator_impl.cc b/ash/wm/session_state_animator_impl.cc index d205155..afe0bbfa 100644 --- a/ash/wm/session_state_animator_impl.cc +++ b/ash/wm/session_state_animator_impl.cc
@@ -9,6 +9,7 @@ #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/wm/wm_window_animations.h" +#include "base/barrier_closure.h" #include "base/memory/ptr_util.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window_event_dispatcher.h" @@ -548,10 +549,12 @@ base::Closure callback) { aura::Window::Windows containers; GetContainers(container_mask, &containers); + base::Closure animation_done_closure = + base::BarrierClosure(containers.size(), callback); for (aura::Window::Windows::const_iterator it = containers.begin(); it != containers.end(); ++it) { ui::LayerAnimationObserver* observer = - new CallbackAnimationObserver(callback); + new CallbackAnimationObserver(animation_done_closure); RunAnimationForWindow(*it, type, speed, observer); } }
diff --git a/ash/wm/session_state_animator_impl_unittest.cc b/ash/wm/session_state_animator_impl_unittest.cc index 05be53c..abcbaa4 100644 --- a/ash/wm/session_state_animator_impl_unittest.cc +++ b/ash/wm/session_state_animator_impl_unittest.cc
@@ -2,11 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/wm/session_state_animator_impl.h" + #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/wm/session_state_animator.h" -#include "ash/wm/session_state_animator_impl.h" +#include "base/bind.h" +#include "base/run_loop.h" #include "ui/aura/client/aura_constants.h" typedef ash::test::AshTestBase SessionStateAnimatiorImplContainersTest; @@ -80,4 +83,22 @@ EXPECT_TRUE(containers.empty()); } +// Test that SessionStateAnimatorImpl invokes the callback only once on +// multi-display env, where it needs to run multiple animations on multiple +// containers. See http://crbug.com/712422 for details. +TEST_F(SessionStateAnimatiorImplContainersTest, + AnimationCallbackOnMultiDisplay) { + UpdateDisplay("200x200,400x400"); + + int callback_count = 0; + SessionStateAnimatorImpl animator; + animator.StartAnimationWithCallback( + SessionStateAnimator::LOCK_SCREEN_CONTAINERS, + SessionStateAnimator::ANIMATION_LIFT, + SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE, + base::Bind([](int* count) { ++(*count); }, &callback_count)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, callback_count); +} + } // namespace ash
diff --git a/base/android/jni_utils.cc b/base/android/jni_utils.cc index 848dfd74..c5e370c 100644 --- a/base/android/jni_utils.cc +++ b/base/android/jni_utils.cc
@@ -15,7 +15,7 @@ return Java_JNIUtils_getClassLoader(env); } -bool isSelectiveJniRegistrationEnabled(JNIEnv* env) { +bool IsSelectiveJniRegistrationEnabled(JNIEnv* env) { return Java_JNIUtils_isSelectiveJniRegistrationEnabled(env); }
diff --git a/base/android/jni_utils.h b/base/android/jni_utils.h index ef645c26..c626ba4 100644 --- a/base/android/jni_utils.h +++ b/base/android/jni_utils.h
@@ -19,7 +19,7 @@ BASE_EXPORT ScopedJavaLocalRef<jobject> GetClassLoader(JNIEnv* env); // Returns true if the current process permits selective JNI registration. -BASE_EXPORT bool isSelectiveJniRegistrationEnabled(JNIEnv* env); +BASE_EXPORT bool IsSelectiveJniRegistrationEnabled(JNIEnv* env); } // namespace android } // namespace base
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index dc9c60d3..0f3ba5c0 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc
@@ -1188,16 +1188,6 @@ void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) { EXPECT_TRUE(sync_token.HasData()); ++mailbox_returned_; - switch (mailbox_returned_) { - case 1: - break; - case 2: - EXPECT_EQ(commit_count_, 5); - EndTest(); - break; - default: - NOTREACHED(); - } } void SetupTree() override { @@ -1227,7 +1217,7 @@ void BeginTest() override { PostSetNeedsCommitToMainThread(); } - void DidCommitAndDrawFrame() override { + void DidReceiveCompositorFrameAck() override { ++commit_count_; switch (commit_count_) { case 1: @@ -1262,6 +1252,8 @@ texture_layer_->ClearClient(); break; case 5: + EXPECT_EQ(2, mailbox_returned_); + EndTest(); break; default: NOTREACHED(); @@ -1284,8 +1276,7 @@ int commit_count_; }; -// Flaky when multi-threaded. crbug.com/702868 -SINGLE_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest); +SINGLE_AND_MULTI_THREAD_TEST_F(TextureLayerChangeInvisibleMailboxTest); // Test that TextureLayerImpl::ReleaseResources can be called which releases // the mailbox back to TextureLayerClient.
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h index aba97ceb..d8a58372 100644 --- a/cc/paint/paint_canvas.h +++ b/cc/paint/paint_canvas.h
@@ -34,7 +34,6 @@ // both recording and gpu work. virtual void flush() = 0; - virtual SkISize getBaseLayerSize() const = 0; virtual bool writePixels(const SkImageInfo& info, const void* pixels, size_t row_bytes,
diff --git a/cc/paint/skia_paint_canvas.cc b/cc/paint/skia_paint_canvas.cc index e29d816..5034107 100644 --- a/cc/paint/skia_paint_canvas.cc +++ b/cc/paint/skia_paint_canvas.cc
@@ -38,10 +38,6 @@ canvas_->flush(); } -SkISize SkiaPaintCanvas::getBaseLayerSize() const { - return canvas_->getBaseLayerSize(); -} - bool SkiaPaintCanvas::writePixels(const SkImageInfo& info, const void* pixels, size_t row_bytes,
diff --git a/cc/paint/skia_paint_canvas.h b/cc/paint/skia_paint_canvas.h index c1decfc7..f50e2321b 100644 --- a/cc/paint/skia_paint_canvas.h +++ b/cc/paint/skia_paint_canvas.h
@@ -38,7 +38,6 @@ void flush() override; - SkISize getBaseLayerSize() const override; bool writePixels(const SkImageInfo& info, const void* pixels, size_t row_bytes,
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 60077ec0..39e641c1 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -279,6 +279,12 @@ test_hooks_->DidRequestImplSideInvalidation(this); } + void DidReceiveCompositorFrameAck() override { + test_hooks_->WillReceiveCompositorFrameAckOnThread(this); + LayerTreeHostImpl::DidReceiveCompositorFrameAck(); + test_hooks_->DidReceiveCompositorFrameAckOnThread(this); + } + AnimationHost* animation_host() const { return static_cast<AnimationHost*>(mutator_host()); }
diff --git a/cc/test/test_hooks.h b/cc/test/test_hooks.h index a7dc57835..46991d38 100644 --- a/cc/test/test_hooks.h +++ b/cc/test/test_hooks.h
@@ -51,6 +51,10 @@ virtual void NotifyAllTileTasksCompleted(LayerTreeHostImpl* host_impl) {} virtual void NotifyTileStateChangedOnThread(LayerTreeHostImpl* host_impl, const Tile* tile) {} + virtual void WillReceiveCompositorFrameAckOnThread( + LayerTreeHostImpl* host_impl) {} + virtual void DidReceiveCompositorFrameAckOnThread( + LayerTreeHostImpl* host_impl) {} virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, bool visible) {} virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 9d04554..c3005c8 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -575,21 +575,20 @@ bool scroll_on_main_thread = false; uint32_t main_thread_scrolling_reasons; - LayerImpl* test_layer_impl = FindScrollLayerForDeviceViewportPoint( + auto* test_scroll_node = FindScrollNodeForDeviceViewportPoint( device_viewport_point, type, layer_impl, &scroll_on_main_thread, &main_thread_scrolling_reasons); if (scroll_on_main_thread) return false; - int test_scroll_tree_index = test_layer_impl->scroll_tree_index(); - if (scrolling_node->id == test_scroll_tree_index) + if (scrolling_node == test_scroll_node) return true; // For active scrolling state treat the inner/outer viewports interchangeably. if (scrolling_node->scrolls_inner_viewport || scrolling_node->scrolls_outer_viewport) { - return test_layer_impl == viewport()->MainScrollLayer(); + return test_scroll_node == OuterViewportScrollNode(); } return false; @@ -2626,7 +2625,7 @@ return false; } -LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( +ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint( const gfx::PointF& device_viewport_point, InputHandler::ScrollInputType type, LayerImpl* layer_impl, @@ -2651,7 +2650,7 @@ if (IsMainThreadScrolling(status, scroll_node)) { *scroll_on_main_thread = true; *main_thread_scrolling_reasons = status.main_thread_scrolling_reasons; - return active_tree_->LayerById(scroll_node->owning_layer_id); + return scroll_node; } if (status.thread == InputHandler::SCROLL_ON_IMPL_THREAD && @@ -2681,11 +2680,7 @@ } } - // TODO(pdr): Refactor this function to directly return |impl_scroll_node| - // instead of using ScrollNode's owning_layer_id to return a LayerImpl. - if (!impl_scroll_node) - return nullptr; - return active_tree_->LayerById(impl_scroll_node->owning_layer_id); + return impl_scroll_node; } InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( @@ -2770,13 +2765,9 @@ } } - auto* scrolling_layer = FindScrollLayerForDeviceViewportPoint( + scrolling_node = FindScrollNodeForDeviceViewportPoint( device_viewport_point, type, layer_impl, &scroll_on_main_thread, &scroll_status.main_thread_scrolling_reasons); - ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; - scrolling_node = - scrolling_layer ? scroll_tree.Node(scrolling_layer->scroll_tree_index()) - : nullptr; } if (scroll_on_main_thread) { @@ -3418,44 +3409,44 @@ // Check if mouse is over a scrollbar or not. // TODO(sahel): get rid of this extera checking when - // FindScrollLayerForDeviceViewportPoint finds the proper layer for - // scrolling on main thread when mouse is over scrollbar as well. - ElementId new_element_id; + // FindScrollNodeForDeviceViewportPoint finds the proper node for scrolling on + // the main thread when the mouse is over a scrollbar as well. + ElementId scroll_element_id; if (layer_impl && layer_impl->ToScrollbarLayer()) - new_element_id = layer_impl->ToScrollbarLayer()->scroll_element_id(); - if (!new_element_id) { + scroll_element_id = layer_impl->ToScrollbarLayer()->scroll_element_id(); + if (!scroll_element_id) { bool scroll_on_main_thread = false; uint32_t main_thread_scrolling_reasons; - LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint( + auto* scroll_node = FindScrollNodeForDeviceViewportPoint( device_viewport_point, InputHandler::TOUCHSCREEN, layer_impl, &scroll_on_main_thread, &main_thread_scrolling_reasons); + if (scroll_node) + scroll_element_id = scroll_node->element_id; // Scrollbars for the viewport are registered with the outer viewport layer. - if (scroll_layer_impl == InnerViewportScrollLayer()) - scroll_layer_impl = OuterViewportScrollLayer(); - - if (scroll_layer_impl) - new_element_id = scroll_layer_impl->element_id(); + if (InnerViewportScrollLayer() && OuterViewportScrollLayer() && + scroll_element_id == InnerViewportScrollLayer()->element_id()) + scroll_element_id = OuterViewportScrollLayer()->element_id(); } - if (new_element_id != scroll_element_id_mouse_currently_over_) { + if (scroll_element_id != scroll_element_id_mouse_currently_over_) { ScrollbarAnimationController* old_animation_controller = ScrollbarAnimationControllerForElementId( scroll_element_id_mouse_currently_over_); if (old_animation_controller) { old_animation_controller->DidMouseLeave(); } - scroll_element_id_mouse_currently_over_ = new_element_id; + scroll_element_id_mouse_currently_over_ = scroll_element_id; } ScrollbarAnimationController* new_animation_controller = - ScrollbarAnimationControllerForElementId(new_element_id); + ScrollbarAnimationControllerForElementId(scroll_element_id); if (!new_animation_controller) return; - int new_layer_id = active_tree_->LayerIdByElementId(new_element_id); + int scroll_layer_id = active_tree_->LayerIdByElementId(scroll_element_id); for (ScrollbarLayerImplBase* scrollbar : - active_tree_->ScrollbarsFor(new_layer_id)) { + active_tree_->ScrollbarsFor(scroll_layer_id)) { new_animation_controller->DidMouseMoveNear( scrollbar->orientation(), DeviceSpaceDistanceToLayer(device_viewport_point, scrollbar) /
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index b3893b08..381424e 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -674,7 +674,7 @@ void ClearCurrentlyScrollingNode(); - LayerImpl* FindScrollLayerForDeviceViewportPoint( + ScrollNode* FindScrollNodeForDeviceViewportPoint( const gfx::PointF& device_viewport_point, InputHandler::ScrollInputType type, LayerImpl* layer_hit_by_point,
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 31f10d9..39f7d496 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -7520,5 +7520,86 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestHudLayerWithLayerLists); +// Verifies that LayerTreeHostClient does not receive frame acks from a released +// CompositorFrameSink. +class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest { + protected: + void SetupTree() override { + scoped_refptr<Layer> root = Layer::Create(); + root->SetBounds(gfx::Size(10, 10)); + layer_tree_host()->SetRootLayer(std::move(root)); + LayerTreeHostTest::SetupTree(); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void WillReceiveCompositorFrameAckOnThread( + LayerTreeHostImpl* host_impl) override { + // This method is called before ack is posted to main thread. This ensures + // that WillReceiveCompositorFrameAck which we PostTask below will be called + // before DidReceiveCompositorFrameAck. + MainThreadTaskRunner()->PostTask( + FROM_HERE, base::Bind(&LayerTreeHostTestDiscardAckAfterRelease:: + WillReceiveCompositorFrameAck, + base::Unretained(this))); + } + + void WillReceiveCompositorFrameAck() { + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + // For the first commit, don't release the CompositorFrameSink. We must + // receive the ack later on. + break; + case 2: + // Release the CompositorFrameSink for the second commit. We'll later + // check that the ack is discarded. + layer_tree_host()->SetVisible(false); + layer_tree_host()->ReleaseCompositorFrameSink(); + break; + default: + NOTREACHED(); + } + } + + void DidReceiveCompositorFrameAckOnThread( + LayerTreeHostImpl* host_impl) override { + // Since this method is called after ack is posted to main thread, we can be + // sure that if the ack is not discarded, it will be definitely received + // before we are in CheckFrameAck. + MainThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&LayerTreeHostTestDiscardAckAfterRelease::CheckFrameAck, + base::Unretained(this))); + } + + void DidReceiveCompositorFrameAck() override { received_ack_ = true; } + + void CheckFrameAck() { + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + // CompositorFrameSink was not released. We must receive the ack. + EXPECT_TRUE(received_ack_); + // Cause damage so that we draw and swap. + layer_tree_host()->root_layer()->SetBackgroundColor(SK_ColorGREEN); + break; + case 2: + // CompositorFrameSink was released. The ack must be discarded. + EXPECT_FALSE(received_ack_); + EndTest(); + break; + default: + NOTREACHED(); + } + received_ack_ = false; + } + + void AfterTest() override {} + + private: + bool received_ack_ = false; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDiscardAckAfterRelease); + } // namespace } // namespace cc
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index 1235c4b..48d1902 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc
@@ -126,10 +126,13 @@ } void ProxyImpl::InitializeCompositorFrameSinkOnImpl( - CompositorFrameSink* compositor_frame_sink) { + CompositorFrameSink* compositor_frame_sink, + base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr) { TRACE_EVENT0("cc", "ProxyImpl::InitializeCompositorFrameSinkOnImplThread"); DCHECK(IsImplThread()); + proxy_main_frame_sink_bound_weak_ptr_ = proxy_main_frame_sink_bound_weak_ptr; + LayerTreeHostImpl* host_impl = layer_tree_host_impl_.get(); bool success = host_impl->InitializeRenderer(compositor_frame_sink); MainThreadTaskRunner()->PostTask( @@ -314,7 +317,7 @@ scheduler_->DidReceiveCompositorFrameAck(); MainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&ProxyMain::DidReceiveCompositorFrameAck, - proxy_main_weak_ptr_)); + proxy_main_frame_sink_bound_weak_ptr_)); } void ProxyImpl::OnCanDrawStateChanged(bool can_draw) {
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h index 68edc33..e80a118 100644 --- a/cc/trees/proxy_impl.h +++ b/cc/trees/proxy_impl.h
@@ -34,7 +34,8 @@ BrowserControlsState current, bool animate); void InitializeCompositorFrameSinkOnImpl( - CompositorFrameSink* compositor_frame_sink); + CompositorFrameSink* compositor_frame_sink, + base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr); void InitializeMutatorOnImpl(std::unique_ptr<LayerTreeMutator> mutator); void MainThreadHasStoppedFlingingOnImpl(); void SetInputThrottledUntilCommitOnImpl(bool is_throttled); @@ -149,6 +150,10 @@ // Used to post tasks to ProxyMain on the main thread. base::WeakPtr<ProxyMain> proxy_main_weak_ptr_; + // A weak pointer to ProxyMain that is invalidated when CompositorFrameSink is + // released. + base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr_; + DISALLOW_COPY_AND_ASSIGN(ProxyImpl); };
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc index c11036c..33dfe12 100644 --- a/cc/trees/proxy_main.cc +++ b/cc/trees/proxy_main.cc
@@ -36,6 +36,7 @@ commit_waits_for_activation_(false), started_(false), defer_commits_(false), + frame_sink_bound_weak_factory_(this), weak_factory_(this) { TRACE_EVENT0("cc", "ProxyMain::ProxyMain"); DCHECK(task_runner_provider_); @@ -298,9 +299,10 @@ void ProxyMain::SetCompositorFrameSink( CompositorFrameSink* compositor_frame_sink) { ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyImpl::InitializeCompositorFrameSinkOnImpl, - base::Unretained(proxy_impl_.get()), - compositor_frame_sink)); + FROM_HERE, + base::BindOnce(&ProxyImpl::InitializeCompositorFrameSinkOnImpl, + base::Unretained(proxy_impl_.get()), compositor_frame_sink, + frame_sink_bound_weak_factory_.GetWeakPtr())); } void ProxyMain::SetVisible(bool visible) { @@ -479,6 +481,7 @@ void ProxyMain::ReleaseCompositorFrameSink() { DCHECK(IsMainThread()); + frame_sink_bound_weak_factory_.InvalidateWeakPtrs(); DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); CompletionEvent completion; ImplThreadTaskRunner()->PostTask(
diff --git a/cc/trees/proxy_main.h b/cc/trees/proxy_main.h index 3d97276..9fb7823d 100644 --- a/cc/trees/proxy_main.h +++ b/cc/trees/proxy_main.h
@@ -129,6 +129,10 @@ // run before we destroy it on the impl thread. std::unique_ptr<ProxyImpl> proxy_impl_; + // WeakPtrs generated by this factory will be invalidated when + // CompositorFrameSink is released. + base::WeakPtrFactory<ProxyMain> frame_sink_bound_weak_factory_; + base::WeakPtrFactory<ProxyMain> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ProxyMain);
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index 07b5afa..29821e38 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc
@@ -52,6 +52,7 @@ inside_synchronous_composite_(false), compositor_frame_sink_creation_requested_(false), compositor_frame_sink_lost_(true), + frame_sink_bound_weak_factory_(this), weak_factory_(this) { TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); DCHECK(task_runner_provider_); @@ -123,6 +124,7 @@ void SingleThreadProxy::ReleaseCompositorFrameSink() { compositor_frame_sink_lost_ = true; + frame_sink_bound_weak_factory_.InvalidateWeakPtrs(); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->DidLoseCompositorFrameSink(); return layer_tree_host_impl_->ReleaseCompositorFrameSink(); @@ -141,6 +143,7 @@ } if (success) { + frame_sink_bound_weak_ptr_ = frame_sink_bound_weak_factory_.GetWeakPtr(); layer_tree_host_->DidInitializeCompositorFrameSink(); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->DidCreateAndInitializeCompositorFrameSink(); @@ -425,7 +428,12 @@ "SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread"); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->DidReceiveCompositorFrameAck(); - layer_tree_host_->DidReceiveCompositorFrameAck(); + // We do a PostTask here because freeing resources in some cases (such as in + // TextureLayer) is PostTasked and we want to make sure ack is received after + // resources are returned. + task_runner_provider_->MainThreadTaskRunner()->PostTask( + FROM_HERE, base::Bind(&SingleThreadProxy::DidReceiveCompositorFrameAck, + frame_sink_bound_weak_ptr_)); } void SingleThreadProxy::OnDrawForCompositorFrameSink( @@ -794,4 +802,8 @@ #endif } +void SingleThreadProxy::DidReceiveCompositorFrameAck() { + layer_tree_host_->DidReceiveCompositorFrameAck(); +} + } // namespace cc
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index 4a09195..4cbb14a 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h
@@ -122,6 +122,8 @@ bool ShouldComposite() const; void ScheduleRequestNewCompositorFrameSink(); + void DidReceiveCompositorFrameAck(); + // Accessed on main thread only. LayerTreeHost* layer_tree_host_; LayerTreeHostSingleThreadClient* single_thread_client_; @@ -158,6 +160,12 @@ // This is the callback for the scheduled RequestNewCompositorFrameSink. base::CancelableClosure compositor_frame_sink_creation_callback_; + base::WeakPtr<SingleThreadProxy> frame_sink_bound_weak_ptr_; + + // WeakPtrs generated by this factory will be invalidated when + // CompositorFrameSink is released. + base::WeakPtrFactory<SingleThreadProxy> frame_sink_bound_weak_factory_; + base::WeakPtrFactory<SingleThreadProxy> weak_factory_; DISALLOW_COPY_AND_ASSIGN(SingleThreadProxy);
diff --git a/chrome/VERSION b/chrome/VERSION index c97ffd5..c0083be 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=60 MINOR=0 -BUILD=3075 +BUILD=3076 PATCH=0
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 0918bf45..a6f23c9 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -3520,8 +3520,8 @@ </message> </if> <if expr="enable_media_router"> - <message name="IDS_UTILITY_PROCESS_DIAL_DEVICE_DESCRIPTION_PARSER_NAME" desc="The name of the utility process used for parsing device description xml."> - Dial Device Description Parser + <message name="IDS_UTILITY_PROCESS_DIAL_DEVICE_DESCRIPTION_PARSER_NAME" desc="The name of the utility process used for parsing XML of uPnP device descriptions of DIAL devices."> + DIAL Device Description Parser </message> </if>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 3e3444d..0f98a47 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -1129,9 +1129,15 @@ <message name="IDS_SETTINGS_INTERNET_ADD_THIRD_PARTY_VPN" desc="Settings > Internet > Add third party VPN label"> Add <ph name="PROVIDER_NAME">$1<ex>VPN Demo</ex></ph>... </message> + <message name="IDS_SETTINGS_INTERNET_DEVICE_ENABLING" desc="Settings > Internet > Message when a device (e.g a Cellular modem) is enabling."> + Enabling + </message> <message name="IDS_SETTINGS_INTERNET_NETWORK_SECTION_ACCESS_POINT" desc="Settings > Internet > Network details: Access Point section label."> Access Point </message> + <message name="IDS_SETTINGS_INTERNET_MOBILE_SEARCH" desc="Settings > Internet > Message in Mobile section when searching for mobile networks."> + Searching for mobile networks + </message> <message name="IDS_SETTINGS_INTERNET_NETWORK_SECTION_ADVANCED" desc="Settings > Internet > Network details: Advanced section label."> Advanced </message>
diff --git a/chrome/browser/android/chrome_entry_point.cc b/chrome/browser/android/chrome_entry_point.cc index fad7aa7..ee46cd6c 100644 --- a/chrome/browser/android/chrome_entry_point.cc +++ b/chrome/browser/android/chrome_entry_point.cc
@@ -23,7 +23,7 @@ // Java side and only register a subset of JNI methods. base::android::InitVM(vm); JNIEnv* env = base::android::AttachCurrentThread(); - if (base::android::isSelectiveJniRegistrationEnabled(env)) { + if (base::android::IsSelectiveJniRegistrationEnabled(env)) { base::android::SetJniRegistrationType( base::android::SELECTIVE_JNI_REGISTRATION); }
diff --git a/chrome/browser/android/offline_pages/prerendering_offliner.cc b/chrome/browser/android/offline_pages/prerendering_offliner.cc index 45bf01d7f..899bc107 100644 --- a/chrome/browser/android/offline_pages/prerendering_offliner.cc +++ b/chrome/browser/android/offline_pages/prerendering_offliner.cc
@@ -96,10 +96,10 @@ if (IsOfflinePagesLoadSignalCollectingEnabled()) { // Stash loading signals for writing when we write out the MHTML. - std::string headers = - base::StringPrintf("%s\r\n%s\r\n\r\n", kContentTransferEncodingBinary, - kXHeaderForSignals); - std::string body = headers + SerializeLoadingSignalData(); + // TODO(petewil): Add this data to the BackgroundLoaderOffliner too. + std::string extra_headers = base::StringPrintf( + "%s\r\n%s", kContentTransferEncodingBinary, kXHeaderForSignals); + std::string body = SerializeLoadingSignalData(); std::string content_type = kContentType; std::string content_location = base::StringPrintf( "cid:signal-data-%" PRId64 "@mhtml.blink", request.request_id()); @@ -108,7 +108,8 @@ content::MHTMLExtraParts::FromWebContents(web_contents); DCHECK(extra_parts); if (extra_parts != nullptr) { - extra_parts->AddExtraMHTMLPart(content_type, content_location, body); + extra_parts->AddExtraMHTMLPart(content_type, content_location, + extra_headers, body); } }
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index 4847d9a..e7d5687 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -1238,6 +1238,17 @@ StartAutoLoginTimer(); } +void ExistingUserController::ContinueLoginWhenCryptohomeAvailable( + base::OnceClosure continuation, + bool service_is_available) { + if (!service_is_available) { + LOG(ERROR) << "Cryptohome service is not available"; + OnAuthFailure(AuthFailure(AuthFailure::COULD_NOT_MOUNT_CRYPTOHOME)); + return; + } + std::move(continuation).Run(); +} + void ExistingUserController::ContinueLoginIfDeviceNotDisabled( const base::Closure& continuation) { // Disable clicking on other windows and status tray. @@ -1283,7 +1294,11 @@ return; } - continuation.Run(); + chromeos::DBusThreadManager::Get() + ->GetCryptohomeClient() + ->WaitForServiceToBeAvailable(base::Bind( + &ExistingUserController::ContinueLoginWhenCryptohomeAvailable, + weak_factory_.GetWeakPtr(), continuation)); } void ExistingUserController::DoCompleteLogin(
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h index 32f8a497..c47e79f 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.h +++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -251,6 +251,11 @@ // auto-login timer is started. void PerformLoginFinishedActions(bool start_auto_login_timer); + // Invokes |continuation| after verifying that cryptohome service is + // available. + void ContinueLoginWhenCryptohomeAvailable(base::OnceClosure continuation, + bool service_is_available); + // Invokes |continuation| after verifying that the device is not disabled. void ContinueLoginIfDeviceNotDisabled(const base::Closure& continuation);
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc index 9566108f..facc5e4a 100644 --- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -784,6 +784,11 @@ ExistingUserControllerTest::SetUpInProcessBrowserTestFixture(); } + void TearDownOnMainThread() override { + base::RunLoop().RunUntilIdle(); + ExistingUserControllerTest::TearDownOnMainThread(); + } + protected: void ExpectLoginFailure() { EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)).Times(2);
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc index 52c56eab..7482a9f7 100644 --- a/chrome/browser/extensions/updater/extension_updater_unittest.cc +++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -811,19 +811,19 @@ EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]); } - void TestUpdateUrlDataFromGallery( - const std::string& gallery_url, + void TestUpdateUrlDataFromUrl( + const std::string& update_url, ManifestFetchData::FetchPriority fetch_priority, - int num_extensions) { + int num_extensions, + bool should_include_traffic_management_headers) { net::TestURLFetcherFactory factory; MockService service(prefs_.get()); MockExtensionDownloaderDelegate delegate; ExtensionDownloader downloader(&delegate, service.request_context()); ExtensionList extensions; - std::string url(gallery_url); - service.CreateTestExtensions(1, num_extensions, &extensions, &url, + service.CreateTestExtensions(1, num_extensions, &extensions, &update_url, Manifest::INTERNAL); for (int i = 0; i < num_extensions; ++i) { @@ -839,49 +839,53 @@ ASSERT_TRUE(fetcher); // Make sure that extensions that update from the gallery ignore any // update URL data. - const std::string& update_url = fetcher->GetOriginalURL().spec(); - std::string::size_type x = update_url.find("x="); + const std::string& fetcher_url = fetcher->GetOriginalURL().spec(); + std::string::size_type x = fetcher_url.find("x="); EXPECT_NE(std::string::npos, x); - std::string::size_type ap = update_url.find("ap%3D", x); + std::string::size_type ap = fetcher_url.find("ap%3D", x); EXPECT_EQ(std::string::npos, ap); net::HttpRequestHeaders fetch_headers; fetcher->GetExtraRequestHeaders(&fetch_headers); - EXPECT_TRUE(fetch_headers.HasHeader( - ExtensionDownloader::kUpdateInteractivityHeader)); - EXPECT_TRUE( - fetch_headers.HasHeader(ExtensionDownloader::kUpdateAppIdHeader)); - EXPECT_TRUE( + EXPECT_EQ(should_include_traffic_management_headers, + fetch_headers.HasHeader( + ExtensionDownloader::kUpdateInteractivityHeader)); + EXPECT_EQ(should_include_traffic_management_headers, + fetch_headers.HasHeader(ExtensionDownloader::kUpdateAppIdHeader)); + EXPECT_EQ( + should_include_traffic_management_headers, fetch_headers.HasHeader(ExtensionDownloader::kUpdateUpdaterHeader)); - std::string interactivity_value; - fetch_headers.GetHeader(ExtensionDownloader::kUpdateInteractivityHeader, - &interactivity_value); + if (should_include_traffic_management_headers) { + std::string interactivity_value; + fetch_headers.GetHeader(ExtensionDownloader::kUpdateInteractivityHeader, + &interactivity_value); - std::string expected_interactivity_value = - fetch_priority == ManifestFetchData::FetchPriority::FOREGROUND ? "fg" - : "bg"; - EXPECT_EQ(expected_interactivity_value, interactivity_value); + std::string expected_interactivity_value = + fetch_priority == ManifestFetchData::FetchPriority::FOREGROUND ? "fg" + : "bg"; + EXPECT_EQ(expected_interactivity_value, interactivity_value); - std::string appid_value; - fetch_headers.GetHeader(ExtensionDownloader::kUpdateAppIdHeader, - &appid_value); - if (num_extensions > 1) { - for (int i = 0; i < num_extensions; ++i) { - EXPECT_TRUE( - testing::IsSubstring("", "", extensions[i]->id(), appid_value)); + std::string appid_value; + fetch_headers.GetHeader(ExtensionDownloader::kUpdateAppIdHeader, + &appid_value); + if (num_extensions > 1) { + for (int i = 0; i < num_extensions; ++i) { + EXPECT_TRUE( + testing::IsSubstring("", "", extensions[i]->id(), appid_value)); + } + } else { + EXPECT_EQ(extensions[0]->id(), appid_value); } - } else { - EXPECT_EQ(extensions[0]->id(), appid_value); - } - std::string updater_value; - fetch_headers.GetHeader(ExtensionDownloader::kUpdateUpdaterHeader, - &updater_value); - std::string expected_updater_value = base::StringPrintf( - "%s-%s", UpdateQueryParams::GetProdIdString(UpdateQueryParams::CRX), - UpdateQueryParams::GetProdVersion().c_str()); - EXPECT_EQ(expected_updater_value, updater_value); + std::string updater_value; + fetch_headers.GetHeader(ExtensionDownloader::kUpdateUpdaterHeader, + &updater_value); + const std::string expected_updater_value = base::StringPrintf( + "%s-%s", UpdateQueryParams::GetProdIdString(UpdateQueryParams::CRX), + UpdateQueryParams::GetProdVersion().c_str()); + EXPECT_EQ(expected_updater_value, updater_value); + } } void TestInstallSource() { @@ -2017,14 +2021,18 @@ TestUpdateUrlDataEmpty(); TestUpdateUrlDataSimple(); TestUpdateUrlDataCompound(); - TestUpdateUrlDataFromGallery(extension_urls::GetWebstoreUpdateUrl().spec(), - ManifestFetchData::FetchPriority::BACKGROUND, 1); - TestUpdateUrlDataFromGallery(extension_urls::GetWebstoreUpdateUrl().spec(), - ManifestFetchData::FetchPriority::FOREGROUND, 1); - TestUpdateUrlDataFromGallery(extension_urls::GetWebstoreUpdateUrl().spec(), - ManifestFetchData::FetchPriority::BACKGROUND, 2); - TestUpdateUrlDataFromGallery(extension_urls::GetWebstoreUpdateUrl().spec(), - ManifestFetchData::FetchPriority::FOREGROUND, 4); + std::string gallery_url_spec = extension_urls::GetWebstoreUpdateUrl().spec(); + TestUpdateUrlDataFromUrl( + gallery_url_spec, ManifestFetchData::FetchPriority::BACKGROUND, 1, true); + TestUpdateUrlDataFromUrl( + gallery_url_spec, ManifestFetchData::FetchPriority::FOREGROUND, 1, true); + TestUpdateUrlDataFromUrl( + gallery_url_spec, ManifestFetchData::FetchPriority::BACKGROUND, 2, true); + TestUpdateUrlDataFromUrl( + gallery_url_spec, ManifestFetchData::FetchPriority::FOREGROUND, 4, true); + TestUpdateUrlDataFromUrl("http://example.com/update", + ManifestFetchData::FetchPriority::FOREGROUND, 4, + false); } TEST_F(ExtensionUpdaterTest, TestInstallSource) {
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc index 65f3f90..ae43153 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor.cc
@@ -100,6 +100,12 @@ origin->set_accessed_network(summary.accessed_network); } +bool IsManifestTooOld(const precache::PrecacheManifest& manifest) { + const base::TimeDelta kMaxManifestAge = base::TimeDelta::FromDays(5); + return base::Time::Now() - base::Time::FromDoubleT(manifest.id().id()) > + kMaxManifestAge; +} + // Used to fetch the visit count for a URL from the History database. class GetUrlVisitCountTask : public history::HistoryDBTask { public: @@ -898,16 +904,33 @@ // Use host data if the URL-based prediction isn't available. std::string main_frame_url_host = main_frame_url.host(); if (GetRedirectEndpoint(main_frame_url_host, *host_redirect_table_cache_, - &redirect_endpoint) && - PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, urls)) { - if (prediction) { - prediction->is_host = true; - prediction->main_frame_key = redirect_endpoint; - prediction->is_redirected = (redirect_endpoint != main_frame_url_host); + &redirect_endpoint)) { + if (PopulatePrefetcherRequest(redirect_endpoint, *host_table_cache_, + urls)) { + if (prediction) { + prediction->is_host = true; + prediction->main_frame_key = redirect_endpoint; + prediction->is_redirected = (redirect_endpoint != main_frame_url_host); + } + return true; } - return true; - } + if (config_.is_manifests_enabled) { + // Use manifest data for host if available. + std::string manifest_host = redirect_endpoint; + if (base::StartsWith(manifest_host, "www.", base::CompareCase::SENSITIVE)) + manifest_host.assign(manifest_host, 4, std::string::npos); + if (PopulateFromManifest(manifest_host, urls)) { + if (prediction) { + prediction->is_host = true; + prediction->main_frame_key = redirect_endpoint; + prediction->is_redirected = + (redirect_endpoint != main_frame_url_host); + } + return true; + } + } + } return false; } @@ -931,6 +954,46 @@ return has_prefetchable_resource; } +bool ResourcePrefetchPredictor::PopulateFromManifest( + const std::string& manifest_host, + std::vector<GURL>* urls) const { + auto it = manifest_table_cache_->find(manifest_host); + if (it == manifest_table_cache_->end()) + return false; + + const precache::PrecacheManifest& manifest = it->second; + + if (IsManifestTooOld(manifest)) + return false; + + // This is roughly in line with the threshold we use for resource confidence. + const float kMinWeight = 0.7f; + + // Don't prefetch resource if it has false bit in any of the following + // bitsets. All bits assumed to be true if an optional has no value. + base::Optional<std::vector<bool>> not_unused = + precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment); + base::Optional<std::vector<bool>> not_versioned = precache::GetResourceBitset( + manifest, internal::kVersionedRemovedExperiment); + base::Optional<std::vector<bool>> not_no_store = precache::GetResourceBitset( + manifest, internal::kNoStoreRemovedExperiment); + + bool has_prefetchable_resource = false; + for (int i = 0; i < manifest.resource_size(); ++i) { + const precache::PrecacheResource& resource = manifest.resource(i); + if (resource.weight_ratio() > kMinWeight && + (!not_unused.has_value() || not_unused.value()[i]) && + (!not_versioned.has_value() || not_versioned.value()[i]) && + (!not_no_store.has_value() || not_no_store.value()[i])) { + has_prefetchable_resource = true; + if (urls) + urls->emplace_back(resource.url()); + } + } + + return has_prefetchable_resource; +} + void ResourcePrefetchPredictor::CreateCaches( std::unique_ptr<PrefetchDataMap> url_data_map, std::unique_ptr<PrefetchDataMap> host_data_map, @@ -1637,7 +1700,7 @@ if (initialization_state_ != INITIALIZED) return; - if (!config_.is_manifests_enabled) + if (!config_.is_manifests_enabled || IsManifestTooOld(manifest)) return; // The manifest host has "www." prefix stripped, the manifest host could @@ -1688,10 +1751,11 @@ for (int i = 0; i < manifest.resource_size(); ++i) manifest_index.insert({manifest.resource(i).url(), i}); - bool was_updated = false; - base::Optional<std::vector<bool>> unused_bitset = + base::Optional<std::vector<bool>> not_unused = precache::GetResourceBitset(manifest, internal::kUnusedRemovedExperiment); - if (unused_bitset.has_value()) { + + bool was_updated = false; + if (not_unused.has_value()) { // Remove unused resources from |data|. auto new_end = std::remove_if( data.mutable_resources()->begin(), data.mutable_resources()->end(), @@ -1699,7 +1763,7 @@ auto it = manifest_index.find(x.resource_url()); if (it == manifest_index.end()) return false; - return !unused_bitset.value()[it->second]; + return !not_unused.value()[it->second]; }); was_updated = new_end != data.mutable_resources()->end(); data.mutable_resources()->erase(new_end, data.mutable_resources()->end());
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h index 750ac83b..fa4469c 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor.h +++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -63,7 +63,9 @@ constexpr char kResourcePrefetchPredictorRedirectStatusHistogram[] = "ResourcePrefetchPredictor.RedirectStatus"; +const uint32_t kVersionedRemovedExperiment = 0x03ff25e3; const uint32_t kUnusedRemovedExperiment = 0xf7f77166; +const uint32_t kNoStoreRemovedExperiment = 0xd90a199a; } // namespace internal class TestObserver; @@ -288,6 +290,7 @@ FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, HandledResourceTypes); FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, PopulatePrefetcherRequest); + FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, PopulateFromManifest); FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, GetRedirectEndpoint); FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, GetPrefetchData); FRIEND_TEST_ALL_PREFIXES(ResourcePrefetchPredictorTest, @@ -359,11 +362,17 @@ // Returns true iff the |data_map| contains PrefetchData that can be used // for a |main_frame_key| and fills |urls| with resources that need to be - // prefetched. |urls| pointer may be equal nullptr to get return value only. + // prefetched. |urls| may be nullptr to get the return value only. bool PopulatePrefetcherRequest(const std::string& main_frame_key, const PrefetchDataMap& data_map, std::vector<GURL>* urls) const; + // Returns true iff the manifest table contains PrecacheManifest that can be + // used for a |manifest_host| and fills |urls| with resources that need to be + // prefetched. |urls| may be nullptr to get the return value only. + bool PopulateFromManifest(const std::string& manifest_host, + std::vector<GURL>* urls) const; + // Callback for task to read predictor database. Takes ownership of // all arguments. void CreateCaches(std::unique_ptr<PrefetchDataMap> url_data_map,
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc b/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc index 522e507..a6d10b9 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc
@@ -111,12 +111,9 @@ return data; } -precache::PrecacheManifest CreateManifestData(uint64_t id) { - precache::PrecacheManifestId* manifest_id = - new precache::PrecacheManifestId(); - manifest_id->set_id(id); +precache::PrecacheManifest CreateManifestData(int64_t id) { precache::PrecacheManifest manifest; - manifest.set_allocated_id(manifest_id); + manifest.mutable_id()->set_id(id); return manifest; }
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_test_util.h b/chrome/browser/predictors/resource_prefetch_predictor_test_util.h index fe328ee..21339d4 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_test_util.h +++ b/chrome/browser/predictors/resource_prefetch_predictor_test_util.h
@@ -51,7 +51,7 @@ uint64_t last_visit_time = 0); RedirectData CreateRedirectData(const std::string& primary_key, uint64_t last_visit_time = 0); -precache::PrecacheManifest CreateManifestData(uint64_t id = 0); +precache::PrecacheManifest CreateManifestData(int64_t id = 0); OriginData CreateOriginData(const std::string& host, uint64_t last_visit_time = 0);
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc index 0a517a0..76307692 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -1094,7 +1094,8 @@ } TEST_F(ResourcePrefetchPredictorTest, ManifestHostNotInDB) { - precache::PrecacheManifest manifest = CreateManifestData(1); + precache::PrecacheManifest manifest = + CreateManifestData(base::Time::Now().ToDoubleT()); InitializePrecacheResource(manifest.add_resource(), "http://cdn.google.com/script.js", 0.9); InitializePrecacheResource(manifest.add_resource(), @@ -1118,7 +1119,8 @@ InitializePredictor(); EXPECT_EQ(2U, predictor_->manifest_table_cache_->size()); - precache::PrecacheManifest manifest = CreateManifestData(1); + precache::PrecacheManifest manifest = + CreateManifestData(base::Time::Now().ToDoubleT()); InitializePrecacheResource(manifest.add_resource(), "http://google.com/image.jpg", 0.1); @@ -1140,7 +1142,8 @@ InitializePredictor(); EXPECT_EQ(2U, predictor_->manifest_table_cache_->size()); - precache::PrecacheManifest manifest = CreateManifestData(1); + precache::PrecacheManifest manifest = + CreateManifestData(base::Time::Now().ToDoubleT()); InitializePrecacheResource(manifest.add_resource(), "http://en.wikipedia.org/logo.png", 1.0); @@ -1154,7 +1157,8 @@ } TEST_F(ResourcePrefetchPredictorTest, ManifestUnknownFieldsRemoved) { - precache::PrecacheManifest manifest = CreateManifestData(1); + precache::PrecacheManifest manifest = + CreateManifestData(base::Time::Now().ToDoubleT()); InitializePrecacheResource(manifest.add_resource(), "http://cdn.google.com/script.js", 0.9); InitializePrecacheResource(manifest.add_resource(), @@ -1180,6 +1184,19 @@ predictor_->OnManifestFetched("google.com", manifest_with_unknown_fields); } +TEST_F(ResourcePrefetchPredictorTest, ManifestTooOld) { + base::Time old_time = base::Time::Now() - base::TimeDelta::FromDays(7); + precache::PrecacheManifest manifest = + CreateManifestData(old_time.ToDoubleT()); + InitializePrecacheResource(manifest.add_resource(), + "http://cdn.google.com/script.js", 0.9); + InitializePrecacheResource(manifest.add_resource(), + "http://cdn.google.com/style.css", 0.75); + + // No calls to DB should happen. + predictor_->OnManifestFetched("google.com", manifest); +} + TEST_F(ResourcePrefetchPredictorTest, ManifestUnusedRemoved) { const std::string& script_url = "http://cdn.google.com/script.js"; const std::string& style_url = "http://cdn.google.com/style.css"; @@ -1192,7 +1209,8 @@ net::MEDIUM, false, false); predictor_->host_table_cache_->insert({google.primary_key(), google}); - precache::PrecacheManifest manifest = CreateManifestData(1); + precache::PrecacheManifest manifest = + CreateManifestData(base::Time::Now().ToDoubleT()); InitializePrecacheResource(manifest.add_resource(), script_url, 0.9); InitializePrecacheResource(manifest.add_resource(), style_url, 0.75); InitializeExperiment(&manifest, internal::kUnusedRemovedExperiment, @@ -1773,6 +1791,52 @@ EXPECT_TRUE(urls.empty()); } +TEST_F(ResourcePrefetchPredictorTest, PopulateFromManifest) { + // The data that will be used in populating. + precache::PrecacheManifest google = + CreateManifestData(base::Time::Now().ToDoubleT()); + InitializePrecacheResource(google.add_resource(), + "https://static.google.com/good", 0.9); + InitializePrecacheResource(google.add_resource(), + "https://static.google.com/low_confidence", 0.6); + InitializePrecacheResource(google.add_resource(), + "https://static.google.com/versionned_removed", + 0.8); + InitializePrecacheResource(google.add_resource(), + "https://static.google.com/unused_removed", 0.8); + InitializePrecacheResource(google.add_resource(), + "https://static.google.com/no_store", 0.8); + InitializeExperiment(&google, internal::kVersionedRemovedExperiment, + {true, true, false, true, true}); + InitializeExperiment(&google, internal::kUnusedRemovedExperiment, + {true, true, true, false, true}); + InitializeExperiment(&google, internal::kNoStoreRemovedExperiment, + {true, true, true, true, false}); + + // The data that's too old. + base::Time old_time = base::Time::Now() - base::TimeDelta::FromDays(7); + precache::PrecacheManifest facebook = + CreateManifestData(old_time.ToDoubleT()); + InitializePrecacheResource(facebook.add_resource(), + "https://static.facebook.com/good", 0.9); + + predictor_->manifest_table_cache_->insert({"google.com", google}); + predictor_->manifest_table_cache_->insert({"facebook.com", facebook}); + + std::vector<GURL> urls; + EXPECT_TRUE(predictor_->PopulateFromManifest("google.com", &urls)); + EXPECT_THAT(urls, + UnorderedElementsAre(GURL("https://static.google.com/good"))); + + urls.clear(); + EXPECT_FALSE(predictor_->PopulateFromManifest("facebook.com", &urls)); + EXPECT_TRUE(urls.empty()); + + urls.clear(); + EXPECT_FALSE(predictor_->PopulateFromManifest("404.com", &urls)); + EXPECT_TRUE(urls.empty()); +} + TEST_F(ResourcePrefetchPredictorTest, GetRedirectEndpoint) { // The data to be requested for the confident endpoint. RedirectData nyt = CreateRedirectData("http://nyt.com", 1); @@ -1827,8 +1891,19 @@ // No prefetch data. EXPECT_FALSE(predictor_->GetPrefetchData(main_frame_url, &prediction)); + // Add a manifest associated with the main frame host. + const std::string& resource_url = "https://static.google.com/resource"; + precache::PrecacheManifest manifest = + CreateManifestData(base::Time::Now().ToDoubleT()); + InitializePrecacheResource(manifest.add_resource(), resource_url, 0.9); + predictor_->manifest_table_cache_->insert({"google.com", manifest}); + + urls.clear(); + EXPECT_TRUE(predictor_->GetPrefetchData(main_frame_url, &prediction)); + EXPECT_THAT(urls, UnorderedElementsAre(GURL(resource_url))); + // Add a resource associated with the main frame host. - PrefetchData google_host = CreatePrefetchData("google.com", 1); + PrefetchData google_host = CreatePrefetchData("google.com", 2); const std::string script_url = "https://cdn.google.com/script.js"; InitializeResourceData(google_host.add_resources(), script_url, content::RESOURCE_TYPE_SCRIPT, 10, 0, 1, 2.1, @@ -1843,7 +1918,7 @@ // Add host-based redirect. RedirectData host_redirect = CreateRedirectData("google.com", 3); InitializeRedirectStat(host_redirect.add_redirect_endpoints(), - "www.google.com", 10, 0, 0); + "www.google.fr", 10, 0, 0); predictor_->host_redirect_table_cache_->insert( std::make_pair(host_redirect.primary_key(), host_redirect)); @@ -1852,7 +1927,7 @@ EXPECT_FALSE(predictor_->GetPrefetchData(main_frame_url, &prediction)); // Add a resource associated with host redirect endpoint. - PrefetchData www_google_host = CreatePrefetchData("www.google.com", 4); + PrefetchData www_google_host = CreatePrefetchData("www.google.fr", 4); const std::string style_url = "https://cdn.google.com/style.css"; InitializeResourceData(www_google_host.add_resources(), style_url, content::RESOURCE_TYPE_STYLESHEET, 10, 0, 1, 2.1, @@ -1866,7 +1941,7 @@ // Add a resource associated with the main frame url. PrefetchData google_url = - CreatePrefetchData("http://google.com/?query=cats", 2); + CreatePrefetchData("http://google.com/?query=cats", 5); const std::string image_url = "https://cdn.google.com/image.png"; InitializeResourceData(google_url.add_resources(), image_url, content::RESOURCE_TYPE_IMAGE, 10, 0, 1, 2.1, @@ -1880,7 +1955,7 @@ // Add url-based redirect. RedirectData url_redirect = - CreateRedirectData("http://google.com/?query=cats", 5); + CreateRedirectData("http://google.com/?query=cats", 6); InitializeRedirectStat(url_redirect.add_redirect_endpoints(), "https://www.google.com/?query=cats", 10, 0, 0); predictor_->url_redirect_table_cache_->insert( @@ -1894,7 +1969,7 @@ // Add a resource associated with url redirect endpoint. PrefetchData www_google_url = - CreatePrefetchData("https://www.google.com/?query=cats", 4); + CreatePrefetchData("https://www.google.com/?query=cats", 7); const std::string font_url = "https://cdn.google.com/comic-sans-ms.woff"; InitializeResourceData(www_google_url.add_resources(), font_url, content::RESOURCE_TYPE_FONT_RESOURCE, 10, 0, 1, 2.1,
diff --git a/chrome/browser/resources/settings/internet_page/network_summary.js b/chrome/browser/resources/settings/internet_page/network_summary.js index b2e8852..10ed729 100644 --- a/chrome/browser/resources/settings/internet_page/network_summary.js +++ b/chrome/browser/resources/settings/internet_page/network_summary.js
@@ -276,7 +276,7 @@ newDeviceStates[state.Type] = state; } } else { - newDeviceStates = this.deviceStates; + newDeviceStates = Object.assign({}, this.deviceStates); } // Clear any current networks.
diff --git a/chrome/browser/resources/settings/internet_page/network_summary_item.js b/chrome/browser/resources/settings/internet_page/network_summary_item.js index 0e0b204..55fb84b1 100644 --- a/chrome/browser/resources/settings/internet_page/network_summary_item.js +++ b/chrome/browser/resources/settings/internet_page/network_summary_item.js
@@ -64,8 +64,19 @@ var name = CrOnc.getNetworkName(network); if (state) return this.getConnectionStateText_(state, name); - if (this.deviceIsEnabled_(this.deviceState)) - return CrOncStrings.networkListItemNotConnected; + var deviceState = this.deviceState; + if (deviceState) { + if (deviceState.State == + chrome.networkingPrivate.DeviceStateType.ENABLING) { + return this.i18n('internetDeviceEnabling'); + } + if (deviceState.Type == CrOnc.Type.CELLULAR && + this.deviceState.Scanning) { + return this.i18n('internetMobileSearching'); + } + if (deviceState.State == chrome.networkingPrivate.DeviceStateType.ENABLED) + return CrOncStrings.networkListItemNotConnected; + } return this.i18n('deviceOff'); }, @@ -193,7 +204,8 @@ * @private */ showDetailsIsVisible_: function() { - return this.deviceIsEnabled_(this.deviceState); + return this.deviceIsEnabled_(this.deviceState) && + (!!this.activeNetworkState.GUID || this.networkStateList.length > 0); }, /**
diff --git a/chrome/browser/resources/settings/languages_page/languages.js b/chrome/browser/resources/settings/languages_page/languages.js index 40d9eb0..48f91f2e 100644 --- a/chrome/browser/resources/settings/languages_page/languages.js +++ b/chrome/browser/resources/settings/languages_page/languages.js
@@ -204,6 +204,8 @@ return; } + // TODO(dpapad): Cleanup this code. It uses results[3] and results[4] + // which only exist for ChromeOS. this.createModel_(results[1], results[2], results[3], results[4]); this.resolver_.resolve(); }.bind(this)); @@ -483,13 +485,13 @@ return this.resolver_.promise; }, +// <if expr="chromeos or is_win"> /** * Sets the prospective UI language to the chosen language. This won't affect * the actual UI language until a restart. * @param {string} languageCode */ setProspectiveUILanguage: function(languageCode) { - assert(cr.isChromeOS || cr.isWindows); chrome.send('setProspectiveUILanguage', [languageCode]); }, @@ -501,6 +503,7 @@ return this.originalProspectiveUILanguage_ != this.languages.prospectiveUILanguage; }, +// </if> /** * @param {string} languageCode @@ -726,18 +729,9 @@ return this.supportedLanguageMap_.get(languageCode); }, - /** - * @param {string} id - * @return {!chrome.languageSettingsPrivate.InputMethod|undefined} - */ - getInputMethod: function(id) { - assert(cr.isChromeOS); - return this.supportedInputMethodMap_.get(id); - }, - +// <if expr="chromeos"> /** @param {string} id */ addInputMethod: function(id) { - assert(cr.isChromeOS); if (!this.supportedInputMethodMap_.has(id)) return; this.languageSettingsPrivate.addInputMethod(id); @@ -745,7 +739,6 @@ /** @param {string} id */ removeInputMethod: function(id) { - assert(cr.isChromeOS); if (!this.supportedInputMethodMap_.has(id)) return; this.languageSettingsPrivate.removeInputMethod(id); @@ -753,7 +746,6 @@ /** @param {string} id */ setCurrentInputMethod: function(id) { - assert(cr.isChromeOS); this.inputMethodPrivate.setCurrentInputMethod(id); }, @@ -770,32 +762,28 @@ * @return {boolean} */ isComponentIme: function(inputMethod) { - assert(cr.isChromeOS); return inputMethod.id.startsWith('_comp_'); }, /** @param {string} id Input method ID. */ openInputMethodOptions: function(id) { - assert(cr.isChromeOS); this.inputMethodPrivate.openOptionsPage(id); }, /** @param {string} id New current input method ID. */ onInputMethodChanged_: function(id) { - assert(cr.isChromeOS); this.set('languages.inputMethods.currentId', id); }, /** @param {string} id Added input method ID. */ onInputMethodAdded_: function(id) { - assert(cr.isChromeOS); this.updateEnabledInputMethods_(); }, /** @param {string} id Removed input method ID. */ onInputMethodRemoved_: function(id) { - assert(cr.isChromeOS); this.updateEnabledInputMethods_(); }, +// </if> }); })();
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.js b/chrome/browser/resources/settings/languages_page/languages_page.js index a04ef195..97b058d 100644 --- a/chrome/browser/resources/settings/languages_page/languages_page.js +++ b/chrome/browser/resources/settings/languages_page/languages_page.js
@@ -42,12 +42,14 @@ /** @type {!LanguageHelper} */ languageHelper: Object, +// <if expr="not is_macosx"> /** @private */ spellCheckSecondaryText_: { type: String, value: '', computed: 'getSpellCheckSecondaryText_(languages.enabled.*)', }, +// </if> /** * The language to display the details for. @@ -80,24 +82,6 @@ }, /** - * Handler for enabling or disabling spell check. - * @param {!{target: Element, model: !{item: !LanguageState}}} e - */ - onSpellCheckChange_: function(e) { - var item = e.model.item; - if (!item.language.supportsSpellcheck) - return; - - this.languageHelper.toggleSpellCheck(item.language.code, - !item.spellCheckEnabled); - }, - - /** @private */ - onBackTap_: function() { - this.$.pages.back(); - }, - - /** * Stamps and opens the Add Languages dialog, registering a listener to * disable the dialog's dom-if again on close. * @param {!Event} e @@ -160,6 +144,87 @@ return this.languages.enabled.length <= 1; }, +// <if expr="chromeos"> + /** + * Applies Chrome OS session tweaks to the menu. + * @param {!CrActionMenuElement} menu + * @private + */ + tweakMenuForCrOS_: function(menu) { + // In a CrOS multi-user session, the primary user controls the UI language. + // TODO(michaelpg): The language selection should not be hidden, but should + // show a policy indicator. crbug.com/648498 + if (this.isSecondaryUser_()) + menu.querySelector('#uiLanguageItem').hidden = true; + + // The UI language choice doesn't persist for guests. + if (uiAccountTweaks.UIAccountTweaks.loggedInAsGuest() || + uiAccountTweaks.UIAccountTweaks.loggedInAsPublicAccount()) { + menu.querySelector('#uiLanguageItem').hidden = true; + } + }, + + /** + * Opens the Manage Input Methods page. + * @private + */ + onManageInputMethodsTap_: function() { + settings.navigateTo(settings.Route.INPUT_METHODS); + }, + + /** + * Handler for tap and <Enter> events on an input method on the main page, + * which sets it as the current input method. + * @param {!{model: !{item: !chrome.languageSettingsPrivate.InputMethod}, + * target: !{tagName: string}, + * type: string, + * key: (string|undefined)}} e + */ + onInputMethodTap_: function(e) { + // Taps on the paper-icon-button are handled in onInputMethodOptionsTap_. + if (e.target.tagName == 'PAPER-ICON-BUTTON') + return; + + // Ignore key presses other than <Enter>. + if (e.type == 'keypress' && e.key != 'Enter') + return; + + // Set the input method. + this.languageHelper.setCurrentInputMethod(e.model.item.id); + }, + + /** + * Opens the input method extension's options page in a new tab (or focuses + * an existing instance of the IME's options). + * @param {!{model: !{item: chrome.languageSettingsPrivate.InputMethod}}} e + * @private + */ + onInputMethodOptionsTap_: function(e) { + this.languageHelper.openInputMethodOptions(e.model.item.id); + }, +// </if> + +// <if expr="chromeos or is_win"> + /** + * @return {boolean} True for a secondary user in a multi-profile session. + * @private + */ + isSecondaryUser_: function() { + return cr.isChromeOS && loadTimeData.getBoolean('isSecondaryUser'); + }, + + /** + * @param {string} languageCode The language code identifying a language. + * @param {string} prospectiveUILanguage The prospective UI language. + * @return {boolean} True if the prospective UI language is set to + * |languageCode| but requires a restart to take effect. + * @private + */ + isRestartRequired_: function(languageCode, prospectiveUILanguage) { + return prospectiveUILanguage == languageCode && + this.languageHelper.requiresRestart(); + }, + /** * @param {!LanguageState} languageState * @param {string} prospectiveUILanguage The chosen UI language. @@ -186,14 +251,6 @@ }, /** - * @return {boolean} True for a secondary user in a multi-profile session. - * @private - */ - isSecondaryUser_: function() { - return cr.isChromeOS && loadTimeData.getBoolean('isSecondaryUser'); - }, - - /** * Handler for changes to the UI language checkbox. * @param {!{target: !PaperCheckboxElement}} e * @private @@ -207,6 +264,7 @@ this.closeMenuSoon_(); }, +// </if> /** * @param {!chrome.languageSettingsPrivate.Language} language @@ -286,49 +344,40 @@ this.languageHelper.disableLanguage(this.detailLanguage_.language.code); }, +// <if expr="chromeos or is_win"> /** - * Opens the Manage Input Methods page. + * Checks whether the prospective UI language (the pref that indicates what + * language to use in Chrome) matches the current language. This pref is used + * only on Chrome OS and Windows; we don't control the UI language elsewhere. + * @param {string} languageCode The language code identifying a language. + * @param {string} prospectiveUILanguage The prospective UI language. + * @return {boolean} True if the given language matches the prospective UI + * pref (which may be different from the actual UI language). * @private */ - onManageInputMethodsTap_: function() { - assert(cr.isChromeOS); - settings.navigateTo(settings.Route.INPUT_METHODS); + isProspectiveUILanguage_: function(languageCode, prospectiveUILanguage) { + return languageCode == prospectiveUILanguage; }, - /** - * Handler for tap and <Enter> events on an input method on the main page, - * which sets it as the current input method. - * @param {!{model: !{item: !chrome.languageSettingsPrivate.InputMethod}, - * target: !{tagName: string}, - * type: string, - * key: (string|undefined)}} e - */ - onInputMethodTap_: function(e) { - assert(cr.isChromeOS); - - // Taps on the paper-icon-button are handled in onInputMethodOptionsTap_. - if (e.target.tagName == 'PAPER-ICON-BUTTON') - return; - - // Ignore key presses other than <Enter>. - if (e.type == 'keypress' && e.key != 'Enter') - return; - - // Set the input method. - this.languageHelper.setCurrentInputMethod(e.model.item.id); + /** + * @param {string} prospectiveUILanguage + * @return {string} + * @private + */ + getProspectiveUILanguageName_: function(prospectiveUILanguage) { + return this.languageHelper.getLanguage(prospectiveUILanguage).displayName; }, +// </if> /** - * Opens the input method extension's options page in a new tab (or focuses - * an existing instance of the IME's options). - * @param {!{model: !{item: chrome.languageSettingsPrivate.InputMethod}}} e + * @return {string} * @private */ - onInputMethodOptionsTap_: function(e) { - assert(cr.isChromeOS); - this.languageHelper.openInputMethodOptions(e.model.item.id); + getLanguageListTwoLine_: function() { + return cr.isChromeOS || cr.isWindows ? 'two-line' : ''; }, +// <if expr="not is_macosx"> /** * Returns the secondary text for the spell check subsection based on the * enabled spell check languages, listing at most 2 languages. @@ -372,42 +421,20 @@ * @private */ onEditDictionaryTap_: function() { - assert(!cr.isMac); settings.navigateTo(settings.Route.EDIT_DICTIONARY); }, /** - * Checks whether the prospective UI language (the pref that indicates what - * language to use in Chrome) matches the current language. This pref is used - * only on Chrome OS and Windows; we don't control the UI language elsewhere. - * @param {string} languageCode The language code identifying a language. - * @param {string} prospectiveUILanguage The prospective UI language. - * @return {boolean} True if the given language matches the prospective UI - * pref (which may be different from the actual UI language). - * @private + * Handler for enabling or disabling spell check. + * @param {!{target: Element, model: !{item: !LanguageState}}} e */ - isProspectiveUILanguage_: function(languageCode, prospectiveUILanguage) { - assert(cr.isChromeOS || cr.isWindows); - return languageCode == prospectiveUILanguage; - }, + onSpellCheckChange_: function(e) { + var item = e.model.item; + if (!item.language.supportsSpellcheck) + return; -// <if expr="chromeos or is_win"> - /** - * @param {string} prospectiveUILanguage - * @return {string} - * @private - */ - getProspectiveUILanguageName_: function(prospectiveUILanguage) { - return this.languageHelper.getLanguage(prospectiveUILanguage).displayName; - }, -// </if> - - /** - * @return {string} - * @private - */ - getLanguageListTwoLine_: function() { - return cr.isChromeOS || cr.isWindows ? 'two-line' : ''; + this.languageHelper.toggleSpellCheck(item.language.code, + !item.spellCheckEnabled); }, /** @@ -417,6 +444,7 @@ getSpellCheckListTwoLine_: function() { return this.spellCheckSecondaryText_.length ? 'two-line' : ''; }, +// </if> /** * Returns either the "selected" class, if the language matches the @@ -435,18 +463,7 @@ return ''; }, - /** - * @param {string} languageCode The language code identifying a language. - * @param {string} prospectiveUILanguage The prospective UI language. - * @return {boolean} True if the prospective UI language is set to - * |languageCode| but requires a restart to take effect. - * @private - */ - isRestartRequired_: function(languageCode, prospectiveUILanguage) { - return prospectiveUILanguage == languageCode && - this.languageHelper.requiresRestart(); - }, - +// <if expr="chromeos"> /** * @param {string} id The input method ID. * @param {string} currentId The ID of the currently enabled input method. @@ -477,6 +494,7 @@ }); return inputMethod ? inputMethod.displayName : ''; }, +// </if> /** * @param {!Event} e @@ -494,33 +512,15 @@ this.$.menu.getIfExists()); if (!menu) { menu = /** @type {!CrActionMenuElement} */(this.$.menu.get()); - this.initializeMenu_(menu); +// <if expr="chromeos"> + this.tweakMenuForCrOS_(menu); +// </if> } menu.showAt(/** @type {!Element} */ (e.target)); }, /** - * Applies Chrome OS session tweaks to the menu. - * @param {!CrActionMenuElement} menu - * @private - */ - initializeMenu_: function(menu) { - // In a CrOS multi-user session, the primary user controls the UI language. - // TODO(michaelpg): The language selection should not be hidden, but should - // show a policy indicator. crbug.com/648498 - if (this.isSecondaryUser_()) - menu.querySelector('#uiLanguageItem').hidden = true; - - // The UI language choice doesn't persist for guests. - if (cr.isChromeOS && - (uiAccountTweaks.UIAccountTweaks.loggedInAsGuest() || - uiAccountTweaks.UIAccountTweaks.loggedInAsPublicAccount())) { - menu.querySelector('#uiLanguageItem').hidden = true; - } - }, - - /** * Closes the shared action menu after a short delay, so when a checkbox is * tapped it can be seen to change state before disappearing. * @private @@ -533,6 +533,7 @@ }, settings.kMenuCloseDelay); }, +// <if expr="chromeos or is_win"> /** * Handler for the restart button. * @private @@ -541,10 +542,11 @@ // <if expr="chromeos"> settings.LifetimeBrowserProxyImpl.getInstance().signOutAndRestart(); // </if> -// <if expr="not chromeos"> +// <if expr="is_win"> settings.LifetimeBrowserProxyImpl.getInstance().restart(); // </if> }, +// </if> /** * Toggles the expand button within the element being listened to.
diff --git a/chrome/browser/resources/settings/languages_page/languages_types.js b/chrome/browser/resources/settings/languages_page/languages_types.js index b4db7db..36d446f 100644 --- a/chrome/browser/resources/settings/languages_page/languages_types.js +++ b/chrome/browser/resources/settings/languages_page/languages_types.js
@@ -64,6 +64,7 @@ /** @return {!Promise} */ whenReady: assertNotReached, +// <if expr="chromeos or is_win"> /** * Sets the prospective UI language to the chosen language. This won't affect * the actual UI language until a restart. @@ -76,6 +77,7 @@ * @return {boolean} */ requiresRestart: assertNotReached, +// </if> /** * @param {string} languageCode @@ -159,12 +161,7 @@ */ getLanguage: assertNotReached, - /** - * @param {string} id - * @return {!chrome.languageSettingsPrivate.InputMethod|undefined} - */ - getInputMethod: assertNotReached, - +// <if expr="chromeos"> /** @param {string} id */ addInputMethod: assertNotReached, @@ -188,4 +185,5 @@ /** @param {string} id Input method ID. */ openInputMethodOptions: assertNotReached, +// </if> };
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index 92e1e9b..cf539f3c 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -648,8 +648,6 @@ behavior_options |= PROCESS_STARTUP; if (is_post_crash_launch) behavior_options |= IS_POST_CRASH_LAUNCH; - if (command_line_.HasSwitch(switches::kRestoreLastSession)) - behavior_options |= HAS_RESTORE_SWITCH; if (command_line_.HasSwitch(switches::kOpenInNewWindow)) behavior_options |= HAS_NEW_WINDOW_SWITCH; if (!cmd_line_tabs.empty()) @@ -883,8 +881,8 @@ if (pref.type == SessionStartupPref::LAST) { // Don't perform a session restore on a post-crash launch, as this could - // cause a crash loop. These checks can be overridden by a switch. - if (!(options & IS_POST_CRASH_LAUNCH) || (options & HAS_RESTORE_SWITCH)) + // cause a crash loop. + if (!(options & IS_POST_CRASH_LAUNCH)) return BrowserOpenBehavior::SYNCHRONOUS_RESTORE; }
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.h b/chrome/browser/ui/startup/startup_browser_creator_impl.h index 7094147..17aec3a 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.h +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.h
@@ -98,11 +98,10 @@ // Boolean flags used to indicate state for DetermineBrowserOpenBehavior. enum BehaviorFlags { - PROCESS_STARTUP = (1 << 0), - IS_POST_CRASH_LAUNCH = (1 << 1), - HAS_RESTORE_SWITCH = (1 << 2), - HAS_NEW_WINDOW_SWITCH = (1 << 3), - HAS_CMD_LINE_TABS = (1 << 4), + PROCESS_STARTUP = (1 << 0), + IS_POST_CRASH_LAUNCH = (1 << 1), + HAS_NEW_WINDOW_SWITCH = (1 << 2), + HAS_CMD_LINE_TABS = (1 << 3), }; using BrowserOpenBehaviorOptions = uint32_t;
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc b/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc index 5424ca2..5ebc37b 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl_unittest.cc
@@ -253,12 +253,6 @@ Creator::BrowserOpenBehavior output = Creator::DetermineBrowserOpenBehavior( pref_last, Creator::PROCESS_STARTUP | Creator::IS_POST_CRASH_LAUNCH); EXPECT_EQ(Creator::BrowserOpenBehavior::NEW, output); - - // Exception: this can be overridden by passing a switch. - output = Creator::DetermineBrowserOpenBehavior( - pref_last, Creator::PROCESS_STARTUP | Creator::IS_POST_CRASH_LAUNCH | - Creator::HAS_RESTORE_SWITCH); - EXPECT_EQ(Creator::BrowserOpenBehavior::SYNCHRONOUS_RESTORE, output); } TEST(StartupBrowserCreatorImplTest, DetermineBrowserOpenBehavior_NotStartup) {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 6fb0b37..9bb9be5 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -68,7 +68,6 @@ #include "extensions/common/extension.h" #include "extensions/common/extension_set.h" #include "ui/accessibility/ax_node_data.h" -#include "ui/base/dragdrop/drag_utils.h" #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/page_transition_types.h"
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container.cc b/chrome/browser/ui/views/toolbar/browser_actions_container.cc index 4b6ae91e..f2f57fd 100644 --- a/chrome/browser/ui/views/toolbar/browser_actions_container.cc +++ b/chrome/browser/ui/views/toolbar/browser_actions_container.cc
@@ -29,7 +29,6 @@ #include "extensions/common/feature_switch.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/accessibility/ax_node_data.h" -#include "ui/base/dragdrop/drag_utils.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/nine_image_painter_factory.h" #include "ui/base/resource/resource_bundle.h" @@ -522,10 +521,9 @@ ToolbarActionViewController* view_controller = (*it)->view_controller(); gfx::Size size(ToolbarActionsBar::IconWidth(false), ToolbarActionsBar::IconHeight()); - drag_utils::SetDragImageOnDataObject( + data->provider().SetDragImage( view_controller->GetIcon(GetCurrentWebContents(), size).AsImageSkia(), - press_pt.OffsetFromOrigin(), - data); + press_pt.OffsetFromOrigin()); // Fill in the remaining info. BrowserActionDragData drag_data(view_controller->GetId(), it - toolbar_action_views_.cbegin());
diff --git a/chrome/browser/ui/webui/settings/languages_handler.cc b/chrome/browser/ui/webui/settings/languages_handler.cc index d3b4595c..2f98827 100644 --- a/chrome/browser/ui/webui/settings/languages_handler.cc +++ b/chrome/browser/ui/webui/settings/languages_handler.cc
@@ -7,14 +7,11 @@ #include "base/bind.h" #include "base/values.h" #include "build/build_config.h" -#include "chrome/browser/profiles/profile.h" -#include "content/public/browser/web_ui.h" - -#if defined(OS_WIN) || defined(OS_CHROMEOS) #include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" -#endif +#include "content/public/browser/web_ui.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -44,7 +41,6 @@ void LanguagesHandler::HandleGetProspectiveUILanguage( const base::ListValue* args) { -#if defined(OS_WIN) || defined(OS_CHROMEOS) const base::Value* callback_id; CHECK(args->Get(0, &callback_id)); @@ -62,9 +58,6 @@ } ResolveJavascriptCallback(*callback_id, base::Value(locale)); -#else - NOTREACHED() << "Attempting to get locale on unsupported platform"; -#endif // defined(OS_WIN) || defined(OS_CHROMEOS) } void LanguagesHandler::HandleSetProspectiveUILanguage( @@ -89,8 +82,6 @@ profile_->ChangeAppLocale(language_code, Profile::APP_LOCALE_CHANGED_VIA_SETTINGS); } -#else - NOTREACHED() << "Attempting to set locale on unsupported platform"; #endif }
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 3d97561..d54278d 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -867,7 +867,9 @@ {"internetAddVPN", IDS_SETTINGS_INTERNET_ADD_VPN}, {"internetAddWiFi", IDS_SETTINGS_INTERNET_ADD_WIFI}, {"internetDetailPageTitle", IDS_SETTINGS_INTERNET_DETAIL}, + {"internetDeviceEnabling", IDS_SETTINGS_INTERNET_DEVICE_ENABLING}, {"internetKnownNetworksPageTitle", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS}, + {"internetMobileSearching", IDS_SETTINGS_INTERNET_MOBILE_SEARCH}, {"internetNoNetworks", IDS_SETTINGS_INTERNET_NO_NETWORKS}, {"internetPageTitle", IDS_SETTINGS_INTERNET}, {"internetToggleMobileA11yLabel",
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index fa30ab1..1e778ae 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/ui/webui/settings/downloads_handler.h" #include "chrome/browser/ui/webui/settings/extension_control_handler.h" #include "chrome/browser/ui/webui/settings/font_handler.h" -#include "chrome/browser/ui/webui/settings/languages_handler.h" #include "chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.h" #include "chrome/browser/ui/webui/settings/metrics_reporting_handler.h" #include "chrome/browser/ui/webui/settings/on_startup_handler.h" @@ -45,6 +44,10 @@ #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" +#if defined(OS_WIN) || defined(OS_CHROMEOS) +#include "chrome/browser/ui/webui/settings/languages_handler.h" +#endif // defined(OS_WIN) || defined(OS_CHROMEOS) + #if defined(OS_CHROMEOS) #include "ash/system/palette/palette_utils.h" #include "ash/system/power/power_status.h" @@ -109,7 +112,11 @@ AddSettingsPageUIHandler(base::MakeUnique<ExtensionControlHandler>()); AddSettingsPageUIHandler(base::MakeUnique<FontHandler>(web_ui)); AddSettingsPageUIHandler(base::MakeUnique<ImportDataHandler>()); + +#if defined(OS_WIN) || defined(OS_CHROMEOS) AddSettingsPageUIHandler(base::MakeUnique<LanguagesHandler>(web_ui)); +#endif // defined(OS_WIN) || defined(OS_CHROMEOS) + AddSettingsPageUIHandler( base::MakeUnique<MediaDevicesSelectionHandler>(profile)); #if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 3981bb5e..4633374 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -746,7 +746,10 @@ const char kRemoteDebuggingTargets[] = "remote-debugging-targets"; // Indicates the last session should be restored on startup. This overrides the -// preferences value. +// preferences value. Note that this does not force automatic session restore +// following a crash, so as to prevent a crash loop. This switch is used to +// implement support for OS-specific "continue where you left off" functionality +// on OS X and Windows. const char kRestoreLastSession[] = "restore-last-session"; // Disable saving pages as HTML-only, disable saving pages as HTML Complete
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 4797d5f3..2f0a982 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -210,6 +210,10 @@ 'JavascriptEnabledDriverTest.testChangeEventIsFiredAppropriatelyWhenFocusIsLost', 'TypingTest.testShouldBeAbleToTypeIntoEmptyContentEditableElement', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=922 + 'CorrectEventFiringTest.testShouldEmitOnClickEventsWhenSelectingElements', + 'CorrectEventFiringTest.testSendingKeysToAnotherElementShouldCauseTheBlurEventToFire', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1176 'ChromeDriverTests.clientLogShouldBeEnabledByDefault', @@ -245,6 +249,18 @@ 'BasicMouseInterfaceTest.testDraggingElementWithMouseMovesItToAnotherList', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=998 'ImplicitWaitTest.testShouldImplicitlyWaitForASingleElement', + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=922 + 'ClickTest.testCanClickOnAnElementWithTopSetToANegativeNumber', + 'CorrectEventFiringTest.testClickEventsShouldBubble', + 'CorrectEventFiringTest.testShouldFireMouseUpEventWhenClicking', + 'CorrectEventFiringTest.testShouldFireMouseDownEventWhenClicking', + 'CorrectEventFiringTest.testSendingKeysToAFocusedElementShouldNotBlurThatElement', + 'ImplicitWaitTest.testShouldImplicitlyWaitUntilAtLeastOneElementIsFoundWhenSearchingForMany', + 'ImplicitWaitTest.testShouldImplicitlyWaitForAnElementToBeVisibleBeforeInteracting', + 'JavascriptEnabledDriverTest.testShouldBeAbleToClickOnSubmitButtons', + 'JavascriptEnabledDriverTest.testIssue80ClickShouldGenerateClickEvent', + 'TypingTest.testShiftSelectionDeletes', + 'VisibilityTest.testShouldModifyTheVisibilityOfAnElementDynamically', ] ) _OS_NEGATIVE_FILTER['android:chromedriver_webview_shell'] = (
diff --git a/chrome/test/data/webui/settings/fingerprint_browsertest_chromeos.js b/chrome/test/data/webui/settings/fingerprint_browsertest_chromeos.js index 63708fe..ebd2f86e 100644 --- a/chrome/test/data/webui/settings/fingerprint_browsertest_chromeos.js +++ b/chrome/test/data/webui/settings/fingerprint_browsertest_chromeos.js
@@ -126,6 +126,7 @@ Polymer.dom.flush(); return browserProxy.whenCalled('getFingerprintsList').then(function() { assertEquals(0, fingerprintList.fingerprints_.length); + browserProxy.resetResolver('getFingerprintsList'); }); }); @@ -171,25 +172,33 @@ assertFalse(dialog.$.dialog.open); MockInteractions.tap(fingerprintList.$$('.action-button')); return browserProxy.whenCalled('startEnroll').then(function() { + browserProxy.resetResolver('startEnroll'); + assertTrue(dialog.$.dialog.open); assertEquals(0, dialog.receivedScanCount_); assertFalse(isVisible(addAnotherButton)); browserProxy.scanReceived(settings.FingerprintResultType.SUCCESS, true); assertEquals(settings.FingerprintSetupStep.READY, dialog.step_); - // Once the first fingerprint is enrolled, verify that enrolling the - // second fingerprint without closing the dialog works as expected. - return browserProxy.whenCalled('getFingerprintsList'); - }).then(function() { - assertEquals(1, fingerprintList.fingerprints_.length); assertTrue(dialog.$.dialog.open); assertTrue(isVisible(addAnotherButton)); MockInteractions.tap(addAnotherButton); - return browserProxy.whenCalled('startEnroll'); + + // Once the first fingerprint is enrolled, verify that enrolling the + // second fingerprint without closing the dialog works as expected. + return Promise.all([ + browserProxy.whenCalled('startEnroll'), + browserProxy.whenCalled('getFingerprintsList')]); }).then(function() { + browserProxy.resetResolver('getFingerprintsList'); + assertTrue(dialog.$.dialog.open); assertFalse(isVisible(addAnotherButton)); browserProxy.scanReceived(settings.FingerprintResultType.SUCCESS, true); + + // Verify that by tapping the continue button we should exit the dialog + // and the fingerprint list should have two fingerprints registered. + MockInteractions.tap(dialog.$.closeButton); return browserProxy.whenCalled('getFingerprintsList'); }).then(function() { assertEquals(2, fingerprintList.fingerprints_.length); @@ -221,6 +230,7 @@ fingerprintList.updateFingerprintsList_(); return browserProxy.whenCalled('getFingerprintsList').then(function() { + browserProxy.resetResolver('getFingerprintsList'); assertEquals(2, fingerprintList.fingerprints_.length); fingerprintList.onFingerprintDeleteTapped_(createFakeEvent(0)); @@ -257,6 +267,7 @@ // Verify that new fingerprints cannot be added when there are already five // registered fingerprints. return browserProxy.whenCalled('getFingerprintsList').then(function() { + browserProxy.resetResolver('getFingerprintsList'); assertEquals(5, fingerprintList.fingerprints_.length); assertTrue(fingerprintList.$$('.action-button').disabled); fingerprintList.onFingerprintDeleteTapped_(createFakeEvent(0));
diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc index 0a49f61..790fc4ff 100644 --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
@@ -166,7 +166,9 @@ new testing::ScopedSubresourceFilterFeatureToggle( base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationLevelEnabled, kActivationScopeActivationList, kActivationListSubresourceFilter)); - auto client = base::MakeUnique<MockSubresourceFilterClient>(); + // Note: Using NiceMock to allow uninteresting calls and suppress warnings. + auto client = + base::MakeUnique<::testing::NiceMock<MockSubresourceFilterClient>>(); ContentSubresourceFilterDriverFactory::CreateForWebContents( RenderViewHostTestHarness::web_contents(), std::move(client)); fake_safe_browsing_database_ = new FakeSafeBrowsingDatabaseManager();
diff --git a/content/browser/dom_storage/dom_storage_browsertest.cc b/content/browser/dom_storage/dom_storage_browsertest.cc index 8c4b7450..3a109c96 100644 --- a/content/browser/dom_storage/dom_storage_browsertest.cc +++ b/content/browser/dom_storage/dom_storage_browsertest.cc
@@ -98,7 +98,13 @@ SimpleTest(GetTestUrl("dom_storage", "verify_data.html"), kNotIncognito); } -IN_PROC_BROWSER_TEST_F(MojoDOMStorageBrowserTest, SanityCheck) { +// http://crbug.com/712872 All the mojo tests are flaky on Mac. +#if defined(OS_MACOSX) +#define MAYBE_SanityCheck DISABLED_SanityCheck +#else +#define MAYBE_SanityCheck SanityCheck +#endif +IN_PROC_BROWSER_TEST_F(MojoDOMStorageBrowserTest, MAYBE_SanityCheck) { SimpleTest(GetTestUrl("dom_storage", "sanity_check.html"), kNotIncognito); } @@ -112,6 +118,11 @@ Flush(); } +// http://crbug.com/712872 All the mojo tests are flaky on Mac. +#if defined(OS_MACOSX) +#undef MAYBE_DataPersists +#define MAYBE_DataPersists DISABLED_DataPersists +#endif IN_PROC_BROWSER_TEST_F(MojoDOMStorageBrowserTest, MAYBE_DataPersists) { SimpleTest(GetTestUrl("dom_storage", "verify_data.html"), kNotIncognito); } @@ -135,6 +146,9 @@ // http://crbug.com/654704 PRE_ tests aren't supported on Android. #if defined(OS_ANDROID) #define MAYBE_DataMigrates DISABLED_DataMigrates +#elif defined(OS_MACOSX) +// http://crbug.com/712872 All the mojo tests are flaky on Mac. +#define MAYBE_DataMigrates DISABLED_DataMigrates #else #define MAYBE_DataMigrates DataMigrates #endif
diff --git a/content/browser/download/mhtml_extra_parts_impl.cc b/content/browser/download/mhtml_extra_parts_impl.cc index 02ca159..c961477 100644 --- a/content/browser/download/mhtml_extra_parts_impl.cc +++ b/content/browser/download/mhtml_extra_parts_impl.cc
@@ -11,6 +11,13 @@ namespace content { +MHTMLExtraDataPart::MHTMLExtraDataPart() = default; + +MHTMLExtraDataPart::~MHTMLExtraDataPart() = default; + +MHTMLExtraDataPart::MHTMLExtraDataPart(const MHTMLExtraDataPart& other) = + default; + MHTMLExtraPartsImpl::MHTMLExtraPartsImpl() = default; MHTMLExtraPartsImpl::~MHTMLExtraPartsImpl() = default; @@ -37,10 +44,12 @@ void MHTMLExtraPartsImpl::AddExtraMHTMLPart(const std::string& content_type, const std::string& content_location, + const std::string& extra_headers, const std::string& body) { MHTMLExtraDataPart part; part.content_type = content_type; part.content_location = content_location; + part.extra_headers = extra_headers; part.body = body; // Add this part to the list of parts to be saved out when the file is
diff --git a/content/browser/download/mhtml_extra_parts_impl.h b/content/browser/download/mhtml_extra_parts_impl.h index d1879dc..ef890ddf 100644 --- a/content/browser/download/mhtml_extra_parts_impl.h +++ b/content/browser/download/mhtml_extra_parts_impl.h
@@ -13,7 +13,12 @@ struct MHTMLExtraDataPart { std::string content_type; std::string content_location; + std::string extra_headers; std::string body; + + MHTMLExtraDataPart(); + ~MHTMLExtraDataPart(); + MHTMLExtraDataPart(const MHTMLExtraDataPart& other); }; // Class used as a data object for WebContents UserData to represent an MHTML @@ -36,6 +41,7 @@ // Creates a MHTMLExtraDataPart and adds it to our vector of parts. void AddExtraMHTMLPart(const std::string& content_type, const std::string& content_location, + const std::string& extra_headers, const std::string& body) override; private:
diff --git a/content/browser/download/mhtml_generation_browsertest.cc b/content/browser/download/mhtml_generation_browsertest.cc index 343e386..3f99ffb7 100644 --- a/content/browser/download/mhtml_generation_browsertest.cc +++ b/content/browser/download/mhtml_generation_browsertest.cc
@@ -687,15 +687,16 @@ // Place the extra data we need into the web contents user data. std::string content_type(kFakeContentType); std::string content_location(kFakeContentLocation); + std::string extra_headers; // Get the MHTMLExtraParts MHTMLExtraParts* extra_parts = MHTMLExtraParts::FromWebContents(shell()->web_contents()); // Add two extra data parts to the MHTML. - extra_parts->AddExtraMHTMLPart(content_type, content_location, + extra_parts->AddExtraMHTMLPart(content_type, content_location, extra_headers, kFakeSignalData1); - extra_parts->AddExtraMHTMLPart(content_type, content_location, + extra_parts->AddExtraMHTMLPart(content_type, content_location, extra_headers, kFakeSignalData2); EXPECT_EQ(extra_parts->size(), 2); GenerateMHTML(params, url);
diff --git a/content/browser/download/mhtml_generation_manager.cc b/content/browser/download/mhtml_generation_manager.cc index 91392ce9..001d30d 100644 --- a/content/browser/download/mhtml_generation_manager.cc +++ b/content/browser/download/mhtml_generation_manager.cc
@@ -487,12 +487,13 @@ // For each extra part, serialize that part and add to our accumulator // string. for (auto part : extra_data_parts) { - // Write a newline, then a boundary, another newline, then the content - // location, another newline, the content type, another newline, the another - // newline, the extra data string, and end with a newline. + // Write a newline, then a boundary, a newline, then the content + // location, a newline, the content type, a newline, extra_headers, + // two newlines, the body, and end with a newline. std::string serialized_extra_data_part = base::StringPrintf( - "--%s\r\n%s%s\r\n%s%s\r\n%s\r\n", boundary.c_str(), kContentLocation, - part.content_location.c_str(), kContentType, part.content_type.c_str(), + "--%s\r\n%s%s\r\n%s%s\r\n%s\r\n\r\n%s\r\n", boundary.c_str(), + kContentLocation, part.content_location.c_str(), kContentType, + part.content_type.c_str(), part.extra_headers.c_str(), part.body.c_str()); DCHECK(base::IsStringASCII(serialized_extra_data_part));
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index cf60f55..0f264ed 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -722,9 +722,7 @@ } if (IsSchemeSupportedForAppCache(common_params_.url)) { - RenderFrameHostImpl* render_frame_host = - frame_tree_node_->render_manager()->GetFrameHostForNavigation(*this); - if (render_frame_host->GetRenderViewHost() + if (navigating_frame_host->GetRenderViewHost() ->GetWebkitPreferences() .application_cache_enabled) { navigation_handle_->InitAppCacheHandle(
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index 68481ad24..a2a0fe1 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -61,7 +61,6 @@ #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/custom_data_helper.h" #include "ui/base/dragdrop/drag_drop_types.h" -#include "ui/base/dragdrop/drag_utils.h" #include "ui/base/dragdrop/drop_target_event.h" #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/dragdrop/os_exchange_data_provider_factory.h" @@ -974,7 +973,7 @@ std::move(provider)); // takes ownership of |provider|. if (!image.isNull()) - drag_utils::SetDragImageOnDataObject(image, image_offset, &data); + data.provider().SetDragImage(image, image_offset); std::unique_ptr<WebDragSourceAura> drag_source( new WebDragSourceAura(GetNativeView(), web_contents_));
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index 8100d6d..f7cfe7be 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -45,6 +45,9 @@ ], "service_manager:service_factory": [ "service_manager::mojom::ServiceFactory" + ], + "utility": [ + "memory_instrumentation::mojom::Coordinator" ] }, "requires": {
diff --git a/content/public/app/mojo/content_utility_manifest.json b/content/public/app/mojo/content_utility_manifest.json index 310936a..0a058d7 100644 --- a/content/public/app/mojo/content_utility_manifest.json +++ b/content/public/app/mojo/content_utility_manifest.json
@@ -14,6 +14,7 @@ ] }, "requires": { + "content_browser": [ "utility" ], "device": [ "device:power_monitor", "device:time_zone_monitor"
diff --git a/content/public/browser/mhtml_extra_parts.h b/content/public/browser/mhtml_extra_parts.h index 53cfb39..69cad1f 100644 --- a/content/public/browser/mhtml_extra_parts.h +++ b/content/public/browser/mhtml_extra_parts.h
@@ -24,6 +24,7 @@ // use the body provided. virtual void AddExtraMHTMLPart(const std::string& content_type, const std::string& content_location, + const std::string& extra_headers, const std::string& body) = 0; // Returns the number of extra parts added.
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index c32c1cb1..e639f32 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -46,7 +46,7 @@ # canvas.commit() promise synchronization isn't fully reliable yet. self.Fail('conformance/offscreencanvas/offscreencanvas-resize.html', - bug=709484) + bug=709484) self.Fail('conformance2/rendering/depth-stencil-feedback-loop.html', bug=660844) # WebGL 2.0.1 @@ -58,6 +58,14 @@ self.Fail('conformance/textures/misc/tex-sub-image-2d-bad-args.html', bug=625738) + self.Fail('conformance/glsl/misc/uninitialized-local-global-variables.html', + bug=1966) # angle bug ID + + self.Fail('conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html', + bug=712584) + self.Fail('conformance2/extensions/ext-color-buffer-float.html', + bug=712584) + # Windows only. self.Fail('conformance2/rendering/blitframebuffer-outside-readbuffer.html', ['win', 'd3d11'], bug=644740) @@ -701,6 +709,10 @@ ['linux', 'amd', 'intel'], bug=662644) # WebGL 2.0.1 # Linux NVIDIA + self.Fail('conformance2/textures/canvas_sub_rectangle/' + + 'tex-2d-r32f-red-float.html', + ['linux', 'nvidia'], bug=713127) + # This test is flaky both with and without ANGLE. self.Flaky('deqp/functional/gles3/texturespecification/' + 'random_teximage2d_2d.html', @@ -738,8 +750,6 @@ ['linux', ('nvidia', 0x1cb3)], bug=709320) # Linux Intel - self.Fail('conformance2/extensions/ext-color-buffer-float.html', - ['linux', 'intel'], bug=640389) self.Fail('WebglExtension_EXT_disjoint_timer_query_webgl2', ['linux', 'intel'], bug=687210) @@ -1009,8 +1019,6 @@ ['linux', 'amd', 'no_angle'], bug=483282) self.Fail('conformance2/textures/misc/tex-unpack-params.html', ['linux', 'amd', 'no_angle'], bug=483282) - self.Fail('conformance2/extensions/ext-color-buffer-float.html', - ['linux', 'amd'], bug=633022) self.Fail('conformance2/rendering/blitframebuffer-filter-outofbounds.html', ['linux', 'amd'], bug=655147)
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index a314343..e18a62f 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -103,7 +103,10 @@ # canvas.commit() promise synchronization isn't fully reliable yet. self.Fail('conformance/offscreencanvas/offscreencanvas-resize.html', - bug=709484) + bug=709484) + + self.Fail('conformance/glsl/misc/uninitialized-local-global-variables.html', + bug=1966) # angle bug ID # Passthrough command decoder self.Fail('conformance/extensions/ext-sRGB.html',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_revision.txt b/content/test/gpu/gpu_tests/webgl_conformance_revision.txt index 62564a4..57413a2d 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_revision.txt +++ b/content/test/gpu/gpu_tests/webgl_conformance_revision.txt
@@ -1,3 +1,3 @@ # AUTOGENERATED FILE - DO NOT EDIT # SEE roll_webgl_conformance.py -Current webgl revision fd73a606f94d1837eba4d165f1f5b3afd542fc08 +Current webgl revision 73fd432435e8a8563f2117737c7639331761bddd
diff --git a/device/vr/openvr/openvr_device.cc b/device/vr/openvr/openvr_device.cc index 0ced4955..f129d977 100644 --- a/device/vr/openvr/openvr_device.cc +++ b/device/vr/openvr/openvr_device.cc
@@ -33,6 +33,45 @@ return out; } +std::string GetOpenVRString(vr::IVRSystem* vr_system, + vr::TrackedDeviceProperty prop) { + std::string out; + + vr::TrackedPropertyError error = vr::TrackedProp_Success; + char openvr_string[vr::k_unMaxPropertyStringSize]; + vr_system->GetStringTrackedDeviceProperty( + vr::k_unTrackedDeviceIndex_Hmd, prop, openvr_string, + vr::k_unMaxPropertyStringSize, &error); + + if (error == vr::TrackedProp_Success) + out = openvr_string; + + return out; +} + +std::vector<float> HmdMatrix34ToWebVRTransformMatrix( + const vr::HmdMatrix34_t& mat) { + std::vector<float> transform; + transform.resize(16); + transform[0] = mat.m[0][0]; + transform[1] = mat.m[1][0]; + transform[2] = mat.m[2][0]; + transform[3] = 0.0f; + transform[4] = mat.m[0][1]; + transform[5] = mat.m[1][1]; + transform[6] = mat.m[2][1]; + transform[7] = 0.0f; + transform[8] = mat.m[0][2]; + transform[9] = mat.m[1][2]; + transform[10] = mat.m[2][2]; + transform[11] = 0.0f; + transform[12] = mat.m[0][3]; + transform[13] = mat.m[1][3]; + transform[14] = mat.m[2][3]; + transform[15] = 1.0f; + return transform; +} + } // namespace namespace device { @@ -54,6 +93,9 @@ mojom::VRDisplayInfoPtr device = mojom::VRDisplayInfo::New(); device->index = id(); + device->displayName = + GetOpenVRString(vr_system, vr::Prop_ManufacturerName_String) + " " + + GetOpenVRString(vr_system, vr::Prop_ModelNumber_String); device->capabilities = mojom::VRDisplayCapabilities::New(); device->capabilities->hasPosition = true; device->capabilities->hasExternalDisplay = true; @@ -90,6 +132,21 @@ right_eye->renderWidth = left_eye->renderWidth; right_eye->renderHeight = left_eye->renderHeight; + device->stageParameters = mojom::VRStageParameters::New(); + vr::HmdMatrix34_t mat = + vr_system->GetSeatedZeroPoseToStandingAbsoluteTrackingPose(); + device->stageParameters->standingTransform = + HmdMatrix34ToWebVRTransformMatrix(mat); + + vr::IVRChaperone* chaperone = vr::VRChaperone(); + if (chaperone) { + chaperone->GetPlayAreaSize(&device->stageParameters->sizeX, + &device->stageParameters->sizeZ); + } else { + device->stageParameters->sizeX = 0.0f; + device->stageParameters->sizeZ = 0.0f; + } + render_loop_ = std::make_unique<OpenVRRenderLoop>(vr_system); on_created.Run(std::move(device));
diff --git a/docs/adding_to_third_party.md b/docs/adding_to_third_party.md index 745e7598..512c621 100644 --- a/docs/adding_to_third_party.md +++ b/docs/adding_to_third_party.md
@@ -65,8 +65,8 @@ * `src/tools/licenses.py scan` - This will complain about incomplete or missing data for third_party checkins. We use 'licenses.py credits' to generate the about:credits page in Google Chrome builds. -* `src/tools/checklicenses/checklicenses.py` - See below for info how to handle - possible failures. +* `src/tools/checklicenses/checklicenses.py` - See below for info on how to + handle possible failures. * If you are adding code that will be present in the content layer, please make sure that the license used is compliant with Android tree requirements because this code will also be used in Android WebView. You need to run
diff --git a/extensions/browser/updater/extension_downloader.cc b/extensions/browser/updater/extension_downloader.cc index b3e084a..17982851 100644 --- a/extensions/browser/updater/extension_downloader.cc +++ b/extensions/browser/updater/extension_downloader.cc
@@ -489,18 +489,20 @@ net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DISABLE_CACHE); - // Send traffic-management headers. + // Send traffic-management headers to the webstore. // https://bugs.chromium.org/p/chromium/issues/detail?id=647516 - manifest_fetcher_->AddExtraRequestHeader(base::StringPrintf( - "%s: %s", kUpdateInteractivityHeader, - active_request->foreground_check() ? kUpdateInteractivityForeground - : kUpdateInteractivityBackground)); - manifest_fetcher_->AddExtraRequestHeader( - base::StringPrintf("%s: %s", kUpdateAppIdHeader, id_list.c_str())); - manifest_fetcher_->AddExtraRequestHeader(base::StringPrintf( - "%s: %s-%s", kUpdateUpdaterHeader, - UpdateQueryParams::GetProdIdString(UpdateQueryParams::CRX), - UpdateQueryParams::GetProdVersion().c_str())); + if (extension_urls::IsWebstoreUpdateUrl(active_request->full_url())) { + manifest_fetcher_->AddExtraRequestHeader(base::StringPrintf( + "%s: %s", kUpdateInteractivityHeader, + active_request->foreground_check() ? kUpdateInteractivityForeground + : kUpdateInteractivityBackground)); + manifest_fetcher_->AddExtraRequestHeader( + base::StringPrintf("%s: %s", kUpdateAppIdHeader, id_list.c_str())); + manifest_fetcher_->AddExtraRequestHeader(base::StringPrintf( + "%s: %s-%s", kUpdateUpdaterHeader, + UpdateQueryParams::GetProdIdString(UpdateQueryParams::CRX), + UpdateQueryParams::GetProdVersion().c_str())); + } // Update checks can be interrupted if a network change is detected; this is // common for the retail mode AppPack on ChromeOS. Retrying once should be
diff --git a/headless/lib/browser/headless_devtools_client_impl.cc b/headless/lib/browser/headless_devtools_client_impl.cc index ca315fa..9cb9de77 100644 --- a/headless/lib/browser/headless_devtools_client_impl.cc +++ b/headless/lib/browser/headless_devtools_client_impl.cc
@@ -31,7 +31,9 @@ HeadlessDevToolsClientImpl::HeadlessDevToolsClientImpl() : agent_host_(nullptr), + raw_protocol_listener_(nullptr), next_message_id_(0), + next_raw_message_id_(1), renderer_crashed_(false), accessibility_domain_(this), animation_domain_(this), @@ -95,10 +97,47 @@ pending_messages_.clear(); } +void HeadlessDevToolsClientImpl::SetRawProtocolListener( + RawProtocolListener* raw_protocol_listener) { + raw_protocol_listener_ = raw_protocol_listener; +} + +int HeadlessDevToolsClientImpl::GetNextRawDevToolsMessageId() { + int id = next_raw_message_id_; + next_raw_message_id_ += 2; + return id; +} + +void HeadlessDevToolsClientImpl::SendRawDevToolsMessage( + const std::string& json_message) { +#ifndef NDEBUG + std::unique_ptr<base::Value> message = + base::JSONReader::Read(json_message, base::JSON_PARSE_RFC); + const base::DictionaryValue* message_dict; + int id = 0; + if (!message || !message->GetAsDictionary(&message_dict) || + !message_dict->GetInteger("id", &id)) { + NOTREACHED() << "Badly formed message"; + return; + } + DCHECK_EQ((id % 2), 1) << "Raw devtools messages must have an odd ID."; +#endif + + agent_host_->DispatchProtocolMessage(this, json_message); +} + +void HeadlessDevToolsClientImpl::SendRawDevToolsMessage( + const base::DictionaryValue& message) { + std::string json_message; + base::JSONWriter::Write(message, &json_message); + SendRawDevToolsMessage(json_message); +} + void HeadlessDevToolsClientImpl::DispatchProtocolMessage( content::DevToolsAgentHost* agent_host, const std::string& json_message) { DCHECK_EQ(agent_host_, agent_host); + std::unique_ptr<base::Value> message = base::JSONReader::Read(json_message, base::JSON_PARSE_RFC); const base::DictionaryValue* message_dict; @@ -106,6 +145,13 @@ NOTREACHED() << "Badly formed reply"; return; } + + if (raw_protocol_listener_ && + raw_protocol_listener_->OnProtocolMessage(agent_host->GetId(), + json_message, *message_dict)) { + return; + } + if (!DispatchMessageReply(*message_dict) && !DispatchEvent(std::move(message), *message_dict)) { DLOG(ERROR) << "Unhandled protocol message: " << json_message; @@ -314,7 +360,8 @@ if (renderer_crashed_) return; DCHECK(agent_host_); - int id = next_message_id_++; + int id = next_message_id_; + next_message_id_ += 2; // We only send even numbered messages. message->SetInteger("id", id); std::string json_message; base::JSONWriter::Write(*message, &json_message);
diff --git a/headless/lib/browser/headless_devtools_client_impl.h b/headless/lib/browser/headless_devtools_client_impl.h index c7c248b..1b17967 100644 --- a/headless/lib/browser/headless_devtools_client_impl.h +++ b/headless/lib/browser/headless_devtools_client_impl.h
@@ -93,6 +93,11 @@ service_worker::Domain* GetServiceWorker() override; target::Domain* GetTarget() override; tracing::Domain* GetTracing() override; + void SetRawProtocolListener( + RawProtocolListener* raw_protocol_listener) override; + int GetNextRawDevToolsMessageId() override; + void SendRawDevToolsMessage(const std::string& json_message) override; + void SendRawDevToolsMessage(const base::DictionaryValue& message) override; // content::DevToolstAgentHostClient implementation: void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host, @@ -151,8 +156,10 @@ const EventHandler* event_handler, const base::DictionaryValue* result_dict); - content::DevToolsAgentHost* agent_host_; // Not owned. + content::DevToolsAgentHost* agent_host_; // Not owned. + RawProtocolListener* raw_protocol_listener_; // Not owned. int next_message_id_; + int next_raw_message_id_; std::unordered_map<int, Callback> pending_messages_; EventHandlerMap event_handlers_;
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc index ad43eb9..aea5aef 100644 --- a/headless/lib/browser/headless_web_contents_impl.cc +++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -213,6 +213,35 @@ service.service_factory, browser()->BrowserMainThread()); } + + std::string devtools_agent_host_id = + content::DevToolsAgentHost::GetOrCreateFor(render_frame_host)->GetId(); + render_frame_host_to_devtools_agent_host_id_[render_frame_host] = + devtools_agent_host_id; + devtools_agent_id_to_frame_tree_node_id_[devtools_agent_host_id] = + render_frame_host->GetFrameTreeNodeId(); +} + +void HeadlessWebContentsImpl::RenderFrameDeleted( + content::RenderFrameHost* render_frame_host) { + auto find_it = + render_frame_host_to_devtools_agent_host_id_.find(render_frame_host); + if (find_it == render_frame_host_to_devtools_agent_host_id_.end()) + return; + + devtools_agent_id_to_frame_tree_node_id_.erase(find_it->second); + render_frame_host_to_devtools_agent_host_id_.erase(find_it); +} + +bool HeadlessWebContentsImpl::GetFrameTreeNodeIdForDevToolsAgentHostId( + const std::string& devtools_agent_host_id, + int* frame_tree_node_id) const { + const auto& find_it = + devtools_agent_id_to_frame_tree_node_id_.find(devtools_agent_host_id); + if (find_it == devtools_agent_id_to_frame_tree_node_id_.end()) + return false; + *frame_tree_node_id = find_it->second; + return true; } bool HeadlessWebContentsImpl::OpenURL(const GURL& url) {
diff --git a/headless/lib/browser/headless_web_contents_impl.h b/headless/lib/browser/headless_web_contents_impl.h index 3d6377d..1dd6c6d6 100644 --- a/headless/lib/browser/headless_web_contents_impl.h +++ b/headless/lib/browser/headless_web_contents_impl.h
@@ -55,6 +55,9 @@ void RemoveObserver(Observer* observer) override; HeadlessDevToolsTarget* GetDevToolsTarget() override; HeadlessTabSocket* GetHeadlessTabSocket() const override; + bool GetFrameTreeNodeIdForDevToolsAgentHostId( + const std::string& devtools_agent_host_id, + int* frame_tree_node_id) const override; // HeadlessDevToolsTarget implementation: bool AttachClient(HeadlessDevToolsClient* client) override; @@ -70,6 +73,7 @@ // content::WebContentsObserver implementation: void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; + void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; content::WebContents* web_contents() const; bool OpenURL(const GURL& url); @@ -96,6 +100,10 @@ void InitializeScreen(const gfx::Size& initial_size); using MojoService = HeadlessWebContents::Builder::MojoService; + std::unordered_map<content::RenderFrameHost*, std::string> + render_frame_host_to_devtools_agent_host_id_; + std::unordered_map<std::string, int> devtools_agent_id_to_frame_tree_node_id_; + class Delegate; std::unique_ptr<Delegate> web_contents_delegate_; std::unique_ptr<HeadlessWindowTreeHost> window_tree_host_;
diff --git a/headless/lib/headless_devtools_client_browsertest.cc b/headless/lib/headless_devtools_client_browsertest.cc index bc67e65d..dd4474b 100644 --- a/headless/lib/headless_devtools_client_browsertest.cc +++ b/headless/lib/headless_devtools_client_browsertest.cc
@@ -987,4 +987,39 @@ HEADLESS_ASYNC_DEVTOOLED_TEST_F(DevToolsHeaderStrippingTest); +class RawDevtoolsProtocolTest + : public HeadlessAsyncDevTooledBrowserTest, + public HeadlessDevToolsClient::RawProtocolListener { + public: + void RunDevTooledTest() override { + devtools_client_->SetRawProtocolListener(this); + + base::DictionaryValue message; + message.SetInteger("id", devtools_client_->GetNextRawDevToolsMessageId()); + message.SetString("method", "Runtime.evaluate"); + std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue()); + params->SetString("expression", "1+1"); + message.Set("params", std::move(params)); + devtools_client_->SendRawDevToolsMessage(message); + } + + bool OnProtocolMessage(const std::string& devtools_agent_host_id, + const std::string& json_message, + const base::DictionaryValue& parsed_message) override { + EXPECT_EQ( + "{\"id\":1,\"result\":{\"result\":{\"type\":\"number\"," + "\"value\":2,\"description\":\"2\"}}}", + json_message); + + int frame_tree_node_id = 0; + EXPECT_TRUE(web_contents_->GetFrameTreeNodeIdForDevToolsAgentHostId( + devtools_agent_host_id, &frame_tree_node_id)); + EXPECT_NE(0, frame_tree_node_id); + FinishAsynchronousTest(); + return true; + } +}; + +HEADLESS_ASYNC_DEVTOOLED_TEST_F(RawDevtoolsProtocolTest); + } // namespace headless
diff --git a/headless/public/headless_devtools_client.h b/headless/public/headless_devtools_client.h index 573336a..7e7d979 100644 --- a/headless/public/headless_devtools_client.h +++ b/headless/public/headless_devtools_client.h
@@ -146,6 +146,31 @@ virtual target::Domain* GetTarget() = 0; virtual tracing::Domain* GetTracing() = 0; + class HEADLESS_EXPORT RawProtocolListener { + public: + RawProtocolListener() {} + virtual ~RawProtocolListener() {} + + // Returns true if the listener handled the message. + virtual bool OnProtocolMessage( + const std::string& devtools_agent_host_id, + const std::string& json_message, + const base::DictionaryValue& parsed_message) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(RawProtocolListener); + }; + + virtual void SetRawProtocolListener( + RawProtocolListener* raw_protocol_listener) = 0; + + // Generates an odd numbered ID. + virtual int GetNextRawDevToolsMessageId() = 0; + + // The id within the message must be odd to prevent collisions. + virtual void SendRawDevToolsMessage(const std::string& json_message) = 0; + virtual void SendRawDevToolsMessage(const base::DictionaryValue& message) = 0; + // TODO(skyostil): Add notification for disconnection. private:
diff --git a/headless/public/headless_web_contents.h b/headless/public/headless_web_contents.h index bbae478..031045f0 100644 --- a/headless/public/headless_web_contents.h +++ b/headless/public/headless_web_contents.h
@@ -75,6 +75,12 @@ // Returns the headless tab socket for JS -> C++ if one was created. virtual HeadlessTabSocket* GetHeadlessTabSocket() const = 0; + // Returns the frame tree node id associated with the |devtools_agent_host_id| + // if any. + virtual bool GetFrameTreeNodeIdForDevToolsAgentHostId( + const std::string& devtools_agent_host_id, + int* frame_tree_node_id) const = 0; + private: friend class HeadlessWebContentsImpl; HeadlessWebContents() {}
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm index 3b5ecee..191d4938 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -144,7 +144,7 @@ GURL ntpUrl = GURL(kChromeUINewTabURL); Tab* currentTab = [[browserViewInformation currentTabModel] currentTab]; - if (currentTab && [currentTab url] == ntpUrl) { + if (currentTab && currentTab.lastCommittedURL == ntpUrl) { startupInformation.firstUserActionRecorder->RecordStartOnNTP(); [startupInformation resetFirstUserActionRecorder]; } else {
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index d3fc692..8d13fe4 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -293,6 +293,7 @@ "//components/content_settings/core/browser", "//components/content_settings/core/common", "//components/strings", + "//components/version_info:version_info", "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/browser_state",
diff --git a/ios/chrome/browser/web/visible_url_egtest.mm b/ios/chrome/browser/web/visible_url_egtest.mm index 364fb65..290aa57 100644 --- a/ios/chrome/browser/web/visible_url_egtest.mm +++ b/ios/chrome/browser/web/visible_url_egtest.mm
@@ -7,6 +7,11 @@ #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "components/version_info/version_info.h" +#include "ios/chrome/browser/chrome_url_constants.h" +#import "ios/chrome/browser/ui/commands/generic_chrome_command.h" +#include "ios/chrome/browser/ui/commands/ios_command_ids.h" #include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/test/app/chrome_test_util.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" @@ -498,6 +503,38 @@ assertWithMatcher:grey_notNil()]; } +// Tests that visible URL is always the same as last committed URL if user +// issues 2 go forward commands to WebUI page (crbug.com/711465). +- (void)testDoubleForwardNavigationToWebUIPage { + // Create 3rd entry in the history, to be able to go back twice. + GURL URL(kChromeUIVersionURL); + [ChromeEarlGrey loadURL:GURL(kChromeUIVersionURL)]; + + // Tap the back button twice in the toolbar and wait for URL 1 to load. + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:WebViewContainingText(kTestPage1)] + assertWithMatcher:grey_notNil()]; + + // Quickly (using chrome command) navigate forward twice and wait for + // kChromeUIVersionURL to load. + base::scoped_nsobject<GenericChromeCommand> forwardCommand( + [[GenericChromeCommand alloc] initWithTag:IDC_FORWARD]); + chrome_test_util::RunCommandWithActiveViewController(forwardCommand); + chrome_test_util::RunCommandWithActiveViewController(forwardCommand); + + const std::string version = version_info::GetVersionNumber(); + [[EarlGrey selectElementWithMatcher:WebViewContainingText(version)] + assertWithMatcher:grey_notNil()]; + + // Make sure that kChromeUIVersionURL URL is displayed in the omnibox. + std::string expectedText = base::UTF16ToUTF8(web::GetDisplayTitleForUrl(URL)); + [[EarlGrey selectElementWithMatcher:OmniboxText(expectedText)] + assertWithMatcher:grey_notNil()]; +} + // Tests that visible URL is always the same as last committed URL if page calls // window.history.back() twice. - (void)testDoubleBackJSNavigation {
diff --git a/ios/chrome/search_widget_extension/BUILD.gn b/ios/chrome/search_widget_extension/BUILD.gn index 80a585f..4b63249 100644 --- a/ios/chrome/search_widget_extension/BUILD.gn +++ b/ios/chrome/search_widget_extension/BUILD.gn
@@ -20,6 +20,21 @@ } ios_appex_bundle("search_widget_extension") { + deps = [ + ":search_widget", + ] + + extra_substitutions = [ + "CHROME_CHANNEL_SCHEME=$url_channel_scheme", + "CHROMIUM_SHORT_NAME=$chromium_short_name", + "WIDGET_EXTENSION_BUNDLE_ID=$chromium_bundle_id.SearchTodayExtension", + ] + + entitlements_target = ":entitlements" + info_plist_target = ":tweak_info_plist" +} + +source_set("search_widget") { sources = [ "search_widget_view.h", "search_widget_view.mm", @@ -30,17 +45,7 @@ deps = [ "//base", "//components/open_from_clipboard:open_from_clipboard_impl", - "//components/prefs", - "//components/variations", - "//components/version_info", - "//ios/chrome/common", "//ios/chrome/common/app_group", - "//ios/chrome/common/app_group:client", - "//ios/chrome/common/physical_web", - "//ios/chrome/today_extension/strings", - "//ios/third_party/material_components_ios", - "//net", - "//ui/base", ] libs = [ @@ -49,14 +54,17 @@ "UIKit.framework", ] - extra_substitutions = [ - "CHROME_CHANNEL_SCHEME=$url_channel_scheme", - "CHROMIUM_SHORT_NAME=$chromium_short_name", - "WIDGET_EXTENSION_BUNDLE_ID=$chromium_bundle_id.SearchTodayExtension", - ] - configs += [ "//build/config/compiler:enable_arc" ] +} - entitlements_target = ":entitlements" - info_plist_target = ":tweak_info_plist" +source_set("unit_tests") { + testonly = true + sources = [ + "search_widget_view_controller_unittest.mm", + ] + deps = [ + ":search_widget", + "//testing/gtest", + ] + configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/chrome/search_widget_extension/search_widget_view_controller_unittest.mm b/ios/chrome/search_widget_extension/search_widget_view_controller_unittest.mm new file mode 100644 index 0000000..e4823b5 --- /dev/null +++ b/ios/chrome/search_widget_extension/search_widget_view_controller_unittest.mm
@@ -0,0 +1,21 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/search_widget_extension/search_widget_view_controller.h" + +#import "ios/chrome/search_widget_extension/search_widget_view_controller.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using SearchWidgetViewControllerTest = PlatformTest; + +TEST_F(SearchWidgetViewControllerTest, Alloc) { + SearchWidgetViewController* controller = + [[SearchWidgetViewController alloc] init]; + ASSERT_NE(controller, nil); +}
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 2f986dd..ebe9c3e 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -189,6 +189,7 @@ "//ios/chrome/browser/web_resource:unit_tests", "//ios/chrome/browser/web_state_list:unit_tests", "//ios/chrome/common:unit_tests", + "//ios/chrome/search_widget_extension:unit_tests", "//ios/chrome/test/base:unit_tests", "//ios/shared/chrome/browser/ui/browser_list:unit_tests", "//ios/shared/chrome/browser/ui/commands:unit_tests",
diff --git a/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn b/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn index 6f271877..4f11f72f 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tab_grid/BUILD.gn
@@ -27,6 +27,7 @@ "//ios/shared/chrome/browser/ui/browser_list", "//ios/shared/chrome/browser/ui/commands", "//ios/shared/chrome/browser/ui/coordinators", + "//ios/shared/chrome/browser/ui/tools_menu", "//ios/web", "//net", "//ui/base",
diff --git a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm index be61ce7..e0fbd35 100644 --- a/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
@@ -20,6 +20,7 @@ #import "ios/shared/chrome/browser/ui/browser_list/browser.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" +#import "ios/shared/chrome/browser/ui/tools_menu/tools_menu_configuration.h" #import "ios/web/public/navigation_manager.h" #include "ios/web/public/web_state/web_state.h" #import "net/base/mac/url_conversions.h" @@ -141,6 +142,10 @@ - (void)showToolsMenu { ToolsCoordinator* toolsCoordinator = [[ToolsCoordinator alloc] init]; [self addChildCoordinator:toolsCoordinator]; + ToolsMenuConfiguration* menuConfiguration = + [[ToolsMenuConfiguration alloc] initWithDisplayView:nil]; + menuConfiguration.inTabSwitcher = YES; + toolsCoordinator.toolsMenuConfiguration = menuConfiguration; [toolsCoordinator start]; self.toolsMenuCoordinator = toolsCoordinator; }
diff --git a/ios/clean/chrome/browser/ui/toolbar/BUILD.gn b/ios/clean/chrome/browser/ui/toolbar/BUILD.gn index 5718cc1d0a..7669b66 100644 --- a/ios/clean/chrome/browser/ui/toolbar/BUILD.gn +++ b/ios/clean/chrome/browser/ui/toolbar/BUILD.gn
@@ -21,6 +21,7 @@ "//ios/shared/chrome/browser/ui/browser_list", "//ios/shared/chrome/browser/ui/commands", "//ios/shared/chrome/browser/ui/coordinators", + "//ios/shared/chrome/browser/ui/tools_menu", "//ios/web", ] }
diff --git a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm index c6743ce..b995e24 100644 --- a/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm +++ b/ios/clean/chrome/browser/ui/toolbar/toolbar_coordinator.mm
@@ -12,6 +12,7 @@ #import "ios/shared/chrome/browser/ui/browser_list/browser.h" #import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator+internal.h" +#import "ios/shared/chrome/browser/ui/tools_menu/tools_menu_configuration.h" #import "ios/web/public/navigation_manager.h" #include "ios/web/public/web_state/web_state.h" @@ -100,6 +101,10 @@ - (void)showToolsMenu { ToolsCoordinator* toolsCoordinator = [[ToolsCoordinator alloc] init]; [self addChildCoordinator:toolsCoordinator]; + ToolsMenuConfiguration* menuConfiguration = + [[ToolsMenuConfiguration alloc] initWithDisplayView:nil]; + menuConfiguration.inTabSwitcher = NO; + toolsCoordinator.toolsMenuConfiguration = menuConfiguration; [toolsCoordinator start]; self.toolsMenuCoordinator = toolsCoordinator; }
diff --git a/ios/clean/chrome/browser/ui/tools/BUILD.gn b/ios/clean/chrome/browser/ui/tools/BUILD.gn index beee4a94..d13cffd 100644 --- a/ios/clean/chrome/browser/ui/tools/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tools/BUILD.gn
@@ -20,6 +20,7 @@ "//ios/clean/chrome/browser/ui/presenters", "//ios/shared/chrome/browser/ui/browser_list", "//ios/shared/chrome/browser/ui/coordinators", + "//ios/shared/chrome/browser/ui/tools_menu", ] } @@ -62,6 +63,7 @@ ":tools_ui", "//base/test:test_support", "//ios/chrome/test/base", + "//ios/shared/chrome/browser/ui/tools_menu", "//testing/gtest", "//third_party/ocmock", ]
diff --git a/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm b/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm index 0c2940a5..3810f1c 100644 --- a/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm +++ b/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm
@@ -29,12 +29,14 @@ @property(nonatomic, strong) NSArray<ToolsMenuItem*>* menuItems; @property(nonatomic, strong) MenuOverflowControlsStackView* toolbarOverflowStackView; +@property(nonatomic, assign) BOOL displayOverflowControls; @end @implementation MenuViewController @synthesize dispatcher = _dispatcher; @synthesize menuItems = _menuItems; @synthesize toolbarOverflowStackView = _toolbarOverflowStackView; +@synthesize displayOverflowControls = _displayOverflowControls; - (void)loadView { CGRect frame; @@ -79,7 +81,8 @@ // Stack view to hold overflow ToolbarButtons. if (self.traitCollection.horizontalSizeClass == - UIUserInterfaceSizeClassCompact) { + UIUserInterfaceSizeClassCompact && + self.displayOverflowControls) { self.toolbarOverflowStackView = [[MenuOverflowControlsStackView alloc] init]; // PLACEHOLDER: ToolsMenuButton might end up being part of the MenuVC's view @@ -122,4 +125,8 @@ _menuItems = menuItems; } +- (void)displayOverflowControls:(BOOL)displayOverflowControls { + self.displayOverflowControls = displayOverflowControls; +} + @end
diff --git a/ios/clean/chrome/browser/ui/tools/tools_consumer.h b/ios/clean/chrome/browser/ui/tools/tools_consumer.h index f2df6bf5..7855f90 100644 --- a/ios/clean/chrome/browser/ui/tools/tools_consumer.h +++ b/ios/clean/chrome/browser/ui/tools/tools_consumer.h
@@ -14,6 +14,9 @@ // final and might change depending on how ToolsMenuVC model is set up. // Sets the Tools Menu items. - (void)setToolsMenuItems:(NSArray*)menuItems; +// Sets a flag so the consumer knows if it should display the Menu overflow +// controls. +- (void)setDisplayOverflowControls:(BOOL)displayOverflowControls; @end #endif // IOS_CLEAN_CHROME_BROWSER_UI_TOOLS_TOOLS_CONSUMER_H_
diff --git a/ios/clean/chrome/browser/ui/tools/tools_coordinator.h b/ios/clean/chrome/browser/ui/tools/tools_coordinator.h index fc585225..457392d6 100644 --- a/ios/clean/chrome/browser/ui/tools/tools_coordinator.h +++ b/ios/clean/chrome/browser/ui/tools/tools_coordinator.h
@@ -7,9 +7,12 @@ #import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h" +@class ToolsMenuConfiguration; + // Coordinator that shows an inteface for the user to select a // tool or action to use. @interface ToolsCoordinator : BrowserCoordinator +@property(nonatomic, strong) ToolsMenuConfiguration* toolsMenuConfiguration; @end #endif // IOS_CLEAN_CHROME_BROWSER_UI_TOOLS_TOOLS_COORDINATOR_H_
diff --git a/ios/clean/chrome/browser/ui/tools/tools_coordinator.mm b/ios/clean/chrome/browser/ui/tools/tools_coordinator.mm index d7f7c52..5e13f6d4 100644 --- a/ios/clean/chrome/browser/ui/tools/tools_coordinator.mm +++ b/ios/clean/chrome/browser/ui/tools/tools_coordinator.mm
@@ -22,6 +22,7 @@ @implementation ToolsCoordinator @synthesize viewController = _viewController; @synthesize mediator = _mediator; +@synthesize toolsMenuConfiguration = _toolsMenuConfiguration; #pragma mark - BrowserCoordinator @@ -30,7 +31,9 @@ self.viewController.modalPresentationStyle = UIModalPresentationCustom; self.viewController.transitioningDelegate = self; self.viewController.dispatcher = static_cast<id>(self.browser->dispatcher()); - self.mediator = [[ToolsMediator alloc] initWithConsumer:self.viewController]; + self.mediator = + [[ToolsMediator alloc] initWithConsumer:self.viewController + andConfiguration:self.toolsMenuConfiguration]; [super start]; }
diff --git a/ios/clean/chrome/browser/ui/tools/tools_mediator.h b/ios/clean/chrome/browser/ui/tools/tools_mediator.h index a879db4..d13f54d9 100644 --- a/ios/clean/chrome/browser/ui/tools/tools_mediator.h +++ b/ios/clean/chrome/browser/ui/tools/tools_mediator.h
@@ -8,11 +8,13 @@ #import <Foundation/Foundation.h> @protocol ToolsConsumer; +@class ToolsMenuConfiguration; // A mediator object that sets a ToolsMenuVC appeareance based on various data // sources. @interface ToolsMediator : NSObject - (instancetype)initWithConsumer:(id<ToolsConsumer>)consumer + andConfiguration:(ToolsMenuConfiguration*)menuConfiguration NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; @end
diff --git a/ios/clean/chrome/browser/ui/tools/tools_mediator.mm b/ios/clean/chrome/browser/ui/tools/tools_mediator.mm index bc38c242..a7e17da3 100644 --- a/ios/clean/chrome/browser/ui/tools/tools_mediator.mm +++ b/ios/clean/chrome/browser/ui/tools/tools_mediator.mm
@@ -8,6 +8,7 @@ #import "ios/clean/chrome/browser/ui/tools/tools_actions.h" #import "ios/clean/chrome/browser/ui/tools/tools_consumer.h" #import "ios/clean/chrome/browser/ui/tools/tools_menu_item.h" +#import "ios/shared/chrome/browser/ui/tools_menu/tools_menu_configuration.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -15,15 +16,19 @@ @interface ToolsMediator () @property(nonatomic, strong) id<ToolsConsumer> consumer; +@property(nonatomic, strong) ToolsMenuConfiguration* toolsMenuConfiguration; @end @implementation ToolsMediator @synthesize consumer = _consumer; +@synthesize toolsMenuConfiguration = _toolsMenuConfiguration; -- (instancetype)initWithConsumer:(id<ToolsConsumer>)consumer { +- (instancetype)initWithConsumer:(id<ToolsConsumer>)consumer + andConfiguration:(ToolsMenuConfiguration*)menuConfiguration { self = [super init]; if (self) { + self.toolsMenuConfiguration = menuConfiguration; self.consumer = consumer; } return self; @@ -68,6 +73,8 @@ menuItems[10].title = @"Help"; [_consumer setToolsMenuItems:menuItems]; + [_consumer + setDisplayOverflowControls:!self.toolsMenuConfiguration.isInTabSwitcher]; } @end
diff --git a/ios/clean/chrome/browser/ui/tools/tools_mediator_unittest.mm b/ios/clean/chrome/browser/ui/tools/tools_mediator_unittest.mm index 5329a2f..ca08ce0 100644 --- a/ios/clean/chrome/browser/ui/tools/tools_mediator_unittest.mm +++ b/ios/clean/chrome/browser/ui/tools/tools_mediator_unittest.mm
@@ -5,6 +5,7 @@ #import "ios/clean/chrome/browser/ui/tools/tools_mediator.h" #import "ios/clean/chrome/browser/ui/tools/tools_consumer.h" +#import "ios/shared/chrome/browser/ui/tools_menu/tools_menu_configuration.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h" #include "third_party/ocmock/gtest_support.h" @@ -22,9 +23,14 @@ TEST_F(ToolsMediatorTest, TestSetConsumer) { id consumer = OCMProtocolMock(@protocol(ToolsConsumer)); - mediator_ = [[ToolsMediator alloc] initWithConsumer:consumer]; + id configuration = OCMClassMock([ToolsMenuConfiguration class]); + OCMStub([configuration isInTabSwitcher]).andReturn(YES); + + mediator_ = [[ToolsMediator alloc] initWithConsumer:consumer + andConfiguration:configuration]; [[consumer verify] setToolsMenuItems:[OCMArg any]]; + [[consumer verify] setDisplayOverflowControls:NO]; } } // namespace
diff --git a/ios/showcase/BUILD.gn b/ios/showcase/BUILD.gn index c8832832..f361a1e 100644 --- a/ios/showcase/BUILD.gn +++ b/ios/showcase/BUILD.gn
@@ -25,6 +25,7 @@ group("features") { deps = [ + "//ios/chrome/search_widget_extension:search_widget", "//ios/clean/chrome/browser/ui/tools:tools_ui", "//ios/showcase/content_suggestions", "//ios/showcase/ntp",
diff --git a/ios/showcase/core/showcase_model.mm b/ios/showcase/core/showcase_model.mm index ee7d3da..ded20c1 100644 --- a/ios/showcase/core/showcase_model.mm +++ b/ios/showcase/core/showcase_model.mm
@@ -81,6 +81,11 @@ showcase::kClassForInstantiationKey : @"UIKitTableViewCellViewController", showcase::kUseCaseKey : @"UIKit Table Cells", }, + @{ + showcase::kClassForDisplayKey : @"SearchWidgetViewController", + showcase::kClassForInstantiationKey : @"SearchWidgetViewController", + showcase::kUseCaseKey : @"Search Widget", + }, ]; }
diff --git a/ios/web/navigation/crw_session_controller.h b/ios/web/navigation/crw_session_controller.h index 4ed7a98..301f3e3 100644 --- a/ios/web/navigation/crw_session_controller.h +++ b/ios/web/navigation/crw_session_controller.h
@@ -134,7 +134,8 @@ - (void)copyStateFromSessionControllerAndPrune:(CRWSessionController*)source; // Sets |lastCommittedItemIndex| to the |index| if it's in the entries bounds. -- (void)goToItemAtIndex:(NSInteger)index; +// Discards pending and transient entries if |discard| is YES. +- (void)goToItemAtIndex:(NSInteger)index discardNonCommittedItems:(BOOL)discard; // Removes the item at |index| after discarding any noncomitted entries. // |index| must not be the index of the last committed item, or a noncomitted
diff --git a/ios/web/navigation/crw_session_controller.mm b/ios/web/navigation/crw_session_controller.mm index cf5175e1..58d095a8 100644 --- a/ios/web/navigation/crw_session_controller.mm +++ b/ios/web/navigation/crw_session_controller.mm
@@ -541,21 +541,26 @@ self.items.size()); } -- (void)goToItemAtIndex:(NSInteger)index { +- (void)goToItemAtIndex:(NSInteger)index + discardNonCommittedItems:(BOOL)discard { if (index < 0 || static_cast<NSUInteger>(index) >= self.items.size()) return; - if (index < _lastCommittedItemIndex) { - // Going back. - [self discardNonCommittedItems]; - } else if (_lastCommittedItemIndex < index) { - // Going forward. - [self discardTransientItem]; - } else { - // |delta| is 0, no need to change the last committed item index. + if (index == _lastCommittedItemIndex) { + // |delta| is 0, no need to change current navigation index. return; } + if (discard) { + if (index < _lastCommittedItemIndex) { + // Going back. + [self discardNonCommittedItems]; + } else if (_lastCommittedItemIndex < index) { + // Going forward. + [self discardTransientItem]; + } + } + _previousItemIndex = _lastCommittedItemIndex; _lastCommittedItemIndex = index; }
diff --git a/ios/web/navigation/crw_session_controller_unittest.mm b/ios/web/navigation/crw_session_controller_unittest.mm index 6e7eb988..b23a26b 100644 --- a/ios/web/navigation/crw_session_controller_unittest.mm +++ b/ios/web/navigation/crw_session_controller_unittest.mm
@@ -372,7 +372,7 @@ [session_controller_ commitPendingItem]; // Go back to the first item. - [session_controller_ goToItemAtIndex:0]; + [session_controller_ goToItemAtIndex:0 discardNonCommittedItems:NO]; // Create and commit a new pending item. [session_controller_ @@ -416,7 +416,7 @@ ASSERT_EQ(3U, [session_controller_ items].size()); // Go to the middle, and commit first pending item index. - [session_controller_ goToItemAtIndex:1]; + [session_controller_ goToItemAtIndex:1 discardNonCommittedItems:NO]; [session_controller_ setPendingItemIndex:0]; ASSERT_EQ(0, [session_controller_ pendingItemIndex]); web::NavigationItem* pending_item = [session_controller_ pendingItem]; @@ -824,16 +824,16 @@ EXPECT_EQ(session_controller_.get().previousItemIndex, 1); - [session_controller_ goToItemAtIndex:1]; + [session_controller_ goToItemAtIndex:1 discardNonCommittedItems:NO]; EXPECT_EQ(session_controller_.get().previousItemIndex, 2); - [session_controller_ goToItemAtIndex:0]; + [session_controller_ goToItemAtIndex:0 discardNonCommittedItems:NO]; EXPECT_EQ(session_controller_.get().previousItemIndex, 1); - [session_controller_ goToItemAtIndex:1]; + [session_controller_ goToItemAtIndex:1 discardNonCommittedItems:NO]; EXPECT_EQ(session_controller_.get().previousItemIndex, 0); - [session_controller_ goToItemAtIndex:2]; + [session_controller_ goToItemAtIndex:2 discardNonCommittedItems:NO]; EXPECT_EQ(session_controller_.get().previousItemIndex, 1); } @@ -999,11 +999,11 @@ EXPECT_TRUE([session_controller_ forwardItems].empty()); EXPECT_EQ("http://www.example.com/redirect", backItems[0]->GetURL().spec()); - [session_controller_ goToItemAtIndex:1]; + [session_controller_ goToItemAtIndex:1 discardNonCommittedItems:NO]; EXPECT_EQ(1U, [session_controller_ backwardItems].size()); EXPECT_EQ(1U, [session_controller_ forwardItems].size()); - [session_controller_ goToItemAtIndex:0]; + [session_controller_ goToItemAtIndex:0 discardNonCommittedItems:NO]; web::NavigationItemList forwardItems = [session_controller_ forwardItems]; EXPECT_EQ(0U, [session_controller_ backwardItems].size()); EXPECT_EQ(2U, forwardItems.size()); @@ -1052,8 +1052,20 @@ EXPECT_TRUE([session_controller_ pendingItem]); EXPECT_TRUE([session_controller_ transientItem]); + // Going back and forth without discaring transient and pending items. + [session_controller_ goToItemAtIndex:1 discardNonCommittedItems:NO]; + EXPECT_EQ(1, session_controller_.get().lastCommittedItemIndex); + EXPECT_EQ(3, session_controller_.get().previousItemIndex); + EXPECT_TRUE(session_controller_.get().pendingItem); + EXPECT_TRUE(session_controller_.get().transientItem); + [session_controller_ goToItemAtIndex:3 discardNonCommittedItems:NO]; + EXPECT_EQ(3, session_controller_.get().lastCommittedItemIndex); + EXPECT_EQ(1, session_controller_.get().previousItemIndex); + EXPECT_TRUE(session_controller_.get().pendingItem); + EXPECT_TRUE(session_controller_.get().transientItem); + // Going back should discard transient and pending items. - [session_controller_ goToItemAtIndex:1]; + [session_controller_ goToItemAtIndex:1 discardNonCommittedItems:YES]; EXPECT_EQ(1, session_controller_.get().lastCommittedItemIndex); EXPECT_EQ(3, session_controller_.get().previousItemIndex); EXPECT_FALSE(session_controller_.get().pendingItem); @@ -1062,21 +1074,22 @@ // Going forward should discard transient item. [session_controller_ addTransientItemWithURL:GURL("http://www.example.com")]; EXPECT_TRUE(session_controller_.get().transientItem); - [session_controller_ goToItemAtIndex:2]; + [session_controller_ goToItemAtIndex:2 discardNonCommittedItems:YES]; EXPECT_EQ(2, session_controller_.get().lastCommittedItemIndex); EXPECT_EQ(1, session_controller_.get().previousItemIndex); EXPECT_FALSE(session_controller_.get().transientItem); // Out of bounds navigations should be no-op. - [session_controller_ goToItemAtIndex:-1]; + [session_controller_ goToItemAtIndex:-1 discardNonCommittedItems:NO]; EXPECT_EQ(2, session_controller_.get().lastCommittedItemIndex); EXPECT_EQ(1, session_controller_.get().previousItemIndex); - [session_controller_ goToItemAtIndex:NSIntegerMax]; + [session_controller_ goToItemAtIndex:NSIntegerMax + discardNonCommittedItems:NO]; EXPECT_EQ(2, session_controller_.get().lastCommittedItemIndex); EXPECT_EQ(1, session_controller_.get().previousItemIndex); // Going to current index should not change the previous index. - [session_controller_ goToItemAtIndex:2]; + [session_controller_ goToItemAtIndex:2 discardNonCommittedItems:NO]; EXPECT_EQ(2, session_controller_.get().lastCommittedItemIndex); EXPECT_EQ(1, session_controller_.get().previousItemIndex); }
diff --git a/ios/web/navigation/navigation_manager_impl_unittest.mm b/ios/web/navigation/navigation_manager_impl_unittest.mm index 3035b93..21e319e 100644 --- a/ios/web/navigation/navigation_manager_impl_unittest.mm +++ b/ios/web/navigation/navigation_manager_impl_unittest.mm
@@ -176,15 +176,15 @@ EXPECT_TRUE(navigation_manager()->CanGoBack()); EXPECT_TRUE(navigation_manager()->CanGoToOffset(-1)); - [session_controller() goToItemAtIndex:1]; + [session_controller() goToItemAtIndex:1 discardNonCommittedItems:NO]; EXPECT_TRUE(navigation_manager()->CanGoBack()); EXPECT_TRUE(navigation_manager()->CanGoToOffset(-1)); - [session_controller() goToItemAtIndex:0]; + [session_controller() goToItemAtIndex:0 discardNonCommittedItems:NO]; EXPECT_FALSE(navigation_manager()->CanGoBack()); EXPECT_FALSE(navigation_manager()->CanGoToOffset(-1)); - [session_controller() goToItemAtIndex:1]; + [session_controller() goToItemAtIndex:1 discardNonCommittedItems:NO]; EXPECT_TRUE(navigation_manager()->CanGoBack()); EXPECT_TRUE(navigation_manager()->CanGoToOffset(-1)); } @@ -230,19 +230,19 @@ EXPECT_FALSE(navigation_manager()->CanGoForward()); EXPECT_FALSE(navigation_manager()->CanGoToOffset(1)); - [session_controller() goToItemAtIndex:1]; + [session_controller() goToItemAtIndex:1 discardNonCommittedItems:NO]; EXPECT_TRUE(navigation_manager()->CanGoForward()); EXPECT_TRUE(navigation_manager()->CanGoToOffset(1)); - [session_controller() goToItemAtIndex:0]; + [session_controller() goToItemAtIndex:0 discardNonCommittedItems:NO]; EXPECT_TRUE(navigation_manager()->CanGoForward()); EXPECT_TRUE(navigation_manager()->CanGoToOffset(1)); - [session_controller() goToItemAtIndex:1]; + [session_controller() goToItemAtIndex:1 discardNonCommittedItems:NO]; EXPECT_TRUE(navigation_manager()->CanGoForward()); EXPECT_TRUE(navigation_manager()->CanGoToOffset(1)); - [session_controller() goToItemAtIndex:2]; + [session_controller() goToItemAtIndex:2 discardNonCommittedItems:NO]; EXPECT_FALSE(navigation_manager()->CanGoForward()); EXPECT_FALSE(navigation_manager()->CanGoToOffset(1)); } @@ -282,7 +282,7 @@ ASSERT_EQ(4, navigation_manager()->GetLastCommittedItemIndex()); // Go to entry at index 1 and test API from that state. - [session_controller() goToItemAtIndex:1]; + [session_controller() goToItemAtIndex:1 discardNonCommittedItems:NO]; ASSERT_EQ(1, navigation_manager()->GetLastCommittedItemIndex()); ASSERT_EQ(-1, navigation_manager()->GetPendingItemIndex()); EXPECT_FALSE(navigation_manager()->CanGoToOffset(-1)); @@ -306,7 +306,7 @@ EXPECT_EQ(1000000002, navigation_manager()->GetIndexForOffset(1000000000)); // Go to entry at index 2 and test API from that state. - [session_controller() goToItemAtIndex:2]; + [session_controller() goToItemAtIndex:2 discardNonCommittedItems:NO]; ASSERT_EQ(2, navigation_manager()->GetLastCommittedItemIndex()); ASSERT_EQ(-1, navigation_manager()->GetPendingItemIndex()); EXPECT_TRUE(navigation_manager()->CanGoToOffset(-1)); @@ -328,7 +328,7 @@ EXPECT_EQ(1000000003, navigation_manager()->GetIndexForOffset(1000000000)); // Go to entry at index 4 and test API from that state. - [session_controller() goToItemAtIndex:4]; + [session_controller() goToItemAtIndex:4 discardNonCommittedItems:NO]; ASSERT_EQ(4, navigation_manager()->GetLastCommittedItemIndex()); ASSERT_EQ(-1, navigation_manager()->GetPendingItemIndex()); EXPECT_TRUE(navigation_manager()->CanGoToOffset(-1)); @@ -424,7 +424,7 @@ EXPECT_EQ(1000000003, navigation_manager()->GetIndexForOffset(1000000000)); // Set pending index to 4 and committed entry to 1 and test. - [session_controller() goToItemAtIndex:1]; + [session_controller() goToItemAtIndex:1 discardNonCommittedItems:NO]; [session_controller() setPendingItemIndex:4]; ASSERT_EQ(1, navigation_manager()->GetLastCommittedItemIndex()); ASSERT_EQ(4, navigation_manager()->GetPendingItemIndex()); @@ -447,7 +447,7 @@ EXPECT_EQ(1000000004, navigation_manager()->GetIndexForOffset(1000000000)); // Test with existing transient entry in the end of the stack. - [session_controller() goToItemAtIndex:4]; + [session_controller() goToItemAtIndex:4 discardNonCommittedItems:NO]; [session_controller() setPendingItemIndex:-1]; [session_controller() addTransientItemWithURL:GURL("http://www.url.com")]; ASSERT_EQ(5, navigation_manager()->GetItemCount()); @@ -506,7 +506,7 @@ // Now go forward to that middle transient item (pending index is 1, // current index is 0). - [session_controller() goToItemAtIndex:0]; + [session_controller() goToItemAtIndex:0 discardNonCommittedItems:NO]; [session_controller() setPendingItemIndex:1]; ASSERT_EQ(3, navigation_manager()->GetItemCount()); ASSERT_EQ(0, navigation_manager()->GetLastCommittedItemIndex()); @@ -1159,7 +1159,7 @@ web::NavigationManager::UserAgentOverrideOption::INHERIT); [session_controller() commitPendingItem]; - [session_controller() goToItemAtIndex:1]; + [session_controller() goToItemAtIndex:1 discardNonCommittedItems:NO]; EXPECT_EQ(1, navigation_manager()->GetLastCommittedItemIndex()); navigation_manager()->Reload(web::ReloadType::NORMAL, @@ -1287,7 +1287,7 @@ web::NavigationManager::UserAgentOverrideOption::INHERIT); [session_controller() commitPendingItem]; - [session_controller() goToItemAtIndex:1]; + [session_controller() goToItemAtIndex:1 discardNonCommittedItems:NO]; EXPECT_EQ(1, navigation_manager()->GetLastCommittedItemIndex()); navigation_manager()->Reload(web::ReloadType::ORIGINAL_REQUEST_URL,
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index fec250d..703e210 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -619,10 +619,11 @@ // events. Navigation is considered complete when the document has finished // loading, or when other page load mechanics are completed on a // non-document-changing URL change. -- (void)didFinishNavigation; +- (void)didFinishNavigation:(WKNavigation*)navigation; // Update the appropriate parts of the model and broadcast to the embedder. This // may be called multiple times and thus must be idempotent. -- (void)loadCompleteWithSuccess:(BOOL)loadSuccess; +- (void)loadCompleteWithSuccess:(BOOL)loadSuccess + forNavigation:(WKNavigation*)navigation; // Called after URL is finished loading and _loadPhase is set to PAGE_LOADED. - (void)didFinishWithURL:(const GURL&)currentURL loadSuccess:(BOOL)loadSuccess; // Navigates forwards or backwards by |delta| pages. No-op if delta is out of @@ -759,7 +760,7 @@ // provided by web view. - (void)updateSSLStatusForCurrentNavigationItem; // Called when a load ends in an SSL error and certificate chain. -- (void)handleSSLCertError:(NSError*)error; +- (void)handleSSLCertError:(NSError*)error forNavigation:navigation; // Used in webView:didReceiveAuthenticationChallenge:completionHandler: to // reply with NSURLSessionAuthChallengeDisposition and credentials. @@ -892,7 +893,9 @@ // TODO(stuartmorgan): Figure out if there's actually enough shared logic that // this makes sense. At the very least remove inMainFrame since that only makes // sense for UIWebView. -- (void)handleLoadError:(NSError*)error inMainFrame:(BOOL)inMainFrame; +- (void)handleLoadError:(NSError*)error + inMainFrame:(BOOL)inMainFrame + forNavigation:(WKNavigation*)navigation; // Handles cancelled load in WKWebView (error with NSURLErrorCancelled code). - (void)handleCancelledError:(NSError*)error; @@ -2073,7 +2076,7 @@ [sessionController isSameDocumentNavigationBetweenItem:fromItem andItem:toItem]; if (sameDocumentNavigation) { - [sessionController goToItemAtIndex:index]; + [sessionController goToItemAtIndex:index discardNonCommittedItems:YES]; [self updateHTML5HistoryState]; } else { [sessionController discardNonCommittedItems]; @@ -2091,15 +2094,16 @@ return _loadPhase == web::PAGE_LOADED; } -- (void)didFinishNavigation { +- (void)didFinishNavigation:(WKNavigation*)navigation { // This can be called at multiple times after the document has loaded. Do // nothing if the document has already loaded. if (_loadPhase == web::PAGE_LOADED) return; - [self loadCompleteWithSuccess:YES]; + [self loadCompleteWithSuccess:YES forNavigation:navigation]; } -- (void)loadCompleteWithSuccess:(BOOL)loadSuccess { +- (void)loadCompleteWithSuccess:(BOOL)loadSuccess + forNavigation:(WKNavigation*)navigation { [self removePlaceholderOverlay]; // The webView may have been torn down (or replaced by a native view). Be // safe and do nothing if that's happened. @@ -2114,10 +2118,10 @@ [self optOutScrollsToTopForSubviews]; - // Ensure the URL is as expected (and already reported to the delegate). - // If |_lastRegisteredRequestURL| is invalid then |currentURL| will be - // "about:blank". - DCHECK((currentURL == _lastRegisteredRequestURL) || + DCHECK((currentURL == _lastRegisteredRequestURL) || // latest navigation + // previous navigation + ![[_navigationStates lastAddedNavigation] isEqual:navigation] || + // invalid URL load (!_lastRegisteredRequestURL.is_valid() && _documentURL.spec() == url::kAboutBlankURL)) << std::endl @@ -2826,7 +2830,7 @@ return; base::scoped_nsobject<CRWWebController> strongSelf([weakSelf retain]); [strongSelf optOutScrollsToTopForSubviews]; - [strongSelf didFinishNavigation]; + [strongSelf didFinishNavigation:nil]; }]; return YES; } @@ -2881,7 +2885,7 @@ if (!weakSelf || weakSelf.get()->_isBeingDestroyed) return; base::scoped_nsobject<CRWWebController> strongSelf([weakSelf retain]); - [strongSelf didFinishNavigation]; + [strongSelf didFinishNavigation:nil]; }]; return YES; } @@ -3116,7 +3120,9 @@ return YES; } -- (void)handleLoadError:(NSError*)error inMainFrame:(BOOL)inMainFrame { +- (void)handleLoadError:(NSError*)error + inMainFrame:(BOOL)inMainFrame + forNavigation:(WKNavigation*)navigation { NSString* MIMEType = [_pendingNavigationInfo MIMEType]; if ([_passKitDownloader isMIMETypePassKitType:MIMEType]) return; @@ -3179,7 +3185,7 @@ id<CRWNativeContent> controller = [_delegate controllerForUnhandledContentAtURL:errorGURL]; if (controller) { - [self loadCompleteWithSuccess:NO]; + [self loadCompleteWithSuccess:NO forNavigation:navigation]; [self removeWebViewAllowingCachedReconstruction:NO]; [self setNativeController:controller]; [self loadNativeViewWithSuccess:YES]; @@ -3207,7 +3213,7 @@ NSURLErrorFailingURLStringErrorKey : [errorURL absoluteString], NSUnderlyingErrorKey : error }]; - [self loadCompleteWithSuccess:NO]; + [self loadCompleteWithSuccess:NO forNavigation:navigation]; [self loadErrorInNativeView:wrapperError]; return; } @@ -3219,7 +3225,7 @@ return; } - [self loadCompleteWithSuccess:NO]; + [self loadCompleteWithSuccess:NO forNavigation:navigation]; [self loadErrorInNativeView:error]; } @@ -3952,7 +3958,8 @@ _webStateImpl->OnVisibleSecurityStateChange(); } -- (void)handleSSLCertError:(NSError*)error { +- (void)handleSSLCertError:(NSError*)error + forNavigation:(WKNavigation*)navigation { CHECK(web::IsWKWebViewSSLCertError(error)); net::SSLInfo info; @@ -3962,7 +3969,7 @@ // |info.cert| can be null if certChain in NSError is empty or can not be // parsed, in this case do not ask delegate if error should be allowed, it // should not be. - [self handleLoadError:error inMainFrame:YES]; + [self handleLoadError:error inMainFrame:YES forNavigation:navigation]; return; } @@ -4181,7 +4188,9 @@ messageRouter:messageRouter completionHandler:^(NSError* loadError) { if (loadError) - [self handleLoadError:loadError inMainFrame:YES]; + [self handleLoadError:loadError + inMainFrame:YES + forNavigation:nil]; else self.webStateImpl->SetContentsMimeType("text/html"); }]; @@ -4445,6 +4454,13 @@ [_navigationStates setState:web::WKNavigationState::STARTED forNavigation:navigation]; + if (navigation && + ![[_navigationStates lastAddedNavigation] isEqual:navigation]) { + // |navigation| is not the latest navigation and will be cancelled. + // Ignore |navigation| as a new navigation will start soon. + return; + } + GURL webViewURL = net::GURLWithNSURL(webView.URL); if (webViewURL.is_empty()) { // May happen on iOS9, however in didCommitNavigation: callback the URL @@ -4532,9 +4548,9 @@ error = WKWebViewErrorWithSource(error, PROVISIONAL_LOAD); if (web::IsWKWebViewSSLCertError(error)) - [self handleSSLCertError:error]; + [self handleSSLCertError:error forNavigation:navigation]; else - [self handleLoadError:error inMainFrame:YES]; + [self handleLoadError:error inMainFrame:YES forNavigation:navigation]; } // This must be reset at the end, since code above may need information about @@ -4564,8 +4580,15 @@ // will be "about:blank". [[self sessionController] updatePendingItem:_documentURL]; } - DCHECK(_documentURL == _lastRegisteredRequestURL || - (!_lastRegisteredRequestURL.is_valid() && + + // If |navigation| is nil (which happens for windows open by DOM), then it + // should be the first and the only pending navigaiton. + BOOL isLastNavigation = + !navigation || + [[_navigationStates lastAddedNavigation] isEqual:navigation]; + DCHECK(_documentURL == _lastRegisteredRequestURL || // latest navigation + !isLastNavigation || // previous navigation + (!_lastRegisteredRequestURL.is_valid() && // invalid URL load _documentURL.spec() == url::kAboutBlankURL)); self.webStateImpl->UpdateHttpResponseHeaders(_documentURL); @@ -4592,7 +4615,23 @@ [self injectWindowID]; } - [self webPageChanged]; + if (isLastNavigation) { + [self webPageChanged]; + } else { + // WKWebView has more than one in progress navigation, and committed + // navigation was not the latest. It is critical to keep last committed + // URL the same as actual document URL, so try guessing which navigation + // item should be set to current. + // TODO(crbug.com/712269): + for (int i = 0; i < self.navigationManagerImpl->GetItemCount(); i++) { + web::NavigationItem* item = self.navigationManagerImpl->GetItemAtIndex(i); + if (item->GetURL() == _documentURL) { + // Do not discard pending entry, because another pending navigation is + // still in progress and will commit or fail soon. + [self.sessionController goToItemAtIndex:i discardNonCommittedItems:NO]; + } + } + } self.webStateImpl->OnNavigationCommitted(_documentURL); [self updateSSLStatusForCurrentNavigationItem]; @@ -4624,7 +4663,7 @@ // WKUserScriptInjectionTimeAtDocumentEnd to inject this material at the // appropriate time rather than invoking here. web::ExecuteJavaScript(webView, @"__gCrWeb.didFinishNavigation()", nil); - [self didFinishNavigation]; + [self didFinishNavigation:navigation]; } - (void)webView:(WKWebView*)webView @@ -4634,7 +4673,8 @@ forNavigation:navigation]; [self handleLoadError:WKWebViewErrorWithSource(error, NAVIGATION) - inMainFrame:YES]; + inMainFrame:YES + forNavigation:navigation]; _certVerificationErrors->Clear(); } @@ -4794,7 +4834,7 @@ // Fast back forward navigation may not call |didFinishNavigation:|, so // signal did finish navigation explicitly. if (_lastRegisteredRequestURL == _documentURL) { - [self didFinishNavigation]; + [self didFinishNavigation:nil]; } } @@ -4941,7 +4981,7 @@ [self didStartLoadingURL:_documentURL]; _webStateImpl->OnSameDocumentNavigation(newURL); [self updateSSLStatusForCurrentNavigationItem]; - [self didFinishNavigation]; + [self didFinishNavigation:nil]; } }
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index 699b2f8f..5adc3da 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc
@@ -507,7 +507,8 @@ // Only allow negative timestamps past if we know they'll be fixed up by the // code paths below; otherwise they should be treated as a parse error. - if (!fixup_negative_timestamps_ && buffer->timestamp() < base::TimeDelta()) { + if ((!fixup_negative_timestamps_ || last_packet_timestamp_ == kNoTimestamp) && + buffer->timestamp() < base::TimeDelta()) { MEDIA_LOG(DEBUG, media_log_) << "FFmpegDemuxer: unfixable negative timestamp"; demuxer_->NotifyDemuxerError(DEMUXER_ERROR_COULD_NOT_PARSE);
diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc index e513e69..6075b8f 100644 --- a/media/renderers/renderer_impl_unittest.cc +++ b/media/renderers/renderer_impl_unittest.cc
@@ -136,6 +136,25 @@ base::Bind(&CallbackHelper::OnInitialize, base::Unretained(&callbacks_))); base::RunLoop().RunUntilIdle(); + + if (start_status == PIPELINE_OK && audio_stream_) { + ON_CALL(*audio_renderer_, Flush(_)) + .WillByDefault(DoAll(SetBufferingState(&audio_renderer_client_, + BUFFERING_HAVE_NOTHING), + RunClosure<0>())); + ON_CALL(*audio_renderer_, StartPlaying()) + .WillByDefault(SetBufferingState(&audio_renderer_client_, + BUFFERING_HAVE_ENOUGH)); + } + if (start_status == PIPELINE_OK && video_stream_) { + ON_CALL(*video_renderer_, Flush(_)) + .WillByDefault(DoAll(SetBufferingState(&video_renderer_client_, + BUFFERING_HAVE_NOTHING), + RunClosure<0>())); + ON_CALL(*video_renderer_, StartPlayingFrom(_)) + .WillByDefault(SetBufferingState(&video_renderer_client_, + BUFFERING_HAVE_ENOUGH)); + } } void CreateAudioStream() { @@ -215,15 +234,11 @@ EXPECT_CALL(time_source_, StartTicking()); if (audio_stream_) { - EXPECT_CALL(*audio_renderer_, StartPlaying()) - .WillOnce(SetBufferingState(&audio_renderer_client_, - BUFFERING_HAVE_ENOUGH)); + EXPECT_CALL(*audio_renderer_, StartPlaying()); } if (video_stream_) { - EXPECT_CALL(*video_renderer_, StartPlayingFrom(start_time)) - .WillOnce(SetBufferingState(&video_renderer_client_, - BUFFERING_HAVE_ENOUGH)); + EXPECT_CALL(*video_renderer_, StartPlayingFrom(start_time)); } renderer_impl_->StartPlayingFrom(start_time); @@ -231,19 +246,11 @@ } void SetFlushExpectationsForAVRenderers() { - if (audio_stream_) { - EXPECT_CALL(*audio_renderer_, Flush(_)) - .WillOnce(DoAll(SetBufferingState(&audio_renderer_client_, - BUFFERING_HAVE_NOTHING), - RunClosure<0>())); - } + if (audio_stream_) + EXPECT_CALL(*audio_renderer_, Flush(_)); - if (video_stream_) { - EXPECT_CALL(*video_renderer_, Flush(_)) - .WillOnce(DoAll(SetBufferingState(&video_renderer_client_, - BUFFERING_HAVE_NOTHING), - RunClosure<0>())); - } + if (video_stream_) + EXPECT_CALL(*video_renderer_, Flush(_)); } void Flush(bool underflowed) { @@ -751,10 +758,10 @@ // the video renderer (which simulates spool up time for the video renderer). const base::TimeDelta kStartTime; EXPECT_CALL(time_source_, SetMediaTime(kStartTime)); - EXPECT_CALL(*audio_renderer_, StartPlaying()) - .WillOnce( - SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)); + EXPECT_CALL(time_source_, StartTicking()); + EXPECT_CALL(*audio_renderer_, StartPlaying()); EXPECT_CALL(*video_renderer_, StartPlayingFrom(kStartTime)); + EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); renderer_impl_->StartPlayingFrom(kStartTime); // Nothing else should primed on the message loop. @@ -772,25 +779,20 @@ InitializeAndExpect(PIPELINE_OK); Play(); + EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); + // Verify that DemuxerStream status changes cause the corresponding // audio/video renderer to be flushed and restarted. EXPECT_CALL(time_source_, StopTicking()); - EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>()); - EXPECT_CALL(*audio_renderer_, StartPlaying()) - .Times(1) - .WillOnce( - SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)); + EXPECT_CALL(*audio_renderer_, Flush(_)); + EXPECT_CALL(*audio_renderer_, StartPlaying()); + EXPECT_CALL(time_source_, StartTicking()); stream_status_change_cb.Run(audio_stream_.get(), false, base::TimeDelta()); - EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>()); - EXPECT_CALL(*video_renderer_, StartPlayingFrom(_)) - .Times(1) - .WillOnce(DoAll( - SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH), - PostQuitWhenIdle())); - + EXPECT_CALL(*video_renderer_, Flush(_)); + EXPECT_CALL(*video_renderer_, StartPlayingFrom(_)); stream_status_change_cb.Run(video_stream_.get(), false, base::TimeDelta()); - base::RunLoop().Run(); + base::RunLoop().RunUntilIdle(); } // Stream status changes are handled asynchronously by the renderer and may take @@ -815,18 +817,8 @@ EXPECT_CALL(time_source_, StopTicking()).Times(2); EXPECT_CALL(time_source_, StartTicking()).Times(2); - EXPECT_CALL(*audio_renderer_, Flush(_)) - .Times(2) - .WillRepeatedly(DoAll( - SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_NOTHING), - WithArg<0>(PostCallback()))); - EXPECT_CALL(*audio_renderer_, StartPlaying()) - .Times(2) - .WillOnce( - SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)) - .WillOnce(DoAll( - SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH), - PostQuitWhenIdle())); + EXPECT_CALL(*audio_renderer_, Flush(_)).Times(2); + EXPECT_CALL(*audio_renderer_, StartPlaying()).Times(2); // The first stream status change will be processed immediately. Each status // change processing involves Flush + StartPlaying when the Flush is done. The // Flush operation is async in this case, so the second status change will be @@ -834,20 +826,10 @@ // we must still get two pairs of Flush/StartPlaying calls eventually. stream_status_change_cb.Run(audio_stream_.get(), false, base::TimeDelta()); stream_status_change_cb.Run(audio_stream_.get(), true, base::TimeDelta()); - base::RunLoop().Run(); + base::RunLoop().RunUntilIdle(); - EXPECT_CALL(*video_renderer_, Flush(_)) - .Times(2) - .WillRepeatedly(DoAll( - SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_NOTHING), - WithArg<0>(PostCallback()))); - EXPECT_CALL(*video_renderer_, StartPlayingFrom(base::TimeDelta())) - .Times(2) - .WillOnce( - SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH)) - .WillOnce(DoAll( - SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH), - PostQuitWhenIdle())); + EXPECT_CALL(*video_renderer_, Flush(_)).Times(2); + EXPECT_CALL(*video_renderer_, StartPlayingFrom(base::TimeDelta())).Times(2); // The first stream status change will be processed immediately. Each status // change processing involves Flush + StartPlaying when the Flush is done. The // Flush operation is async in this case, so the second status change will be @@ -855,7 +837,7 @@ // we must still get two pairs of Flush/StartPlaying calls eventually. stream_status_change_cb.Run(video_stream_.get(), false, base::TimeDelta()); stream_status_change_cb.Run(video_stream_.get(), true, base::TimeDelta()); - base::RunLoop().Run(); + base::RunLoop().RunUntilIdle(); } // Verify that a RendererImpl::Flush gets postponed until after stream status @@ -875,10 +857,7 @@ base::Closure audio_renderer_flush_cb; EXPECT_CALL(*audio_renderer_, Flush(_)) .WillOnce(SaveArg<0>(&audio_renderer_flush_cb)); - EXPECT_CALL(*audio_renderer_, StartPlaying()) - .Times(1) - .WillOnce( - SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_ENOUGH)); + EXPECT_CALL(*audio_renderer_, StartPlaying()); // This should start flushing the audio renderer (due to audio stream status // change) and should populate the |audio_renderer_flush_cb|. @@ -919,10 +898,7 @@ base::Closure video_renderer_flush_cb; EXPECT_CALL(*video_renderer_, Flush(_)) .WillOnce(SaveArg<0>(&video_renderer_flush_cb)); - EXPECT_CALL(*video_renderer_, StartPlayingFrom(_)) - .Times(1) - .WillOnce( - SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_ENOUGH)); + EXPECT_CALL(*video_renderer_, StartPlayingFrom(_)); // This should start flushing the video renderer (due to video stream status // change) and should populate the |video_renderer_flush_cb|. @@ -967,10 +943,7 @@ Play(); EXPECT_CALL(time_source_, StopTicking()).Times(testing::AnyNumber()); - EXPECT_CALL(*video_renderer_, Flush(_)) - .WillRepeatedly(DoAll( - SetBufferingState(&video_renderer_client_, BUFFERING_HAVE_NOTHING), - RunClosure<0>())); + EXPECT_CALL(*video_renderer_, Flush(_)); // Initiate RendererImpl::Flush, but postpone its completion by not calling // audio renderer flush callback right away, i.e. pretending audio renderer @@ -1025,10 +998,7 @@ EXPECT_CALL(time_source_, StopTicking()).Times(testing::AnyNumber()); EXPECT_CALL(*video_renderer_, OnTimeStopped()).Times(testing::AnyNumber()); - EXPECT_CALL(*audio_renderer_, Flush(_)) - .WillRepeatedly(DoAll( - SetBufferingState(&audio_renderer_client_, BUFFERING_HAVE_NOTHING), - RunClosure<0>())); + EXPECT_CALL(*audio_renderer_, Flush(_)); // Initiate RendererImpl::Flush, but postpone its completion by not calling // video renderer flush callback right away, i.e. pretending video renderer
diff --git a/net/reporting/reporting_context.cc b/net/reporting/reporting_context.cc index 1dd255b..5a976b3 100644 --- a/net/reporting/reporting_context.cc +++ b/net/reporting/reporting_context.cc
@@ -13,7 +13,6 @@ #include "base/time/default_tick_clock.h" #include "base/time/tick_clock.h" #include "base/time/time.h" -#include "base/timer/timer.h" #include "net/base/backoff_entry.h" #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_delegate.h" @@ -23,6 +22,7 @@ #include "net/reporting/reporting_observer.h" #include "net/reporting/reporting_persister.h" #include "net/reporting/reporting_policy.h" +#include "net/reporting/reporting_uploader.h" namespace net { @@ -58,8 +58,14 @@ void ReportingContext::Initialize() { DCHECK(!initialized_); + // This order isn't *critical*, but things will work better with it in this + // order: with the DeliveryAgent after the Persister, it can schedule delivery + // of persisted reports instead of waiting for a new one to be generated, and + // with the GarbageCollector in between, it won't bother scheduling delivery + // of reports that should be discarded instead. persister_->Initialize(); garbage_collector_->Initialize(); + delivery_agent_->Initialize(); initialized_ = true; } @@ -95,7 +101,7 @@ initialized_(false), cache_(base::MakeUnique<ReportingCache>(this)), endpoint_manager_(base::MakeUnique<ReportingEndpointManager>(this)), - delivery_agent_(base::MakeUnique<ReportingDeliveryAgent>(this)), + delivery_agent_(ReportingDeliveryAgent::Create(this)), persister_(ReportingPersister::Create(this)), garbage_collector_(ReportingGarbageCollector::Create(this)) {}
diff --git a/net/reporting/reporting_delivery_agent.cc b/net/reporting/reporting_delivery_agent.cc index f39dde9..e614aa1 100644 --- a/net/reporting/reporting_delivery_agent.cc +++ b/net/reporting/reporting_delivery_agent.cc
@@ -13,9 +13,11 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/time/tick_clock.h" +#include "base/timer/timer.h" #include "base/values.h" #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_endpoint_manager.h" +#include "net/reporting/reporting_observer.h" #include "net/reporting/reporting_report.h" #include "net/reporting/reporting_uploader.h" #include "url/gurl.h" @@ -46,97 +48,174 @@ DCHECK(json_written); } -} // namespace - -ReportingDeliveryAgent::ReportingDeliveryAgent(ReportingContext* context) - : context_(context), weak_factory_(this) {} -ReportingDeliveryAgent::~ReportingDeliveryAgent() {} - -class ReportingDeliveryAgent::Delivery { +class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent, + public ReportingObserver { public: - Delivery(const GURL& endpoint, - const std::vector<const ReportingReport*>& reports) - : endpoint(endpoint), reports(reports) {} - - ~Delivery() {} - - const GURL endpoint; - const std::vector<const ReportingReport*> reports; -}; - -void ReportingDeliveryAgent::SendReports() { - std::vector<const ReportingReport*> reports; - cache()->GetReports(&reports); - - // Sort reports into (origin, group) buckets. - std::map<OriginGroup, std::vector<const ReportingReport*>> - origin_group_reports; - for (const ReportingReport* report : reports) { - OriginGroup origin_group(url::Origin(report->url), report->group); - origin_group_reports[origin_group].push_back(report); + ReportingDeliveryAgentImpl(ReportingContext* context) + : context_(context), + timer_(base::MakeUnique<base::OneShotTimer>()), + weak_factory_(this) { + context_->AddObserver(this); } - // Find endpoint for each (origin, group) bucket and sort reports into - // endpoint buckets. Don't allow concurrent deliveries to the same (origin, - // group) bucket. - std::map<GURL, std::vector<const ReportingReport*>> endpoint_reports; - for (auto& it : origin_group_reports) { - const OriginGroup& origin_group = it.first; + // ReportingDeliveryAgent implementation: - if (base::ContainsKey(pending_origin_groups_, origin_group)) - continue; + ~ReportingDeliveryAgentImpl() override { context_->RemoveObserver(this); } - GURL endpoint_url; - if (!endpoint_manager()->FindEndpointForOriginAndGroup( - origin_group.first, origin_group.second, &endpoint_url)) { - continue; + void Initialize() override { + if (CacheHasReports()) + StartTimer(); + } + + void SetTimerForTesting(std::unique_ptr<base::Timer> timer) override { + DCHECK(!timer_->IsRunning()); + timer_ = std::move(timer); + } + + // ReportingObserver implementation: + void OnCacheUpdated() override { + if (CacheHasReports()) + StartTimer(); + } + + private: + class Delivery { + public: + Delivery(const GURL& endpoint, + const std::vector<const ReportingReport*>& reports) + : endpoint(endpoint), reports(reports) {} + + ~Delivery() {} + + const GURL endpoint; + const std::vector<const ReportingReport*> reports; + }; + + using OriginGroup = std::pair<url::Origin, std::string>; + + bool CacheHasReports() { + std::vector<const ReportingReport*> reports; + context_->cache()->GetReports(&reports); + return !reports.empty(); + } + + void StartTimer() { + timer_->Start(FROM_HERE, policy().delivery_interval, + base::Bind(&ReportingDeliveryAgentImpl::OnTimerFired, + base::Unretained(this))); + } + + void OnTimerFired() { + if (CacheHasReports()) { + SendReports(); + StartTimer(); + } + } + + void SendReports() { + std::vector<const ReportingReport*> reports; + cache()->GetReports(&reports); + + // Sort reports into (origin, group) buckets. + std::map<OriginGroup, std::vector<const ReportingReport*>> + origin_group_reports; + for (const ReportingReport* report : reports) { + OriginGroup origin_group(url::Origin(report->url), report->group); + origin_group_reports[origin_group].push_back(report); } - endpoint_reports[endpoint_url].insert(endpoint_reports[endpoint_url].end(), - it.second.begin(), it.second.end()); - pending_origin_groups_.insert(origin_group); + // Find endpoint for each (origin, group) bucket and sort reports into + // endpoint buckets. Don't allow concurrent deliveries to the same (origin, + // group) bucket. + std::map<GURL, std::vector<const ReportingReport*>> endpoint_reports; + for (auto& it : origin_group_reports) { + const OriginGroup& origin_group = it.first; + + if (base::ContainsKey(pending_origin_groups_, origin_group)) + continue; + + GURL endpoint_url; + if (!endpoint_manager()->FindEndpointForOriginAndGroup( + origin_group.first, origin_group.second, &endpoint_url)) { + continue; + } + + endpoint_reports[endpoint_url].insert( + endpoint_reports[endpoint_url].end(), it.second.begin(), + it.second.end()); + pending_origin_groups_.insert(origin_group); + } + + // Start a delivery to each endpoint. + for (auto& it : endpoint_reports) { + const GURL& endpoint = it.first; + const std::vector<const ReportingReport*>& reports = it.second; + + endpoint_manager()->SetEndpointPending(endpoint); + cache()->SetReportsPending(reports); + + std::string json; + SerializeReports(reports, tick_clock()->NowTicks(), &json); + + uploader()->StartUpload( + endpoint, json, + base::Bind(&ReportingDeliveryAgentImpl::OnUploadComplete, + weak_factory_.GetWeakPtr(), + base::MakeUnique<Delivery>(endpoint, reports))); + } } - // Start a delivery to each endpoint. - for (auto& it : endpoint_reports) { - const GURL& endpoint = it.first; - const std::vector<const ReportingReport*>& reports = it.second; + void OnUploadComplete(const std::unique_ptr<Delivery>& delivery, + ReportingUploader::Outcome outcome) { + if (outcome == ReportingUploader::Outcome::SUCCESS) { + cache()->RemoveReports(delivery->reports); + endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, true); + } else { + cache()->IncrementReportsAttempts(delivery->reports); + endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, false); + } - endpoint_manager()->SetEndpointPending(endpoint); - cache()->SetReportsPending(reports); + if (outcome == ReportingUploader::Outcome::REMOVE_ENDPOINT) + cache()->RemoveClientsForEndpoint(delivery->endpoint); - std::string json; - SerializeReports(reports, tick_clock()->NowTicks(), &json); + for (const ReportingReport* report : delivery->reports) { + pending_origin_groups_.erase( + OriginGroup(url::Origin(report->url), report->group)); + } - uploader()->StartUpload( - endpoint, json, - base::Bind(&ReportingDeliveryAgent::OnUploadComplete, - weak_factory_.GetWeakPtr(), - base::MakeUnique<Delivery>(endpoint, reports))); + endpoint_manager()->ClearEndpointPending(delivery->endpoint); + cache()->ClearReportsPending(delivery->reports); } + + const ReportingPolicy& policy() { return context_->policy(); } + base::TickClock* tick_clock() { return context_->tick_clock(); } + ReportingCache* cache() { return context_->cache(); } + ReportingUploader* uploader() { return context_->uploader(); } + ReportingEndpointManager* endpoint_manager() { + return context_->endpoint_manager(); + } + + ReportingContext* context_; + + std::unique_ptr<base::Timer> timer_; + + // Tracks OriginGroup tuples for which there is a pending delivery running. + // (Would be an unordered_set, but there's no hash on pair.) + std::set<OriginGroup> pending_origin_groups_; + + base::WeakPtrFactory<ReportingDeliveryAgentImpl> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(ReportingDeliveryAgentImpl); +}; + +} // namespace + +// static +std::unique_ptr<ReportingDeliveryAgent> ReportingDeliveryAgent::Create( + ReportingContext* context) { + return base::MakeUnique<ReportingDeliveryAgentImpl>(context); } -void ReportingDeliveryAgent::OnUploadComplete( - const std::unique_ptr<Delivery>& delivery, - ReportingUploader::Outcome outcome) { - if (outcome == ReportingUploader::Outcome::SUCCESS) { - cache()->RemoveReports(delivery->reports); - endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, true); - } else { - cache()->IncrementReportsAttempts(delivery->reports); - endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, false); - } - - if (outcome == ReportingUploader::Outcome::REMOVE_ENDPOINT) - cache()->RemoveClientsForEndpoint(delivery->endpoint); - - for (const ReportingReport* report : delivery->reports) { - pending_origin_groups_.erase( - OriginGroup(url::Origin(report->url), report->group)); - } - - endpoint_manager()->ClearEndpointPending(delivery->endpoint); - cache()->ClearReportsPending(delivery->reports); -} +ReportingDeliveryAgent::~ReportingDeliveryAgent() {} } // namespace net
diff --git a/net/reporting/reporting_delivery_agent.h b/net/reporting/reporting_delivery_agent.h index eaae8a3..e4ed370 100644 --- a/net/reporting/reporting_delivery_agent.h +++ b/net/reporting/reporting_delivery_agent.h
@@ -6,27 +6,17 @@ #define NET_REPORTING_REPORTING_DELIVERY_AGENT_H_ #include <memory> -#include <set> -#include <string> -#include <utility> #include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "net/base/backoff_entry.h" #include "net/base/net_export.h" -#include "net/reporting/reporting_context.h" -#include "net/reporting/reporting_uploader.h" -#include "url/gurl.h" -#include "url/origin.h" namespace base { -class TickClock; +class Timer; } // namespace base namespace net { -class ReportingCache; -class ReportingEndpointManager; +class ReportingContext; // Takes reports from the ReportingCache, assembles reports into deliveries to // endpoints, and sends those deliveries using ReportingUploader. @@ -59,39 +49,20 @@ // delivery attempt. class NET_EXPORT ReportingDeliveryAgent { public: - // |context| must outlive the ReportingDeliveryAgent. - ReportingDeliveryAgent(ReportingContext* context); - ~ReportingDeliveryAgent(); + // Creates a ReportingDeliveryAgent. |context| must outlive the agent. + static std::unique_ptr<ReportingDeliveryAgent> Create( + ReportingContext* context); - // Tries to deliver all of the reports in the cache. Reports that are already - // being delivered will not be attempted a second time, and reports that do - // not have a viable endpoint will be neither attempted nor removed. - void SendReports(); + virtual ~ReportingDeliveryAgent(); - private: - class Delivery; + // Initializes the DeliveryAgent, which schedules delivery (after the Policy's + // delivery_interval) for any previously-persisted reports that can still be + // delivered. + virtual void Initialize() = 0; - using OriginGroup = std::pair<url::Origin, std::string>; - - void OnUploadComplete(const std::unique_ptr<Delivery>& delivery, - ReportingUploader::Outcome outcome); - - base::TickClock* tick_clock() { return context_->tick_clock(); } - ReportingCache* cache() { return context_->cache(); } - ReportingUploader* uploader() { return context_->uploader(); } - ReportingEndpointManager* endpoint_manager() { - return context_->endpoint_manager(); - } - - ReportingContext* context_; - - // Tracks OriginGroup tuples for which there is a pending delivery running. - // (Would be an unordered_set, but there's no hash on pair.) - std::set<OriginGroup> pending_origin_groups_; - - base::WeakPtrFactory<ReportingDeliveryAgent> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ReportingDeliveryAgent); + // Replaces the internal Timer used for scheduling report delivery attempts + // with a caller-specified one so that unittests can provide a MockTimer. + virtual void SetTimerForTesting(std::unique_ptr<base::Timer> timer) = 0; }; } // namespace net
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc index d62f97c..c108c78 100644 --- a/net/reporting/reporting_delivery_agent_unittest.cc +++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -11,6 +11,7 @@ #include "base/test/simple_test_tick_clock.h" #include "base/test/values_test_util.h" #include "base/time/time.h" +#include "base/timer/mock_timer.h" #include "base/values.h" #include "net/base/backoff_entry.h" #include "net/reporting/reporting_cache.h" @@ -42,11 +43,6 @@ return tick_clock()->NowTicks() + base::TimeDelta::FromDays(1); } - const std::vector<std::unique_ptr<TestReportingUploader::PendingUpload>>& - pending_uploads() { - return uploader()->pending_uploads(); - } - const GURL kUrl_ = GURL("https://origin/path"); const url::Origin kOrigin_ = url::Origin(GURL("https://origin/")); const GURL kEndpoint_ = GURL("https://endpoint/"); @@ -67,7 +63,8 @@ tick_clock()->Advance(base::TimeDelta::FromMilliseconds(kAgeMillis)); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url()); @@ -104,7 +101,8 @@ base::MakeUnique<base::DictionaryValue>(), tick_clock()->NowTicks(), 0); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); pending_uploads()[0]->Complete(ReportingUploader::Outcome::FAILURE); @@ -118,7 +116,8 @@ // Since endpoint is now failing, an upload won't be started despite a pending // report. ASSERT_TRUE(pending_uploads().empty()); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); EXPECT_TRUE(pending_uploads().empty()); } @@ -136,7 +135,8 @@ base::MakeUnique<base::DictionaryValue>(), tick_clock()->NowTicks(), 0); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); pending_uploads()[0]->Complete(ReportingUploader::Outcome::REMOVE_ENDPOINT); @@ -153,7 +153,8 @@ // Since endpoint is now failing, an upload won't be started despite a pending // report. - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); EXPECT_TRUE(pending_uploads().empty()); } @@ -164,7 +165,8 @@ base::MakeUnique<base::DictionaryValue>(), tick_clock()->NowTicks(), 0); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); // Remove the report while the upload is running. @@ -209,7 +211,8 @@ base::MakeUnique<base::DictionaryValue>(), tick_clock()->NowTicks(), 0); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); @@ -232,20 +235,23 @@ base::MakeUnique<base::DictionaryValue>(), tick_clock()->NowTicks(), 0); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); EXPECT_EQ(1u, pending_uploads().size()); cache()->AddReport(kDifferentUrl, kGroup_, kType_, base::MakeUnique<base::DictionaryValue>(), tick_clock()->NowTicks(), 0); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); EXPECT_EQ(0u, pending_uploads().size()); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); @@ -267,20 +273,23 @@ base::MakeUnique<base::DictionaryValue>(), tick_clock()->NowTicks(), 0); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); EXPECT_EQ(1u, pending_uploads().size()); cache()->AddReport(kUrl_, kGroup_, kType_, base::MakeUnique<base::DictionaryValue>(), tick_clock()->NowTicks(), 0); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); EXPECT_EQ(0u, pending_uploads().size()); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(1u, pending_uploads().size()); pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); @@ -306,7 +315,8 @@ base::MakeUnique<base::DictionaryValue>(), tick_clock()->NowTicks(), 0); - delivery_agent()->SendReports(); + EXPECT_TRUE(delivery_timer()->IsRunning()); + delivery_timer()->Fire(); ASSERT_EQ(2u, pending_uploads().size()); pending_uploads()[1]->Complete(ReportingUploader::Outcome::SUCCESS);
diff --git a/net/reporting/reporting_policy.cc b/net/reporting/reporting_policy.cc index 9461bfcb..d700889 100644 --- a/net/reporting/reporting_policy.cc +++ b/net/reporting/reporting_policy.cc
@@ -9,7 +9,8 @@ namespace net { ReportingPolicy::ReportingPolicy() - : persistence_interval(base::TimeDelta::FromMinutes(1)), + : delivery_interval(base::TimeDelta::FromMinutes(1)), + persistence_interval(base::TimeDelta::FromMinutes(1)), persist_reports_across_restarts(false), persist_clients_across_restarts(true), garbage_collection_interval(base::TimeDelta::FromMinutes(5)), @@ -25,7 +26,8 @@ } ReportingPolicy::ReportingPolicy(const ReportingPolicy& other) - : endpoint_backoff_policy(other.endpoint_backoff_policy), + : delivery_interval(base::TimeDelta::FromMinutes(1)), + endpoint_backoff_policy(other.endpoint_backoff_policy), persistence_interval(other.persistence_interval), persist_reports_across_restarts(other.persist_reports_across_restarts), persist_clients_across_restarts(other.persist_clients_across_restarts),
diff --git a/net/reporting/reporting_policy.h b/net/reporting/reporting_policy.h index 51bba69..59663ed 100644 --- a/net/reporting/reporting_policy.h +++ b/net/reporting/reporting_policy.h
@@ -18,6 +18,9 @@ ReportingPolicy(const ReportingPolicy& other); ~ReportingPolicy(); + // Minimum interval at which to attempt delivery of queued reports. + base::TimeDelta delivery_interval; + // Backoff policy for failing endpoints. BackoffEntry::Policy endpoint_backoff_policy;
diff --git a/net/reporting/reporting_test_util.cc b/net/reporting/reporting_test_util.cc index 8a7dbd06..74d0cb4 100644 --- a/net/reporting/reporting_test_util.cc +++ b/net/reporting/reporting_test_util.cc
@@ -14,11 +14,11 @@ #include "base/test/simple_test_clock.h" #include "base/test/simple_test_tick_clock.h" #include "base/timer/mock_timer.h" -#include "base/timer/timer.h" #include "net/reporting/reporting_cache.h" #include "net/reporting/reporting_client.h" #include "net/reporting/reporting_context.h" #include "net/reporting/reporting_delegate.h" +#include "net/reporting/reporting_delivery_agent.h" #include "net/reporting/reporting_garbage_collector.h" #include "net/reporting/reporting_persister.h" #include "net/reporting/reporting_policy.h" @@ -124,6 +124,8 @@ base::MakeUnique<base::SimpleTestClock>(), base::MakeUnique<base::SimpleTestTickClock>(), base::MakeUnique<TestReportingUploader>()), + delivery_timer_(new base::MockTimer(/* retain_user_task= */ false, + /* is_repeating= */ false)), persistence_timer_(new base::MockTimer(/* retain_user_task= */ false, /* is_repeating= */ false)), garbage_collection_timer_( @@ -132,9 +134,11 @@ persister()->SetTimerForTesting(base::WrapUnique(persistence_timer_)); garbage_collector()->SetTimerForTesting( base::WrapUnique(garbage_collection_timer_)); + delivery_agent()->SetTimerForTesting(base::WrapUnique(delivery_timer_)); } TestReportingContext::~TestReportingContext() { + delivery_timer_ = nullptr; persistence_timer_ = nullptr; garbage_collection_timer_ = nullptr; } @@ -178,6 +182,10 @@ return tick_clock()->NowTicks() - base::TimeDelta::FromDays(1); } +base::TimeTicks ReportingTestBase::now() { + return tick_clock()->NowTicks(); +} + base::TimeTicks ReportingTestBase::tomorrow() { return tick_clock()->NowTicks() + base::TimeDelta::FromDays(1); }
diff --git a/net/reporting/reporting_test_util.h b/net/reporting/reporting_test_util.h index 098fe0f..2fa0d46c 100644 --- a/net/reporting/reporting_test_util.h +++ b/net/reporting/reporting_test_util.h
@@ -110,6 +110,7 @@ base::SimpleTestTickClock* test_tick_clock() { return reinterpret_cast<base::SimpleTestTickClock*>(tick_clock()); } + base::MockTimer* test_delivery_timer() { return delivery_timer_; } base::MockTimer* test_persistence_timer() { return persistence_timer_; } base::MockTimer* test_garbage_collection_timer() { return garbage_collection_timer_; @@ -122,6 +123,7 @@ // Owned by the Persister and GarbageCollector, respectively, but referenced // here to preserve type: + base::MockTimer* delivery_timer_; base::MockTimer* persistence_timer_; base::MockTimer* garbage_collection_timer_; @@ -153,6 +155,7 @@ base::SimpleTestTickClock* tick_clock() { return context_->test_tick_clock(); } + base::MockTimer* delivery_timer() { return context_->test_delivery_timer(); } base::MockTimer* persistence_timer() { return context_->test_persistence_timer(); } @@ -175,9 +178,14 @@ ReportingPersister* persister() { return context_->persister(); } base::TimeTicks yesterday(); - + base::TimeTicks now(); base::TimeTicks tomorrow(); + const std::vector<std::unique_ptr<TestReportingUploader::PendingUpload>>& + pending_uploads() { + return uploader()->pending_uploads(); + } + private: void CreateAndInitializeContext( const ReportingPolicy& policy,
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index f700691b..53eedf0a 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -268,6 +268,298 @@ # ====== LayoutNG-only failures from here ====== # LayoutNG - is a new layout system for Blink. +#### external/wpt/css/CSS2/normal-flow +#### Passed: 420 59% +#### Skipped: 288 +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-formatting-context-height-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-formatting-context-height-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-formatting-contexts-008.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-formatting-contexts-009.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-formatting-contexts-010.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-formatting-contexts-011.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-formatting-contexts-012.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-formatting-contexts-015.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-insert-001f.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-insert-002f.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-margins-001a.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-margins-001b.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-margins-002a.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-margins-002b.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-percents-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-non-replaced-height-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-non-replaced-height-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-non-replaced-width-007.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-height-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-height-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-height-004.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-height-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-height-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-height-007.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-width-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-width-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-013.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-016.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-017.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-018.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-019.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-025.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-026.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-004.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-012.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-013.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-015.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-016.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-023.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-024.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-026.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-027.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-034.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-035.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-037.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-038.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-045.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-046.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-048.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-049.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-056.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-057.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-059.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-060.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-067.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-068.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-070.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-071.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-078.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-079.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-081.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-082.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-089.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-090.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-091.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-092.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-093.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-104.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-114.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-applies-to-014.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-percentage-004.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/height-percentage-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-004.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-non-replaced-height-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-008.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-009.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-width-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-width-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-width-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-width-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-width-007.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-width-008.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-valign-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-zorder-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-non-replaced-height-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-non-replaced-height-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-non-replaced-width-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-non-replaced-width-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-height-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-height-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-height-008.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-height-009.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-008.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-009.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-012.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-013.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-014.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-015.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-002a.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-002b.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-height-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-height-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-valign-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-zorder-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-zorder-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-zorder-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-table-zorder-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inlines-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inlines-004.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inlines-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inlines-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inlines-013.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inlines-016.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inlines-017.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inlines-020.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-004.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-013.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-015.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-016.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-024.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-026.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-027.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-035.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-037.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-038.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-046.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-047.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-048.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-049.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-057.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-059.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-060.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-068.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-070.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-071.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-079.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-081.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-082.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-090.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-091.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-092.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-093.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-101.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-104.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-applies-to-008.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-applies-to-012.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-percentage-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-percentage-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-007.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-017.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-018.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-028.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-029.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-039.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-040.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-050.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-051.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-061.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-062.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-072.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-073.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-083.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-084.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-094.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-095.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-106.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-110.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-applies-to-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-applies-to-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-applies-to-008.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-applies-to-012.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-applies-to-013.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-applies-to-014.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-width-percentage-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-004.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-012.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-013.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-015.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-016.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-023.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-024.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-026.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-027.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-034.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-035.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-037.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-038.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-045.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-046.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-047.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-048.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-049.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-056.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-057.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-059.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-060.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-067.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-068.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-070.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-071.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-078.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-079.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-081.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-082.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-089.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-090.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-091.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-092.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-093.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-100.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-101.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-102.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-103.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-104.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-106.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-height-applies-to-012.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-007.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-017.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-018.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-028.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-029.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-039.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-040.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-050.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-051.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-061.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-062.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-072.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-073.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-083.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-084.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-094.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-095.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-applies-to-005.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-applies-to-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-applies-to-008.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-applies-to-012.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-applies-to-014.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/min-width-percentage-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-002.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/replaced-intrinsic-003.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/root-box-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/table-in-inline-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-006.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-007.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-017.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-018.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-028.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-029.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-039.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-040.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-050.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-051.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-061.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-062.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-072.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-073.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-083.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-084.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-094.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-095.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-applies-to-012.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-inherit-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-percentage-001.xht [ Skip ] +crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/width-percentage-002.xht [ Skip ] + #### fast/block/basic #### Passed: 5 #### Skipped: 27 @@ -660,6 +952,9 @@ crbug.com/676432 fullscreen/full-screen-iframe-zIndex.html [ Skip ] crbug.com/676432 virtual/android/fullscreen/full-screen-iframe-zIndex.html [ Skip ] +crbug.com/709846 paint/pagination/pagination-change-clip-crash.html [ NeedsRebaseline ] +crbug.com/709846 virtual/disable-spinvalidation/paint/pagination/pagination-change-clip-crash.html [ NeedsRebaseline ] + crbug.com/538697 [ Win7 Debug ] virtual/threaded/printing/webgl-oversized-printing.html [ Failure Crash ] crbug.com/538697 [ Win7 Debug ] printing/webgl-oversized-printing.html [ Failure Crash ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 53dda9c..18fb6a9 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -463,6 +463,11 @@ "args": ["--enable-blink-features=LayoutNG"] }, { + "prefix": "layout_ng", + "base": "external/wpt/css/CSS2/normal-flow", + "args": ["--enable-blink-features=LayoutNG"] + }, + { "prefix": "feature-policy", "base": "http/tests/feature-policy", "args": ["--enable-blink-features=FeaturePolicy"]
diff --git a/third_party/WebKit/LayoutTests/bindings/sequence-type.html b/third_party/WebKit/LayoutTests/bindings/sequence-type.html new file mode 100644 index 0000000..c50b3b3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/bindings/sequence-type.html
@@ -0,0 +1,207 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> + function createIterable(iterations) { + return { + [Symbol.iterator]() { + var i = 0; + return {next: () => iterations[i++]}; + }, + }; + } + + test(() => { + let sequenceTest = internals.sequenceTest(); + + assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(null) }, + "Converting null to sequence must throw a type error"); + assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(undefined) }, + "Converting undefined to sequence must throw a type error"); + assert_equals(sequenceTest.identityOctetSequenceOrNull(null), null, + "Converting null to a nullable sequence works"); + assert_equals(sequenceTest.identityOctetSequenceOrNull(undefined), null, + "Converting undefined to a nullable sequence works"); + }, "null and undefined conversions"); + + test(() => { + let sequenceTest = internals.sequenceTest(); + + let emptyArray = []; + let emptyObject = createIterable([{done: true}]); + + let convertedArray = sequenceTest.identityLongSequence(emptyArray); + assert_array_equals(convertedArray, [], "Empty array produces an empty vector"); + let convertedObject = sequenceTest.identityLongSequence(emptyObject); + assert_array_equals(convertedObject, [], "Empty object produces an empty vector"); + }, "Empty sequences"); + + test(() => { + let sequenceTest = internals.sequenceTest(); + + let obj = createIterable([ + { done: false, value: 34 }, + { done: false, value: 42 }, + { done: true } + ]); + let convertedObj = sequenceTest.identityLongSequence(obj); + assert_array_equals(convertedObj, [34, 42], + "'done: true' does not need a value property"); + + obj = createIterable([ + { done: false, value: 34 }, + { done: false, value: 42 }, + { done: true, value: 88 } + ]); + convertedObj = sequenceTest.identityLongSequence(obj); + assert_array_equals(convertedObj, [34, 42], + "'value' is ignored when 'done' is true"); + + obj = createIterable([ + { done: 0, value: 42 }, + { done: 1, value: 34 } + ]); + convertedObj = sequenceTest.identityDoubleSequence(obj); + assert_array_equals(convertedObj, [42], + "'done' is always converted to a boolean"); + }, "Iterator stop values"); + + test(() => { + let sequenceTest = internals.sequenceTest(); + + let array = [1, 2]; + let convertedArray = sequenceTest.identityDoubleSequence(array); + assert_not_equals(array, convertedArray); + convertedArray.push(42); + let convertedArray2 = sequenceTest.identityDoubleSequence(array); + assert_equals(array.length, 2); + assert_not_equals(convertedArray, convertedArray2); + assert_array_equals(convertedArray2, [1, 2]); + }, "Sequences are passed by value"); + + test(() => { + let sequenceTest = internals.sequenceTest(); + + let longArray = ['not', 'a', 'long']; + longArray[5] = 42; + let convertedLongArray = sequenceTest.identityLongSequence(longArray); + assert_array_equals(convertedLongArray, [0, 0, 0, 0, 0, 42], + "Long array with gaps correctly produces a vector"); + + let doubleArray = [34, 42.5]; + doubleArray[9] = 2; // The elements inbetween are all undefined. + assert_throws(new TypeError, () => { sequenceTest.identityDoubleSequence(doubleArray) }, + "Converting an undefined value to double throws a TypeError and " + + "causes the sequence -> C++ conversion to fail"); + + let byteStringSequenceSequence = [ + ["foo"], + ["bar"] + ]; + byteStringSequenceSequence[7] = ["baz"]; + assert_throws(new TypeError, () => { + sequenceTest.identityByteStringSequenceSequence(byteStringSequenceSequence); + }, "Converting an undefined to a sequence<> throws a TypeError and causes the " + + "entire conversion to fail"); + }, "Arrays with gaps in the elements"); + + test(() => { + let sequenceTest = internals.sequenceTest(); + + assert_throws(new TypeError, () => { sequenceTest.identityLongSequence({}) }, + "Objects without Symbol.iterator cannot be converted"); + + let obj = { + [Symbol.iterator]: 42 + }; + assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, + "Symbol.iterator must be callable"); + + obj = { + [Symbol.iterator]() { + return 42; + } + } + assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, + "Symbol.iterator must return an object"); + + obj = { + [Symbol.iterator]() { + return {} + } + } + assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, + "Symbol.iterator must return an object with a 'next' callable"); + + obj = { + [Symbol.iterator]() { + return {'next': 42} + } + } + assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, + "Symbol.iterator must return an object with a 'next' callable"); + + obj = { + [Symbol.iterator]() { + return {'next': () => { return 42 }} + } + } + assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, + "'next' must return an object"); + }, "Invalid iterable protocols"); + + test(() => { + let sequenceTest = internals.sequenceTest(); + + assert_false(sequenceTest.unionReceivedSequence(42), + "Passing a double should convert the union to double"); + assert_false(sequenceTest.unionReceivedSequence(true), + "Passing a boolean should convert the union to double"); + assert_true(sequenceTest.unionReceivedSequence([]), + "Passing an empty array should convert the union to a sequence"); + assert_true(sequenceTest.unionReceivedSequence([34, 42]), + "Passing an array should convert the union to a sequence"); + let obj = createIterable([{done: false, value: 99}, + {done: false, value: -3.14}, + {done: true}]); + assert_true(sequenceTest.unionReceivedSequence(obj), + "Passing an iterable object should convert the union to a sequence"); + }, "Sequences in unions"); + + test(() => { + let sequenceTest = internals.sequenceTest(); + + let foods = ["Sushi", "Beer"]; + assert_throws(new TypeError, () => { sequenceTest.identityFoodEnumSequence(foods) }, + "Invalid enum type must throw a type error"); + + foods = createIterable([{done: false, value: "Spaghetti"}, + {done: false, value: "Bread"}, + {done: true}]); + assert_array_equals(sequenceTest.identityFoodEnumSequence(foods), + ["Spaghetti", "Bread"]); + }, "Enum sequences"); + + test(() => { + let sequenceTest = internals.sequenceTest(); + + let sequenceCreationFunctions = [ + (elem) => { return [elem] }, + (elem) => { return createIterable([{done: false, value: elem}, + {done: true}]) } + ]; + for (sequenceCreationFunction of sequenceCreationFunctions) { + let elem = document.createElement('p'); + sequenceTest.setElementSequence(sequenceCreationFunction(elem)); + assert_array_equals(sequenceTest.getElementSequence(), [elem], + "The same DOM object was stored in the sequence"); + assert_not_equals(sequenceTest.getElementSequence()[0], + document.createElement('br'), + "The same DOM object was stored in the sequence"); + + elem = document.createElement('br'); + assert_not_equals(sequenceTest.getElementSequence()[0], elem, + "Changing the original object does not change the sequence value"); + } + }, "Converting DOM object sequences"); +</script>
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/aes-cbc/generateKey-failures-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/aes-cbc/generateKey-failures-expected.txt index 8c3fbe2..d262cbb 100644 --- a/third_party/WebKit/LayoutTests/crypto/subtle/aes-cbc/generateKey-failures-expected.txt +++ b/third_party/WebKit/LayoutTests/crypto/subtle/aes-cbc/generateKey-failures-expected.txt
@@ -5,10 +5,10 @@ generateKey() with invalid keyUsages value that is -1... -error is: TypeError: Failed to execute 'generateKey' on 'SubtleCrypto': The 3rd argument is neither an array, nor does it have indexed properties. +error is: TypeError: Failed to execute 'generateKey' on 'SubtleCrypto': The provided value cannot be converted to a sequence. generateKey() with invalid keyUsages value that is null... -error is: TypeError: Failed to execute 'generateKey' on 'SubtleCrypto': The 3rd argument is neither an array, nor does it have indexed properties. +error is: TypeError: Failed to execute 'generateKey' on 'SubtleCrypto': The provided value cannot be converted to a sequence. generateKey() with an invalid key usage of 'boo'... error is: TypeError: Invalid keyUsages argument
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/unwrapKey-badParameters-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/unwrapKey-badParameters-expected.txt index 6f5cec4e..98d8c65 100644 --- a/third_party/WebKit/LayoutTests/crypto/subtle/unwrapKey-badParameters-expected.txt +++ b/third_party/WebKit/LayoutTests/crypto/subtle/unwrapKey-badParameters-expected.txt
@@ -5,7 +5,7 @@ error is: TypeError: Failed to execute 'unwrapKey' on 'SubtleCrypto': The provided value is not of type '(ArrayBuffer or ArrayBufferView)' error is: TypeError: Failed to execute 'unwrapKey' on 'SubtleCrypto': parameter 3 is not of type 'CryptoKey'. -error is: TypeError: Failed to execute 'unwrapKey' on 'SubtleCrypto': The 7th argument is neither an array, nor does it have indexed properties. +error is: TypeError: Failed to execute 'unwrapKey' on 'SubtleCrypto': The provided value cannot be converted to a sequence. error is: TypeError: Algorithm: Not an object error is: NotSupportedError: Algorithm: Unrecognized name error is: TypeError: Invalid keyFormat argument
diff --git a/third_party/WebKit/LayoutTests/external/wpt/FileAPI/blob/Blob-constructor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/blob/Blob-constructor-expected.txt index 7681618..dc7cce1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/FileAPI/blob/Blob-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/blob/Blob-constructor-expected.txt
@@ -1,21 +1,19 @@ This is a testharness.js-based test. -Found 61 tests; 54 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 61 tests; 57 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Blob interface object PASS Blob constructor with no arguments PASS Blob constructor with no arguments, without 'new' PASS Blob constructor without brackets PASS Blob constructor with undefined as first argument -FAIL Passing non-objects, Dates and RegExps for blobParts should throw a TypeError. assert_throws: Should throw for argument object "[object Object]". function "function () { - new Blob(arg); - }" did not throw -FAIL A plain object with @@iterator should be treated as a sequence for the blobParts argument. Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties. +PASS Passing non-objects, Dates and RegExps for blobParts should throw a TypeError. +PASS A plain object with @@iterator should be treated as a sequence for the blobParts argument. PASS A plain object with @@iterator and a length property should be treated as a sequence for the blobParts argument. PASS A String object should be treated as a sequence for the blobParts argument. PASS A Uint8Array object should be treated as a sequence for the blobParts argument. PASS The length getter should be invoked and any exceptions should be propagated. PASS A platform object that supports indexed properties should be treated as a sequence for the blobParts argument (overwritten 'length'.) PASS ToUint32 should be applied to the length and any exceptions should be propagated. -FAIL Getters and value conversions should happen in order until an exception is thrown. assert_array_equals: lengths differ, expected 8 got 5 +PASS Getters and value conversions should happen in order until an exception is thrown. PASS ToString should be called on elements of the blobParts array and any exceptions should be propagated. FAIL Changes to the blobParts array should be reflected in the returned Blob (pop). assert_equals: expected 4 but got 13 FAIL Changes to the blobParts array should be reflected in the returned Blob (unshift). assert_equals: expected 4 but got 2
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-record-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-record-expected.txt deleted file mode 100644 index f702de2..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/headers/headers-record-expected.txt +++ /dev/null
@@ -1,14 +0,0 @@ -This is a testharness.js-based test. -PASS Passing nothing to Headers constructor -PASS Passing undefined to Headers constructor -PASS Passing null to Headers constructor -FAIL Basic operation with one property assert_equals: expected 4 but got 3 -FAIL Basic operation with one property and a proto assert_equals: expected 4 but got 3 -FAIL Correct operation ordering with two properties assert_equals: expected 6 but got 5 -FAIL Correct operation ordering with two properties one of which has an invalid name assert_equals: expected 5 but got 4 -FAIL Correct operation ordering with two properties one of which has an invalid value assert_equals: expected 4 but got 3 -FAIL Correct operation ordering with non-enumerable properties assert_equals: expected 6 but got 5 -FAIL Correct operation ordering with undefined descriptors assert_equals: expected 6 but got 5 -FAIL Correct operation ordering with repeated keys assert_equals: expected 9 but got 8 -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-expected.txt index 867dd03..bc8b50b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 50 tests; 34 PASS, 16 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 50 tests; 35 PASS, 15 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS non-animatable property 'animation' is not accessed when using a property-indexed keyframe object PASS non-animatable property 'animationDelay' is not accessed when using a property-indexed keyframe object PASS non-animatable property 'animationDirection' is not accessed when using a property-indexed keyframe object @@ -44,14 +44,7 @@ FAIL easing and offset are ignored on iterable objects. effect.getKeyframes is not a function FAIL Custom iterator with multiple properties specified. effect.getKeyframes is not a function FAIL Custom iterator with offset specified. effect.getKeyframes is not a function -FAIL Custom iterator with non object keyframe should throw. assert_throws: function "function () { - new KeyframeEffect(null, createIterable([ - {done: false, value: {left: '100px'}}, - {done: false, value: 1234}, - {done: false, value: {left: '200px'}}, - {done: true}, - ])); - }" did not throw +PASS Custom iterator with non object keyframe should throw. FAIL Custom iterator with value list in keyframe should give bizarre string representation of list. effect.getKeyframes is not a function FAIL Only enumerable properties on keyframes are considered anim.effect.getKeyframes is not a function FAIL Only properties defined directly on keyframes are considered anim.effect.getKeyframes is not a function
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-lineDash-input-sequence.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-lineDash-input-sequence.html index 1cbcb5f..e854b30 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-lineDash-input-sequence.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-lineDash-input-sequence.html
@@ -13,17 +13,30 @@ var arrayValues = [5, 15, 25]; + function createIterableObject() { + return { + [Symbol.iterator]() { + var i = 0; + return { + next() { + if (i >= arrayValues.length) + return { done: true }; + return { done: false, value: arrayValues[i++] }; + } + } + } + } + } + function createTestArray(arrayType) { var array; if (arrayType == Object) { - // Test a "sequence" (Object with length property). - array = {length: arrayValues.length}; + array = createIterableObject(); } else { array = new arrayType(arrayValues.length); + for (var i = 0; i < arrayValues.length; ++i) + array[i] = arrayValues[i]; } - - for (var i = 0; i < arrayValues.length; ++i) - array[i] = arrayValues[i] return array; }
diff --git a/third_party/WebKit/LayoutTests/fast/dom/idl-union-type-unittest-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/idl-union-type-unittest-expected.txt index fb9eb0a..704d1082 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/idl-union-type-unittest-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/idl-union-type-unittest-expected.txt
@@ -34,17 +34,17 @@ PASS unionTypesTest.doubleOrStringArrayArg([3.14, "foo"]) is "double: 3.14, string: foo" PASS unionTypesTest.doubleOrStringArrayArg([1, "foo", "bar", 2]) is "double: 1, string: foo, string: bar, double: 2" PASS unionTypesTest.doubleOrStringArrayArg([null, undefined, {}, []]) is "string: null, string: undefined, string: [object Object], string: " -PASS unionTypesTest.doubleOrStringArrayArg(null) threw exception TypeError: Failed to execute 'doubleOrStringArrayArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties.. -PASS unionTypesTest.doubleOrStringArrayArg(undefined) threw exception TypeError: Failed to execute 'doubleOrStringArrayArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties.. -PASS unionTypesTest.doubleOrStringArrayArg({}) threw exception TypeError: Failed to execute 'doubleOrStringArrayArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties.. +PASS unionTypesTest.doubleOrStringArrayArg(null) threw exception TypeError: Failed to execute 'doubleOrStringArrayArg' on 'UnionTypesTest': The provided value cannot be converted to a sequence.. +PASS unionTypesTest.doubleOrStringArrayArg(undefined) threw exception TypeError: Failed to execute 'doubleOrStringArrayArg' on 'UnionTypesTest': The provided value cannot be converted to a sequence.. +PASS unionTypesTest.doubleOrStringArrayArg({}) threw exception TypeError: Failed to execute 'doubleOrStringArrayArg' on 'UnionTypesTest': Iterator getter is not callable.. PASS unionTypesTest.doubleOrStringSequenceArg([]) is "" PASS unionTypesTest.doubleOrStringSequenceArg([3.14, "foo"]) is "double: 3.14, string: foo" PASS unionTypesTest.doubleOrStringSequenceArg([1, "foo", "bar", 2]) is "double: 1, string: foo, string: bar, double: 2" PASS unionTypesTest.doubleOrStringSequenceArg([null, undefined, {}, []]) is "string: null, string: undefined, string: [object Object], string: " -PASS unionTypesTest.doubleOrStringSequenceArg(null) threw exception TypeError: Failed to execute 'doubleOrStringSequenceArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties.. -PASS unionTypesTest.doubleOrStringSequenceArg(undefined) threw exception TypeError: Failed to execute 'doubleOrStringSequenceArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties.. -PASS unionTypesTest.doubleOrStringSequenceArg({}) threw exception TypeError: Failed to execute 'doubleOrStringSequenceArg' on 'UnionTypesTest': The 1st argument is neither an array, nor does it have indexed properties.. +PASS unionTypesTest.doubleOrStringSequenceArg(null) threw exception TypeError: Failed to execute 'doubleOrStringSequenceArg' on 'UnionTypesTest': The provided value cannot be converted to a sequence.. +PASS unionTypesTest.doubleOrStringSequenceArg(undefined) threw exception TypeError: Failed to execute 'doubleOrStringSequenceArg' on 'UnionTypesTest': The provided value cannot be converted to a sequence.. +PASS unionTypesTest.doubleOrStringSequenceArg({}) threw exception TypeError: Failed to execute 'doubleOrStringSequenceArg' on 'UnionTypesTest': Iterator getter is not callable.. Tests for method arguments with defaults PASS unionTypesTest.doubleOrStringDefaultDoubleArg() is "double is passed: 3.14"
diff --git a/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt b/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt index f532692..d73a00d 100644 --- a/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor-expected.txt
@@ -83,19 +83,20 @@ PASS new MessageEvent('eventType', { ports: [] }).ports is [] PASS new MessageEvent('eventType', { ports: undefined }).ports is null PASS new MessageEvent('eventType', { ports: null }).ports is null -PASS new MessageEvent('eventType', { ports: [1, 2, 3] }).ports[2] threw exception TypeError: Failed to construct 'MessageEvent': Invalid Array element type. -PASS new MessageEvent('eventType', { ports: test_object }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new MessageEvent('eventType', { ports: document }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new MessageEvent('eventType', { ports: false }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new MessageEvent('eventType', { ports: true }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new MessageEvent('eventType', { ports: '' }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new MessageEvent('eventType', { ports: 'chocolate' }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new MessageEvent('eventType', { ports: 12345 }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new MessageEvent('eventType', { ports: 18446744073709551615 }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new MessageEvent('eventType', { ports: NaN }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new MessageEvent('eventType', { get ports() { return 123; } }).ports threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. +PASS new MessageEvent('eventType', { ports: [1, 2, 3] }).ports[2] threw exception TypeError: Failed to construct 'MessageEvent': Failed to convert value to 'MessagePort'.. +PASS new MessageEvent('eventType', { ports: test_object }).ports threw exception TypeError: Failed to construct 'MessageEvent': Iterator getter is not callable.. +PASS new MessageEvent('eventType', { ports: document }).ports threw exception TypeError: Failed to construct 'MessageEvent': Iterator getter is not callable.. +PASS new MessageEvent('eventType', { ports: false }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. +PASS new MessageEvent('eventType', { ports: true }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. +PASS new MessageEvent('eventType', { ports: '' }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. +PASS new MessageEvent('eventType', { ports: 'chocolate' }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. +PASS new MessageEvent('eventType', { ports: 12345 }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. +PASS new MessageEvent('eventType', { ports: 18446744073709551615 }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. +PASS new MessageEvent('eventType', { ports: NaN }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. +PASS new MessageEvent('eventType', { get ports() { return 123; } }).ports threw exception TypeError: Failed to construct 'MessageEvent': The provided value cannot be converted to a sequence.. PASS new MessageEvent('eventType', { get ports() { throw 'MessageEvent Error'; } }) threw exception MessageEvent Error. -PASS new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0] threw exception TypeError: Failed to construct 'MessageEvent': The value provided is neither an array, nor does it have indexed properties.. +PASS new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0] threw exception TypeError: Failed to construct 'MessageEvent': Iterator getter is not callable.. +PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: {length: 3, 0: channel.port1, 1: channel.port2, 2: channel2.port1} }).ports[2] threw exception TypeError: Failed to construct 'MessageEvent': Iterator getter is not callable.. PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).bubbles is true PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).cancelable is true PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).data is test_object @@ -105,7 +106,6 @@ PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).ports[0] is channel.port1 PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).ports[1] is channel.port2 PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).ports[2] is channel2.port1 -PASS new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: {length: 3, 0: channel.port1, 1: channel.port2, 2: channel2.port1} }).ports[2] is channel2.port1 PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor.html b/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor.html index 55f18f8b..9061746d 100644 --- a/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor.html +++ b/third_party/WebKit/LayoutTests/fast/events/constructors/message-event-constructor.html
@@ -119,6 +119,7 @@ shouldThrow("new MessageEvent('eventType', { get ports() { throw 'MessageEvent Error'; } })"); // Note that valueOf() is not called, when the left hand side is evaluated. shouldThrow("new MessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0]"); +shouldThrow("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: {length: 3, 0: channel.port1, 1: channel.port2, 2: channel2.port1} }).ports[2]"); // All initializers are passed. shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).bubbles", "true"); @@ -130,7 +131,6 @@ shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).ports[0]", "channel.port1"); shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).ports[1]", "channel.port2"); shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: [channel.port1, channel.port2, channel2.port1] }).ports[2]", "channel2.port1"); -shouldBe("new MessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: window, ports: {length: 3, 0: channel.port1, 1: channel.port2, 2: channel2.port1} }).ports[2]", "channel2.port1"); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/message-event-max-ports-expected.txt b/third_party/WebKit/LayoutTests/fast/events/message-event-max-ports-expected.txt index b6338cd..a917356a 100644 --- a/third_party/WebKit/LayoutTests/fast/events/message-event-max-ports-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/events/message-event-max-ports-expected.txt
@@ -3,7 +3,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS new MessageEvent("message", {ports:{length: 1 << 29}}) threw exception RangeError: Failed to construct 'MessageEvent': Array length exceeds supported limit.. +PASS new MessageEvent("message", {ports:ports}) threw exception RangeError: Failed to construct 'MessageEvent': Array length exceeds supported limit.. PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/events/message-event-max-ports.html b/third_party/WebKit/LayoutTests/fast/events/message-event-max-ports.html index 4471732..c8babf7 100644 --- a/third_party/WebKit/LayoutTests/fast/events/message-event-max-ports.html +++ b/third_party/WebKit/LayoutTests/fast/events/message-event-max-ports.html
@@ -7,7 +7,9 @@ <script> description('Excessively long port sequences should gracefully fail.'); -shouldThrow('new MessageEvent("message", {ports:{length: 1 << 29}})'); +let ports = []; +ports.length = 1<<29; +shouldThrow('new MessageEvent("message", {ports:ports})'); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/files/blob-constructor-expected.txt b/third_party/WebKit/LayoutTests/fast/files/blob-constructor-expected.txt index 284953da3..0a6eeb57 100644 --- a/third_party/WebKit/LayoutTests/fast/files/blob-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/files/blob-constructor-expected.txt
@@ -15,9 +15,9 @@ PASS (new Blob(undefined)).size is 0 PASS (new Blob()).type is "" PASS (new Blob(undefined)).type is "" -PASS new Blob('hello') threw exception TypeError: Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties.. -PASS new Blob(0) threw exception TypeError: Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties.. -PASS new Blob(null) threw exception TypeError: Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties.. +PASS new Blob('hello') threw exception TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence.. +PASS new Blob(0) threw exception TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence.. +PASS new Blob(null) threw exception TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence.. PASS (new Blob([])) instanceof window.Blob is true PASS (new Blob(['stringPrimitive'])) instanceof window.Blob is true PASS (new Blob([String('stringObject')])) instanceof window.Blob is true @@ -81,8 +81,8 @@ PASS new Blob([(new Float64Array(100)).buffer]).size is 800 PASS new Blob([(new Float64Array(100)).buffer, (new Int32Array(100)).buffer, (new Uint8Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1400 PASS new Blob([new Blob([(new Int32Array(100)).buffer]), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1000 -PASS new Blob({length: 0}).size is 0 -PASS new Blob({length: 1, 0: 'string'}).size is 6 +PASS new Blob(createIterable([{done:true}])).size is 0 +PASS new Blob(createIterable([{done:false, value:'string'},{done:true}])).size is 6 PASS OMICRON_WITH_OXIA.charCodeAt(0) is 0x1F79 PASS reader.result.charCodeAt(0) is 0x1F79 PASS CONTAINS_UNPAIRED_SURROGATES.charCodeAt(3) is 0xDC00
diff --git a/third_party/WebKit/LayoutTests/fast/files/blob-constructor.html b/third_party/WebKit/LayoutTests/fast/files/blob-constructor.html index df34b9c..7ceae69 100644 --- a/third_party/WebKit/LayoutTests/fast/files/blob-constructor.html +++ b/third_party/WebKit/LayoutTests/fast/files/blob-constructor.html
@@ -22,9 +22,9 @@ shouldBeEqualToString("(new Blob(undefined)).type", ""); // Test invalid blob parts. -shouldThrow("new Blob('hello')", '"TypeError: Failed to construct \'Blob\': The 1st argument is neither an array, nor does it have indexed properties."'); -shouldThrow("new Blob(0)", '"TypeError: Failed to construct \'Blob\': The 1st argument is neither an array, nor does it have indexed properties."'); -shouldThrow("new Blob(null)", '"TypeError: Failed to construct \'Blob\': The 1st argument is neither an array, nor does it have indexed properties."'); +shouldThrow("new Blob('hello')", '"TypeError: Failed to construct \'Blob\': The provided value cannot be converted to a sequence."'); +shouldThrow("new Blob(0)", '"TypeError: Failed to construct \'Blob\': The provided value cannot be converted to a sequence."'); +shouldThrow("new Blob(null)", '"TypeError: Failed to construct \'Blob\': The provided value cannot be converted to a sequence."'); // Test valid blob parts. shouldBeTrue("(new Blob([])) instanceof window.Blob"); @@ -128,37 +128,44 @@ shouldThrow("new Blob([new Uint8Array(new SharedArrayBuffer(4))])", '"TypeError: Failed to construct \'Blob\': The provided ArrayBufferView value must not be shared."'); } -// Test passing blob parts in objects with indexed properties. -// (This depends on the bindings code handling of sequence<T>) -shouldBe("new Blob({length: 0}).size", "0"); -shouldBe("new Blob({length: 1, 0: 'string'}).size", "6"); +// Custom iterators, converted via the bindings code to sequence<T>. +function createIterable(iterations) { + return { + [Symbol.iterator]() { + var i = 0; + return {next: () => iterations[i++]}; + }, + }; +} +shouldBe("new Blob(createIterable([{done:true}])).size", "0"); +shouldBe("new Blob(createIterable([{done:false, value:'string'},{done:true}])).size", "6"); testNormalization(); function testNormalization() { - // Test that strings are not NFC normalized - OMICRON_WITH_OXIA = '\u1F79'; // NFC normalized to U+3CC - shouldBe("OMICRON_WITH_OXIA.charCodeAt(0)", "0x1F79"); - reader = new FileReader(); - reader.readAsText(new Blob([OMICRON_WITH_OXIA])); - reader.onload = function() { - shouldBe("reader.result.charCodeAt(0)", "0x1F79"); - testEncodingReplacements(); - }; + // Test that strings are not NFC normalized + OMICRON_WITH_OXIA = '\u1F79'; // NFC normalized to U+3CC + shouldBe("OMICRON_WITH_OXIA.charCodeAt(0)", "0x1F79"); + reader = new FileReader(); + reader.readAsText(new Blob([OMICRON_WITH_OXIA])); + reader.onload = function() { + shouldBe("reader.result.charCodeAt(0)", "0x1F79"); + testEncodingReplacements(); + }; } function testEncodingReplacements() { - // Test that invalid UTF-16 code units are replaced. - CONTAINS_UNPAIRED_SURROGATES = 'abc\uDC00def\uD800ghi'; - shouldBe("CONTAINS_UNPAIRED_SURROGATES.charCodeAt(3)", "0xDC00"); - shouldBe("CONTAINS_UNPAIRED_SURROGATES.charCodeAt(7)", "0xD800"); - reader = new FileReader(); - reader.readAsText(new Blob([CONTAINS_UNPAIRED_SURROGATES])); - reader.onload = function() { - shouldBe("reader.result.charCodeAt(3)", "0xFFFD"); - shouldBe("reader.result.charCodeAt(7)", "0xFFFD"); - finishJSTest(); - }; + // Test that invalid UTF-16 code units are replaced. + CONTAINS_UNPAIRED_SURROGATES = 'abc\uDC00def\uD800ghi'; + shouldBe("CONTAINS_UNPAIRED_SURROGATES.charCodeAt(3)", "0xDC00"); + shouldBe("CONTAINS_UNPAIRED_SURROGATES.charCodeAt(7)", "0xD800"); + reader = new FileReader(); + reader.readAsText(new Blob([CONTAINS_UNPAIRED_SURROGATES])); + reader.onload = function() { + shouldBe("reader.result.charCodeAt(3)", "0xFFFD"); + shouldBe("reader.result.charCodeAt(7)", "0xFFFD"); + finishJSTest(); + }; } </script>
diff --git a/third_party/WebKit/LayoutTests/fast/files/file-constructor-expected.txt b/third_party/WebKit/LayoutTests/fast/files/file-constructor-expected.txt index 81e3fad57c..d5eb656 100644 --- a/third_party/WebKit/LayoutTests/fast/files/file-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/files/file-constructor-expected.txt
@@ -16,9 +16,9 @@ PASS (new File([], 1)) instanceof window.File is true PASS (new File([], '')) instanceof window.File is true PASS (new File([], document)) instanceof window.File is true -PASS new File('hello', 'world.html') threw exception TypeError: Failed to construct 'File': The 1st argument is neither an array, nor does it have indexed properties.. -PASS new File(0, 'world.html') threw exception TypeError: Failed to construct 'File': The 1st argument is neither an array, nor does it have indexed properties.. -PASS new File(null, 'world.html') threw exception TypeError: Failed to construct 'File': The 1st argument is neither an array, nor does it have indexed properties.. +PASS new File('hello', 'world.html') threw exception TypeError: Failed to construct 'File': The provided value cannot be converted to a sequence.. +PASS new File(0, 'world.html') threw exception TypeError: Failed to construct 'File': The provided value cannot be converted to a sequence.. +PASS new File(null, 'world.html') threw exception TypeError: Failed to construct 'File': The provided value cannot be converted to a sequence.. PASS (new File([], 'world.html')) instanceof window.File is true PASS (new File(['stringPrimitive'], 'world.html')) instanceof window.File is true PASS (new File([String('stringObject')], 'world.html')) instanceof window.File is true @@ -99,8 +99,8 @@ PASS new File([new Blob([(new Int32Array(100)).buffer]), new File([new Uint16Array(100).buffer], 'world.txt'), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer], 'world.html').size is 1200 PASS new Blob([new Blob([new Int32Array(100)]), new File([new Uint16Array(100)], 'world.txt'), new Uint8Array(100), new Float32Array(100), new DataView(new ArrayBuffer(100))]).size is 1200 PASS new Blob([new Blob([(new Int32Array(100)).buffer]), new File([new Uint16Array(100).buffer], 'world.txt'), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1200 -PASS new File({length: 0}, 'world.txt').size is 0 -PASS new File({length: 1, 0: 'string'}, 'world.txt').size is 6 +PASS new File(createIterable([{done:true}]), 'world.txt').size is 0 +PASS new File(createIterable([{done:false, value:'string'},{done:true}]), 'world.txt').size is 6 PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/files/file-constructor.html b/third_party/WebKit/LayoutTests/fast/files/file-constructor.html index 37dc7e6b..bd6e8a2f 100644 --- a/third_party/WebKit/LayoutTests/fast/files/file-constructor.html +++ b/third_party/WebKit/LayoutTests/fast/files/file-constructor.html
@@ -26,9 +26,9 @@ shouldBeTrue("(new File([], document)) instanceof window.File"); // Test invalid file parts. -shouldThrow("new File('hello', 'world.html')", '"TypeError: Failed to construct \'File\': The 1st argument is neither an array, nor does it have indexed properties."'); -shouldThrow("new File(0, 'world.html')", '"TypeError: Failed to construct \'File\': The 1st argument is neither an array, nor does it have indexed properties."'); -shouldThrow("new File(null, 'world.html')", '"TypeError: Failed to construct \'File\': The 1st argument is neither an array, nor does it have indexed properties."'); +shouldThrow("new File('hello', 'world.html')", '"TypeError: Failed to construct \'File\': The provided value cannot be converted to a sequence."'); +shouldThrow("new File(0, 'world.html')", '"TypeError: Failed to construct \'File\': The provided value cannot be converted to a sequence."'); +shouldThrow("new File(null, 'world.html')", '"TypeError: Failed to construct \'File\': The provided value cannot be converted to a sequence."'); // Test valid file parts. shouldBeTrue("(new File([], 'world.html')) instanceof window.File"); @@ -151,8 +151,15 @@ shouldBe("new Blob([new Blob([new Int32Array(100)]), new File([new Uint16Array(100)], 'world.txt'), new Uint8Array(100), new Float32Array(100), new DataView(new ArrayBuffer(100))]).size", "1200"); shouldBe("new Blob([new Blob([(new Int32Array(100)).buffer]), new File([new Uint16Array(100).buffer], 'world.txt'), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size", "1200"); -// Test passing blob parts in objects with indexed properties. -// (This depends on the bindings code handling of sequence<T>) -shouldBe("new File({length: 0}, 'world.txt').size", "0"); -shouldBe("new File({length: 1, 0: 'string'}, 'world.txt').size", "6"); +// Custom iterators, converted via the bindings code to sequence<T>. +function createIterable(iterations) { + return { + [Symbol.iterator]() { + var i = 0; + return {next: () => iterations[i++]}; + }, + }; +} +shouldBe("new File(createIterable([{done:true}]), 'world.txt').size", "0"); +shouldBe("new File(createIterable([{done:false, value:'string'},{done:true}]), 'world.txt').size", "6"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor-expected.txt b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor-expected.txt index ee3f5df0..f35fa621 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamConstructor-expected.txt
@@ -14,10 +14,10 @@ PASS localStream.getVideoTracks().length is 1 PASS checkIdAttribute(localStream.id) is true PASS new MediaStream(document) threw exception TypeError: Failed to construct 'MediaStream': No matching constructor signature.. -PASS new MediaStream([document]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. -PASS new MediaStream([stream.getAudioTracks()[0], document]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. -PASS new MediaStream([null]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. -PASS new MediaStream([undefined]) threw exception TypeError: Failed to construct 'MediaStream': Invalid Array element type. +PASS new MediaStream([document]) threw exception TypeError: Failed to construct 'MediaStream': Failed to convert value to 'MediaStreamTrack'.. +PASS new MediaStream([stream.getAudioTracks()[0], document]) threw exception TypeError: Failed to construct 'MediaStream': Failed to convert value to 'MediaStreamTrack'.. +PASS new MediaStream([null]) threw exception TypeError: Failed to construct 'MediaStream': Failed to convert value to 'MediaStreamTrack'.. +PASS new MediaStream([undefined]) threw exception TypeError: Failed to construct 'MediaStream': Failed to convert value to 'MediaStreamTrack'.. PASS new MediaStream(null) threw exception TypeError: Failed to construct 'MediaStream': No matching constructor signature.. PASS new MediaStream(undefined) threw exception TypeError: Failed to construct 'MediaStream': No matching constructor signature.. Stream constructed
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-expected.txt b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-expected.txt index c2d3e6f96..389da5ae 100644 --- a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-expected.txt
@@ -21,7 +21,7 @@ PASS new RTCPeerConnection({iceServers:[{urls:['stun:foo.com', 'turn:foo.com'], username:'x', credential:'x'}]}); did not throw exception. PASS new RTCPeerConnection({iceServers:[{urls:['stun:foo.com', 'turn:foo.com']}]}); threw exception InvalidAccessError: Failed to construct 'RTCPeerConnection': Both username and credential are required when the URL scheme is "turn" or "turns".. PASS new RTCPeerConnection({fooServers:[]}); did not throw exception. -PASS new RTCPeerConnection({iceServers:true}); threw exception TypeError: Failed to construct 'RTCPeerConnection': The value provided is neither an array, nor does it have indexed properties.. +PASS new RTCPeerConnection({iceServers:true}); threw exception TypeError: Failed to construct 'RTCPeerConnection': The provided value cannot be converted to a sequence.. PASS new RTCPeerConnection({iceServers:[1, 2, 3]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': cannot convert to dictionary.. PASS new RTCPeerConnection({iceServers:[{}]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed RTCIceServer. PASS new RTCPeerConnection({iceServers:[{url:'foo'}]}); threw exception SyntaxError: Failed to construct 'RTCPeerConnection': 'foo' is not a valid URL.. @@ -60,11 +60,11 @@ PASS new RTCPeerConnection(null, {valid_and_supported_1:1}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed constraints object.. PASS new RTCPeerConnection(null, {valid_but_unsupported_1:1}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed constraints object.. PASS new RTCPeerConnection(null, {valid_and_supported_2:1, mandatory:{valid_and_supported_1:1}}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Malformed constraints object.. -PASS new RTCPeerConnection({iceServers:[], certificates:null}); threw exception TypeError: Failed to construct 'RTCPeerConnection': The value provided is neither an array, nor does it have indexed properties.. +PASS new RTCPeerConnection({iceServers:[], certificates:null}); threw exception TypeError: Failed to construct 'RTCPeerConnection': The provided value cannot be converted to a sequence.. PASS new RTCPeerConnection({iceServers:[], certificates:undefined}); did not throw exception. PASS new RTCPeerConnection({iceServers:[], certificates:[]}); did not throw exception. -PASS new RTCPeerConnection({iceServers:[], certificates:[null]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Invalid Array element type. -PASS new RTCPeerConnection({iceServers:[], certificates:[1337]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Invalid Array element type. +PASS new RTCPeerConnection({iceServers:[], certificates:[null]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Failed to convert value to 'RTCCertificate'.. +PASS new RTCPeerConnection({iceServers:[], certificates:[1337]}); threw exception TypeError: Failed to construct 'RTCPeerConnection': Failed to convert value to 'RTCCertificate'.. PASS new RTCPeerConnection({iceServers:[], certificates:[certRSA]}, null); did not throw exception. PASS new RTCPeerConnection({iceServers:[], certificates:[certECDSA]}, null); did not throw exception. PASS certExpired.expires <= new Date().getTime() is true
diff --git a/third_party/WebKit/LayoutTests/paint/pagination/pagination-change-clip-crash-expected.txt b/third_party/WebKit/LayoutTests/paint/pagination/pagination-change-clip-crash-expected.txt new file mode 100644 index 0000000..ef1810a --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/pagination/pagination-change-clip-crash-expected.txt
@@ -0,0 +1,33 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [785, 736], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutView #document", + "rect": [0, 636, 785, 100], + "reason": "incremental" + } + ] + }, + { + "name": "LayoutBlockFlow DIV id='background'", + "position": [8, 428], + "bounds": [769, 300] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutView #document", + "reason": "incremental" + }, + { + "object": "LayoutBlockFlow DIV id='background'", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/paint/pagination/pagination-change-clip-crash.html b/third_party/WebKit/LayoutTests/paint/pagination/pagination-change-clip-crash.html new file mode 100644 index 0000000..2b8bb91 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/pagination/pagination-change-clip-crash.html
@@ -0,0 +1,15 @@ +<!doctype HTML> +<script src="../invalidation/resources/text-based-repaint.js"></script> +Passes if it does not crash. +<div id=multicol style="columns:3;"> + <div style="height:300px; background:white;"> + </div> +</div> +<div style="width: 10px; height: 300px"></div> +<div style="height:200px; transform: translateZ(0)" id="background"> +<script> +function repaintTest() { + background.style.padding = "50px"; +} +onload = runRepaintTest; +</script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/FileAPI/blob/Blob-constructor-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/FileAPI/blob/Blob-constructor-expected.txt index 7681618..dc7cce1 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/FileAPI/blob/Blob-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/FileAPI/blob/Blob-constructor-expected.txt
@@ -1,21 +1,19 @@ This is a testharness.js-based test. -Found 61 tests; 54 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 61 tests; 57 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Blob interface object PASS Blob constructor with no arguments PASS Blob constructor with no arguments, without 'new' PASS Blob constructor without brackets PASS Blob constructor with undefined as first argument -FAIL Passing non-objects, Dates and RegExps for blobParts should throw a TypeError. assert_throws: Should throw for argument object "[object Object]". function "function () { - new Blob(arg); - }" did not throw -FAIL A plain object with @@iterator should be treated as a sequence for the blobParts argument. Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties. +PASS Passing non-objects, Dates and RegExps for blobParts should throw a TypeError. +PASS A plain object with @@iterator should be treated as a sequence for the blobParts argument. PASS A plain object with @@iterator and a length property should be treated as a sequence for the blobParts argument. PASS A String object should be treated as a sequence for the blobParts argument. PASS A Uint8Array object should be treated as a sequence for the blobParts argument. PASS The length getter should be invoked and any exceptions should be propagated. PASS A platform object that supports indexed properties should be treated as a sequence for the blobParts argument (overwritten 'length'.) PASS ToUint32 should be applied to the length and any exceptions should be propagated. -FAIL Getters and value conversions should happen in order until an exception is thrown. assert_array_equals: lengths differ, expected 8 got 5 +PASS Getters and value conversions should happen in order until an exception is thrown. PASS ToString should be called on elements of the blobParts array and any exceptions should be propagated. FAIL Changes to the blobParts array should be reflected in the returned Blob (pop). assert_equals: expected 4 but got 13 FAIL Changes to the blobParts array should be reflected in the returned Blob (unshift). assert_equals: expected 4 but got 2
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/FileAPI/blob/Blob-constructor-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/FileAPI/blob/Blob-constructor-expected.txt index 951ac6f..e35edb1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/FileAPI/blob/Blob-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/FileAPI/blob/Blob-constructor-expected.txt
@@ -1,21 +1,19 @@ This is a testharness.js-based test. -Found 61 tests; 54 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 61 tests; 57 PASS, 4 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Blob interface object PASS Blob constructor with no arguments PASS Blob constructor with no arguments, without 'new' PASS Blob constructor without brackets PASS Blob constructor with undefined as first argument -FAIL Passing non-objects, Dates and RegExps for blobParts should throw a TypeError. assert_throws: Should throw for argument object "[object Object]". function "function () { - new Blob(arg); - }" did not throw -FAIL A plain object with @@iterator should be treated as a sequence for the blobParts argument. Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties. +PASS Passing non-objects, Dates and RegExps for blobParts should throw a TypeError. +PASS A plain object with @@iterator should be treated as a sequence for the blobParts argument. PASS A plain object with @@iterator and a length property should be treated as a sequence for the blobParts argument. PASS A String object should be treated as a sequence for the blobParts argument. PASS A Uint8Array object should be treated as a sequence for the blobParts argument. PASS The length getter should be invoked and any exceptions should be propagated. PASS A platform object that supports indexed properties should be treated as a sequence for the blobParts argument (overwritten 'length'.) PASS ToUint32 should be applied to the length and any exceptions should be propagated. -FAIL Getters and value conversions should happen in order until an exception is thrown. assert_array_equals: lengths differ, expected 8 got 5 +PASS Getters and value conversions should happen in order until an exception is thrown. PASS ToString should be called on elements of the blobParts array and any exceptions should be propagated. FAIL Changes to the blobParts array should be reflected in the returned Blob (pop). assert_equals: expected 4 but got 13 FAIL Changes to the blobParts array should be reflected in the returned Blob (unshift). assert_equals: expected 4 but got 2
diff --git a/third_party/WebKit/LayoutTests/storage/websql/execute-sql-args-expected.txt b/third_party/WebKit/LayoutTests/storage/websql/execute-sql-args-expected.txt index 78fee448..d0b4991 100644 --- a/third_party/WebKit/LayoutTests/storage/websql/execute-sql-args-expected.txt +++ b/third_party/WebKit/LayoutTests/storage/websql/execute-sql-args-expected.txt
@@ -6,8 +6,8 @@ PASS. executeSql("", undefined) did not throw an exception PASS. executeSql("", []) did not throw an exception PASS. executeSql("", [ "arg0" ]) did not throw an exception -PASS. executeSql("", { length: 0 }) did not throw an exception -PASS. executeSql("", { length: 1, 0: "arg0" }) did not throw an exception +PASS. executeSql("", emptyIterableObject) did not throw an exception +PASS. executeSql("", singleItemIterableObject) did not throw an exception PASS. executeSql("", null, null) did not throw an exception PASS. executeSql("", null, undefined) did not throw an exception PASS. executeSql("", null, function(){}) did not throw an exception @@ -22,6 +22,8 @@ PASS. executeSql("", 0) threw an exception as expected. PASS. executeSql("", "") threw an exception as expected. PASS. executeSql("", { }) threw an exception as expected. +PASS. executeSql("", { length: 0 }) threw an exception as expected. +PASS. executeSql("", { length: 1, 0: "arg0" }) threw an exception as expected. PASS. executeSql("", null, 0) threw an exception as expected. PASS. executeSql("", null, "") threw an exception as expected. PASS. executeSql("", null, { }) threw an exception as expected.
diff --git a/third_party/WebKit/LayoutTests/storage/websql/execute-sql-args.js b/third_party/WebKit/LayoutTests/storage/websql/execute-sql-args.js index 551f067..b7b6691 100644 --- a/third_party/WebKit/LayoutTests/storage/websql/execute-sql-args.js +++ b/third_party/WebKit/LayoutTests/storage/websql/execute-sql-args.js
@@ -7,6 +7,17 @@ var throwOnGetZeroObject = { length: 1 }; throwOnGetZeroObject.__defineGetter__("0", function () { throw "Cannot get 0 property of this object."; }); +function createIterable(iterations) { + return { + [Symbol.iterator]() { + var i = 0; + return {next: () => iterations[i++]}; + }, + }; +} +var emptyIterableObject = createIterable([{done: true}]); +var singleItemIterableObject = createIterable([{done: false, value: "arg0"}, {done: true}]); + var expectNoException = [ 'null', 'undefined', @@ -16,8 +27,8 @@ '"", undefined', '"", []', '"", [ "arg0" ]', - '"", { length: 0 }', - '"", { length: 1, 0: "arg0" }', + '"", emptyIterableObject', + '"", singleItemIterableObject', '"", null, null', '"", null, undefined', '"", null, function(){}', @@ -35,6 +46,8 @@ '"", 0', '"", ""', '"", { }', + '"", { length: 0 }', + '"", { length: 1, 0: "arg0" }', '"", null, 0', '"", null, ""', '"", null, { }',
diff --git a/third_party/WebKit/LayoutTests/virtual/layout_ng/external/wpt/css/CSS2/normal-flow/README.txt b/third_party/WebKit/LayoutTests/virtual/layout_ng/external/wpt/css/CSS2/normal-flow/README.txt new file mode 100644 index 0000000..d1d6195d --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/layout_ng/external/wpt/css/CSS2/normal-flow/README.txt
@@ -0,0 +1,3 @@ +# This suite runs the tests in external/wpt/css/CSS2/normal-flow with +# --enable-blink-features=LayoutNG. +# The LayoutNG project is described here: http://goo.gl/1hwhfX
diff --git a/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/fast/files/blob-constructor-expected.txt b/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/fast/files/blob-constructor-expected.txt index 195ef38..fba6ca5 100644 --- a/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/fast/files/blob-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/fast/files/blob-constructor-expected.txt
@@ -15,9 +15,9 @@ PASS (new Blob(undefined)).size is 0 PASS (new Blob()).type is "" PASS (new Blob(undefined)).type is "" -PASS new Blob('hello') threw exception TypeError: Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties.. -PASS new Blob(0) threw exception TypeError: Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties.. -PASS new Blob(null) threw exception TypeError: Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties.. +PASS new Blob('hello') threw exception TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence.. +PASS new Blob(0) threw exception TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence.. +PASS new Blob(null) threw exception TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence.. PASS (new Blob([])) instanceof window.Blob is true PASS (new Blob(['stringPrimitive'])) instanceof window.Blob is true PASS (new Blob([String('stringObject')])) instanceof window.Blob is true @@ -82,8 +82,8 @@ PASS new Blob([(new Float64Array(100)).buffer, (new Int32Array(100)).buffer, (new Uint8Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1400 PASS new Blob([new Blob([(new Int32Array(100)).buffer]), (new Uint8Array(100)).buffer, (new Float32Array(100)).buffer, (new DataView(new ArrayBuffer(100))).buffer]).size is 1000 PASS new Blob([new Uint8Array(new SharedArrayBuffer(4))]) threw exception TypeError: Failed to construct 'Blob': The provided ArrayBufferView value must not be shared.. -PASS new Blob({length: 0}).size is 0 -PASS new Blob({length: 1, 0: 'string'}).size is 6 +PASS new Blob(createIterable([{done:true}])).size is 0 +PASS new Blob(createIterable([{done:false, value:'string'},{done:true}])).size is 6 PASS OMICRON_WITH_OXIA.charCodeAt(0) is 0x1F79 PASS reader.result.charCodeAt(0) is 0x1F79 PASS CONTAINS_UNPAIRED_SURROGATES.charCodeAt(3) is 0xDC00
diff --git a/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/webaudio/dom-exceptions-expected.txt b/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/webaudio/dom-exceptions-expected.txt index 686176d7..824bb4c 100644 --- a/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/webaudio/dom-exceptions-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/sharedarraybuffer/webaudio/dom-exceptions-expected.txt
@@ -44,8 +44,8 @@ PASS context.createChannelMerger(99) threw IndexSizeError: "Failed to execute 'createChannelMerger' on 'BaseAudioContext': The number of inputs provided (99) is outside the range [1, 32].". PASS < [createChannelMerger] All assertions passed. (total 1 assertions) PASS > [createPeriodicWave] -PASS context.createPeriodicWave(null, null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': The 1st argument is neither an array, nor does it have indexed properties.". -PASS context.createPeriodicWave(new Float32Array(10), null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': The 2nd argument is neither an array, nor does it have indexed properties.". +PASS context.createPeriodicWave(null, null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': The provided value cannot be converted to a sequence.". +PASS context.createPeriodicWave(new Float32Array(10), null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': The provided value cannot be converted to a sequence.". PASS context.createPeriodicWave(new Float32Array(4100), new Float32Array(4100)) did not throw an exception. PASS context.createPeriodicWave(new Float32Array(8192), new Float32Array(8192)) did not throw an exception. PASS context.createPeriodicWave(new Float32Array(10000), new Float32Array(10000)) did not throw an exception. @@ -103,7 +103,7 @@ PASS context.destination.channelCount = 99 threw IndexSizeError: [error message omitted]. PASS < [channel-stuff] All assertions passed. (total 7 assertions) PASS > [audioparam] -PASS param.setValueCurveAtTime(null, 0, 0) threw TypeError: "Failed to execute 'setValueCurveAtTime' on 'AudioParam': The 1st argument is neither an array, nor does it have indexed properties.". +PASS param.setValueCurveAtTime(null, 0, 0) threw TypeError: "Failed to execute 'setValueCurveAtTime' on 'AudioParam': The provided value cannot be converted to a sequence.". PASS node.gain.exponentialRampToValueAtTime(-1, 0.1) did not throw an exception. PASS node.gain.exponentialRampToValueAtTime(0, 0.1) threw InvalidAccessError: "Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).". PASS node.gain.exponentialRampToValueAtTime(1e-100, 0.1) threw InvalidAccessError: "Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).".
diff --git a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-low-freq.html b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-low-freq.html index 5a1e0d2..46d33147 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-low-freq.html +++ b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-low-freq.html
@@ -5,7 +5,7 @@ <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> - <script src="../resources/audio-testing.js"></script> + <script src="../resources/audit.js"></script> </head> <body> @@ -34,7 +34,7 @@ var audit = Audit.createTaskRunner(); // Compute the SNR between the actual result and expected cosine wave - function checkCosineResult(result, freq, sampleRate) { + function checkCosineResult(should, result, freq, sampleRate) { var signal = 0; var noise = 0; var omega = 2 * Math.PI * freq / sampleRate; @@ -50,13 +50,11 @@ var snr = 10 * Math.log10(signal / noise); - Should("SNR of " + desiredFrequencyHz + " Hz sine wave", snr, { - brief: true - }).beGreaterThanOrEqualTo(snrThreshold); - testPassed("PeriodicWave coefficients that must be ignored were correctly ignored."); + should(snr, "SNR of " + desiredFrequencyHz + " Hz sine wave") + .beGreaterThanOrEqualTo(snrThreshold); } - function runTest() { + audit.define("low-freq-oscillator", (task, should) => { context = new OfflineAudioContext(1, sampleRate, sampleRate); osc = context.createOscillator(); @@ -76,11 +74,12 @@ osc.connect(context.destination); osc.start(); context.startRendering().then(function (buffer) { - checkCosineResult(buffer, desiredFrequencyHz, sampleRate); - }); - }; + checkCosineResult(should, buffer, desiredFrequencyHz, sampleRate); + }) + .then(() => task.done()); + }); - runTest(); + audit.run(); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-negative-freq.html b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-negative-freq.html index 26088cb..3a06a02 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-negative-freq.html +++ b/third_party/WebKit/LayoutTests/webaudio/Oscillator/osc-negative-freq.html
@@ -4,7 +4,7 @@ <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> - <script src="../resources/audio-testing.js"></script> + <script src="../resources/audit.js"></script> <title>Test OscillatorNode with Negative Frequency</title> </head> @@ -22,40 +22,40 @@ var audit = Audit.createTaskRunner(); - audit.defineTask("sine", function (done) { - runTest({ + audit.define("sine", (task, should) => { + runTest(should, { message: "Sum of positive and negative frequency sine oscillators", type: "sine", threshold: 3.5763e-7 - }).then(done); + }).then(() => task.done()); }); - audit.defineTask("square", function (done) { - runTest({ + audit.define("square", (task, should) => { + runTest(should, { message: "Sum of positive and negative frequency square oscillators", type: "square", threshold: 1.4753e-6 - }).then(done); + }).then(() => task.done()); }); - audit.defineTask("sawtooth", function (done) { - runTest({ + audit.define("sawtooth", (task, should) => { + runTest(should, { message: "Sum of positive and negative frequency sawtooth oscillators", type: "sawtooth", threshold: 1.4753e-6 - }).then(done); + }).then(() => task.done()); }); - audit.defineTask("triangle", function (done) { - runTest({ + audit.define("triangle", (task, should) => { + runTest(should, { message: "Sum of positive and negative frequency triangle oscillators", type: "triangle", threshold: 2.9803e-7 - }).then(done); + }).then(() => task.done()); }); - audit.defineTask("auto-sawtooth", function (done) { - runTest({ + audit.define("auto-sawtooth", (task, should) => { + runTest(should, { message: "Sum of positive and negative frequency-ramped sawtooth oscillators", type: "sawtooth", automation: { @@ -66,10 +66,10 @@ endFrequency: sampleRate / 4 }, threshold: 1.2368e-6 - }).then(done); + }).then(() => task.done()); }); - audit.defineTask("periodic-wave", function (done) { + audit.define("periodic-wave", (task, should) => { // Test negative frequencies for a custom oscillator. Two channels are // needed for the context; one for the expected result, and one for the // actual, as explained below. @@ -139,17 +139,17 @@ var expected = buffer.getChannelData(0); var actual = buffer.getChannelData(1); - Should("Sum of positive and negative frequency custom oscillators", - actual, { - precision: 6 - }) - .beCloseToArray(expected, 3.5763e-7); - }).then(done); + should(actual, + "Sum of positive and negative frequency custom oscillators") + .beCloseToArray(expected, { + absoluteThreshold: 3.5763e-7 + }); + }).then(() => task.done()); }); - audit.runTasks(); + audit.run(); - function runTest(options) { + function runTest(should, options) { // To test if negative frequencies work, create two oscillators. One // has a positive frequency and the other has a negative frequency. // Sum the oscillator outputs; the output should be zero because all of @@ -183,11 +183,10 @@ return context.startRendering().then(function (buffer) { var result = buffer.getChannelData(0); - var zero = new Float32Array(result.length); - zero.fill(0); - Should(options.message, result, { - verbose: true - }).beCloseToArray(zero, options.threshold || 0); + should(result, options.message) + .beCloseToArray(new Float32Array(result.length), { + absoluteThreshold: options.threshold || 0 + }); }); } </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/Oscillator/oscillator-basic.html b/third_party/WebKit/LayoutTests/webaudio/Oscillator/oscillator-basic.html index 88a070a2..9981d83 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Oscillator/oscillator-basic.html +++ b/third_party/WebKit/LayoutTests/webaudio/Oscillator/oscillator-basic.html
@@ -8,7 +8,7 @@ <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> -<script src="../resources/audio-testing.js"></script> +<script src="../resources/audit.js"></script> </head> <body> @@ -18,44 +18,52 @@ var oscTypes = ["sine", "square", "sawtooth", "triangle", "custom"]; -function runTest() -{ +let audit = Audit.createTaskRunner(); + +audit.define("basic osc tests", (task, should) => { // Create offline audio context. - var context = new OfflineAudioContext(2, sampleRate * renderLengthSeconds, sampleRate); + var context = new OfflineAudioContext(2, sampleRate * + renderLengthSeconds, sampleRate); var osc = context.createOscillator(); - // Set each possible oscillator type (except CUSTOM) and verify that the type is correct. - // Here we're setting the type using WebIDL enum values which are strings. + // Set each possible oscillator type (except CUSTOM) and verify that the + // type is correct. Here we're setting the type using WebIDL enum values + // which are strings. for (var k = 0; k < oscTypes.length - 1; ++k) { osc.type = oscTypes[k]; - Should("osc.type = '" + oscTypes[k] + "'", osc.type).beEqualTo(oscTypes[k]); + should(osc.type, "osc.type = '" + oscTypes[k] + "'") + .beEqualTo(oscTypes[k]); } - // Verify that setting a custom type directly does not set the custom type. This test has to be - // done before using setPeriodicWave. - - Should("osc.type = 'custom'", function () { - osc.type = "custom"; - }).throw('InvalidStateError'); + // Verify that setting a custom type directly does not set the custom + // type. This test has to be done before using setPeriodicWave. + + should(function () { + osc.type = "custom"; + }, "osc.type = 'custom'") + .throw('InvalidStateError'); // Now set a custom oscillator var coeffA = new Float32Array([0, 1, 0.5]); - var coeffB = new Float32Array([0, 0, 0]); + var coeffB = new Float32Array([0, 0, 0]); var wave = context.createPeriodicWave(coeffA, coeffB); - Should("osc.setPeriodicWave(wave)", function () { - osc.setPeriodicWave(wave); - }).notThrow(); - Should("After setting periodicWave, osc.type", osc.type).beEqualTo("custom"); - + should(function () { + osc.setPeriodicWave(wave); + }, "osc.setPeriodicWave(wave)").notThrow(); + should(osc.type, "After setting periodicWave, osc.type") + .beEqualTo("custom"); + // Check that numerical values are no longer supported var oldType = osc.type; osc.type = 0; - Should("osc.type = 0", osc.type).notBeEqualTo(0); - Should("osc.type", osc.type).beEqualTo(oldType); -} + should(osc.type, "osc.type = 0").notBeEqualTo(0); + should(osc.type, "osc.type").beEqualTo(oldType); -runTest(); + task.done(); +}); + +audit.run(); </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/Oscillator/oscillator-late-start.html b/third_party/WebKit/LayoutTests/webaudio/Oscillator/oscillator-late-start.html index 38232bc4..6d757bca 100644 --- a/third_party/WebKit/LayoutTests/webaudio/Oscillator/oscillator-late-start.html +++ b/third_party/WebKit/LayoutTests/webaudio/Oscillator/oscillator-late-start.html
@@ -5,7 +5,7 @@ <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> <script src="../resources/audit-util.js"></script> - <script src="../resources/audio-testing.js"></script> + <script src="../resources/audit.js"></script> <script src="../resources/late-start-testing.js"></script> </head>
diff --git a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt index 715f8bf..870937f5 100644 --- a/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt +++ b/third_party/WebKit/LayoutTests/webaudio/dom-exceptions-expected.txt
@@ -44,8 +44,8 @@ PASS context.createChannelMerger(99) threw IndexSizeError: "Failed to execute 'createChannelMerger' on 'BaseAudioContext': The number of inputs provided (99) is outside the range [1, 32].". PASS < [createChannelMerger] All assertions passed. (total 1 assertions) PASS > [createPeriodicWave] -PASS context.createPeriodicWave(null, null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': The 1st argument is neither an array, nor does it have indexed properties.". -PASS context.createPeriodicWave(new Float32Array(10), null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': The 2nd argument is neither an array, nor does it have indexed properties.". +PASS context.createPeriodicWave(null, null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': The provided value cannot be converted to a sequence.". +PASS context.createPeriodicWave(new Float32Array(10), null) threw TypeError: "Failed to execute 'createPeriodicWave' on 'BaseAudioContext': The provided value cannot be converted to a sequence.". PASS context.createPeriodicWave(new Float32Array(4100), new Float32Array(4100)) did not throw an exception. PASS context.createPeriodicWave(new Float32Array(8192), new Float32Array(8192)) did not throw an exception. PASS context.createPeriodicWave(new Float32Array(10000), new Float32Array(10000)) did not throw an exception. @@ -99,7 +99,7 @@ PASS context.destination.channelCount = 99 threw IndexSizeError: [error message omitted]. PASS < [channel-stuff] All assertions passed. (total 7 assertions) PASS > [audioparam] -PASS param.setValueCurveAtTime(null, 0, 0) threw TypeError: "Failed to execute 'setValueCurveAtTime' on 'AudioParam': The 1st argument is neither an array, nor does it have indexed properties.". +PASS param.setValueCurveAtTime(null, 0, 0) threw TypeError: "Failed to execute 'setValueCurveAtTime' on 'AudioParam': The provided value cannot be converted to a sequence.". PASS node.gain.exponentialRampToValueAtTime(-1, 0.1) did not throw an exception. PASS node.gain.exponentialRampToValueAtTime(0, 0.1) threw InvalidAccessError: "Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).". PASS node.gain.exponentialRampToValueAtTime(1e-100, 0.1) threw InvalidAccessError: "Failed to execute 'exponentialRampToValueAtTime' on 'AudioParam': The float target value provided (0) should not be in the range (-1.40130e-45, 1.40130e-45).".
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/late-start-testing.js b/third_party/WebKit/LayoutTests/webaudio/resources/late-start-testing.js index 49baebb..2d6dc0b0 100644 --- a/third_party/WebKit/LayoutTests/webaudio/resources/late-start-testing.js +++ b/third_party/WebKit/LayoutTests/webaudio/resources/late-start-testing.js
@@ -13,7 +13,7 @@ node.connect(context.destination); // Task: schedule a suspend and start rendering. - audit.defineTask('test-late-start', function (done) { + audit.define('test-late-start', (task, should) => { // The node's start time will be clamped to the render quantum boundary // >0.1 sec. Thus the rendered buffer will have non-zero frames. // See issue: crbug.com/462167 @@ -35,17 +35,13 @@ } } - var success = - Should('The index of first non-zero value',nonZeroValueIndex) + should(nonZeroValueIndex, 'The index of first non-zero value') .notBeEqualTo(-1); - success = Should('The first sample value', channelData[0]) - .beEqualTo(0) && success; - Should('The rendered buffer', success) - .summarize('contains non-zero values after the first sample', - 'was all zeros or has non-zero first sample.'); - done(); + should(channelData[0], 'The first sample value') + .beEqualTo(0); + task.done(); }); }); - audit.runTasks(); + audit.run(); }
diff --git a/third_party/WebKit/PerformanceTests/Bindings/sequence-conversion-custom-iterator.html b/third_party/WebKit/PerformanceTests/Bindings/sequence-conversion-custom-iterator.html new file mode 100644 index 0000000..f60fb45 --- /dev/null +++ b/third_party/WebKit/PerformanceTests/Bindings/sequence-conversion-custom-iterator.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/runner.js"></script> +<script> +let dataArray = []; +for (let i = 0; i < 100000; i++) + dataArray.push(''); + +let iterableData = { + [Symbol.iterator]() { + var count = 0; + return { + next() { + if (count >= dataArray.length) + return {done: true}; + return {done: false, value: dataArray[count++]}; + } + } + } +}; + +PerfTestRunner.measureRunsPerSecond({ + description: "This benchmark measures the overhead of converting JavaScript objects into WebIDL sequences (slow path using the @@iteratorprotocol)", + run: function() { + new Blob(iterableData); + }}); +</script> +</body> +</html>
diff --git a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h index 81ac179..d033478 100644 --- a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h +++ b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImpl.h
@@ -283,17 +283,121 @@ // Nondependent types need to be explicitly qualified to be accessible. using typename NativeValueTraitsBase<IDLSequence<T>>::ImplType; + // https://heycam.github.io/webidl/#es-sequence static ImplType NativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exception_state) { - return NativeValue(isolate, value, exception_state, 0); + if (!value->IsObject()) { + exception_state.ThrowTypeError( + "The provided value cannot be converted to a sequence."); + return ImplType(); + } + + ImplType result; + // TODO(rakuco): Checking for IsArray() may not be enough. Other engines + // also prefer regular array iteration over a custom @@iterator when the + // latter is defined, but it is not clear if this is a valid optimization. + if (value->IsArray()) { + ConvertSequenceFast(isolate, value.As<v8::Array>(), exception_state, + result); + } else { + ConvertSequenceSlow(isolate, value.As<v8::Object>(), exception_state, + result); + } + + if (exception_state.HadException()) + return ImplType(); + return result; } - static ImplType NativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exception_state, - int index) { - return ToImplArray<ImplType, T>(value, index, isolate, exception_state); + private: + // Fast case: we're interating over an Array that adheres to + // %ArrayIteratorPrototype%'s protocol. + static void ConvertSequenceFast(v8::Isolate* isolate, + v8::Local<v8::Array> v8_array, + ExceptionState& exception_state, + ImplType& result) { + const uint32_t length = v8_array->Length(); + if (length > ImplType::MaxCapacity()) { + exception_state.ThrowRangeError("Array length exceeds supported limit."); + return; + } + result.ReserveInitialCapacity(length); + v8::TryCatch block(isolate); + for (uint32_t i = 0; i < length; ++i) { + v8::Local<v8::Value> element; + if (!v8_array->Get(isolate->GetCurrentContext(), i).ToLocal(&element)) { + exception_state.RethrowV8Exception(block.Exception()); + return; + } + result.UncheckedAppend( + NativeValueTraits<T>::NativeValue(isolate, element, exception_state)); + if (exception_state.HadException()) + return; + } + } + + // Slow case: follow WebIDL's "Creating a sequence from an iterable" steps to + // iterate through each element. + // https://heycam.github.io/webidl/#create-sequence-from-iterable + static void ConvertSequenceSlow(v8::Isolate* isolate, + v8::Local<v8::Object> v8_object, + ExceptionState& exception_state, + ImplType& result) { + v8::TryCatch block(isolate); + + v8::Local<v8::Object> iterator = + GetEsIterator(isolate, v8_object, exception_state); + if (exception_state.HadException()) + return; + + v8::Local<v8::String> next_key = V8String(isolate, "next"); + v8::Local<v8::String> value_key = V8String(isolate, "value"); + v8::Local<v8::String> done_key = V8String(isolate, "done"); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + while (true) { + v8::Local<v8::Value> next; + if (!iterator->Get(context, next_key).ToLocal(&next)) { + exception_state.RethrowV8Exception(block.Exception()); + return; + } + if (!next->IsFunction()) { + exception_state.ThrowTypeError("Iterator.next should be callable."); + return; + } + v8::Local<v8::Value> next_result; + if (!V8ScriptRunner::CallFunction(next.As<v8::Function>(), + ToExecutionContext(context), iterator, + 0, nullptr, isolate) + .ToLocal(&next_result)) { + exception_state.RethrowV8Exception(block.Exception()); + return; + } + if (!next_result->IsObject()) { + exception_state.ThrowTypeError( + "Iterator.next() did not return an object."); + return; + } + v8::Local<v8::Object> result_object = next_result.As<v8::Object>(); + v8::Local<v8::Value> element; + v8::Local<v8::Value> done; + if (!result_object->Get(context, value_key).ToLocal(&element) || + !result_object->Get(context, done_key).ToLocal(&done)) { + exception_state.RethrowV8Exception(block.Exception()); + return; + } + bool done_boolean; + if (!done->BooleanValue(context).To(&done_boolean)) { + exception_state.RethrowV8Exception(block.Exception()); + return; + } + if (done_boolean) + break; + result.emplace_back( + NativeValueTraits<T>::NativeValue(isolate, element, exception_state)); + if (exception_state.HadException()) + return; + } } };
diff --git a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp index 3674e80..71a82a2f 100644 --- a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp
@@ -273,6 +273,184 @@ } } +TEST(NativeValueTraitsImplTest, IDLSequence) { + V8TestingScope scope; + { + v8::Local<v8::Array> v8_array = v8::Array::New(scope.GetIsolate()); + NonThrowableExceptionState exception_state; + const auto& sequence = + NativeValueTraits<IDLSequence<IDLOctet>>::NativeValue( + scope.GetIsolate(), v8_array, exception_state); + EXPECT_TRUE(sequence.IsEmpty()); + } + { + v8::Local<v8::Array> v8_array = v8::Array::New(scope.GetIsolate()); + for (int32_t i = 0; i < 5; ++i) { + v8_array->Set(scope.GetContext(), ToV8(&scope, i), ToV8(&scope, i)) + .ToChecked(); + } + NonThrowableExceptionState exception_state; + const auto& sequence = NativeValueTraits<IDLSequence<IDLLong>>::NativeValue( + scope.GetIsolate(), v8_array, exception_state); + EXPECT_EQ(Vector<int32_t>({0, 1, 2, 3, 4}), sequence); + } + { + const double double_pi = 3.141592653589793238; + const float float_pi = double_pi; + v8::Local<v8::Array> v8_real_array = v8::Array::New(scope.GetIsolate(), 1); + v8_real_array + ->Set(scope.GetContext(), ToV8(&scope, 0), ToV8(&scope, double_pi)) + .ToChecked(); + + NonThrowableExceptionState exception_state; + Vector<double> double_vector = + NativeValueTraits<IDLSequence<IDLDouble>>::NativeValue( + scope.GetIsolate(), v8_real_array, exception_state); + EXPECT_EQ(1U, double_vector.size()); + EXPECT_EQ(double_pi, double_vector[0]); + + Vector<float> float_vector = + NativeValueTraits<IDLSequence<IDLFloat>>::NativeValue( + scope.GetIsolate(), v8_real_array, exception_state); + EXPECT_EQ(1U, float_vector.size()); + EXPECT_EQ(float_pi, float_vector[0]); + } + { + v8::Local<v8::Array> v8_array = v8::Array::New(scope.GetIsolate(), 3); + EXPECT_TRUE(v8_array + ->Set(scope.GetContext(), ToV8(&scope, 0), + ToV8(&scope, "Vini, vidi, vici.")) + .ToChecked()); + EXPECT_TRUE( + v8_array->Set(scope.GetContext(), ToV8(&scope, 1), ToV8(&scope, 65535)) + .ToChecked()); + EXPECT_TRUE( + v8_array->Set(scope.GetContext(), ToV8(&scope, 2), ToV8(&scope, 0.125)) + .ToChecked()); + + NonThrowableExceptionState exception_state; + Vector<ScriptValue> script_value_vector = + NativeValueTraits<IDLSequence<ScriptValue>>::NativeValue( + scope.GetIsolate(), v8_array, exception_state); + EXPECT_EQ(3U, script_value_vector.size()); + String report_on_zela; + EXPECT_TRUE(script_value_vector[0].ToString(report_on_zela)); + EXPECT_EQ("Vini, vidi, vici.", report_on_zela); + EXPECT_EQ(65535U, + ToUInt32(scope.GetIsolate(), script_value_vector[1].V8Value(), + kNormalConversion, exception_state)); + } + { + v8::Local<v8::Array> v8_string_array1 = + v8::Array::New(scope.GetIsolate(), 2); + EXPECT_TRUE( + v8_string_array1 + ->Set(scope.GetContext(), ToV8(&scope, 0), ToV8(&scope, "foo")) + .ToChecked()); + EXPECT_TRUE( + v8_string_array1 + ->Set(scope.GetContext(), ToV8(&scope, 1), ToV8(&scope, "bar")) + .ToChecked()); + v8::Local<v8::Array> v8_string_array2 = + v8::Array::New(scope.GetIsolate(), 3); + EXPECT_TRUE( + v8_string_array2 + ->Set(scope.GetContext(), ToV8(&scope, 0), ToV8(&scope, "x")) + .ToChecked()); + EXPECT_TRUE( + v8_string_array2 + ->Set(scope.GetContext(), ToV8(&scope, 1), ToV8(&scope, "y")) + .ToChecked()); + EXPECT_TRUE( + v8_string_array2 + ->Set(scope.GetContext(), ToV8(&scope, 2), ToV8(&scope, "z")) + .ToChecked()); + v8::Local<v8::Array> v8_string_array_array = + v8::Array::New(scope.GetIsolate(), 2); + EXPECT_TRUE(v8_string_array_array + ->Set(scope.GetContext(), ToV8(&scope, 0), v8_string_array1) + .ToChecked()); + EXPECT_TRUE(v8_string_array_array + ->Set(scope.GetContext(), ToV8(&scope, 1), v8_string_array2) + .ToChecked()); + + NonThrowableExceptionState exception_state; + Vector<Vector<String>> string_vector_vector = + NativeValueTraits<IDLSequence<IDLSequence<IDLString>>>::NativeValue( + scope.GetIsolate(), v8_string_array_array, exception_state); + EXPECT_EQ(2U, string_vector_vector.size()); + EXPECT_EQ(2U, string_vector_vector[0].size()); + EXPECT_EQ("foo", string_vector_vector[0][0]); + EXPECT_EQ("bar", string_vector_vector[0][1]); + EXPECT_EQ(3U, string_vector_vector[1].size()); + EXPECT_EQ("x", string_vector_vector[1][0]); + EXPECT_EQ("y", string_vector_vector[1][1]); + EXPECT_EQ("z", string_vector_vector[1][2]); + } + { + v8::Local<v8::String> script_code = + ToV8(&scope, + "let arr = [1, 2, 3];" + "let iterations = [" + " {done: false, value: 8}," + " {done: false, value: 5}," + " {done: true}" + "];" + "arr[Symbol.iterator] = function() {" + " let i = 0;" + " return {next: () => iterations[i++]};" + "}; arr") + .As<v8::String>(); + v8::MicrotasksScope microtasks(scope.GetIsolate(), + v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::Local<v8::Value> v8_array = + v8::Script::Compile(scope.GetContext(), script_code) + .ToLocalChecked() + ->Run(scope.GetContext()) + .ToLocalChecked(); + EXPECT_TRUE(v8_array->IsArray()); + + NonThrowableExceptionState exception_state; + const auto& sequence = NativeValueTraits<IDLSequence<IDLByte>>::NativeValue( + scope.GetIsolate(), v8_array, exception_state); + EXPECT_EQ(Vector<int8_t>({1, 2, 3}), sequence); + } + { + v8::Local<v8::String> script_code = + ToV8(&scope, + "let obj = {" + " iterations: [" + " {done: false, value: 55}," + " {done: false, value: 0}," + " {done: true, value: 99}" + " ]," + " [Symbol.iterator]() {" + " let i = 0;" + " return {next: () => this.iterations[i++]};" + " }" + "}; obj") + .As<v8::String>(); + v8::MicrotasksScope microtasks(scope.GetIsolate(), + v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::Local<v8::Value> v8_object = + v8::Script::Compile(scope.GetContext(), script_code) + .ToLocalChecked() + ->Run(scope.GetContext()) + .ToLocalChecked(); + EXPECT_TRUE(v8_object->IsObject()); + + NonThrowableExceptionState exception_state; + const auto& byte_sequence = + NativeValueTraits<IDLSequence<IDLByte>>::NativeValue( + scope.GetIsolate(), v8_object, exception_state); + EXPECT_EQ(Vector<int8_t>({55, 0}), byte_sequence); + const auto& boolean_sequence = + NativeValueTraits<IDLSequence<IDLBoolean>>::NativeValue( + scope.GetIsolate(), v8_object, exception_state); + EXPECT_EQ(Vector<bool>({true, false}), boolean_sequence); + } +} + } // namespace } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptValue.h b/third_party/WebKit/Source/bindings/core/v8/ScriptValue.h index 0cece6fb..f837319 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptValue.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptValue.h
@@ -174,6 +174,16 @@ RefPtr<SharedPersistent<v8::Value>> value_; }; +template <> +struct NativeValueTraits<ScriptValue> + : public NativeValueTraitsBase<ScriptValue> { + static inline ScriptValue NativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exception_state) { + return ScriptValue(ScriptState::Current(isolate), value); + } +}; + } // namespace blink #endif // ScriptValue_h
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp index 44a149e..91a12d24 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp
@@ -904,6 +904,23 @@ return iterator.As<v8::Object>(); } +bool HasCallableIteratorSymbol(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exception_state) { + if (!value->IsObject()) + return false; + v8::TryCatch block(isolate); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + v8::Local<v8::Value> iterator_getter; + if (!value.As<v8::Object>() + ->Get(context, v8::Symbol::GetIterator(isolate)) + .ToLocal(&iterator_getter)) { + exception_state.RethrowV8Exception(block.Exception()); + return false; + } + return iterator_getter->IsFunction(); +} + bool AddHiddenValueToArray(v8::Isolate* isolate, v8::Local<v8::Object> object, v8::Local<v8::Value> value,
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h index f783f6a..0beb32ac 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
@@ -829,6 +829,12 @@ length = sequence_length; return true; } +// Validates that the passed object is a sequence type per the WebIDL spec: it +// has a callable @iterator. +// https://heycam.github.io/webidl/#es-sequence +CORE_EXPORT bool HasCallableIteratorSymbol(v8::Isolate*, + v8::Local<v8::Value>, + ExceptionState&); // TODO(rakuco): remove the specializations below (and consequently the // non-IDLBase version of NativeValueTraitsBase) once we manage to convert all @@ -895,7 +901,8 @@ }; template <> -struct NativeValueTraits<v8::Local<v8::Value>> { +struct NativeValueTraits<v8::Local<v8::Value>> + : public NativeValueTraitsBase<v8::Local<v8::Value>> { static inline v8::Local<v8::Value> NativeValue( v8::Isolate* isolate, v8::Local<v8::Value> value, @@ -904,15 +911,6 @@ } }; -template <> -struct NativeValueTraits<ScriptValue> { - static inline ScriptValue NativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exception_state) { - return ScriptValue(ScriptState::Current(isolate), value); - } -}; - template <typename T> struct NativeValueTraits<Vector<T>> { static inline Vector<T> NativeValue(v8::Isolate* isolate,
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_methods.py b/third_party/WebKit/Source/bindings/scripts/v8_methods.py index 97f74ac..fa613df7 100644 --- a/third_party/WebKit/Source/bindings/scripts/v8_methods.py +++ b/third_party/WebKit/Source/bindings/scripts/v8_methods.py
@@ -377,7 +377,7 @@ if argument.is_variadic: return v8_value_to_local_cpp_variadic_value(method, argument, index, return_promise) return idl_type.v8_value_to_local_cpp_value(extended_attributes, 'info[%s]' % index, - name, index=index, declare_variable=False, + name, declare_variable=False, use_exception_state=method.returns_promise)
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_types.py b/third_party/WebKit/Source/bindings/scripts/v8_types.py index 32c6b85..fbb0dc8 100644 --- a/third_party/WebKit/Source/bindings/scripts/v8_types.py +++ b/third_party/WebKit/Source/bindings/scripts/v8_types.py
@@ -425,7 +425,9 @@ def includes_for_array_or_sequence_type(idl_type, extended_attributes=None): - return idl_type.element_type.includes_for_type(extended_attributes) + return set.union(set(['bindings/core/v8/IDLTypes.h', + 'bindings/core/v8/NativeValueTraitsImpl.h']), + idl_type.element_type.includes_for_type(extended_attributes)) IdlArrayOrSequenceType.includes_for_type = includes_for_array_or_sequence_type @@ -578,15 +580,10 @@ return name -def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name, index, isolate): +def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name, isolate): if idl_type.name == 'void': return '' - # Array or sequence types - native_array_element_type = idl_type.native_array_element_type - if native_array_element_type: - return v8_value_to_cpp_value_array_or_sequence(native_array_element_type, v8_value, index, isolate) - # Simple types idl_type = idl_type.preprocessed_type base_idl_type = idl_type.as_union_type.name if idl_type.is_union_type else idl_type.base_type @@ -628,7 +625,7 @@ '{idl_type}::Create(ScriptState::Current({isolate}), {v8_value})') elif idl_type.v8_conversion_needs_exception_state: # Effectively, this if branch means everything with v8_conversion_needs_exception_state == True - # except for unions, sequences and dictionary interfaces. + # except for unions and dictionary interfaces. base_idl_type = native_value_traits_type_name(idl_type) cpp_expression_format = ( 'NativeValueTraits<{idl_type}>::NativeValue({isolate}, {arguments})') @@ -639,47 +636,15 @@ return cpp_expression_format.format(arguments=arguments, idl_type=base_idl_type, v8_value=v8_value, variable_name=variable_name, isolate=isolate) -def v8_value_to_cpp_value_array_or_sequence(native_array_element_type, v8_value, index, isolate='info.GetIsolate()'): - # Index is None for setters, index (starting at 0) for method arguments, - # and is used to provide a human-readable exception message - if index is None: - index = 0 # special case, meaning "setter" - else: - index += 1 # human-readable index - if (native_array_element_type.is_interface_type and - native_array_element_type.name != 'Dictionary'): - this_cpp_type = None - expression_format = 'ToMemberNativeArray<{native_array_element_type}>({v8_value}, {index}, {isolate}, exceptionState)' - else: - this_cpp_type = native_array_element_type.cpp_type - if native_array_element_type.is_dictionary or native_array_element_type.is_union_type: - vector_type = 'HeapVector' - else: - vector_type = 'Vector' - if native_array_element_type.is_primitive_type: - value_type = native_value_traits_type_name(native_array_element_type) - expression_format = ('ToImplArray<%s<{cpp_type}>, %s>' - '({v8_value}, {index}, {isolate}, ' - 'exceptionState)' % (vector_type, value_type)) - else: - expression_format = ('ToImplArray<%s<{cpp_type}>>' - '({v8_value}, {index}, {isolate}, ' - 'exceptionState)' % vector_type) - - expression = expression_format.format(native_array_element_type=native_array_element_type.name, cpp_type=this_cpp_type, - index=index, v8_value=v8_value, isolate=isolate) - return expression - - # FIXME: this function should be refactored, as this takes too many flags. -def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variable_name, index=None, declare_variable=True, +def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variable_name, declare_variable=True, isolate='info.GetIsolate()', bailout_return_value=None, use_exception_state=False): """Returns an expression that converts a V8 value to a C++ value and stores it as a local value.""" this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes, raw_type=True) idl_type = idl_type.preprocessed_type - cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name, index, isolate) + cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name, isolate) # Optional expression that returns a value to be assigned to the local variable. assign_expression = None
diff --git a/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl index e361c1b..b29c391 100644 --- a/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl +++ b/third_party/WebKit/Source/bindings/templates/union_container.cpp.tmpl
@@ -109,10 +109,7 @@ {% endif %} {% if array_or_sequence_type %} {# 11.1, 11.2. Arrays and Sequences #} - {# FIXME: This should also check "object but not RegExp". Add checks - when we implement conversions for Date and RegExp. #} - {# TODO(bashi): Should check @@iterator symbol instead. #} - if (v8Value->IsArray()) { + if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) { {{v8_value_to_local_cpp_value(array_or_sequence_type) | indent}} impl.set{{array_or_sequence_type.type_name}}(cppValue); return;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/BooleanOrElementSequence.cpp b/third_party/WebKit/Source/bindings/tests/results/core/BooleanOrElementSequence.cpp index b096303..778596ad 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/BooleanOrElementSequence.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/BooleanOrElementSequence.cpp
@@ -74,8 +74,8 @@ if (conversionMode == UnionTypeConversionMode::kNullable && IsUndefinedOrNull(v8Value)) return; - if (v8Value->IsArray()) { - HeapVector<Member<Element>> cppValue = ToMemberNativeArray<Element>(v8Value, 0, isolate, exceptionState); + if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) { + HeapVector<Member<Element>> cppValue = NativeValueTraits<IDLSequence<Element>>::NativeValue(isolate, v8Value, exceptionState); if (exceptionState.HadException()) return; impl.setElementSequence(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.cpp b/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.cpp index bd3ff3d..788b54a8 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/ByteStringSequenceSequenceOrByteStringByteStringRecord.cpp
@@ -67,8 +67,8 @@ if (conversionMode == UnionTypeConversionMode::kNullable && IsUndefinedOrNull(v8Value)) return; - if (v8Value->IsArray()) { - Vector<Vector<String>> cppValue = ToImplArray<Vector<Vector<String>>>(v8Value, 0, isolate, exceptionState); + if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) { + Vector<Vector<String>> cppValue = NativeValueTraits<IDLSequence<IDLSequence<IDLByteString>>>::NativeValue(isolate, v8Value, exceptionState); if (exceptionState.HadException()) return; impl.setByteStringSequenceSequence(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/DoubleOrLongOrBooleanSequence.cpp b/third_party/WebKit/Source/bindings/tests/results/core/DoubleOrLongOrBooleanSequence.cpp index 8037130..a141d60 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/DoubleOrLongOrBooleanSequence.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/DoubleOrLongOrBooleanSequence.cpp
@@ -69,8 +69,8 @@ if (conversionMode == UnionTypeConversionMode::kNullable && IsUndefinedOrNull(v8Value)) return; - if (v8Value->IsArray()) { - HeapVector<LongOrBoolean> cppValue = ToImplArray<HeapVector<LongOrBoolean>>(v8Value, 0, isolate, exceptionState); + if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) { + HeapVector<LongOrBoolean> cppValue = NativeValueTraits<IDLSequence<LongOrBoolean>>::NativeValue(isolate, v8Value, exceptionState); if (exceptionState.HadException()) return; impl.setLongOrBooleanSequence(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/DoubleOrStringOrDoubleOrStringSequence.cpp b/third_party/WebKit/Source/bindings/tests/results/core/DoubleOrStringOrDoubleOrStringSequence.cpp index a4777d7..4c453d2 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/DoubleOrStringOrDoubleOrStringSequence.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/DoubleOrStringOrDoubleOrStringSequence.cpp
@@ -86,8 +86,8 @@ if (conversionMode == UnionTypeConversionMode::kNullable && IsUndefinedOrNull(v8Value)) return; - if (v8Value->IsArray()) { - HeapVector<DoubleOrString> cppValue = ToImplArray<HeapVector<DoubleOrString>>(v8Value, 0, isolate, exceptionState); + if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) { + HeapVector<DoubleOrString> cppValue = NativeValueTraits<IDLSequence<DoubleOrString>>::NativeValue(isolate, v8Value, exceptionState); if (exceptionState.HadException()) return; impl.setDoubleOrStringSequence(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/ElementSequenceOrByteStringDoubleOrStringRecord.cpp b/third_party/WebKit/Source/bindings/tests/results/core/ElementSequenceOrByteStringDoubleOrStringRecord.cpp index d22c06f..d51b16f 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/ElementSequenceOrByteStringDoubleOrStringRecord.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/ElementSequenceOrByteStringDoubleOrStringRecord.cpp
@@ -76,8 +76,8 @@ if (conversionMode == UnionTypeConversionMode::kNullable && IsUndefinedOrNull(v8Value)) return; - if (v8Value->IsArray()) { - HeapVector<Member<Element>> cppValue = ToMemberNativeArray<Element>(v8Value, 0, isolate, exceptionState); + if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) { + HeapVector<Member<Element>> cppValue = NativeValueTraits<IDLSequence<Element>>::NativeValue(isolate, v8Value, exceptionState); if (exceptionState.HadException()) return; impl.setElementSequence(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/LongSequenceOrEvent.cpp b/third_party/WebKit/Source/bindings/tests/results/core/LongSequenceOrEvent.cpp index f54f01a5..5f89e84 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/LongSequenceOrEvent.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/LongSequenceOrEvent.cpp
@@ -75,8 +75,8 @@ return; } - if (v8Value->IsArray()) { - Vector<int32_t> cppValue = ToImplArray<Vector<int32_t>, IDLLong>(v8Value, 0, isolate, exceptionState); + if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) { + Vector<int32_t> cppValue = NativeValueTraits<IDLSequence<IDLLong>>::NativeValue(isolate, v8Value, exceptionState); if (exceptionState.HadException()) return; impl.setLongSequence(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord.cpp b/third_party/WebKit/Source/bindings/tests/results/core/NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord.cpp index 46fd2e34..047d778 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord.cpp
@@ -166,8 +166,8 @@ return; } - if (v8Value->IsArray()) { - Vector<int32_t> cppValue = ToImplArray<Vector<int32_t>, IDLLong>(v8Value, 0, isolate, exceptionState); + if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) { + Vector<int32_t> cppValue = NativeValueTraits<IDLSequence<IDLLong>>::NativeValue(isolate, v8Value, exceptionState); if (exceptionState.HadException()) return; impl.setLongSequence(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/StringOrStringSequence.cpp b/third_party/WebKit/Source/bindings/tests/results/core/StringOrStringSequence.cpp index 2cbd113..befae79f 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/StringOrStringSequence.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/StringOrStringSequence.cpp
@@ -67,8 +67,8 @@ if (conversionMode == UnionTypeConversionMode::kNullable && IsUndefinedOrNull(v8Value)) return; - if (v8Value->IsArray()) { - Vector<String> cppValue = ToImplArray<Vector<String>>(v8Value, 0, isolate, exceptionState); + if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) { + Vector<String> cppValue = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(isolate, v8Value, exceptionState); if (exceptionState.HadException()) return; impl.setStringSequence(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp b/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp index 3f118fb2..bf19410 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp
@@ -78,7 +78,7 @@ return false; } - Vector<String> cppValue = ToImplArray<Vector<String>>(v8ReturnValue, 0, m_scriptState->GetIsolate(), exceptionState); + Vector<String> cppValue = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(m_scriptState->GetIsolate(), v8ReturnValue, exceptionState); if (exceptionState.HadException()) return false; returnValue = cppValue;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp index f841653f..536981b 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
@@ -218,7 +218,7 @@ if (doubleOrStringSequenceMemberValue.IsEmpty() || doubleOrStringSequenceMemberValue->IsUndefined()) { // Do nothing. } else { - HeapVector<DoubleOrString> doubleOrStringSequenceMember = ToImplArray<HeapVector<DoubleOrString>>(doubleOrStringSequenceMemberValue, 0, isolate, exceptionState); + HeapVector<DoubleOrString> doubleOrStringSequenceMember = NativeValueTraits<IDLSequence<DoubleOrString>>::NativeValue(isolate, doubleOrStringSequenceMemberValue, exceptionState); if (exceptionState.HadException()) return; impl.setDoubleOrStringSequenceMember(doubleOrStringSequenceMember); @@ -272,7 +272,7 @@ if (enumSequenceMemberValue.IsEmpty() || enumSequenceMemberValue->IsUndefined()) { // Do nothing. } else { - Vector<String> enumSequenceMember = ToImplArray<Vector<String>>(enumSequenceMemberValue, 0, isolate, exceptionState); + Vector<String> enumSequenceMember = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(isolate, enumSequenceMemberValue, exceptionState); if (exceptionState.HadException()) return; const char* validValues[] = { @@ -324,7 +324,7 @@ if (internalDictionarySequenceMemberValue.IsEmpty() || internalDictionarySequenceMemberValue->IsUndefined()) { // Do nothing. } else { - HeapVector<InternalDictionary> internalDictionarySequenceMember = ToImplArray<HeapVector<InternalDictionary>>(internalDictionarySequenceMemberValue, 0, isolate, exceptionState); + HeapVector<InternalDictionary> internalDictionarySequenceMember = NativeValueTraits<IDLSequence<InternalDictionary>>::NativeValue(isolate, internalDictionarySequenceMemberValue, exceptionState); if (exceptionState.HadException()) return; impl.setInternalDictionarySequenceMember(internalDictionarySequenceMember); @@ -461,7 +461,7 @@ if (stringArrayMemberValue.IsEmpty() || stringArrayMemberValue->IsUndefined()) { // Do nothing. } else { - Vector<String> stringArrayMember = ToImplArray<Vector<String>>(stringArrayMemberValue, 0, isolate, exceptionState); + Vector<String> stringArrayMember = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(isolate, stringArrayMemberValue, exceptionState); if (exceptionState.HadException()) return; impl.setStringArrayMember(stringArrayMember); @@ -505,7 +505,7 @@ if (stringSequenceMemberValue.IsEmpty() || stringSequenceMemberValue->IsUndefined()) { // Do nothing. } else { - Vector<String> stringSequenceMember = ToImplArray<Vector<String>>(stringSequenceMemberValue, 0, isolate, exceptionState); + Vector<String> stringSequenceMember = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(isolate, stringSequenceMemberValue, exceptionState); if (exceptionState.HadException()) return; impl.setStringSequenceMember(stringSequenceMember); @@ -568,7 +568,7 @@ if (testInterfaceGarbageCollectedSequenceMemberValue.IsEmpty() || testInterfaceGarbageCollectedSequenceMemberValue->IsUndefined()) { // Do nothing. } else { - HeapVector<Member<TestInterfaceGarbageCollected>> testInterfaceGarbageCollectedSequenceMember = ToMemberNativeArray<TestInterfaceGarbageCollected>(testInterfaceGarbageCollectedSequenceMemberValue, 0, isolate, exceptionState); + HeapVector<Member<TestInterfaceGarbageCollected>> testInterfaceGarbageCollectedSequenceMember = NativeValueTraits<IDLSequence<TestInterfaceGarbageCollected>>::NativeValue(isolate, testInterfaceGarbageCollectedSequenceMemberValue, exceptionState); if (exceptionState.HadException()) return; impl.setTestInterfaceGarbageCollectedSequenceMember(testInterfaceGarbageCollectedSequenceMember); @@ -616,7 +616,7 @@ if (testInterfaceSequenceMemberValue.IsEmpty() || testInterfaceSequenceMemberValue->IsUndefined()) { // Do nothing. } else { - HeapVector<Member<TestInterfaceImplementation>> testInterfaceSequenceMember = ToMemberNativeArray<TestInterface>(testInterfaceSequenceMemberValue, 0, isolate, exceptionState); + HeapVector<Member<TestInterfaceImplementation>> testInterfaceSequenceMember = NativeValueTraits<IDLSequence<TestInterfaceImplementation>>::NativeValue(isolate, testInterfaceSequenceMemberValue, exceptionState); if (exceptionState.HadException()) return; impl.setTestInterfaceSequenceMember(testInterfaceSequenceMember); @@ -630,7 +630,7 @@ if (testObjectSequenceMemberValue.IsEmpty() || testObjectSequenceMemberValue->IsUndefined()) { // Do nothing. } else { - HeapVector<Member<TestObject>> testObjectSequenceMember = ToMemberNativeArray<TestObject>(testObjectSequenceMemberValue, 0, isolate, exceptionState); + HeapVector<Member<TestObject>> testObjectSequenceMember = NativeValueTraits<IDLSequence<TestObject>>::NativeValue(isolate, testObjectSequenceMemberValue, exceptionState); if (exceptionState.HadException()) return; impl.setTestObjectSequenceMember(testObjectSequenceMember);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.cpp index e9dcf30..d0987e3 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.cpp
@@ -99,7 +99,7 @@ if (stringOrDoubleSequenceMemberValue.IsEmpty() || stringOrDoubleSequenceMemberValue->IsUndefined()) { // Do nothing. } else { - HeapVector<StringOrDouble> stringOrDoubleSequenceMember = ToImplArray<HeapVector<StringOrDouble>>(stringOrDoubleSequenceMemberValue, 0, isolate, exceptionState); + HeapVector<StringOrDouble> stringOrDoubleSequenceMember = NativeValueTraits<IDLSequence<StringOrDouble>>::NativeValue(isolate, stringOrDoubleSequenceMemberValue, exceptionState); if (exceptionState.HadException()) return; impl.setStringOrDoubleSequenceMember(stringOrDoubleSequenceMember);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp index a53f25d7..5a9b666 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor.cpp
@@ -112,15 +112,15 @@ if (exceptionState.HadException()) return; - sequenceStringArg = ToImplArray<Vector<String>>(info[4], 5, info.GetIsolate(), exceptionState); + sequenceStringArg = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), info[4], exceptionState); if (exceptionState.HadException()) return; - sequenceDictionaryArg = ToImplArray<Vector<Dictionary>>(info[5], 6, info.GetIsolate(), exceptionState); + sequenceDictionaryArg = NativeValueTraits<IDLSequence<Dictionary>>::NativeValue(info.GetIsolate(), info[5], exceptionState); if (exceptionState.HadException()) return; - sequenceLongOrTestDictionaryArg = ToImplArray<HeapVector<LongOrTestDictionary>>(info[6], 7, info.GetIsolate(), exceptionState); + sequenceLongOrTestDictionaryArg = NativeValueTraits<IDLSequence<LongOrTestDictionary>>::NativeValue(info.GetIsolate(), info[6], exceptionState); if (exceptionState.HadException()) return;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp index b469485..9012e98 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp
@@ -91,7 +91,7 @@ ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kConstructionContext, "TestInterfaceConstructor2"); Vector<Vector<String>> stringSequenceSequenceArg; - stringSequenceSequenceArg = ToImplArray<Vector<Vector<String>>>(info[0], 1, info.GetIsolate(), exceptionState); + stringSequenceSequenceArg = NativeValueTraits<IDLSequence<IDLSequence<IDLString>>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp index ee95987..2cbcbc5 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
@@ -1223,7 +1223,7 @@ ExceptionState exceptionState(isolate, ExceptionState::kSetterContext, "TestObject", "stringArrayAttribute"); // Prepare the value to be set. - Vector<String> cppValue = ToImplArray<Vector<String>>(v8Value, 0, info.GetIsolate(), exceptionState); + Vector<String> cppValue = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), v8Value, exceptionState); if (exceptionState.HadException()) return; @@ -1248,7 +1248,7 @@ ExceptionState exceptionState(isolate, ExceptionState::kSetterContext, "TestObject", "testInterfaceEmptyArrayAttribute"); // Prepare the value to be set. - HeapVector<Member<TestInterfaceEmpty>> cppValue = ToMemberNativeArray<TestInterfaceEmpty>(v8Value, 0, info.GetIsolate(), exceptionState); + HeapVector<Member<TestInterfaceEmpty>> cppValue = NativeValueTraits<IDLSequence<TestInterfaceEmpty>>::NativeValue(info.GetIsolate(), v8Value, exceptionState); if (exceptionState.HadException()) return; @@ -1273,7 +1273,7 @@ ExceptionState exceptionState(isolate, ExceptionState::kSetterContext, "TestObject", "floatArrayAttribute"); // Prepare the value to be set. - Vector<float> cppValue = ToImplArray<Vector<float>, IDLFloat>(v8Value, 0, info.GetIsolate(), exceptionState); + Vector<float> cppValue = NativeValueTraits<IDLSequence<IDLFloat>>::NativeValue(info.GetIsolate(), v8Value, exceptionState); if (exceptionState.HadException()) return; @@ -1298,7 +1298,7 @@ ExceptionState exceptionState(isolate, ExceptionState::kSetterContext, "TestObject", "stringFrozenArrayAttribute"); // Prepare the value to be set. - Vector<String> cppValue = ToImplArray<Vector<String>>(v8Value, 0, info.GetIsolate(), exceptionState); + Vector<String> cppValue = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), v8Value, exceptionState); if (exceptionState.HadException()) return; @@ -1323,7 +1323,7 @@ ExceptionState exceptionState(isolate, ExceptionState::kSetterContext, "TestObject", "testInterfaceEmptyFrozenArrayAttribute"); // Prepare the value to be set. - HeapVector<Member<TestInterfaceEmpty>> cppValue = ToMemberNativeArray<TestInterfaceEmpty>(v8Value, 0, info.GetIsolate(), exceptionState); + HeapVector<Member<TestInterfaceEmpty>> cppValue = NativeValueTraits<IDLSequence<TestInterfaceEmpty>>::NativeValue(info.GetIsolate(), v8Value, exceptionState); if (exceptionState.HadException()) return; @@ -1946,7 +1946,7 @@ ExceptionState exceptionState(isolate, ExceptionState::kSetterContext, "TestObject", "cachedArrayAttribute"); // Prepare the value to be set. - Vector<String> cppValue = ToImplArray<Vector<String>>(v8Value, 0, info.GetIsolate(), exceptionState); + Vector<String> cppValue = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), v8Value, exceptionState); if (exceptionState.HadException()) return; @@ -4907,7 +4907,7 @@ } Vector<int32_t> arrayLongArg; - arrayLongArg = ToImplArray<Vector<int32_t>, IDLLong>(info[0], 1, info.GetIsolate(), exceptionState); + arrayLongArg = NativeValueTraits<IDLSequence<IDLLong>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -4925,7 +4925,7 @@ } Vector<String> arrayStringArg; - arrayStringArg = ToImplArray<Vector<String>>(info[0], 1, info.GetIsolate(), exceptionState); + arrayStringArg = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -4943,7 +4943,7 @@ } HeapVector<Member<TestInterfaceEmpty>> arrayTestInterfaceEmptyArg; - arrayTestInterfaceEmptyArg = ToMemberNativeArray<TestInterfaceEmpty>(info[0], 1, info.GetIsolate(), exceptionState); + arrayTestInterfaceEmptyArg = NativeValueTraits<IDLSequence<TestInterfaceEmpty>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -4962,7 +4962,7 @@ Nullable<Vector<int32_t>> arrayLongArg; if (!IsUndefinedOrNull(info[0])) { - arrayLongArg = ToImplArray<Vector<int32_t>, IDLLong>(info[0], 1, info.GetIsolate(), exceptionState); + arrayLongArg = NativeValueTraits<IDLSequence<IDLLong>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; } @@ -4999,7 +4999,7 @@ } Vector<int32_t> longSequenceArg; - longSequenceArg = ToImplArray<Vector<int32_t>, IDLLong>(info[0], 1, info.GetIsolate(), exceptionState); + longSequenceArg = NativeValueTraits<IDLSequence<IDLLong>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -5017,7 +5017,7 @@ } Vector<String> stringSequenceArg; - stringSequenceArg = ToImplArray<Vector<String>>(info[0], 1, info.GetIsolate(), exceptionState); + stringSequenceArg = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -5035,7 +5035,7 @@ } HeapVector<Member<TestInterfaceEmpty>> testInterfaceEmptySequenceArg; - testInterfaceEmptySequenceArg = ToMemberNativeArray<TestInterfaceEmpty>(info[0], 1, info.GetIsolate(), exceptionState); + testInterfaceEmptySequenceArg = NativeValueTraits<IDLSequence<TestInterfaceEmpty>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -5053,7 +5053,7 @@ } Vector<Vector<String>> stringSequenceSequenceArg; - stringSequenceSequenceArg = ToImplArray<Vector<Vector<String>>>(info[0], 1, info.GetIsolate(), exceptionState); + stringSequenceSequenceArg = NativeValueTraits<IDLSequence<IDLSequence<IDLString>>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -5072,7 +5072,7 @@ Nullable<Vector<int32_t>> longSequenceArg; if (!IsUndefinedOrNull(info[0])) { - longSequenceArg = ToImplArray<Vector<int32_t>, IDLLong>(info[0], 1, info.GetIsolate(), exceptionState); + longSequenceArg = NativeValueTraits<IDLSequence<IDLLong>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; } @@ -5097,7 +5097,7 @@ } Vector<String> stringFrozenArrayArg; - stringFrozenArrayArg = ToImplArray<Vector<String>>(info[0], 1, info.GetIsolate(), exceptionState); + stringFrozenArrayArg = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -5115,7 +5115,7 @@ } HeapVector<Member<TestInterfaceEmpty>> testInterfaceEmptyFrozenArrayArg; - testInterfaceEmptyFrozenArrayArg = ToMemberNativeArray<TestInterfaceEmpty>(info[0], 1, info.GetIsolate(), exceptionState); + testInterfaceEmptyFrozenArrayArg = NativeValueTraits<IDLSequence<TestInterfaceEmpty>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -5740,7 +5740,7 @@ } Vector<Dictionary> dictionarySequenceArg; - dictionarySequenceArg = ToImplArray<Vector<Dictionary>>(info[0], 1, info.GetIsolate(), exceptionState); + dictionarySequenceArg = NativeValueTraits<IDLSequence<Dictionary>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -6278,7 +6278,7 @@ Vector<String> defaultStringSequenceArg; if (!info[0]->IsUndefined()) { - defaultStringSequenceArg = ToImplArray<Vector<String>>(info[0], 1, info.GetIsolate(), exceptionState); + defaultStringSequenceArg = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; } else { @@ -6605,7 +6605,7 @@ TestObject* impl = V8TestObject::toImpl(info.Holder()); Vector<int32_t> longArrayArg; - longArrayArg = ToImplArray<Vector<int32_t>, IDLLong>(info[0], 1, info.GetIsolate(), exceptionState); + longArrayArg = NativeValueTraits<IDLSequence<IDLLong>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -8798,7 +8798,7 @@ } HeapVector<Member<TestInterfaceGarbageCollected>> testInterfaceGarbageCollectedSequenceArg; - testInterfaceGarbageCollectedSequenceArg = ToMemberNativeArray<TestInterfaceGarbageCollected>(info[0], 1, info.GetIsolate(), exceptionState); + testInterfaceGarbageCollectedSequenceArg = NativeValueTraits<IDLSequence<TestInterfaceGarbageCollected>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -8816,7 +8816,7 @@ } HeapVector<Member<TestInterfaceGarbageCollected>> testInterfaceGarbageCollectedArrayArg; - testInterfaceGarbageCollectedArrayArg = ToMemberNativeArray<TestInterfaceGarbageCollected>(info[0], 1, info.GetIsolate(), exceptionState); + testInterfaceGarbageCollectedArrayArg = NativeValueTraits<IDLSequence<TestInterfaceGarbageCollected>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp index e1dd78b..2b6400d8 100644 --- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp +++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp
@@ -136,7 +136,7 @@ impl->voidMethodArrayOfLongsArg(); return; } - arrayOfLongsArg = ToImplArray<Vector<int32_t>, IDLLong>(info[0], 1, info.GetIsolate(), exceptionState); + arrayOfLongsArg = NativeValueTraits<IDLSequence<IDLLong>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -196,7 +196,7 @@ } HeapVector<Member<TestInterfaceEmpty>> testInterfaceEmptyTypeSequenceArg; - testInterfaceEmptyTypeSequenceArg = ToMemberNativeArray<TestInterfaceEmpty>(info[0], 1, info.GetIsolate(), exceptionState); + testInterfaceEmptyTypeSequenceArg = NativeValueTraits<IDLSequence<TestInterfaceEmpty>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -230,7 +230,7 @@ } Vector<String> arrayOfStringsArg; - arrayOfStringsArg = ToImplArray<Vector<String>>(info[0], 1, info.GetIsolate(), exceptionState); + arrayOfStringsArg = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return; @@ -248,7 +248,7 @@ } Vector<String> stringArrayArg; - stringArrayArg = ToImplArray<Vector<String>>(info[0], 1, info.GetIsolate(), exceptionState); + stringArrayArg = NativeValueTraits<IDLSequence<IDLString>>::NativeValue(info.GetIsolate(), info[0], exceptionState); if (exceptionState.HadException()) return;
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index 71e9987..f5db09c3 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -272,6 +272,8 @@ "testing/OriginTrialsTestPartial.h", "testing/RecordTest.cpp", "testing/RecordTest.h", + "testing/SequenceTest.cpp", + "testing/SequenceTest.h", "testing/TypeConversions.h", "testing/UnionTypesTest.cpp", "testing/UnionTypesTest.h",
diff --git a/third_party/WebKit/Source/core/core_idl_files.gni b/third_party/WebKit/Source/core/core_idl_files.gni index 66206dfe..af7026d 100644 --- a/third_party/WebKit/Source/core/core_idl_files.gni +++ b/third_party/WebKit/Source/core/core_idl_files.gni
@@ -609,6 +609,7 @@ "testing/LayerRectList.idl", "testing/OriginTrialsTest.idl", "testing/RecordTest.idl", + "testing/SequenceTest.idl", "testing/TypeConversions.idl", "testing/UnionTypesTest.idl", ],
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp index 0a6cd48..ef3a824 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -470,6 +470,11 @@ geometry_mapper_option, kIgnorePlatformOverlayScrollbarSize, respect_overflow_clip, &offset_from_root, local_painting_info.sub_pixel_accumulation); + // PaintLayer::collectFragments depends on the paint dirty rect in + // complicated ways. For now, always assume a partially painted output + // for fragmented content. + if (layer_fragments.size() > 1) + result = kMayBeClippedByPaintDirtyRect; } if (paint_flags & kPaintLayerPaintingAncestorClippingMaskPhase) { @@ -697,6 +702,7 @@ if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) geometry_mapper_option = PaintLayer::kUseGeometryMapper; + PaintResult result = kFullyPainted; PaintLayer* pagination_layer = paint_layer_.EnclosingPaginationLayer(); PaintLayerFragments layer_fragments; bool is_fixed_position_object_in_paged_media = @@ -739,6 +745,11 @@ painting_info.paint_dirty_rect, cache_slot, geometry_mapper_option, kIgnorePlatformOverlayScrollbarSize, respect_overflow_clip, nullptr, painting_info.sub_pixel_accumulation, &transformed_extent); + // PaintLayer::collectFragments depends on the paint dirty rect in + // complicated ways. For now, always assume a partially painted output + // for fragmented content. + if (layer_fragments.size() > 1) + result = kMayBeClippedByPaintDirtyRect; } Optional<DisplayItemCacheSkipper> cache_skipper; @@ -764,7 +775,6 @@ } } - PaintResult result = kFullyPainted; for (const auto& fragment : layer_fragments) { Optional<LayerClipRecorder> clip_recorder; if (parent_layer && !RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp index cded96f..4f0400c2 100644 --- a/third_party/WebKit/Source/core/testing/Internals.cpp +++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -124,6 +124,7 @@ #include "core/testing/MockHyphenation.h" #include "core/testing/OriginTrialsTest.h" #include "core/testing/RecordTest.h" +#include "core/testing/SequenceTest.h" #include "core/testing/TypeConversions.h" #include "core/testing/UnionTypesTest.h" #include "core/workers/WorkerThread.h" @@ -2388,6 +2389,10 @@ return RecordTest::Create(); } +SequenceTest* Internals::sequenceTest() const { + return SequenceTest::create(); +} + UnionTypesTest* Internals::unionTypesTest() const { return UnionTypesTest::Create(); }
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h index 6db652f..8b6dcfd2 100644 --- a/third_party/WebKit/Source/core/testing/Internals.h +++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -71,6 +71,7 @@ class Page; class Range; class RecordTest; +class SequenceTest; class SerializedScriptValue; class ShadowRoot; class TypeConversions; @@ -384,6 +385,7 @@ TypeConversions* typeConversions() const; RecordTest* recordTest() const; + SequenceTest* sequenceTest() const; DictionaryTest* dictionaryTest() const; UnionTypesTest* unionTypesTest() const; OriginTrialsTest* originTrialsTest() const;
diff --git a/third_party/WebKit/Source/core/testing/Internals.idl b/third_party/WebKit/Source/core/testing/Internals.idl index 7970856a..64c3c2c77 100644 --- a/third_party/WebKit/Source/core/testing/Internals.idl +++ b/third_party/WebKit/Source/core/testing/Internals.idl
@@ -324,6 +324,7 @@ DictionaryTest dictionaryTest(); RecordTest recordTest(); + SequenceTest sequenceTest(); UnionTypesTest unionTypesTest(); CallbackFunctionTest callbackFunctionTest(); [RaisesException] void setScrollChain(ScrollState scrollState, sequence<Element> elements);
diff --git a/third_party/WebKit/Source/core/testing/SequenceTest.cpp b/third_party/WebKit/Source/core/testing/SequenceTest.cpp new file mode 100644 index 0000000..791644d --- /dev/null +++ b/third_party/WebKit/Source/core/testing/SequenceTest.cpp
@@ -0,0 +1,54 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "SequenceTest.h" + +namespace blink { + +SequenceTest::SequenceTest() {} + +SequenceTest::~SequenceTest() {} + +Vector<Vector<String>> SequenceTest::identityByteStringSequenceSequence( + const Vector<Vector<String>>& arg) const { + return arg; +} + +Vector<double> SequenceTest::identityDoubleSequence( + const Vector<double>& arg) const { + return arg; +} + +Vector<String> SequenceTest::identityFoodEnumSequence( + const Vector<String>& arg) const { + return arg; +} + +Vector<int32_t> SequenceTest::identityLongSequence( + const Vector<int32_t>& arg) const { + return arg; +} + +Nullable<Vector<uint8_t>> SequenceTest::identityOctetSequenceOrNull( + const Nullable<Vector<uint8_t>>& arg) const { + return arg; +} + +HeapVector<Member<Element>> SequenceTest::getElementSequence() const { + return m_elementSequence; +} + +void SequenceTest::setElementSequence(const HeapVector<Member<Element>>& arg) { + m_elementSequence = arg; +} + +bool SequenceTest::unionReceivedSequence(const DoubleOrDoubleSequence& arg) { + return arg.isDoubleSequence(); +} + +DEFINE_TRACE(SequenceTest) { + visitor->Trace(m_elementSequence); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/SequenceTest.h b/third_party/WebKit/Source/core/testing/SequenceTest.h new file mode 100644 index 0000000..b09cd62c --- /dev/null +++ b/third_party/WebKit/Source/core/testing/SequenceTest.h
@@ -0,0 +1,49 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SequenceTest_h +#define SequenceTest_h + +#include "bindings/core/v8/DoubleOrDoubleSequence.h" +#include "bindings/core/v8/Nullable.h" +#include "bindings/core/v8/ScriptWrappable.h" +#include "core/dom/Element.h" +#include "platform/heap/Handle.h" +#include "platform/wtf/Vector.h" +#include "platform/wtf/text/WTFString.h" + +namespace blink { + +class SequenceTest final : public GarbageCollectedFinalized<SequenceTest>, + public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + static SequenceTest* create() { return new SequenceTest; } + ~SequenceTest(); + + Vector<Vector<String>> identityByteStringSequenceSequence( + const Vector<Vector<String>>& arg) const; + Vector<double> identityDoubleSequence(const Vector<double>& arg) const; + Vector<String> identityFoodEnumSequence(const Vector<String>& arg) const; + Vector<int32_t> identityLongSequence(const Vector<int32_t>& arg) const; + Nullable<Vector<uint8_t>> identityOctetSequenceOrNull( + const Nullable<Vector<uint8_t>>& arg) const; + + HeapVector<Member<Element>> getElementSequence() const; + void setElementSequence(const HeapVector<Member<Element>>& arg); + + bool unionReceivedSequence(const DoubleOrDoubleSequence& arg); + + DECLARE_TRACE(); + + private: + SequenceTest(); + + HeapVector<Member<Element>> m_elementSequence; +}; + +} // namespace blink + +#endif // SequenceTest_h
diff --git a/third_party/WebKit/Source/core/testing/SequenceTest.idl b/third_party/WebKit/Source/core/testing/SequenceTest.idl new file mode 100644 index 0000000..c0d5e5d --- /dev/null +++ b/third_party/WebKit/Source/core/testing/SequenceTest.idl
@@ -0,0 +1,24 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +enum FoodEnum { + "Bread", + "Spaghetti", + "Sushi" +}; + +interface SequenceTest { + // The identity functions just return what they have received in |arg|, to + // test converting both to and from V8. + sequence<sequence<ByteString>> identityByteStringSequenceSequence(sequence<sequence<ByteString>> arg); + sequence<double> identityDoubleSequence(sequence<double> arg); + sequence<FoodEnum> identityFoodEnumSequence(sequence<FoodEnum> arg); + sequence<long> identityLongSequence(sequence<long> arg); + sequence<octet>? identityOctetSequenceOrNull(sequence<octet>? arg); + + sequence<Element> getElementSequence(); + void setElementSequence(sequence<Element> arg); + + bool unionReceivedSequence((double or sequence<double>) arg); +};
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp index 6ce4fa0..6647e1ff 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -452,7 +452,8 @@ DCHECK(!IsCheckingUnderInvalidation()); under_invalidation_checking_begin_ = begin_index; under_invalidation_message_prefix_ = - "(In cached subsequence of " + cached_item->Client().DebugName() + ")"; + "(In cached subsequence starting with " + + cached_item->Client().DebugName() + ")"; } Vector<PaintChunk>::const_iterator cached_chunk;
diff --git a/third_party/WebKit/Source/platform/mac/GraphicsContextCanvasTest.mm b/third_party/WebKit/Source/platform/mac/GraphicsContextCanvasTest.mm index a422f07..b0001148 100644 --- a/third_party/WebKit/Source/platform/mac/GraphicsContextCanvasTest.mm +++ b/third_party/WebKit/Source/platform/mac/GraphicsContextCanvasTest.mm
@@ -36,7 +36,7 @@ } { SkIRect clip = - SkIRect::MakeSize(canvas.getBaseLayerSize()) + SkIRect::MakeWH(kWidth, kHeight) .makeOffset( (test & kTestTranslate) ? -(static_cast<int>(kWidth)) / 2 : 0, 0);
diff --git a/third_party/libaddressinput/BUILD.gn b/third_party/libaddressinput/BUILD.gn index dadb6c0..2ef85fb 100644 --- a/third_party/libaddressinput/BUILD.gn +++ b/third_party/libaddressinput/BUILD.gn
@@ -15,14 +15,15 @@ "-Wno-deprecated-register", ] } + + # libaddressinput just says `#include "messages.h"` for grit-generated + # headers. + include_dirs = [ target_gen_dir ] } grit("strings") { source = "//chrome/app/address_input_strings.grd" - # libaddressinput's tests just say `#include "messages.h"`. - use_qualified_include = false - outputs = [ "messages.h", "en_messages.cc",
diff --git a/tools/grit/grit_rule.gni b/tools/grit/grit_rule.gni index 367ea816..f436d3a3f 100644 --- a/tools/grit/grit_rule.gni +++ b/tools/grit/grit_rule.gni
@@ -63,9 +63,6 @@ # If set, used to store the depfile and corresponding stamp file. # Defaults to output_dir # -# use_qualified_include (optional) -# If set to false, output_dir is added to include_dirs. -# # configs (optional) # List of additional configs to be applied to the generated target. # deps (optional) @@ -345,17 +342,9 @@ # overwritten inside the inner classes so we need to compute it here. target_visibility = [ ":$target_name" ] - # The current grit setup makes an file in $output_dir/grit/foo.h that - # the source code expects to include via "grit/foo.h". It would be nice to - # change this to including absolute paths relative to the root gen directory - # (like "mycomponent/foo.h"). This config sets up the include path. + # This config sets up flags needed for enable_resource_whitelist_generation. grit_config = target_name + "_grit_config" config(grit_config) { - if (defined(invoker.use_qualified_include) && - !invoker.use_qualified_include) { - include_dirs = [ output_dir ] - } - if ((is_linux || is_android) && enable_resource_whitelist_generation) { cflags = [ "-Wunknown-pragmas",
diff --git a/ui/app_list/views/app_list_item_view.cc b/ui/app_list/views/app_list_item_view.cc index 6a4fbb1..a1fdb97 100644 --- a/ui/app_list/views/app_list_item_view.cc +++ b/ui/app_list/views/app_list_item_view.cc
@@ -14,7 +14,6 @@ #include "ui/app_list/app_list_item.h" #include "ui/app_list/app_list_switches.h" #include "ui/app_list/views/apps_grid_view.h" -#include "ui/base/dragdrop/drag_utils.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/compositor/layer.h"
diff --git a/ui/aura/mus/os_exchange_data_provider_mus.cc b/ui/aura/mus/os_exchange_data_provider_mus.cc index 538cbb1..04e7539 100644 --- a/ui/aura/mus/os_exchange_data_provider_mus.cc +++ b/ui/aura/mus/os_exchange_data_provider_mus.cc
@@ -325,11 +325,11 @@ drag_image_offset_ = cursor_offset; } -const gfx::ImageSkia& OSExchangeDataProviderMus::GetDragImage() const { +gfx::ImageSkia OSExchangeDataProviderMus::GetDragImage() const { return drag_image_; } -const gfx::Vector2d& OSExchangeDataProviderMus::GetDragImageOffset() const { +gfx::Vector2d OSExchangeDataProviderMus::GetDragImageOffset() const { return drag_image_offset_; } #endif
diff --git a/ui/aura/mus/os_exchange_data_provider_mus.h b/ui/aura/mus/os_exchange_data_provider_mus.h index e8037bf..777da5ac 100644 --- a/ui/aura/mus/os_exchange_data_provider_mus.h +++ b/ui/aura/mus/os_exchange_data_provider_mus.h
@@ -89,8 +89,8 @@ #if defined(USE_AURA) || defined(OS_MACOSX) void SetDragImage(const gfx::ImageSkia& image, const gfx::Vector2d& cursor_offset) override; - const gfx::ImageSkia& GetDragImage() const override; - const gfx::Vector2d& GetDragImageOffset() const override; + gfx::ImageSkia GetDragImage() const override; + gfx::Vector2d GetDragImageOffset() const override; #endif private:
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index 65a14c0a..dea73f5 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -165,7 +165,6 @@ "dragdrop/drag_drop_types_win.cc", "dragdrop/drag_source_win.cc", "dragdrop/drag_source_win.h", - "dragdrop/drag_utils_win.cc", "dragdrop/drop_target_event.cc", "dragdrop/drop_target_event.h", "dragdrop/drop_target_win.cc", @@ -339,8 +338,6 @@ "default_theme_provider.h", "dragdrop/cocoa_dnd_util.h", "dragdrop/cocoa_dnd_util.mm", - "dragdrop/drag_utils.cc", - "dragdrop/drag_utils.h", "dragdrop/file_info.cc", "dragdrop/file_info.h", "idle/idle.cc", @@ -488,15 +485,6 @@ ] } - if (is_linux) { - if (!toolkit_views && !use_aura) { - sources -= [ - "dragdrop/drag_utils.cc", - "dragdrop/drag_utils.h", - ] - } - } - if (is_chromeos) { deps += [ "//chromeos" ] sources -= [ "idle/idle_linux.cc" ] @@ -608,8 +596,6 @@ "cursor/image_cursors.cc", "cursor/image_cursors.h", "default_theme_provider.cc", - "dragdrop/drag_utils.cc", - "dragdrop/drag_utils.h", "idle/idle.cc", "idle/idle.h", "idle/idle_android.cc",
diff --git a/ui/base/dragdrop/drag_utils.cc b/ui/base/dragdrop/drag_utils.cc deleted file mode 100644 index 64da198..0000000 --- a/ui/base/dragdrop/drag_utils.cc +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/base/dragdrop/drag_utils.h" - -#include "ui/base/dragdrop/os_exchange_data.h" - -namespace drag_utils { - -#if !defined(OS_WIN) -void SetDragImageOnDataObject(const gfx::ImageSkia& image_skia, - const gfx::Vector2d& cursor_offset, - ui::OSExchangeData* data_object) { - data_object->provider().SetDragImage(image_skia, cursor_offset); -} -#endif - -} // namespace drag_utils
diff --git a/ui/base/dragdrop/drag_utils.h b/ui/base/dragdrop/drag_utils.h deleted file mode 100644 index e8916dd..0000000 --- a/ui/base/dragdrop/drag_utils.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_BASE_DRAGDROP_DRAG_UTILS_H_ -#define UI_BASE_DRAGDROP_DRAG_UTILS_H_ - -#include "ui/base/ui_base_export.h" - -namespace gfx { -class ImageSkia; -class Vector2d; -} - -namespace ui { -class OSExchangeData; -} - -namespace drag_utils { - -// Sets the drag image on data_object from the supplied ImageSkia. -// |cursor_offset| gives the location of the hotspot for the drag image. -UI_BASE_EXPORT void SetDragImageOnDataObject(const gfx::ImageSkia& image_skia, - const gfx::Vector2d& cursor_offset, - ui::OSExchangeData* data_object); - -} // namespace drag_utils - -#endif // UI_BASE_DRAGDROP_DRAG_UTILS_H_
diff --git a/ui/base/dragdrop/drag_utils_win.cc b/ui/base/dragdrop/drag_utils_win.cc deleted file mode 100644 index fa482e2..0000000 --- a/ui/base/dragdrop/drag_utils_win.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/base/dragdrop/drag_utils.h" - -#include <objidl.h> -#include <shlobj.h> -#include <shobjidl.h> -#include <stddef.h> - -#include "base/win/scoped_comptr.h" -#include "base/win/scoped_hdc.h" -#include "skia/ext/skia_utils_win.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "ui/base/dragdrop/os_exchange_data.h" -#include "ui/base/dragdrop/os_exchange_data_provider_win.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/gfx/skbitmap_operations.h" - -namespace drag_utils { - -static void SetDragImageOnDataObject(HBITMAP hbitmap, - const gfx::Size& size_in_pixels, - const gfx::Vector2d& cursor_offset, - IDataObject* data_object) { - base::win::ScopedComPtr<IDragSourceHelper> helper; - HRESULT rv = CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, - IID_IDragSourceHelper, helper.ReceiveVoid()); - if (SUCCEEDED(rv)) { - SHDRAGIMAGE sdi; - sdi.sizeDragImage = size_in_pixels.ToSIZE(); - sdi.crColorKey = 0xFFFFFFFF; - sdi.hbmpDragImage = hbitmap; - sdi.ptOffset = gfx::PointAtOffsetFromOrigin(cursor_offset).ToPOINT(); - helper->InitializeFromBitmap(&sdi, data_object); - } -} - -// Blit the contents of the canvas to a new HBITMAP. It is the caller's -// responsibility to release the |bits| buffer. -static HBITMAP CreateHBITMAPFromSkBitmap(const SkBitmap& sk_bitmap) { - base::win::ScopedGetDC screen_dc(NULL); - BITMAPINFOHEADER header; - skia::CreateBitmapHeader(sk_bitmap.width(), sk_bitmap.height(), &header); - void* bits; - HBITMAP bitmap = - CreateDIBSection(screen_dc, reinterpret_cast<BITMAPINFO*>(&header), - DIB_RGB_COLORS, &bits, NULL, 0); - if (!bitmap || !bits) - return NULL; - DCHECK_EQ(sk_bitmap.rowBytes(), static_cast<size_t>(sk_bitmap.width() * 4)); - SkAutoLockPixels lock(sk_bitmap); - memcpy( - bits, sk_bitmap.getPixels(), sk_bitmap.height() * sk_bitmap.rowBytes()); - return bitmap; -} - -void SetDragImageOnDataObject(const gfx::ImageSkia& image_skia, - const gfx::Vector2d& cursor_offset, - ui::OSExchangeData* data_object) { - DCHECK(data_object && !image_skia.size().IsEmpty()); - // InitializeFromBitmap() doesn't expect an alpha channel and is confused - // by premultiplied colors, so unpremultiply the bitmap. - // SetDragImageOnDataObject(HBITMAP) takes ownership of the bitmap. - HBITMAP bitmap = CreateHBITMAPFromSkBitmap( - SkBitmapOperations::UnPreMultiply(*image_skia.bitmap())); - if (bitmap) { - // Attach 'bitmap' to the data_object. - SetDragImageOnDataObject( - bitmap, - gfx::Size(image_skia.bitmap()->width(), image_skia.bitmap()->height()), - cursor_offset, - ui::OSExchangeDataProviderWin::GetIDataObject(*data_object)); - } - - // TODO: the above code is used in non-Ash, while below is used in Ash. If we - // could figure this context out then we wouldn't do unnecessary work. However - // as it stands getting this information in ui/base would be a layering - // violation. - data_object->provider().SetDragImage(image_skia, cursor_offset); -} - -} // namespace drag_utils
diff --git a/ui/base/dragdrop/os_exchange_data.h b/ui/base/dragdrop/os_exchange_data.h index 683197d..282587d2 100644 --- a/ui/base/dragdrop/os_exchange_data.h +++ b/ui/base/dragdrop/os_exchange_data.h
@@ -133,8 +133,8 @@ #if defined(USE_AURA) || defined(OS_MACOSX) virtual void SetDragImage(const gfx::ImageSkia& image, const gfx::Vector2d& cursor_offset) = 0; - virtual const gfx::ImageSkia& GetDragImage() const = 0; - virtual const gfx::Vector2d& GetDragImageOffset() const = 0; + virtual gfx::ImageSkia GetDragImage() const = 0; + virtual gfx::Vector2d GetDragImageOffset() const = 0; #endif };
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aura.cc b/ui/base/dragdrop/os_exchange_data_provider_aura.cc index 6093a8e..200d0c8 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_aura.cc +++ b/ui/base/dragdrop/os_exchange_data_provider_aura.cc
@@ -183,12 +183,11 @@ drag_image_offset_ = cursor_offset; } -const gfx::ImageSkia& OSExchangeDataProviderAura::GetDragImage() const { +gfx::ImageSkia OSExchangeDataProviderAura::GetDragImage() const { return drag_image_; } -const gfx::Vector2d& -OSExchangeDataProviderAura::GetDragImageOffset() const { +gfx::Vector2d OSExchangeDataProviderAura::GetDragImageOffset() const { return drag_image_offset_; }
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aura.h b/ui/base/dragdrop/os_exchange_data_provider_aura.h index 0a28ef3..fe752434 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_aura.h +++ b/ui/base/dragdrop/os_exchange_data_provider_aura.h
@@ -55,8 +55,8 @@ bool HasHtml() const override; void SetDragImage(const gfx::ImageSkia& image, const gfx::Vector2d& cursor_offset) override; - const gfx::ImageSkia& GetDragImage() const override; - const gfx::Vector2d& GetDragImageOffset() const override; + gfx::ImageSkia GetDragImage() const override; + gfx::Vector2d GetDragImageOffset() const override; private: typedef std::map<Clipboard::FormatType, base::Pickle> PickleData;
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc b/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc index 9b93593d..2e4b975e 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc +++ b/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc
@@ -504,11 +504,11 @@ drag_image_offset_ = cursor_offset; } -const gfx::ImageSkia& OSExchangeDataProviderAuraX11::GetDragImage() const { +gfx::ImageSkia OSExchangeDataProviderAuraX11::GetDragImage() const { return drag_image_; } -const gfx::Vector2d& OSExchangeDataProviderAuraX11::GetDragImageOffset() const { +gfx::Vector2d OSExchangeDataProviderAuraX11::GetDragImageOffset() const { return drag_image_offset_; }
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aurax11.h b/ui/base/dragdrop/os_exchange_data_provider_aurax11.h index 2fb0ea53..fbf19bc 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_aurax11.h +++ b/ui/base/dragdrop/os_exchange_data_provider_aurax11.h
@@ -93,8 +93,8 @@ bool HasHtml() const override; void SetDragImage(const gfx::ImageSkia& image, const gfx::Vector2d& cursor_offset) override; - const gfx::ImageSkia& GetDragImage() const override; - const gfx::Vector2d& GetDragImageOffset() const override; + gfx::ImageSkia GetDragImage() const override; + gfx::Vector2d GetDragImageOffset() const override; // ui::PlatformEventDispatcher: bool CanDispatchEvent(const PlatformEvent& event) override;
diff --git a/ui/base/dragdrop/os_exchange_data_provider_mac.h b/ui/base/dragdrop/os_exchange_data_provider_mac.h index c95fd279..4250f92 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_mac.h +++ b/ui/base/dragdrop/os_exchange_data_provider_mac.h
@@ -51,8 +51,8 @@ bool HasCustomFormat(const Clipboard::FormatType& format) const override; void SetDragImage(const gfx::ImageSkia& image, const gfx::Vector2d& cursor_offset) override; - const gfx::ImageSkia& GetDragImage() const override; - const gfx::Vector2d& GetDragImageOffset() const override; + gfx::ImageSkia GetDragImage() const override; + gfx::Vector2d GetDragImageOffset() const override; // Returns the data for the specified type in the pasteboard. NSData* GetNSDataForType(NSString* type) const;
diff --git a/ui/base/dragdrop/os_exchange_data_provider_mac.mm b/ui/base/dragdrop/os_exchange_data_provider_mac.mm index 11b0a495..2014408 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_mac.mm +++ b/ui/base/dragdrop/os_exchange_data_provider_mac.mm
@@ -181,11 +181,11 @@ cursor_offset_ = cursor_offset; } -const gfx::ImageSkia& OSExchangeDataProviderMac::GetDragImage() const { +gfx::ImageSkia OSExchangeDataProviderMac::GetDragImage() const { return drag_image_; } -const gfx::Vector2d& OSExchangeDataProviderMac::GetDragImageOffset() const { +gfx::Vector2d OSExchangeDataProviderMac::GetDragImageOffset() const { return cursor_offset_; }
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.cc b/ui/base/dragdrop/os_exchange_data_provider_win.cc index 44e6cb6..7657d3a 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_win.cc +++ b/ui/base/dragdrop/os_exchange_data_provider_win.cc
@@ -4,6 +4,9 @@ #include "ui/base/dragdrop/os_exchange_data_provider_win.h" +#include <objidl.h> +#include <shlobj.h> +#include <shobjidl.h> #include <stdint.h> #include <algorithm> @@ -16,12 +19,19 @@ #include "base/memory/ptr_util.h" #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" +#include "base/win/scoped_comptr.h" +#include "base/win/scoped_hdc.h" #include "base/win/scoped_hglobal.h" #include "net/base/filename_util.h" +#include "skia/ext/skia_utils_win.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/clipboard_util_win.h" #include "ui/base/dragdrop/file_info.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/skbitmap_operations.h" #include "ui/strings/grit/ui_strings.h" #include "url/gurl.h" @@ -540,18 +550,70 @@ } void OSExchangeDataProviderWin::SetDragImage( - const gfx::ImageSkia& image, + const gfx::ImageSkia& image_skia, const gfx::Vector2d& cursor_offset) { - drag_image_ = image; - drag_image_offset_ = cursor_offset; + DCHECK(!image_skia.size().IsEmpty()); + + // InitializeFromBitmap() doesn't expect an alpha channel and is confused + // by premultiplied colors, so unpremultiply the bitmap. + SkBitmap unpremul_bitmap = + SkBitmapOperations::UnPreMultiply(*image_skia.bitmap()); + int width = unpremul_bitmap.width(); + int height = unpremul_bitmap.height(); + size_t rowbytes = unpremul_bitmap.rowBytes(); + DCHECK_EQ(rowbytes, static_cast<size_t>(width) * 4u); + + void* bits; + HBITMAP hbitmap; + { + BITMAPINFOHEADER header; + skia::CreateBitmapHeader(width, height, &header); + + base::win::ScopedGetDC screen_dc(NULL); + // By giving a null hSection, the |bits| will be destroyed when the + // |hbitmap| is destroyed. + hbitmap = + CreateDIBSection(screen_dc, reinterpret_cast<BITMAPINFO*>(&header), + DIB_RGB_COLORS, &bits, NULL, 0); + } + if (!hbitmap) + return; + + { + SkAutoLockPixels lock(unpremul_bitmap); + memcpy(bits, unpremul_bitmap.getPixels(), height * rowbytes); + } + + base::win::ScopedComPtr<IDragSourceHelper> helper; + HRESULT rv = CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, + IID_IDragSourceHelper, helper.ReceiveVoid()); + if (!SUCCEEDED(rv)) + return; + + // InitializeFromBitmap() takes ownership of |hbitmap|. + SHDRAGIMAGE sdi; + sdi.sizeDragImage.cx = width; + sdi.sizeDragImage.cy = height; + sdi.crColorKey = 0xFFFFFFFF; + sdi.hbmpDragImage = hbitmap; + sdi.ptOffset = gfx::PointAtOffsetFromOrigin(cursor_offset).ToPOINT(); + helper->InitializeFromBitmap(&sdi, data_object()); } -const gfx::ImageSkia& OSExchangeDataProviderWin::GetDragImage() const { - return drag_image_; +gfx::ImageSkia OSExchangeDataProviderWin::GetDragImage() const { + // This class sets the image on data_object() so it shouldn't be used in + // situations where the drag image is later queried. In that case a different + // OSExchangeData::Provider should be used. + NOTREACHED(); + return gfx::ImageSkia(); } -const gfx::Vector2d& OSExchangeDataProviderWin::GetDragImageOffset() const { - return drag_image_offset_; +gfx::Vector2d OSExchangeDataProviderWin::GetDragImageOffset() const { + // This class sets the image on data_object() so it shouldn't be used in + // situations where the drag image is later queried. In that case a different + // OSExchangeData::Provider should be used. + NOTREACHED(); + return gfx::Vector2d(); } ///////////////////////////////////////////////////////////////////////////////
diff --git a/ui/base/dragdrop/os_exchange_data_provider_win.h b/ui/base/dragdrop/os_exchange_data_provider_win.h index 9987779f..86f95a6 100644 --- a/ui/base/dragdrop/os_exchange_data_provider_win.h +++ b/ui/base/dragdrop/os_exchange_data_provider_win.h
@@ -178,19 +178,15 @@ bool HasCustomFormat(const Clipboard::FormatType& format) const override; void SetDownloadFileInfo( const OSExchangeData::DownloadFileInfo& download_info) override; - void SetDragImage(const gfx::ImageSkia& image, + void SetDragImage(const gfx::ImageSkia& image_skia, const gfx::Vector2d& cursor_offset) override; - const gfx::ImageSkia& GetDragImage() const override; - const gfx::Vector2d& GetDragImageOffset() const override; + gfx::ImageSkia GetDragImage() const override; + gfx::Vector2d GetDragImageOffset() const override; private: scoped_refptr<DataObjectImpl> data_; base::win::ScopedComPtr<IDataObject> source_object_; - // Drag image and offset data. Only used for Ash. - gfx::ImageSkia drag_image_; - gfx::Vector2d drag_image_offset_; - DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderWin); };
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index 0783ff0..d06bf13 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc
@@ -2210,9 +2210,17 @@ DISALLOW_COPY_AND_ASSIGN(TestMetricsReporter); }; +// TODO(crbug/709080): LayerWithRealCompositorTest.ReportMetrics is flaky on +// Windows. +#if defined(OS_WIN) +#define MAYBE_ReportMetrics DISABLED_ReportMetrics +#else +#define MAYBE_ReportMetrics ReportMetrics +#endif + // Starts an animation and tests that incrementing compositor frame count can // be used to report animation smoothness metrics. -TEST_F(LayerWithRealCompositorTest, ReportMetrics) { +TEST_F(LayerWithRealCompositorTest, MAYBE_ReportMetrics) { std::unique_ptr<Layer> root(CreateLayer(LAYER_SOLID_COLOR)); GetCompositor()->SetRootLayer(root.get()); LayerAnimator* animator = root->GetAnimator();
diff --git a/ui/keyboard/keyboard_layout_manager.cc b/ui/keyboard/keyboard_layout_manager.cc index 613800f..178a864 100644 --- a/ui/keyboard/keyboard_layout_manager.cc +++ b/ui/keyboard/keyboard_layout_manager.cc
@@ -99,7 +99,7 @@ // We need to send out this notification only if keyboard is visible since // keyboard window is resized even if keyboard is hidden. if (controller_->keyboard_visible()) - controller_->NotifyKeyboardBoundsChanging(requested_bounds); + controller_->NotifyKeyboardBoundsChanging(new_bounds); } else if (controller_->keyboard_mode() == FLOATING) { controller_->NotifyKeyboardBoundsChanging(gfx::Rect()); }
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface.cc b/ui/ozone/platform/drm/gpu/gbm_surface.cc index 5995d89..649f4b0 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surface.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surface.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/logging.h" +#include "ui/display/types/display_snapshot.h" #include "ui/gfx/native_pixmap.h" #include "ui/gl/gl_image_native_pixmap.h" #include "ui/gl/gl_surface_egl.h" @@ -123,14 +124,15 @@ return true; for (size_t i = 0; i < arraysize(textures_); i++) { scoped_refptr<gfx::NativePixmap> pixmap = - surface_factory()->CreateNativePixmap(widget(), GetSize(), - gfx::BufferFormat::BGRA_8888, - gfx::BufferUsage::SCANOUT); + surface_factory()->CreateNativePixmap( + widget(), GetSize(), display::DisplaySnapshot::PrimaryFormat(), + gfx::BufferUsage::SCANOUT); if (!pixmap) return false; scoped_refptr<gl::GLImageNativePixmap> image = - new gl::GLImageNativePixmap(GetSize(), GL_BGRA_EXT); - if (!image->Initialize(pixmap.get(), gfx::BufferFormat::BGRA_8888)) + new gl::GLImageNativePixmap(GetSize(), GL_RGB); + if (!image->Initialize(pixmap.get(), + display::DisplaySnapshot::PrimaryFormat())) return false; images_[i] = image; // Bind image to texture.
diff --git a/ui/views/button_drag_utils.cc b/ui/views/button_drag_utils.cc index c3bf393..230fb8e 100644 --- a/ui/views/button_drag_utils.cc +++ b/ui/views/button_drag_utils.cc
@@ -5,7 +5,6 @@ #include "ui/views/button_drag_utils.h" #include "base/strings/utf_string_conversions.h" -#include "ui/base/dragdrop/drag_utils.h" #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/resource/resource_bundle.h" #include "ui/compositor/canvas_painter.h" @@ -87,7 +86,7 @@ SkColor color = SK_ColorTRANSPARENT; button.Paint(ui::CanvasPainter(&bitmap, size, raster_scale, color).context()); gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, raster_scale)); - drag_utils::SetDragImageOnDataObject(image, press_point, data); + data->provider().SetDragImage(image, press_point); } } // namespace button_drag_utils
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 3f9436db..d581719 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -10,7 +10,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "build/build_config.h" -#include "ui/base/dragdrop/drag_utils.h" #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/display/screen.h" #include "ui/events/event.h" @@ -1253,8 +1252,7 @@ OSExchangeData data; item->GetDelegate()->WriteDragData(item, &data); - drag_utils::SetDragImageOnDataObject(image, press_loc.OffsetFromOrigin(), - &data); + data.provider().SetDragImage(image, press_loc.OffsetFromOrigin()); StopScrolling(); int drag_ops = item->GetDelegate()->GetDragOperations(item);
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 1586362..877820490 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -17,7 +17,6 @@ #include "ui/base/cursor/cursor.h" #include "ui/base/default_style.h" #include "ui/base/dragdrop/drag_drop_types.h" -#include "ui/base/dragdrop/drag_utils.h" #include "ui/base/ime/input_method.h" #include "ui/base/ime/text_edit_commands.h" #include "ui/base/material_design/material_design_controller.h" @@ -1090,7 +1089,7 @@ ui::CanvasPainter(&bitmap, label.size(), raster_scale, color).context()); const gfx::Vector2d kOffset(-15, 0); gfx::ImageSkia image(gfx::ImageSkiaRep(bitmap, raster_scale)); - drag_utils::SetDragImageOnDataObject(image, kOffset, data); + data->provider().SetDragImage(image, kOffset); if (controller_) controller_->OnWriteDragData(data); }