diff --git a/DEPS b/DEPS index 9b8bbcec..82f1db1 100644 --- a/DEPS +++ b/DEPS
@@ -121,7 +121,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '1345366c21ea285b4225ce9bf0de4ef401d76d72', + 'skia_revision': '88bfed46ab6e0e4aec5416092a349e394c72ba59', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -133,7 +133,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '794364ebd51c1c7d113fc4208857a15cd557b4db', + 'angle_revision': '48d040e8c5241d22ba04746de1fb920268a25aeb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -145,7 +145,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'a2e2d7f291cfa232c3e5ef48d086c0002b0e06df', + 'pdfium_revision': '7a629886aed968d8bfcabfe48cd898465e4ef469', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -185,7 +185,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': '2061050c4d27b3b27bc3cfc7cf20fc99644f66f7', + 'catapult_revision': 'b6cc5a6baf93cfa6feeb240eea75c454506b0c3c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -233,7 +233,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': '464111eaef80c4951e63473bc1c9e072f8d33588', + 'spv_tools_revision': '453b7c85c8fde99251028125a19cd3a20a1a758b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -694,7 +694,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6e669b46b4792ae79198377d36757053c9b445aa', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '2e5e7db63cd9aaa4d7052b10fe18f54f4acbfa26', 'condition': 'checkout_linux', }, @@ -719,7 +719,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '50b187ca83716db937923d9ed1ef031f6e071d2a', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '39b0b8e32a4ed0675a38d97799e8a219cc549910', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -948,7 +948,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '9ecc0e779a29281e5698451bfd1b3ebe8f053bfd', + Var('chromium_git') + '/webm/libvpx.git' + '@' + 'cde3da57b9a18636026531694ca76671894d1dce', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4931ebc0a816458c18a6734e91a4d1b5acd5c56', @@ -1258,7 +1258,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@26fd840339f85a6169bbbc0cd0d4cd2d847ea0e5', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@2cde328881f0aaec7d59c81f2b861d4fbace3d10', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/HeapProfilingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/HeapProfilingTest.java index 3057d796..6f4f333 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/HeapProfilingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/HeapProfilingTest.java
@@ -36,28 +36,35 @@ public void testModeBrowser() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue( - shim.runTestForMode("browser", false, "native-include-thread-names", false, false)); + Assert.assertTrue(shim.runTestForMode( + "browser", false, "native-include-thread-names", true, false, false)); } @Test @MediumTest public void testModeBrowserDynamicPseudo() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", false, false)); + Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, false, false)); } @Test @MediumTest public void testModeBrowserDynamicPseudoSampleEverything() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, true)); + Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, true, true)); } @Test @MediumTest public void testModeBrowserDynamicPseudoSamplePartial() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, false)); + Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, true, false)); + } + + @Test + @MediumTest + public void testModeBrowserDynamicPseudoSamplePartialNonStreaming() throws Exception { + HeapProfilingTestShim shim = new HeapProfilingTestShim(); + Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", false, true, false)); } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/HeapProfilingTestShim.java b/android_webview/javatests/src/org/chromium/android_webview/test/HeapProfilingTestShim.java index 7403f6b5..6a3f052 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/HeapProfilingTestShim.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/HeapProfilingTestShim.java
@@ -24,9 +24,9 @@ * rather than native stacks. */ public boolean runTestForMode(String mode, boolean dynamicallyStartProfiling, String stackMode, - boolean shouldSample, boolean sampleEverything) { + boolean streamSamples, boolean shouldSample, boolean sampleEverything) { return nativeRunTestForMode(mNativeHeapProfilingTestShim, mode, dynamicallyStartProfiling, - stackMode, shouldSample, sampleEverything); + stackMode, streamSamples, shouldSample, sampleEverything); } /** @@ -44,6 +44,6 @@ private native long nativeInit(); private native void nativeDestroy(long nativeHeapProfilingTestShim); private native boolean nativeRunTestForMode(long nativeHeapProfilingTestShim, String mode, - boolean dynamicallyStartProfiling, String stackMode, boolean shouldSample, - boolean sampleEverything); + boolean dynamicallyStartProfiling, String stackMode, boolean streamSamples, + boolean shouldSample, boolean sampleEverything); }
diff --git a/ash/login/ui/login_user_menu_view.cc b/ash/login/ui/login_user_menu_view.cc index 5ab0776..8fed571 100644 --- a/ash/login/ui/login_user_menu_view.cc +++ b/ash/login/ui/login_user_menu_view.cc
@@ -10,6 +10,8 @@ #include "base/strings/utf_string_conversions.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/views/controls/separator.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" @@ -252,6 +254,13 @@ LoginUserMenuView::~LoginUserMenuView() = default; +void LoginUserMenuView::ResetState() { + if (remove_user_confirm_data_) { + remove_user_confirm_data_->SetVisible(false); + remove_user_label_->SetEnabledColor(kRemoveUserInitialColor); + } +} + LoginButton* LoginUserMenuView::GetBubbleOpener() const { return bubble_opener_; } @@ -264,7 +273,6 @@ remove_user_confirm_data_->SetVisible(true); remove_user_label_->SetEnabledColor(kRemoveUserConfirmColor); - SetSize(GetPreferredSize()); Layout(); // Fire an accessibility alert to make ChromeVox read the warning message @@ -294,6 +302,24 @@ if (GetAnchorView()) position.set_y(position.y() + kAnchorViewUserMenuVerticalSpacingDp); + gfx::Rect screen_bounds = + display::Screen::GetScreen()->GetPrimaryDisplay().bounds(); + + // In handling the cases where the bubble could go off screen, we assume that + // the bubble can go either off the right side or off the bottom side. + if (position.x() + width() > screen_bounds.right() && GetAnchorView()) { + // If bubble would go off the right side of the screen, go left instead + position.set_x(position.x() + GetAnchorView()->width() - width()); + } else if (position.y() + height() > screen_bounds.bottom() && + GetAnchorView()) { + // If bubble would go off the bottom of the screen, go to the right of the + // anchor and upward. + position.set_x(position.x() + kAnchorViewUserMenuVerticalSpacingDp + + GetAnchorView()->width()); + position.set_y(position.y() + + (screen_bounds.bottom() - (position.y() + height()))); + } + return position; }
diff --git a/ash/login/ui/login_user_menu_view.h b/ash/login/ui/login_user_menu_view.h index d14a1fe..2bd29a3 100644 --- a/ash/login/ui/login_user_menu_view.h +++ b/ash/login/ui/login_user_menu_view.h
@@ -45,6 +45,9 @@ ~LoginUserMenuView() override; + // Resets the user menu to the state where Remove User has not been pressed. + void ResetState(); + // LoginBaseBubbleView: LoginButton* GetBubbleOpener() const override; gfx::Point CalculatePosition() override;
diff --git a/ash/login/ui/login_user_menu_view_unittest.cc b/ash/login/ui/login_user_menu_view_unittest.cc index 81427f1..016b836 100644 --- a/ash/login/ui/login_user_menu_view_unittest.cc +++ b/ash/login/ui/login_user_menu_view_unittest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include "ash/login/ui/login_user_menu_view.h" #include "ash/login/ui/login_button.h" #include "ash/login/ui/login_test_base.h" @@ -141,4 +143,29 @@ EXPECT_FALSE(ink_drop_api.GetInkDrop()->IsHighlightFadingInOrVisible()); } +TEST_F(LoginUserMenuViewTest, ResetStateHidesConfirmData) { + auto* container = new views::View; + container->SetLayoutManager( + std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + SetWidget(CreateWidgetWithContent(container)); + + auto* bubble = new LoginUserMenuView( + base::string16(), base::string16(), user_manager::USER_TYPE_REGULAR, + false /*is_owner*/, nullptr /*anchor*/, nullptr /*bubble_opener*/, + true /*show_remove_user*/, base::DoNothing(), base::DoNothing()); + container->AddChildView(bubble); + + bubble->Show(); + + LoginUserMenuView::TestApi test_api(bubble); + EXPECT_FALSE(test_api.remove_user_confirm_data()->visible()); + + test_api.remove_user_button()->RequestFocus(); + GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); + EXPECT_TRUE(test_api.remove_user_confirm_data()->visible()); + + bubble->ResetState(); + EXPECT_FALSE(test_api.remove_user_confirm_data()->visible()); +} + } // namespace ash
diff --git a/ash/login/ui/login_user_view.cc b/ash/login/ui/login_user_view.cc index 4c4b6f7..e34cb5d 100644 --- a/ash/login/ui/login_user_view.cc +++ b/ash/login/ui/login_user_view.cc
@@ -552,6 +552,8 @@ if (!menu_->parent()) login_views_utils::GetTopLevelParentView(this)->AddChildView(menu_); + // Reset state in case the remove-user button was clicked once previously. + menu_->ResetState(); menu_->Show(); // If the menu was opened by pressing Enter on the focused dropdown, focus
diff --git a/ash/login/ui/login_user_view.h b/ash/login/ui/login_user_view.h index 61300eb..34d04b4 100644 --- a/ash/login/ui/login_user_view.h +++ b/ash/login/ui/login_user_view.h
@@ -123,7 +123,7 @@ // Bubble used for displaying the user dropdown menu. Its parent is the top // level view, either LockContentsView or LockDebugView. This allows the menu // to be clicked outside the bounds of the user view. - LoginBaseBubbleView* menu_ = nullptr; + LoginUserMenuView* menu_ = nullptr; // Show the domain information for public account user. UserDomainInfoView* user_domain_ = nullptr;
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index 3b7c95a..8082a87c 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -207,7 +207,6 @@ // See content::RunAllTasksUntilIdle(). void RunAllTasksUntilIdle() { - LOG(ERROR) << "RunAllTasksUntilIdle - before"; while (true) { TaskObserver task_observer; base::MessageLoopCurrent::Get()->AddTaskObserver(&task_observer); @@ -220,7 +219,6 @@ if (!task_observer.processed()) break; } - LOG(ERROR) << "RunAllTasksUntilIdle - after"; } // A test implementation of the WallpaperObserver mojo interface.
diff --git a/base/base_paths_fuchsia.cc b/base/base_paths_fuchsia.cc index 72179a9..5e4741d 100644 --- a/base/base_paths_fuchsia.cc +++ b/base/base_paths_fuchsia.cc
@@ -17,7 +17,7 @@ bool PathProviderFuchsia(int key, FilePath* result) { switch (key) { case FILE_MODULE: - NOTIMPLEMENTED(); + NOTIMPLEMENTED() << " for FILE_MODULE."; return false; case FILE_EXE: *result = CommandLine::ForCurrentProcess()->GetProgram();
diff --git a/base/process/process_metrics_fuchsia.cc b/base/process/process_metrics_fuchsia.cc index 417f7ccf..7e4e504 100644 --- a/base/process/process_metrics_fuchsia.cc +++ b/base/process/process_metrics_fuchsia.cc
@@ -13,25 +13,25 @@ } size_t GetSystemCommitCharge() { - // Not available, doesn't seem likely that it will be (for the whole system). - NOTIMPLEMENTED(); + // TODO(https://crbug.com/926581): Fuchsia does not support this. + NOTIMPLEMENTED_LOG_ONCE(); return 0; } // static std::unique_ptr<ProcessMetrics> ProcessMetrics::CreateProcessMetrics( ProcessHandle process) { - NOTIMPLEMENTED(); // TODO(fuchsia): https://crbug.com/706592. + NOTIMPLEMENTED_LOG_ONCE(); // TODO(https://crbug.com/926581). return nullptr; } TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { - NOTIMPLEMENTED(); // TODO(fuchsia): https://crbug.com/706592. + NOTIMPLEMENTED_LOG_ONCE(); // TODO(https://crbug.com/926581). return TimeDelta(); } bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo) { - NOTIMPLEMENTED(); // TODO(fuchsia): https://crbug.com/706592. + NOTIMPLEMENTED_LOG_ONCE(); // TODO(https://crbug.com/926581). return false; }
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler.cc b/base/sampling_heap_profiler/poisson_allocation_sampler.cc index eac17086..14f20a5 100644 --- a/base/sampling_heap_profiler/poisson_allocation_sampler.cc +++ b/base/sampling_heap_profiler/poisson_allocation_sampler.cc
@@ -325,6 +325,11 @@ TLSSetValue(g_internal_reentry_guard, false); } +// static +bool PoissonAllocationSampler::ScopedMuteThreadSamples::IsMuted() { + return TLSGetValue(g_internal_reentry_guard); +} + PoissonAllocationSampler* PoissonAllocationSampler::instance_; PoissonAllocationSampler::PoissonAllocationSampler() {
diff --git a/base/sampling_heap_profiler/poisson_allocation_sampler.h b/base/sampling_heap_profiler/poisson_allocation_sampler.h index a55fdea..0dfb8b2a8 100644 --- a/base/sampling_heap_profiler/poisson_allocation_sampler.h +++ b/base/sampling_heap_profiler/poisson_allocation_sampler.h
@@ -54,6 +54,8 @@ public: ScopedMuteThreadSamples(); ~ScopedMuteThreadSamples(); + + static bool IsMuted(); }; // Must be called early during the process initialization. It creates and
diff --git a/base/threading/platform_thread_fuchsia.cc b/base/threading/platform_thread_fuchsia.cc index e1e41a4..b732be7c 100644 --- a/base/threading/platform_thread_fuchsia.cc +++ b/base/threading/platform_thread_fuchsia.cc
@@ -38,7 +38,8 @@ // static void PlatformThread::SetCurrentThreadPriorityImpl(ThreadPriority priority) { if (priority != ThreadPriority::NORMAL) { - NOTIMPLEMENTED() << "setting ThreadPriority " << static_cast<int>(priority); + // TODO(https://crbug.com/926583): Fuchsia does not currently support this. + NOTIMPLEMENTED_LOG_ONCE() << " to non-NORMAL priority."; } }
diff --git a/base/threading/sequence_bound.h b/base/threading/sequence_bound.h index c5fb9d0..683bc42 100644 --- a/base/threading/sequence_bound.h +++ b/base/threading/sequence_bound.h
@@ -214,6 +214,9 @@ // might still be pending destruction on the impl thread. bool is_null() const { return !t_; } + // True if and only if we have an object, with the same caveats as is_null(). + explicit operator bool() const { return !is_null(); } + private: // Pointer to the object, Pointer may be modified on the owning thread. T* t_ = nullptr;
diff --git a/base/threading/sequence_bound_unittest.cc b/base/threading/sequence_bound_unittest.cc index d468aa32..61e2b7b 100644 --- a/base/threading/sequence_bound_unittest.cc +++ b/base/threading/sequence_bound_unittest.cc
@@ -80,6 +80,7 @@ TEST_F(SequenceBoundTest, MAYBE_ConstructThenPostThenReset) { auto derived = SequenceBound<Derived>(task_runner_, &value); EXPECT_FALSE(derived.is_null()); + EXPECT_TRUE(derived); // Nothing should happen until we run the message loop. EXPECT_EQ(value, kInitialValue); @@ -96,6 +97,7 @@ // report that it is null immediately. derived.Reset(); EXPECT_TRUE(derived.is_null()); + EXPECT_FALSE(derived); EXPECT_EQ(value, kDifferentValue); base::RunLoop().RunUntilIdle(); EXPECT_EQ(value, kDerivedDtorValue);
diff --git a/base/trace_event/trace_config.cc b/base/trace_event/trace_config.cc index d5aca59..6b208d4 100644 --- a/base/trace_event/trace_config.cc +++ b/base/trace_event/trace_config.cc
@@ -55,6 +55,8 @@ // String parameter used to parse process filter. const char kIncludedProcessesParam[] = "included_process_ids"; +const char kHistogramNamesParam[] = "histogram_names"; + class ConvertableTraceConfigToTraceFormat : public base::trace_event::ConvertableToTraceFormat { public: @@ -295,6 +297,7 @@ process_filter_config_ = rhs.process_filter_config_; memory_dump_config_ = rhs.memory_dump_config_; event_filters_ = rhs.event_filters_; + histogram_names_ = rhs.histogram_names_; return *this; } @@ -337,6 +340,8 @@ event_filters_.insert(event_filters_.end(), config.event_filters().begin(), config.event_filters().end()); + histogram_names_.insert(config.histogram_names().begin(), + config.histogram_names().end()); } void TraceConfig::Clear() { @@ -348,6 +353,7 @@ memory_dump_config_.Clear(); process_filter_config_.Clear(); event_filters_.clear(); + histogram_names_.clear(); } void TraceConfig::InitializeDefault() { @@ -386,6 +392,9 @@ const base::ListValue* category_event_filters = nullptr; if (dict.GetList(kEventFiltersParam, &category_event_filters)) SetEventFiltersFromConfigList(*category_event_filters); + const base::ListValue* histogram_names = nullptr; + if (dict.GetList(kHistogramNamesParam, &histogram_names)) + SetHistogramNamesFromConfigList(*histogram_names); if (category_filter_.IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) { // If dump triggers not set, the client is using the legacy with just @@ -517,6 +526,13 @@ process_filter_config_ = config; } +void TraceConfig::SetHistogramNamesFromConfigList( + const base::ListValue& histogram_names) { + histogram_names_.clear(); + for (const Value& value : histogram_names.GetList()) + histogram_names_.insert(value.GetString()); +} + void TraceConfig::SetEventFiltersFromConfigList( const base::ListValue& category_event_filters) { event_filters_.clear(); @@ -598,9 +614,21 @@ } dict->Set(kMemoryDumpConfigParam, std::move(memory_dump_config)); } + + if (!histogram_names_.empty()) { + std::unique_ptr<base::ListValue> histogram_names(new base::ListValue()); + for (const std::string& histogram_name : histogram_names_) + histogram_names->AppendString(histogram_name); + dict->Set(kHistogramNamesParam, std::move(histogram_names)); + } + return dict; } +void TraceConfig::EnableHistogram(const std::string& histogram_name) { + histogram_names_.insert(histogram_name); +} + std::string TraceConfig::ToTraceOptionsString() const { std::string ret; switch (record_mode_) {
diff --git a/base/trace_event/trace_config.h b/base/trace_event/trace_config.h index e3be39d..09bdd60 100644 --- a/base/trace_event/trace_config.h +++ b/base/trace_event/trace_config.h
@@ -238,6 +238,7 @@ } void EnableSystrace() { enable_systrace_ = true; } void EnableArgumentFilter() { enable_argument_filter_ = true; } + void EnableHistogram(const std::string& histogram_name); // Writes the string representation of the TraceConfig. The string is JSON // formatted. @@ -280,6 +281,10 @@ event_filters_ = filter_configs; } + const std::unordered_set<std::string>& histogram_names() const { + return histogram_names_; + } + private: FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, TraceConfigFromValidLegacyFormat); FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, @@ -304,6 +309,7 @@ const DictionaryValue& memory_dump_config); void SetDefaultMemoryDumpConfig(); + void SetHistogramNamesFromConfigList(const base::ListValue& histogram_names); void SetEventFiltersFromConfigList(const base::ListValue& event_filters); std::unique_ptr<DictionaryValue> ToDict() const; @@ -320,6 +326,7 @@ ProcessFilterConfig process_filter_config_; EventFilters event_filters_; + std::unordered_set<std::string> histogram_names_; }; } // namespace trace_event
diff --git a/base/trace_event/trace_config_unittest.cc b/base/trace_event/trace_config_unittest.cc index 9fb3753..5cfd4e5 100644 --- a/base/trace_event/trace_config_unittest.cc +++ b/base/trace_event/trace_config_unittest.cc
@@ -37,6 +37,7 @@ "}" "]," "\"excluded_categories\":[\"excluded\",\"exc_pattern*\"]," + "\"histogram_names\":[\"uma1\",\"uma2\"]," "\"included_categories\":[" "\"included\"," "\"inc_pattern*\"," @@ -81,6 +82,21 @@ "disabled-by-default-cc,disabled-by-default-cc2")); } +// Returns an string in which word1 and word2 are swapped. word1 and word2 must +// be non-overlapping substrings of the input string and word1 must be before +// word2. +std::string SwapWords(const std::string& in_str, + const std::string& word1, + const std::string& word2) { + size_t pos1 = in_str.find(word1); + size_t len1 = word1.size(); + size_t pos2 = in_str.find(word2); + size_t len2 = word2.size(); + return in_str.substr(0, pos1) + word2 + + in_str.substr(pos1 + len1, pos2 - pos1 - len1) + word1 + + in_str.substr(pos2 + len2); +} + } // namespace TEST(TraceConfigTest, TraceConfigFromValidLegacyFormat) { @@ -345,7 +361,10 @@ is_dict = custom_value->GetAsDictionary(&custom_dict); DCHECK(is_dict); TraceConfig custom_tc(*custom_dict); - EXPECT_STREQ(kCustomTraceConfigString, custom_tc.ToString().c_str()); + std::string custom_tc_str = custom_tc.ToString(); + EXPECT_TRUE(custom_tc_str == kCustomTraceConfigString || + custom_tc_str == + SwapWords(kCustomTraceConfigString, "uma1", "uma2")); EXPECT_EQ(RECORD_CONTINUOUSLY, custom_tc.GetTraceRecordMode()); EXPECT_TRUE(custom_tc.IsSystraceEnabled()); EXPECT_TRUE(custom_tc.IsArgumentFilterEnabled());
diff --git a/build/config/fuchsia/testing_sandbox_policy b/build/config/fuchsia/testing_sandbox_policy index 03fe2bb..dd1c7f9 100644 --- a/build/config/fuchsia/testing_sandbox_policy +++ b/build/config/fuchsia/testing_sandbox_policy
@@ -8,6 +8,7 @@ "fuchsia.media.Audio", "fuchsia.mediacodec.CodecFactory", "fuchsia.net.LegacySocketProvider", + "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.process.Launcher", "fuchsia.sys.Launcher",
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn index 6b92f3e..f4c94fd20 100644 --- a/build/config/sanitizers/BUILD.gn +++ b/build/config/sanitizers/BUILD.gn
@@ -259,7 +259,6 @@ # Incremental linking causes padding that messes up SanitizerCoverage. # Don't do it. ldflags = [ "/INCREMENTAL:NO" ] - libs = [ "clang_rt.fuzzer_no_main-x86_64.lib" ] } } }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 2c96613..38c0182 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -f8f8ce7b42e9377b18a457804a6928665004e5b5 \ No newline at end of file +092aef2aaad3c9ceb2b9771170055371b987fe69 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index be4b1c9..20d2e7f 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -66374af5ae391a2a5152a90e097e991acf9c8d68 \ No newline at end of file +793fd71e247d7f737d5466cd70c34f32773d5a9e \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 96708ac5..16ea670d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -372,14 +372,15 @@ } /** - * Return whether the passed in class name matches any of the supported tabbed mode activities. + * Return whether the passed in component name matches any of the supported tabbed mode + * activities. */ public static boolean isTabbedModeComponentName(String componentName) { return TextUtils.equals(componentName, ChromeTabbedActivity.class.getName()) || TextUtils.equals( componentName, MultiInstanceChromeTabbedActivity.class.getName()) || TextUtils.equals(componentName, ChromeTabbedActivity2.class.getName()) - || TextUtils.equals(componentName, BuildInfo.getInstance().packageName + ".Main"); + || TextUtils.equals(componentName, "com.google.android.apps.chrome.Main"); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/profiling_host/ProfilingProcessHostAndroidTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/profiling_host/ProfilingProcessHostAndroidTest.java index f229514..d5c59aa 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/profiling_host/ProfilingProcessHostAndroidTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/profiling_host/ProfilingProcessHostAndroidTest.java
@@ -43,22 +43,36 @@ public void testModeBrowser() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue( - shim.runTestForMode("browser", false, "native-include-thread-names", false, false)); + Assert.assertTrue(shim.runTestForMode( + "browser", false, "native-include-thread-names", true, false, false)); } @Test @MediumTest public void testModeBrowserDynamic() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("browser", true, "native", false, false)); + Assert.assertTrue(shim.runTestForMode("browser", true, "native", true, false, false)); + } + + @Test + @MediumTest + public void testModeBrowserDynamicNonStreaming() throws Exception { + HeapProfilingTestShim shim = new HeapProfilingTestShim(); + Assert.assertTrue(shim.runTestForMode("browser", true, "native", false, false, false)); } @Test @MediumTest public void testModeBrowserDynamicPseudo() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", false, false)); + Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, false, false)); + } + + @Test + @MediumTest + public void testModeBrowserDynamicPseudoNonStreaming() throws Exception { + HeapProfilingTestShim shim = new HeapProfilingTestShim(); + Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", false, false, false)); } // Non-browser processes must be profiled with a command line flag, since @@ -73,7 +87,8 @@ Add({"memlog=all-renderers", "memlog-stack-mode=pseudo", "memlog-sampling-rate=1"}) public void testModeRendererPseudo() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("all-renderers", false, "pseudo", false, false)); + Assert.assertTrue( + shim.runTestForMode("all-renderers", false, "pseudo", true, false, false)); } @Test @@ -81,27 +96,28 @@ @CommandLineFlags.Add({"memlog=gpu", "memlog-stack-mode=pseudo", "memlog-sampling-rate=1"}) public void testModeGpuPseudo() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("gpu", false, "native", false, false)); + Assert.assertTrue(shim.runTestForMode("gpu", false, "native", true, false, false)); } @Test @MediumTest public void testModeBrowserDynamicPseudoSampleEverything() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, true)); + Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, true, true)); } @Test @MediumTest public void testModeBrowserDynamicPseudoSamplePartial() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, false)); + Assert.assertTrue(shim.runTestForMode("browser", true, "pseudo", true, true, false)); } @Test @MediumTest public void testModeBrowserAndAllUtility() throws Exception { HeapProfilingTestShim shim = new HeapProfilingTestShim(); - Assert.assertTrue(shim.runTestForMode("utility-and-browser", true, "pseudo", true, false)); + Assert.assertTrue( + shim.runTestForMode("utility-and-browser", true, "pseudo", true, true, false)); } }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index e0f586f..3727f79 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3336,7 +3336,6 @@ } } else { # Non-ChromeOS. sources += [ - "badging/badge_service_delegate.h", "fullscreen.h", "policy/browser_signin_policy_handler.cc", "policy/browser_signin_policy_handler.h", @@ -3353,6 +3352,8 @@ if (is_win) { sources += [ + "badging/badge_manager_delegate_win.cc", + "badging/badge_manager_delegate_win.h", "downgrade/user_data_downgrade.cc", "downgrade/user_data_downgrade.h", "first_run/upgrade_util.cc", @@ -3463,7 +3464,11 @@ if (is_mac) { allow_circular_includes_from += [ "//chrome/browser/apps/app_shim" ] - sources += [ "download/drag_download_item_mac.mm" ] + sources += [ + "badging/badge_manager_delegate_mac.cc", + "badging/badge_manager_delegate_mac.h", + "download/drag_download_item_mac.mm", + ] deps += [ "//chrome/app_shim", "//chrome/browser/apps/app_shim",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 610017f..dfc7893 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -48,6 +48,7 @@ #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/core/common/autofill_util.h" +#include "components/autofill_assistant/browser/features.h" #include "components/browser_sync/browser_sync_switches.h" #include "components/cloud_devices/common/cloud_devices_switches.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h" @@ -2698,10 +2699,6 @@ {"fill-on-account-select", flag_descriptions::kFillOnAccountSelectName, flag_descriptions::kFillOnAccountSelectDescription, kOsAll, FEATURE_VALUE_TYPE(password_manager::features::kFillOnAccountSelect)}, - {"enable-new-remote-playback-pipeline", - flag_descriptions::kNewRemotePlaybackPipelineName, - flag_descriptions::kNewRemotePlaybackPipelineDescription, kOsAll, - FEATURE_VALUE_TYPE(media::kNewRemotePlaybackPipeline)}, {"enable-surfaces-for-videos", flag_descriptions::kUseSurfaceLayerForVideoName, flag_descriptions::kUseSurfaceLayerForVideoDescription, kOsAll, @@ -2976,6 +2973,10 @@ #endif // defined(OS_ANDROID) #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) + {"omnibox-experimental-keyword-mode", + flag_descriptions::kOmniboxExperimentalKeywordModeName, + flag_descriptions::kOmniboxExperimentalKeywordModeDescription, kOsDesktop, + FEATURE_VALUE_TYPE(omnibox::kExperimentalKeywordMode)}, {"omnibox-reverse-answers", flag_descriptions::kOmniboxReverseAnswersName, flag_descriptions::kOmniboxReverseAnswersDescription, kOsDesktop, FEATURE_VALUE_TYPE(omnibox::kOmniboxReverseAnswers)}, @@ -4290,6 +4291,14 @@ FEATURE_VALUE_TYPE(media::kD3D11VideoDecoder)}, #endif +#if defined(OS_ANDROID) + {"autofill-assistant-chrome-entry", + flag_descriptions::kAutofillAssistantChromeEntryName, + flag_descriptions::kAutofillAssistantChromeEntryDescription, kOsAndroid, + FEATURE_VALUE_TYPE( + autofill_assistant::features::kAutofillAssistantChromeEntry)}, +#endif // defined(OS_ANDROID) + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/android/autofill_assistant/client_android.cc b/chrome/browser/android/autofill_assistant/client_android.cc index c3344b8..1ba4a81 100644 --- a/chrome/browser/android/autofill_assistant/client_android.cc +++ b/chrome/browser/android/autofill_assistant/client_android.cc
@@ -21,6 +21,7 @@ #include "chrome/common/channel_info.h" #include "components/autofill_assistant/browser/access_token_fetcher.h" #include "components/autofill_assistant/browser/controller.h" +#include "components/autofill_assistant/browser/features.h" #include "components/signin/core/browser/account_info.h" #include "components/version_info/channel.h" #include "content/public/browser/browser_task_traits.h" @@ -43,7 +44,7 @@ namespace { const base::FeatureParam<std::string> kAutofillAssistantServerUrl{ - &chrome::android::kAutofillAssistant, "url", + &autofill_assistant::features::kAutofillAssistant, "url", "https://automate-pa.googleapis.com"}; // Time between two attempts to destroy the controller.
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 72040b0..812c7ec 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -14,6 +14,7 @@ #include "base/stl_util.h" #include "chrome/common/chrome_features.h" #include "components/autofill/core/common/autofill_features.h" +#include "components/autofill_assistant/browser/features.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h" #include "components/download/public/common/download_features.h" #include "components/feed/feed_feature_list.h" @@ -56,6 +57,7 @@ &autofill::features::kAutofillManualFallbackAndroid, &autofill::features::kAutofillRefreshStyleAndroid, &autofill::features::kAutofillEnableCompanyName, + &autofill_assistant::features::kAutofillAssistant, &contextual_suggestions::kContextualSuggestionsButton, &contextual_suggestions::kContextualSuggestionsIPHReverseScroll, &contextual_suggestions::kContextualSuggestionsOptOut, @@ -89,7 +91,6 @@ &kAndroidPayIntegrationV2, &kAndroidPaymentApps, &kAndroidSiteSettingsUIRefresh, - &kAutofillAssistant, &kCastDeviceFilter, &kCCTBackgroundTab, &kCCTExternalLinkHandling, @@ -222,9 +223,6 @@ const base::Feature kAndroidSiteSettingsUIRefresh{ "AndroidSiteSettingsUIRefresh", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kAutofillAssistant{"AutofillAssistant", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kBackgroundTaskComponentUpdate{ "BackgroundTaskComponentUpdate", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 2bd790c..997c16c0 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -19,7 +19,6 @@ extern const base::Feature kAndroidPayIntegrationV2; extern const base::Feature kAndroidPaymentApps; extern const base::Feature kAndroidSiteSettingsUIRefresh; -extern const base::Feature kAutofillAssistant; extern const base::Feature kBackgroundTaskComponentUpdate; extern const base::Feature kCastDeviceFilter; extern const base::Feature kCCTBackgroundTab;
diff --git a/chrome/browser/badging/badge_manager.cc b/chrome/browser/badging/badge_manager.cc index 9715dd4..f7c5ed4 100644 --- a/chrome/browser/badging/badge_manager.cc +++ b/chrome/browser/badging/badge_manager.cc
@@ -4,21 +4,50 @@ #include "chrome/browser/badging/badge_manager.h" +#include <utility> + +#include "base/i18n/number_formatting.h" #include "base/logging.h" -#include "base/optional.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/strings/grit/ui_strings.h" + +#if defined(OS_MACOSX) +#include "chrome/browser/badging/badge_manager_delegate_mac.h" +#elif defined(OS_WIN) +#include "chrome/browser/badging/badge_manager_delegate_win.h" +#endif namespace badging { -BadgeManager::BadgeManager() = default; +std::string GetBadgeString(base::Optional<uint64_t> badge_content) { + if (!badge_content) + return "•"; + + if (badge_content > 99u) { + return base::UTF16ToUTF8(l10n_util::GetStringFUTF16( + IDS_SATURATED_BADGE_CONTENT, base::FormatNumber(99))); + } + + return base::UTF16ToUTF8(base::FormatNumber(badge_content.value())); +} + +BadgeManager::BadgeManager(Profile* profile) { +#if defined(OS_MACOSX) + SetDelegate(std::make_unique<BadgeManagerDelegateMac>(profile)); +#elif defined(OS_WIN) + SetDelegate(std::make_unique<BadgeManagerDelegateWin>(profile)); +#endif +} BadgeManager::~BadgeManager() = default; void BadgeManager::UpdateBadge(const extensions::ExtensionId& extension_id, - base::Optional<int> contents) { - auto it = badged_apps_.find(extension_id); - if (it != badged_apps_.end() && it->second == contents) - return; - + base::Optional<uint64_t> contents) { badged_apps_[extension_id] = contents; if (!delegate_) @@ -28,16 +57,15 @@ } void BadgeManager::ClearBadge(const extensions::ExtensionId& extension_id) { - auto removed = badged_apps_.erase(extension_id); - if (!removed || !delegate_) + badged_apps_.erase(extension_id); + if (!delegate_) return; delegate_->OnBadgeCleared(extension_id); } -void BadgeManager::SetDelegate(BadgeManagerDelegate* badge_manager_delegate) { - DCHECK(!delegate_); - delegate_ = badge_manager_delegate; +void BadgeManager::SetDelegate(std::unique_ptr<BadgeManagerDelegate> delegate) { + delegate_ = std::move(delegate); } } // namespace badging
diff --git a/chrome/browser/badging/badge_manager.h b/chrome/browser/badging/badge_manager.h index 83dd78e8..940cff3 100644 --- a/chrome/browser/badging/badge_manager.h +++ b/chrome/browser/badging/badge_manager.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_BADGING_BADGE_MANAGER_H_ #include <map> +#include <memory> #include <string> #include "base/macros.h" @@ -15,30 +16,35 @@ #include "extensions/common/extension_id.h" class KeyedService; +class Profile; namespace badging { +// Determines the text to put on the badge based on some badge_content. +std::string GetBadgeString(base::Optional<uint64_t> badge_content); + // Maintains a record of badge contents and dispatches badge changes to a // delegate. class BadgeManager : public KeyedService { public: - BadgeManager(); + explicit BadgeManager(Profile* profile); ~BadgeManager() override; // Records badge contents for an app and notifies the delegate if the badge // contents have changed. - void UpdateBadge(const extensions::ExtensionId&, base::Optional<int>); + void UpdateBadge(const extensions::ExtensionId&, base::Optional<uint64_t>); // Clears badge contents for an app (if existing) and notifies the delegate. void ClearBadge(const extensions::ExtensionId&); - void SetDelegate(BadgeManagerDelegate*); + // Sets the delegate used for setting/clearing badges. + void SetDelegate(std::unique_ptr<BadgeManagerDelegate> delegate); private: - BadgeManagerDelegate* delegate_ = nullptr; + std::unique_ptr<BadgeManagerDelegate> delegate_; // Maps extension id to badge contents. - std::map<extensions::ExtensionId, base::Optional<int>> badged_apps_; + std::map<extensions::ExtensionId, base::Optional<uint64_t>> badged_apps_; DISALLOW_COPY_AND_ASSIGN(BadgeManager); };
diff --git a/chrome/browser/badging/badge_manager_delegate.h b/chrome/browser/badging/badge_manager_delegate.h index 07b0e14..0a6d86c4 100644 --- a/chrome/browser/badging/badge_manager_delegate.h +++ b/chrome/browser/badging/badge_manager_delegate.h
@@ -9,20 +9,28 @@ #include "base/optional.h" +class Profile; + namespace badging { // BadgeManagerDelegate is responsible for dispatching badge events that should // be handled and reflected in the UI. class BadgeManagerDelegate { public: + explicit BadgeManagerDelegate(Profile* profile) : profile_(profile) {} + virtual ~BadgeManagerDelegate() {} // Called when an app's badge has changed. virtual void OnBadgeSet(const std::string& app_id, - base::Optional<int> contents) = 0; + base::Optional<uint64_t> contents) = 0; // Called when a app's badge has been cleared. virtual void OnBadgeCleared(const std::string& app_id) = 0; + + protected: + // The profile the badge manager delegate is associated with. + Profile* profile_; }; } // namespace badging
diff --git a/chrome/browser/badging/badge_manager_delegate_mac.cc b/chrome/browser/badging/badge_manager_delegate_mac.cc new file mode 100644 index 0000000..3c2489b --- /dev/null +++ b/chrome/browser/badging/badge_manager_delegate_mac.cc
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/badging/badge_manager_delegate_mac.h" + +#include "chrome/browser/apps/app_shim/app_shim_host_mac.h" +#include "chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h" +#include "chrome/browser/badging/badge_manager.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/common/mac/app_shim.mojom.h" + +namespace {} // namespace + +namespace badging { + +BadgeManagerDelegateMac::BadgeManagerDelegateMac(Profile* profile) + : BadgeManagerDelegate(profile) {} + +void BadgeManagerDelegateMac::OnBadgeSet(const std::string& app_id, + base::Optional<uint64_t> contents) { + SetAppBadgeLabel(app_id, badging::GetBadgeString(contents)); +} + +void BadgeManagerDelegateMac::OnBadgeCleared(const std::string& app_id) { + SetAppBadgeLabel(app_id, ""); +} + +void BadgeManagerDelegateMac::SetAppBadgeLabel(const std::string& app_id, + const std::string& badge_label) { + auto* shim_handler = apps::ExtensionAppShimHandler::Get(); + if (!shim_handler) + return; + + // On OSX all app instances share a dock icon, so we only need to set the + // badge label once. + AppShimHost* shim_host = shim_handler->FindHost(profile_, app_id); + if (!shim_host) + return; + + chrome::mojom::AppShim* shim = shim_host->GetAppShim(); + if (!shim) + return; + + shim->SetBadgeLabel(badge_label); +} + +} // namespace badging \ No newline at end of file
diff --git a/chrome/browser/badging/badge_manager_delegate_mac.h b/chrome/browser/badging/badge_manager_delegate_mac.h new file mode 100644 index 0000000..54ad591 --- /dev/null +++ b/chrome/browser/badging/badge_manager_delegate_mac.h
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_BADGING_BADGE_MANAGER_DELEGATE_MAC_H_ +#define CHROME_BROWSER_BADGING_BADGE_MANAGER_DELEGATE_MAC_H_ + +#include <string> + +#include "base/optional.h" +#include "chrome/browser/badging/badge_manager_delegate.h" + +class Profile; + +namespace badging { + +// OSX specific implementation of the BadgeManagerDelegate. +class BadgeManagerDelegateMac : public BadgeManagerDelegate { + public: + explicit BadgeManagerDelegateMac(Profile* profile); + + void OnBadgeSet(const std::string& app_id, + base::Optional<uint64_t> contents) override; + + void OnBadgeCleared(const std::string& app_id) override; + + private: + void SetAppBadgeLabel(const std::string& app_id, + const std::string& badge_label); +}; + +} // namespace badging + +#endif // CHROME_BROWSER_BADGING_BADGE_MANAGER_DELEGATE_MAC_H_
diff --git a/chrome/browser/badging/badge_manager_delegate_win.cc b/chrome/browser/badging/badge_manager_delegate_win.cc new file mode 100644 index 0000000..16a10f0 --- /dev/null +++ b/chrome/browser/badging/badge_manager_delegate_win.cc
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/badging/badge_manager_delegate_win.h" + +#include "chrome/browser/badging/badge_manager.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/taskbar/taskbar_decorator_win.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window.h" + +namespace badging { + +BadgeManagerDelegateWin::BadgeManagerDelegateWin(Profile* profile) + : BadgeManagerDelegate(profile) {} + +void BadgeManagerDelegateWin::OnBadgeSet(const std::string& app_id, + base::Optional<uint64_t> contents) { + for (Browser* browser : *BrowserList::GetInstance()) { + if (!IsAppBrowser(browser, app_id)) + continue; + + auto* window = browser->window()->GetNativeWindow(); + taskbar::DrawTaskbarDecorationString(window, + badging::GetBadgeString(contents)); + } +} + +void BadgeManagerDelegateWin::OnBadgeCleared(const std::string& app_id) { + for (Browser* browser : *BrowserList::GetInstance()) { + if (!IsAppBrowser(browser, app_id)) + continue; + + // Restore the decoration to whatever it is naturally (either nothing or a + // profile picture badge). + taskbar::UpdateTaskbarDecoration(browser->profile(), + browser->window()->GetNativeWindow()); + } +} + +bool BadgeManagerDelegateWin::IsAppBrowser(Browser* browser, + const std::string& app_id) { + return browser->hosted_app_controller() && + browser->hosted_app_controller()->GetExtensionId() == app_id && + browser->profile() == profile_; +} + +} // namespace badging
diff --git a/chrome/browser/badging/badge_manager_delegate_win.h b/chrome/browser/badging/badge_manager_delegate_win.h new file mode 100644 index 0000000..efe38265 --- /dev/null +++ b/chrome/browser/badging/badge_manager_delegate_win.h
@@ -0,0 +1,36 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_BADGING_BADGE_MANAGER_DELEGATE_WIN_H_ +#define CHROME_BROWSER_BADGING_BADGE_MANAGER_DELEGATE_WIN_H_ + +#include <string> + +#include "base/optional.h" +#include "chrome/browser/badging/badge_manager_delegate.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" + +class Profile; + +namespace badging { + +// Windows specific implementation of the BadgeManagerDelegate. +class BadgeManagerDelegateWin : public BadgeManagerDelegate { + public: + explicit BadgeManagerDelegateWin(Profile* profile); + + void OnBadgeSet(const std::string& app_id, + base::Optional<uint64_t> contents) override; + + void OnBadgeCleared(const std::string& app_id) override; + + private: + // Determines if a browser is for a specific hosted app, on this profile. + bool IsAppBrowser(Browser* browser, const std::string& app_id); +}; + +} // namespace badging + +#endif // CHROME_BROWSER_BADGING_BADGE_MANAGER_DELEGATE_WIN_H_
diff --git a/chrome/browser/badging/badge_manager_factory.cc b/chrome/browser/badging/badge_manager_factory.cc index 526eade..9d61589 100644 --- a/chrome/browser/badging/badge_manager_factory.cc +++ b/chrome/browser/badging/badge_manager_factory.cc
@@ -36,10 +36,7 @@ KeyedService* BadgeManagerFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - // We don't actually need to use the BrowserContext - we just use the - // BrowserContextKeyedFactory contract to to keep BadgeManagers separate - // across profiles. - return new BadgeManager(); + return new BadgeManager(Profile::FromBrowserContext(context)); } } // namespace badging
diff --git a/chrome/browser/badging/badge_manager_unittest.cc b/chrome/browser/badging/badge_manager_unittest.cc index d1a504f9b..9c1db5ee 100644 --- a/chrome/browser/badging/badge_manager_unittest.cc +++ b/chrome/browser/badging/badge_manager_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/badging/badge_manager.h" +#include <memory> #include <utility> #include <vector> @@ -36,11 +37,12 @@ // Testing delegate that records badge changes. class TestBadgeManagerDelegate : public BadgeManagerDelegate { public: - TestBadgeManagerDelegate() = default; + TestBadgeManagerDelegate() : BadgeManagerDelegate(nullptr) {} + ~TestBadgeManagerDelegate() override = default; void OnBadgeSet(const std::string& app_id, - base::Optional<int> contents) override { + base::Optional<uint64_t> contents) override { set_badges_.push_back(std::make_pair(app_id, contents)); } @@ -63,20 +65,23 @@ void SetUp() override { profile_.reset(new TestingProfile()); - delegate_ = std::make_unique<TestBadgeManagerDelegate>(); + + // Delegate lifetime is managed by BadgeManager + auto owned_delegate = std::make_unique<TestBadgeManagerDelegate>(); + delegate_ = owned_delegate.get(); badge_manager_ = BadgeManagerFactory::GetInstance()->GetForProfile(profile_.get()); - badge_manager_->SetDelegate(delegate_.get()); + badge_manager_->SetDelegate(std::move(owned_delegate)); } void TearDown() override { profile_.reset(); } - TestBadgeManagerDelegate* delegate() const { return delegate_.get(); } + TestBadgeManagerDelegate* delegate() { return delegate_; } BadgeManager* badge_manager() const { return badge_manager_; } private: - std::unique_ptr<TestBadgeManagerDelegate> delegate_; + TestBadgeManagerDelegate* delegate_; BadgeManager* badge_manager_; content::TestBrowserThreadBundle thread_bundle_; std::unique_ptr<TestingProfile> profile_; @@ -100,15 +105,6 @@ EXPECT_EQ(kBadgeContents, delegate()->set_badges().front().second); } -TEST_F(BadgeManagerUnittest, SetBadgeForAppWithNoBadgeChange) { - badge_manager()->UpdateBadge(kExtensionId, kBadgeContents); - badge_manager()->UpdateBadge(kExtensionId, kBadgeContents); - - EXPECT_EQ(1UL, delegate()->set_badges().size()); - EXPECT_EQ(kExtensionId, delegate()->set_badges().front().first); - EXPECT_EQ(kBadgeContents, delegate()->set_badges().front().second); -} - TEST_F(BadgeManagerUnittest, SetBadgeForMultipleApps) { const extensions::ExtensionId otherId("other"); int otherContents = 2; @@ -148,17 +144,14 @@ EXPECT_EQ(kExtensionId, delegate()->cleared_badges().front()); } -TEST_F(BadgeManagerUnittest, ClearBadgeForNonBadgedApp) { - badge_manager()->ClearBadge(kExtensionId); - EXPECT_EQ(0UL, delegate()->cleared_badges().size()); -} - TEST_F(BadgeManagerUnittest, BadgingMultipleProfiles) { std::unique_ptr<Profile> other_profile = std::make_unique<TestingProfile>(); auto* other_badge_manager = BadgeManagerFactory::GetInstance()->GetForProfile(other_profile.get()); - auto other_delegate = std::make_unique<TestBadgeManagerDelegate>(); - other_badge_manager->SetDelegate(other_delegate.get()); + + auto owned_other_delegate = std::make_unique<TestBadgeManagerDelegate>(); + auto* other_delegate = owned_other_delegate.get(); + other_badge_manager->SetDelegate(std::move(owned_other_delegate)); other_badge_manager->UpdateBadge(kExtensionId, base::nullopt); other_badge_manager->UpdateBadge(kExtensionId, kBadgeContents); @@ -171,7 +164,7 @@ EXPECT_EQ(0UL, delegate()->set_badges().size()); EXPECT_EQ(1UL, other_delegate->cleared_badges().size()); - EXPECT_EQ(0UL, delegate()->cleared_badges().size()); + EXPECT_EQ(1UL, delegate()->cleared_badges().size()); EXPECT_EQ(kExtensionId, other_delegate->set_badges().back().first); EXPECT_EQ(base::nullopt, other_delegate->set_badges().back().second);
diff --git a/chrome/browser/badging/badge_service_delegate.h b/chrome/browser/badging/badge_service_delegate.h deleted file mode 100644 index 4c01c82..0000000 --- a/chrome/browser/badging/badge_service_delegate.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_BADGING_BADGE_SERVICE_DELEGATE_H_ -#define CHROME_BROWSER_BADGING_BADGE_SERVICE_DELEGATE_H_ - -#include "base/callback.h" -#include "base/optional.h" - -namespace content { -class WebContents; -} - -// Delegate for setting and clearing app badges. This is implemented at a -// UI-layer, allowing for a platform specific implementation of badging. -class BadgeServiceDelegate { - public: - using SetBadgeCallback = - base::RepeatingCallback<void(content::WebContents*, - base::Optional<uint64_t>)>; - using ClearBadgeCallback = - base::RepeatingCallback<void(content::WebContents*)>; - - BadgeServiceDelegate(); - ~BadgeServiceDelegate(); - - // Sets the Badge for |web_contents|. - void SetBadge(content::WebContents* web_contents, - base::Optional<uint64_t> badge_content); - - // Clears the badge for |web_contents|. - void ClearBadge(content::WebContents* web_contents); - - // Swaps out the implementation of |SetBadge| and |ClearBadge| for testing. - void SetImplForTesting(SetBadgeCallback on_set_badge, - ClearBadgeCallback on_clear_badge); - - private: - SetBadgeCallback on_set_badge_; - ClearBadgeCallback on_clear_badge_; -}; - -#endif // CHROME_BROWSER_BADGING_BADGE_SERVICE_DELEGATE_H_
diff --git a/chrome/browser/badging/badge_service_impl.cc b/chrome/browser/badging/badge_service_impl.cc index 3f6c5035..d75aa6c 100644 --- a/chrome/browser/badging/badge_service_impl.cc +++ b/chrome/browser/badging/badge_service_impl.cc
@@ -9,7 +9,6 @@ #include "base/logging.h" #include "chrome/browser/badging/badge_manager.h" #include "chrome/browser/badging/badge_manager_factory.h" -#include "chrome/browser/badging/badge_service_delegate.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" @@ -19,18 +18,6 @@ #include "content/public/browser/web_contents.h" #include "extensions/common/extension.h" -namespace { - -#if !defined(OS_CHROMEOS) -BadgeServiceDelegate* GetDelegate(content::WebContents* web_contents) { - return chrome::FindBrowserWithWebContents(web_contents) - ->window() - ->GetBadgeServiceDelegate(); -} -#endif - -} // namespace - // static void BadgeServiceImpl::Create(blink::mojom::BadgeServiceRequest request, content::RenderFrameHost* render_frame_host) { @@ -49,35 +36,27 @@ } void BadgeServiceImpl::SetBadge(base::Optional<uint64_t> content) { -#if defined(OS_CHROMEOS) + if (!IsInApp()) + return; + const extensions::Extension* extension = ExtensionFromLastUrl(); if (!extension) return; - badge_manager_->UpdateBadge(extension->id(), base::nullopt); -#else - if (!IsInApp()) - return; - - GetDelegate(web_contents_)->SetBadge(web_contents_, content); -#endif + badge_manager_->UpdateBadge(extension->id(), content); } void BadgeServiceImpl::ClearBadge() { -#if defined(OS_CHROMEOS) + if (!IsInApp()) + return; + const extensions::Extension* extension = ExtensionFromLastUrl(); if (!extension) return; badge_manager_->ClearBadge(extension->id()); -#else - if (!IsInApp()) - return; - - GetDelegate(web_contents_)->ClearBadge(web_contents_); -#endif } BadgeServiceImpl::BadgeServiceImpl(content::RenderFrameHost* render_frame_host, @@ -87,10 +66,8 @@ render_frame_host_(render_frame_host) { web_contents_ = content::WebContents::FromRenderFrameHost(render_frame_host_); browser_context_ = web_contents_->GetBrowserContext(); -#if defined(OS_CHROMEOS) badge_manager_ = badging::BadgeManagerFactory::GetInstance()->GetForProfile( Profile::FromBrowserContext(browser_context_)); -#endif } BadgeServiceImpl::~BadgeServiceImpl() = default;
diff --git a/chrome/browser/badging/badge_service_impl.h b/chrome/browser/badging/badge_service_impl.h index 5f815c8..e5483f7 100644 --- a/chrome/browser/badging/badge_service_impl.h +++ b/chrome/browser/badging/badge_service_impl.h
@@ -19,11 +19,9 @@ class Extension; } -#if defined(OS_CHROMEOS) namespace badging { class BadgeManager; } -#endif // Desktop implementation of the BadgeService mojo service. class BadgeServiceImpl @@ -49,9 +47,7 @@ content::RenderFrameHost* render_frame_host_; content::BrowserContext* browser_context_; content::WebContents* web_contents_; -#if defined(OS_CHROMEOS) badging::BadgeManager* badge_manager_; -#endif }; #endif // CHROME_BROWSER_BADGING_BADGE_SERVICE_IMPL_H_
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_manager.h b/chrome/browser/chromeos/android_sms/android_sms_app_manager.h index 1e30871..99952007 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_manager.h +++ b/chrome/browser/chromeos/android_sms/android_sms_app_manager.h
@@ -36,7 +36,7 @@ ~AndroidSmsAppManager() override; // If no app is installed, null is returned. - virtual base::Optional<GURL> GetInstalledAppUrl() = 0; + virtual base::Optional<GURL> GetCurrentAppUrl() = 0; void AddObserver(Observer* observer); void RemoveObserver(Observer* observer);
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl.cc b/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl.cc index 57732ffb..53d13b8 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl.cc +++ b/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl.cc
@@ -48,7 +48,7 @@ : profile_(profile), setup_controller_(setup_controller), app_list_syncable_service_(app_list_syncable_service), - installed_url_at_last_notify_(GetInstalledAppUrl()), + installed_url_at_last_notify_(GetCurrentAppInstallUrl()), pwa_delegate_(std::make_unique<PwaDelegate>()), weak_ptr_factory_(this) { // Post a task to complete initialization. This portion of the flow must be @@ -62,12 +62,30 @@ AndroidSmsAppManagerImpl::~AndroidSmsAppManagerImpl() = default; -base::Optional<GURL> AndroidSmsAppManagerImpl::GetInstalledAppUrl() { - if (setup_controller_->GetPwa(GetAndroidMessagesURL())) +base::Optional<GURL> AndroidSmsAppManagerImpl::GetCurrentAppUrl() { + if (setup_controller_->GetPwa( + GetAndroidMessagesURL(true /* use_install_url */))) { return GetAndroidMessagesURL(); + } - if (setup_controller_->GetPwa(GetAndroidMessagesURLOld())) + if (setup_controller_->GetPwa( + GetAndroidMessagesURLOld(true /* use_install_url */))) { return GetAndroidMessagesURLOld(); + } + + return base::nullopt; +} + +base::Optional<GURL> AndroidSmsAppManagerImpl::GetCurrentAppInstallUrl() { + if (setup_controller_->GetPwa( + GetAndroidMessagesURL(true /* use_install_url */))) { + return GetAndroidMessagesURL(true /* use_install_url */); + } + + if (setup_controller_->GetPwa( + GetAndroidMessagesURLOld(true /* use_install_url */))) { + return GetAndroidMessagesURLOld(true /* use_install_url */); + } return base::nullopt; } @@ -79,7 +97,8 @@ is_new_app_setup_in_progress_ = true; setup_controller_->SetUpApp( - GetAndroidMessagesURL(), + GetAndroidMessagesURL() /* app_url */, + GetAndroidMessagesURL(true /* use_install_url */) /* install_url */, base::BindOnce(&AndroidSmsAppManagerImpl::OnSetUpNewAppResult, weak_ptr_factory_.GetWeakPtr())); } @@ -90,7 +109,7 @@ } void AndroidSmsAppManagerImpl::TearDownAndroidSmsApp() { - base::Optional<GURL> installed_app_url = GetInstalledAppUrl(); + base::Optional<GURL> installed_app_url = GetCurrentAppUrl(); if (!installed_app_url) return; @@ -101,12 +120,12 @@ void AndroidSmsAppManagerImpl::CompleteAsyncInitialization() { // If the kUseMessagesGoogleComDomain flag has been flipped and the installed // PWA is at the old URL, set up the new app. - if (GetInstalledAppUrl() == GetAndroidMessagesURLOld()) + if (GetCurrentAppUrl() == GetAndroidMessagesURLOld()) SetUpAndroidSmsApp(); } void AndroidSmsAppManagerImpl::NotifyInstalledAppUrlChangedIfNecessary() { - base::Optional<GURL> installed_app_url = GetInstalledAppUrl(); + base::Optional<GURL> installed_app_url = GetCurrentAppInstallUrl(); if (installed_url_at_last_notify_ == installed_app_url) return; @@ -117,8 +136,8 @@ void AndroidSmsAppManagerImpl::OnSetUpNewAppResult(bool success) { is_new_app_setup_in_progress_ = false; - const extensions::Extension* new_pwa = - setup_controller_->GetPwa(GetAndroidMessagesURL()); + const extensions::Extension* new_pwa = setup_controller_->GetPwa( + GetAndroidMessagesURL(true /* use_install_url */)); // If the installation succeeded, a PWA should exist at the new URL. DCHECK_EQ(success, new_pwa != nullptr); @@ -129,8 +148,8 @@ return; } - const extensions::Extension* old_pwa = - setup_controller_->GetPwa(GetAndroidMessagesURLOld()); + const extensions::Extension* old_pwa = setup_controller_->GetPwa( + GetAndroidMessagesURLOld(true /* use_install_url */)); // If there is no PWA installed at the old URL, no migration is needed and // setup is finished. @@ -147,13 +166,15 @@ if (!transfer_attributes_success) { PA_LOG(ERROR) << "AndroidSmsAppManagerImpl::OnSetUpNewAppResult(): Failed " << "to transfer item attributes from " - << GetAndroidMessagesURLOld() << " to " - << GetAndroidMessagesURL() << "."; + << GetAndroidMessagesURLOld(true /* use_install_url */) + << " to " << GetAndroidMessagesURL(true /* use_install_url */) + << "."; } // Finish the migration by removing the old app now that it has been replaced. setup_controller_->RemoveApp( GetAndroidMessagesURLOld(), + GetAndroidMessagesURLOld(true /* use_install_url */), base::BindOnce(&AndroidSmsAppManagerImpl::OnRemoveOldAppResult, weak_ptr_factory_.GetWeakPtr())); } @@ -163,7 +184,8 @@ // should still be notified of the URL change. if (!success) { PA_LOG(ERROR) << "AndroidSmsAppManagerImpl::OnRemoveOldAppResult(): Failed " - << "to remove PWA at old URL " << GetAndroidMessagesURLOld() + << "to remove PWA at old URL " + << GetAndroidMessagesURLOld(true /* use_install_url */) << "."; } @@ -180,7 +202,7 @@ is_app_launch_pending_ = false; // If launch was requested but setup failed, there is no app to launch. - base::Optional<GURL> installed_app_url = GetInstalledAppUrl(); + base::Optional<GURL> installed_app_url = GetCurrentAppInstallUrl(); if (!installed_app_url) return;
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl.h b/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl.h index b8a179f4..0dba6ed 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl.h +++ b/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl.h
@@ -62,13 +62,14 @@ }; // AndroidSmsAppManager: - base::Optional<GURL> GetInstalledAppUrl() override; + base::Optional<GURL> GetCurrentAppUrl() override; // AndroidSmsAppHelperDelegate: void SetUpAndroidSmsApp() override; void SetUpAndLaunchAndroidSmsApp() override; void TearDownAndroidSmsApp() override; + base::Optional<GURL> GetCurrentAppInstallUrl(); void CompleteAsyncInitialization(); void NotifyInstalledAppUrlChangedIfNecessary(); void OnSetUpNewAppResult(bool success);
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl_unittest.cc b/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl_unittest.cc index 2e3d5a5..d8fcd9c 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl_unittest.cc +++ b/chrome/browser/chromeos/android_sms/android_sms_app_manager_impl_unittest.cc
@@ -148,13 +148,15 @@ android_sms_app_manager()->SetUpAndroidSmsApp(); fake_android_sms_app_setup_controller()->CompletePendingSetUpAppRequest( - GetAndroidMessagesURL() /* expected_url */, + GetAndroidMessagesURL() /* expected_app_url */, + GetAndroidMessagesURL( + true /* use_install_url */) /* expected_install_url */, base::nullopt /* id_for_app */); // Verify that no installed app exists and no observers were notified. EXPECT_FALSE(fake_android_sms_app_setup_controller()->GetAppMetadataAtUrl( - GetAndroidMessagesURL())); - EXPECT_FALSE(android_sms_app_manager()->GetInstalledAppUrl()); + GetAndroidMessagesURL(true /* use_install_url */))); + EXPECT_FALSE(android_sms_app_manager()->GetCurrentAppUrl()); EXPECT_EQ(0u, test_observer()->num_installed_app_url_changed_events()); } @@ -164,25 +166,33 @@ android_sms_app_manager()->SetUpAndroidSmsApp(); fake_android_sms_app_setup_controller()->CompletePendingSetUpAppRequest( - GetAndroidMessagesURL() /* expected_url */, kNewAppId); + GetAndroidMessagesURL() /* expected_app_url */, + GetAndroidMessagesURL( + true /* use_install_url */) /* expected_install_url */, + kNewAppId); // Verify that the app was installed and observers were notified. EXPECT_EQ(kNewAppId, fake_android_sms_app_setup_controller() - ->GetAppMetadataAtUrl(GetAndroidMessagesURL()) + ->GetAppMetadataAtUrl(GetAndroidMessagesURL( + true /* use_install_url */)) ->pwa->id()); EXPECT_TRUE(fake_android_sms_app_setup_controller() - ->GetAppMetadataAtUrl(GetAndroidMessagesURL()) + ->GetAppMetadataAtUrl( + GetAndroidMessagesURL(true /* use_install_url */)) ->is_cookie_present); EXPECT_EQ(GetAndroidMessagesURL(), - *android_sms_app_manager()->GetInstalledAppUrl()); + *android_sms_app_manager()->GetCurrentAppUrl()); EXPECT_EQ(1u, test_observer()->num_installed_app_url_changed_events()); // Now, tear down the app, which should remove the DefaultToPersist cookie. android_sms_app_manager()->TearDownAndroidSmsApp(); fake_android_sms_app_setup_controller()->CompletePendingDeleteCookieRequest( - GetAndroidMessagesURL() /* expected_url */); + GetAndroidMessagesURL() /* expected_app_url */, + GetAndroidMessagesURL( + true /* use_install_url */) /* expected_install_url */); EXPECT_FALSE(fake_android_sms_app_setup_controller() - ->GetAppMetadataAtUrl(GetAndroidMessagesURL()) + ->GetAppMetadataAtUrl( + GetAndroidMessagesURL(true /* use_install_url */)) ->is_cookie_present); } @@ -191,17 +201,22 @@ android_sms_app_manager()->SetUpAndLaunchAndroidSmsApp(); fake_android_sms_app_setup_controller()->CompletePendingSetUpAppRequest( - GetAndroidMessagesURL() /* expected_url */, kNewAppId); + GetAndroidMessagesURL() /* expected_app_url */, + GetAndroidMessagesURL( + true /* use_install_url */) /* expected_install_url */, + kNewAppId); // Verify that the app was installed and observers were notified. EXPECT_EQ(kNewAppId, fake_android_sms_app_setup_controller() - ->GetAppMetadataAtUrl(GetAndroidMessagesURL()) + ->GetAppMetadataAtUrl(GetAndroidMessagesURL( + true /* use_install_url */)) ->pwa->id()); EXPECT_TRUE(fake_android_sms_app_setup_controller() - ->GetAppMetadataAtUrl(GetAndroidMessagesURL()) + ->GetAppMetadataAtUrl( + GetAndroidMessagesURL(true /* use_install_url */)) ->is_cookie_present); EXPECT_EQ(GetAndroidMessagesURL(), - *android_sms_app_manager()->GetInstalledAppUrl()); + *android_sms_app_manager()->GetCurrentAppUrl()); EXPECT_EQ(1u, test_observer()->num_installed_app_url_changed_events()); // The app should have been launched. @@ -212,29 +227,33 @@ TestSetUpMessages_PreviousAppExists_Fails) { // Before completing initialization, install the old app. fake_android_sms_app_setup_controller()->SetAppAtUrl( - GetAndroidMessagesURLOld(), kOldAppId); + GetAndroidMessagesURLOld(true /* use_install_url */), kOldAppId); CompleteAsyncInitialization(); // This should trigger the new app to be installed; fail this installation. // This simulates a situation which could occur if the user signs in with the // flag enabled but is offline and thus unable to install the new PWA. fake_android_sms_app_setup_controller()->CompletePendingSetUpAppRequest( - GetAndroidMessagesURL() /* expected_url */, + GetAndroidMessagesURL() /* expected_app_url */, + GetAndroidMessagesURL( + true /* use_install_url */) /* expected_install_url */, base::nullopt /* id_for_app */); // Verify that the new app was not installed and no observers were notified. EXPECT_FALSE(fake_android_sms_app_setup_controller()->GetAppMetadataAtUrl( - GetAndroidMessagesURL())); + GetAndroidMessagesURL(true /* use_install_url */))); EXPECT_EQ(0u, test_observer()->num_installed_app_url_changed_events()); - // The old app should still be active. + // The old app should still be true. EXPECT_EQ(GetAndroidMessagesURLOld(), - *android_sms_app_manager()->GetInstalledAppUrl()); + *android_sms_app_manager()->GetCurrentAppUrl()); EXPECT_EQ(kOldAppId, fake_android_sms_app_setup_controller() - ->GetAppMetadataAtUrl(GetAndroidMessagesURLOld()) + ->GetAppMetadataAtUrl(GetAndroidMessagesURLOld( + true /* use_install_url */)) ->pwa->id()); EXPECT_TRUE(fake_android_sms_app_setup_controller() - ->GetAppMetadataAtUrl(GetAndroidMessagesURLOld()) + ->GetAppMetadataAtUrl( + GetAndroidMessagesURLOld(true /* use_install_url */)) ->is_cookie_present); } @@ -242,24 +261,29 @@ TestSetUpMessages_ThenTearDown_PreviousAppExists) { // Before completing initialization, install the old app. fake_android_sms_app_setup_controller()->SetAppAtUrl( - GetAndroidMessagesURLOld(), kOldAppId); + GetAndroidMessagesURLOld(true /* use_install_url */), kOldAppId); CompleteAsyncInitialization(); // This should trigger the new app to be installed. fake_android_sms_app_setup_controller()->CompletePendingSetUpAppRequest( - GetAndroidMessagesURL() /* expected_url */, kNewAppId /* id_for_app */); + GetAndroidMessagesURL() /* expected_app_url */, + GetAndroidMessagesURL( + true /* use_install_url */) /* expected_install_url */, + kNewAppId /* id_for_app */); // Verify that the app was installed and attributes were transferred. By this // point, observers should not have been notified yet since the old app was // not yet installed. EXPECT_EQ(kNewAppId, fake_android_sms_app_setup_controller() - ->GetAppMetadataAtUrl(GetAndroidMessagesURL()) + ->GetAppMetadataAtUrl(GetAndroidMessagesURL( + true /* use_install_url */)) ->pwa->id()); EXPECT_TRUE(fake_android_sms_app_setup_controller() - ->GetAppMetadataAtUrl(GetAndroidMessagesURL()) + ->GetAppMetadataAtUrl( + GetAndroidMessagesURL(true /* use_install_url */)) ->is_cookie_present); EXPECT_EQ(GetAndroidMessagesURL(), - *android_sms_app_manager()->GetInstalledAppUrl()); + *android_sms_app_manager()->GetCurrentAppUrl()); EXPECT_EQ(std::make_pair(std::string(kOldAppId), std::string(kNewAppId)), test_pwa_delegate()->transfer_item_attribute_params()[0]); EXPECT_EQ(0u, test_observer()->num_installed_app_url_changed_events()); @@ -267,7 +291,10 @@ // Now, complete uninstallation of the old app; this should trigger observers // to be notified. fake_android_sms_app_setup_controller()->CompleteRemoveAppRequest( - GetAndroidMessagesURLOld() /* expected_url */, true /* success */); + GetAndroidMessagesURLOld() /* expected_app_url */, + GetAndroidMessagesURLOld( + true /* use_install_url */) /* expected_install_url */, + true /* success */); EXPECT_EQ(1u, test_observer()->num_installed_app_url_changed_events()); }
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller.h b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller.h index 94e2c13..ef6049d 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller.h +++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller.h
@@ -29,23 +29,31 @@ // (1) Installing the PWA, // (2) Granting permission for the PWA to show notifications, and // (3) Setting a cookie which defaults the PWA to remember this computer. - virtual void SetUpApp(const GURL& url, SuccessCallback callback) = 0; + // The |app_url| parameter should have the root URL of the app to install + // and should be the same as the service worker scope + // The |install_url| parameter is the url to install the app from and cannot + // redirect. + virtual void SetUpApp(const GURL& app_url, + const GURL& install_url, + SuccessCallback callback) = 0; // Returns the extension for the PWA at |url|; if no PWA exists, null is // returned. - virtual const extensions::Extension* GetPwa(const GURL& url) = 0; + virtual const extensions::Extension* GetPwa(const GURL& install_url) = 0; // Deletes the cookie which causes the PWA to remember this computer by // default. Note that this does not actually stop the PWA from remembering // this computer; rather, it stops the PWA from *defaulting* to remember the // computer in the case that the user has not gone through the PWA's setup. virtual void DeleteRememberDeviceByDefaultCookie( - const GURL& url, + const GURL& app_url, SuccessCallback callback) = 0; // Uninstalls the app at |url| and deletes relevant cookies from the setup // process. - virtual void RemoveApp(const GURL& url, SuccessCallback callback) = 0; + virtual void RemoveApp(const GURL& app_url, + const GURL& install_url, + SuccessCallback callback) = 0; private: DISALLOW_COPY_AND_ASSIGN(AndroidSmsAppSetupController);
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc index 9f15b19..1e6be1e 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc +++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.h" +#include <string> +#include <vector> + #include "base/bind.h" #include "base/callback.h" #include "base/containers/flat_map.h" @@ -38,20 +41,21 @@ AndroidSmsAppSetupControllerImpl::PwaDelegate::~PwaDelegate() = default; const extensions::Extension* -AndroidSmsAppSetupControllerImpl::PwaDelegate::GetPwaForUrl(const GURL& url, - Profile* profile) { +AndroidSmsAppSetupControllerImpl::PwaDelegate::GetPwaForUrl( + const GURL& install_url, + Profile* profile) { // PWA windowing is disabled for some browser tests. if (!base::FeatureList::IsEnabled(features::kDesktopPWAWindowing)) return nullptr; - return extensions::util::GetInstalledPwaForUrl(profile, url); + return extensions::util::GetInstalledPwaForUrl(profile, install_url); } network::mojom::CookieManager* AndroidSmsAppSetupControllerImpl::PwaDelegate::GetCookieManager( - const GURL& url, + const GURL& app_url, Profile* profile) { - return content::BrowserContext::GetStoragePartitionForSite(profile, url) + return content::BrowserContext::GetStoragePartitionForSite(profile, app_url) ->GetCookieManagerForBrowserProcess(); } @@ -67,63 +71,66 @@ AndroidSmsAppSetupControllerImpl::~AndroidSmsAppSetupControllerImpl() = default; -void AndroidSmsAppSetupControllerImpl::SetUpApp(const GURL& url, +void AndroidSmsAppSetupControllerImpl::SetUpApp(const GURL& app_url, + const GURL& install_url, SuccessCallback callback) { PA_LOG(VERBOSE) << "AndroidSmsAppSetupControllerImpl::SetUpApp(): Setting " - << "DefaultToPersist cookie at " << url << " before PWA " + << "DefaultToPersist cookie at " << app_url << " before PWA " << "installation."; - pwa_delegate_->GetCookieManager(url, profile_) + pwa_delegate_->GetCookieManager(app_url, profile_) ->SetCanonicalCookie( *net::CanonicalCookie::CreateSanitizedCookie( - url, kDefaultToPersistCookieName, kDefaultToPersistCookieValue, - std::string() /* domain */, std::string() /* path */, - base::Time::Now() /* creation_time */, + app_url, kDefaultToPersistCookieName, + kDefaultToPersistCookieValue, std::string() /* domain */, + std::string() /* path */, base::Time::Now() /* creation_time */, base::Time() /* expiration_time */, base::Time::Now() /* last_access_time */, true /* secure */, false /* http_only */, net::CookieSameSite::STRICT_MODE, net::COOKIE_PRIORITY_DEFAULT), true /* secure_source */, false /* modify_http_only */, base::BindOnce(&AndroidSmsAppSetupControllerImpl::OnSetCookieResult, - weak_ptr_factory_.GetWeakPtr(), url, + weak_ptr_factory_.GetWeakPtr(), app_url, install_url, std::move(callback))); } const extensions::Extension* AndroidSmsAppSetupControllerImpl::GetPwa( - const GURL& url) { - return pwa_delegate_->GetPwaForUrl(url, profile_); + const GURL& install_url) { + return pwa_delegate_->GetPwaForUrl(install_url, profile_); } void AndroidSmsAppSetupControllerImpl::DeleteRememberDeviceByDefaultCookie( - const GURL& url, + const GURL& app_url, SuccessCallback callback) { PA_LOG(INFO) << "AndroidSmsAppSetupControllerImpl::" << "DeleteRememberDeviceByDefaultCookie(): Deleting " - << "DefaultToPersist cookie at " << url << "."; + << "DefaultToPersist cookie at " << app_url << "."; network::mojom::CookieDeletionFilterPtr filter( network::mojom::CookieDeletionFilter::New()); - filter->url = url; + filter->url = app_url; filter->cookie_name = kDefaultToPersistCookieName; - pwa_delegate_->GetCookieManager(url, profile_) + pwa_delegate_->GetCookieManager(app_url, profile_) ->DeleteCookies( std::move(filter), base::BindOnce( &AndroidSmsAppSetupControllerImpl::OnDeleteCookiesResult, - weak_ptr_factory_.GetWeakPtr(), url, std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), app_url, std::move(callback))); } -void AndroidSmsAppSetupControllerImpl::RemoveApp(const GURL& url, +void AndroidSmsAppSetupControllerImpl::RemoveApp(const GURL& app_url, + const GURL& install_url, SuccessCallback callback) { // If there is no app installed at |url|, there is nothing more to do. - if (!pwa_delegate_->GetPwaForUrl(url, profile_)) { + if (!pwa_delegate_->GetPwaForUrl(install_url, profile_)) { PA_LOG(VERBOSE) << "AndroidSmsAppSetupControllerImpl::RemoveApp(): No app " - << "is installed at " << url << "; skipping removal " + << "is installed at " << install_url + << "; skipping removal " << "process."; std::move(callback).Run(true /* success */); return; } PA_LOG(INFO) << "AndroidSmsAppSetupControllerImpl::RemoveApp(): " - << "Uninstalling app at " << url << "."; + << "Uninstalling app at " << install_url << "."; // UninstallApps() takes a base::RepeatedCallback, but |callback| is a // base::OnceCallback; thus, |callback| cannot be included in the closure // because it has move-only semantics. Assign this uninstall attempt an ID @@ -132,33 +139,34 @@ auto id = base::UnguessableToken::Create(); uninstall_id_to_callback_map_.emplace(id, std::move(callback)); pending_app_manager_->UninstallApps( - std::vector<GURL>{url}, + std::vector<GURL>{install_url}, base::BindRepeating( &AndroidSmsAppSetupControllerImpl::OnAppUninstallResult, - weak_ptr_factory_.GetWeakPtr(), id)); + weak_ptr_factory_.GetWeakPtr(), id, app_url)); } void AndroidSmsAppSetupControllerImpl::OnSetCookieResult( - const GURL& url, + const GURL& app_url, + const GURL& install_url, SuccessCallback callback, bool succeeded) { if (!succeeded) { PA_LOG(WARNING) << "AndroidSmsAppSetupControllerImpl::" << "OnSetCookieResult(): Failed to set " - << "DefaultToPersist cookie at " << url << ". Proceeding " - << "with installation request."; + << "DefaultToPersist cookie at " << app_url + << ". Proceeding with installation request."; } // If the app is already installed at |url|, there is nothing more to do. - if (pwa_delegate_->GetPwaForUrl(url, profile_)) { + if (pwa_delegate_->GetPwaForUrl(install_url, profile_)) { PA_LOG(VERBOSE) << "AndroidSmsAppSetupControllerImpl::OnSetCookieResult(): " - << "App is already installed at " << url << "; skipping " - << "setup process."; + << "App is already installed at " << install_url + << "; skipping setup process."; std::move(callback).Run(true /* success */); return; } - web_app::PendingAppManager::AppInfo info(url, + web_app::PendingAppManager::AppInfo info(install_url, web_app::LaunchContainer::kWindow, web_app::InstallSource::kInternal); info.override_previous_user_uninstall = true; @@ -168,34 +176,36 @@ info.require_manifest = true; PA_LOG(VERBOSE) << "AndroidSmsAppSetupControllerImpl::OnSetCookieResult(): " - << "Installing PWA for " << url << "."; + << "Installing PWA for " << install_url << "."; pending_app_manager_->Install( std::move(info), base::BindOnce(&AndroidSmsAppSetupControllerImpl::OnAppInstallResult, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), std::move(callback), + app_url)); } void AndroidSmsAppSetupControllerImpl::OnAppInstallResult( SuccessCallback callback, - const GURL& url, + const GURL& app_url, + const GURL& install_url, web_app::InstallResultCode code) { UMA_HISTOGRAM_ENUMERATION("AndroidSms.PWAInstallationResult", code); if (code != web_app::InstallResultCode::kSuccess) { PA_LOG(WARNING) << "AndroidSmsAppSetupControllerImpl::OnAppInstallResult(): " - << "PWA for " << url << " failed to install. " + << "PWA for " << install_url << " failed to install. " << "InstallResultCode: " << static_cast<int>(code); std::move(callback).Run(false /* success */); return; } PA_LOG(INFO) << "AndroidSmsAppSetupControllerImpl::OnAppInstallResult(): " - << "PWA for " << url << " was installed successfully."; + << "PWA for " << install_url << " was installed successfully."; // Grant notification permission for the PWA. host_content_settings_map_->SetWebsiteSettingDefaultScope( - url, GURL() /* top_level_url */, + app_url, GURL() /* top_level_url */, ContentSettingsType::CONTENT_SETTINGS_TYPE_NOTIFICATIONS, content_settings::ResourceIdentifier(), std::make_unique<base::Value>(ContentSetting::CONTENT_SETTING_ALLOW)); @@ -205,7 +215,8 @@ void AndroidSmsAppSetupControllerImpl::OnAppUninstallResult( const base::UnguessableToken& id, - const GURL& url, + const GURL& app_url, + const GURL& install_url, bool succeeded) { UMA_HISTOGRAM_BOOLEAN("AndroidSms.PWAUninstallationResult", succeeded); @@ -218,22 +229,22 @@ if (!succeeded) { PA_LOG(ERROR) << "AndroidSmsAppSetupControllerImpl::OnAppUninstallResult(): " - << "PWA for " << url << " failed to uninstall."; + << "PWA for " << install_url << " failed to uninstall."; std::move(callback).Run(false /* success */); return; } - DeleteRememberDeviceByDefaultCookie(url, std::move(callback)); + DeleteRememberDeviceByDefaultCookie(app_url, std::move(callback)); } void AndroidSmsAppSetupControllerImpl::OnDeleteCookiesResult( - const GURL& url, + const GURL& app_url, SuccessCallback callback, uint32_t num_deleted) { if (num_deleted != 1u) { PA_LOG(WARNING) << "AndroidSmsAppSetupControllerImpl::" << "OnDeleteCookiesResult(): Tried to delete a single " - << "cookie at " << url << ", but " << num_deleted << " " + << "cookie at " << app_url << ", but " << num_deleted << " " << "cookies were deleted."; }
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.h b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.h index 95036f4c..bbf8fbc 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.h +++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.h
@@ -47,29 +47,36 @@ PwaDelegate(); virtual ~PwaDelegate(); - virtual const extensions::Extension* GetPwaForUrl(const GURL& url, + virtual const extensions::Extension* GetPwaForUrl(const GURL& install_url, Profile* profile); - virtual network::mojom::CookieManager* GetCookieManager(const GURL& url, + virtual network::mojom::CookieManager* GetCookieManager(const GURL& app_url, Profile* profile); }; // AndroidSmsAppSetupController: - void SetUpApp(const GURL& url, SuccessCallback callback) override; - const extensions::Extension* GetPwa(const GURL& url) override; - void DeleteRememberDeviceByDefaultCookie(const GURL& url, + void SetUpApp(const GURL& app_url, + const GURL& install_url, + SuccessCallback callback) override; + const extensions::Extension* GetPwa(const GURL& install_url) override; + void DeleteRememberDeviceByDefaultCookie(const GURL& app_url, SuccessCallback callback) override; - void RemoveApp(const GURL& url, SuccessCallback callback) override; + void RemoveApp(const GURL& app_url, + const GURL& install_url, + SuccessCallback callback) override; - void OnSetCookieResult(const GURL& url, + void OnSetCookieResult(const GURL& app_url, + const GURL& install_url, SuccessCallback callback, bool succeeded); void OnAppInstallResult(SuccessCallback callback, - const GURL& url, + const GURL& app_url, + const GURL& install_url, web_app::InstallResultCode code); void OnAppUninstallResult(const base::UnguessableToken& id, - const GURL& url, + const GURL& app_url, + const GURL& install_url, bool succeeded); - void OnDeleteCookiesResult(const GURL& url, + void OnDeleteCookiesResult(const GURL& app_url, SuccessCallback callback, uint32_t num_deleted);
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc index b2e3f79..9acda9ef 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc +++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc
@@ -36,6 +36,7 @@ namespace { const char kTestUrl1[] = "https://test-url-1.com/"; +const char kTestInstallUrl1[] = "https://test-url-1.com/install"; const char kTestUrl2[] = "https://test-url-2.com/"; web_app::PendingAppManager::AppInfo GetAppInfoForUrl(const GURL& url) { @@ -159,15 +160,15 @@ } // AndroidSmsAppSetupControllerImpl::PwaDelegate: - const extensions::Extension* GetPwaForUrl(const GURL& url, + const extensions::Extension* GetPwaForUrl(const GURL& install_url, Profile* profile) override { - if (!base::ContainsKey(url_to_pwa_map_, url)) + if (!base::ContainsKey(url_to_pwa_map_, install_url)) return nullptr; - return url_to_pwa_map_[url].get(); + return url_to_pwa_map_[install_url].get(); } - network::mojom::CookieManager* GetCookieManager(const GURL& url, + network::mojom::CookieManager* GetCookieManager(const GURL& app_url, Profile* profile) override { return fake_cookie_manager_; } @@ -205,7 +206,9 @@ ->SetPwaDelegateForTesting(std::move(base_delegate)); } - void CallSetUpApp(const GURL url, size_t num_expected_app_installs) { + void CallSetUpApp(const GURL& app_url, + const GURL& install_url, + size_t num_expected_app_installs) { const auto& install_requests = test_pending_app_manager_->install_requests(); size_t num_install_requests_before_call = install_requests.size(); @@ -214,7 +217,7 @@ base::HistogramTester histogram_tester; setup_controller_->SetUpApp( - url, + app_url, install_url, base::BindOnce(&AndroidSmsAppSetupControllerImplTest::OnSetUpAppResult, base::Unretained(this), run_loop.QuitClosure())); @@ -225,12 +228,12 @@ // If the PWA was not already installed at the URL, SetUpApp() should // install it. - if (!test_pwa_delegate_->GetPwaForUrl(url, &profile_)) { + if (!test_pwa_delegate_->GetPwaForUrl(install_url, &profile_)) { EXPECT_EQ(num_install_requests_before_call + 1u, install_requests.size()); - EXPECT_EQ(GetAppInfoForUrl(url), install_requests.back()); + EXPECT_EQ(GetAppInfoForUrl(install_url), install_requests.back()); EXPECT_EQ(ContentSetting::CONTENT_SETTING_ALLOW, - GetNotificationSetting(url)); + GetNotificationSetting(app_url)); } if (num_expected_app_installs) { @@ -244,16 +247,17 @@ last_set_up_app_result_.reset(); } - void CallDeleteRememberDeviceByDefaultCookie(const GURL url) { + void CallDeleteRememberDeviceByDefaultCookie(const GURL& app_url) { base::RunLoop run_loop; setup_controller_->DeleteRememberDeviceByDefaultCookie( - url, base::BindOnce(&AndroidSmsAppSetupControllerImplTest:: - OnDeleteRememberDeviceByDefaultCookieResult, - base::Unretained(this), run_loop.QuitClosure())); + app_url, + base::BindOnce(&AndroidSmsAppSetupControllerImplTest:: + OnDeleteRememberDeviceByDefaultCookieResult, + base::Unretained(this), run_loop.QuitClosure())); fake_cookie_manager_->InvokePendingDeleteCookiesCallback( - url, "default_to_persist" /* expected_cookie_name */, + app_url, "default_to_persist" /* expected_cookie_name */, true /* success */); run_loop.Run(); @@ -261,7 +265,9 @@ last_delete_cookie_result_.reset(); } - void CallRemoveApp(const GURL url, size_t num_expected_app_uninstalls) { + void CallRemoveApp(const GURL& app_url, + const GURL& install_url, + size_t num_expected_app_uninstalls) { const auto& uninstall_requests = test_pending_app_manager_->uninstall_requests(); size_t num_uninstall_requests_before_call = uninstall_requests.size(); @@ -270,19 +276,19 @@ base::HistogramTester histogram_tester; setup_controller_->RemoveApp( - url, + app_url, install_url, base::BindOnce(&AndroidSmsAppSetupControllerImplTest::OnRemoveAppResult, base::Unretained(this), run_loop.QuitClosure())); // If the PWA was already installed at the URL, RemoveApp() should uninstall // the it. - if (test_pwa_delegate_->GetPwaForUrl(url, &profile_)) { + if (test_pwa_delegate_->GetPwaForUrl(install_url, &profile_)) { EXPECT_EQ(num_uninstall_requests_before_call + 1u, uninstall_requests.size()); - EXPECT_EQ(url, uninstall_requests.back()); + EXPECT_EQ(install_url, uninstall_requests.back()); fake_cookie_manager_->InvokePendingDeleteCookiesCallback( - url, "default_to_persist" /* expected_cookie_name */, + app_url, "default_to_persist" /* expected_cookie_name */, true /* success */); } @@ -345,43 +351,52 @@ }; TEST_F(AndroidSmsAppSetupControllerImplTest, SetUpApp_NoPreviousApp) { - CallSetUpApp(GURL(kTestUrl1), 1u /* num_expected_app_installs */); + CallSetUpApp(GURL(kTestUrl1), GURL(kTestInstallUrl1), + 1u /* num_expected_app_installs */); } TEST_F(AndroidSmsAppSetupControllerImplTest, SetUpApp_AppAlreadyInstalled) { // Start with a PWA already installed at the URL. - test_pwa_delegate()->SetHasPwa(GURL(kTestUrl1), true); - CallSetUpApp(GURL(kTestUrl1), 0u /* num_expected_app_installs */); + test_pwa_delegate()->SetHasPwa(GURL(kTestInstallUrl1), true); + CallSetUpApp(GURL(kTestUrl1), GURL(kTestInstallUrl1), + 0u /* num_expected_app_installs */); } TEST_F(AndroidSmsAppSetupControllerImplTest, SetUpApp_OtherPwaInstalled) { // Start with a PWA already installed at a different URL. test_pwa_delegate()->SetHasPwa(GURL(kTestUrl2), true); - CallSetUpApp(GURL(kTestUrl1), 1u /* num_expected_app_installs */); + CallSetUpApp(GURL(kTestUrl1), GURL(kTestInstallUrl1), + 1u /* num_expected_app_installs */); } TEST_F(AndroidSmsAppSetupControllerImplTest, SetUpAppThenDeleteCookie) { - CallSetUpApp(GURL(kTestUrl1), 1u /* num_expected_app_installs */); + CallSetUpApp(GURL(kTestUrl1), GURL(kTestInstallUrl1), + 1u /* num_expected_app_installs */); CallDeleteRememberDeviceByDefaultCookie(GURL(kTestUrl1)); } TEST_F(AndroidSmsAppSetupControllerImplTest, SetUpAppThenRemove) { // Install and remove. - CallSetUpApp(GURL(kTestUrl1), 1u /* num_expected_app_installs */); - test_pwa_delegate()->SetHasPwa(GURL(kTestUrl1), true); - CallRemoveApp(GURL(kTestUrl1), 1u /* num_expected_app_uninstalls */); - test_pwa_delegate()->SetHasPwa(GURL(kTestUrl1), false); + CallSetUpApp(GURL(kTestUrl1), GURL(kTestInstallUrl1), + 1u /* num_expected_app_installs */); + test_pwa_delegate()->SetHasPwa(GURL(kTestInstallUrl1), true); + CallRemoveApp(GURL(kTestUrl1), GURL(kTestInstallUrl1), + 1u /* num_expected_app_uninstalls */); + test_pwa_delegate()->SetHasPwa(GURL(kTestInstallUrl1), false); // Repeat once more. - CallSetUpApp(GURL(kTestUrl1), 1u /* num_expected_app_installs */); - test_pwa_delegate()->SetHasPwa(GURL(kTestUrl1), true); - CallRemoveApp(GURL(kTestUrl1), 1u /* num_expected_app_uninstalls */); - test_pwa_delegate()->SetHasPwa(GURL(kTestUrl1), false); + CallSetUpApp(GURL(kTestUrl1), GURL(kTestInstallUrl1), + 1u /* num_expected_app_installs */); + test_pwa_delegate()->SetHasPwa(GURL(kTestInstallUrl1), true); + CallRemoveApp(GURL(kTestUrl1), GURL(kTestInstallUrl1), + 1u /* num_expected_app_uninstalls */); + test_pwa_delegate()->SetHasPwa(GURL(kTestInstallUrl1), false); } TEST_F(AndroidSmsAppSetupControllerImplTest, RemoveApp_NoInstalledApp) { // Do not have an installed app before attempting to remove it. - CallRemoveApp(GURL(kTestUrl1), 0u /* num_expected_app_uninstalls */); + CallRemoveApp(GURL(kTestUrl1), GURL(kTestInstallUrl1), + 0u /* num_expected_app_uninstalls */); } } // namespace android_sms
diff --git a/chrome/browser/chromeos/android_sms/android_sms_pairing_state_tracker_impl.cc b/chrome/browser/chromeos/android_sms/android_sms_pairing_state_tracker_impl.cc index 8e47f19..a5d1640 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_pairing_state_tracker_impl.cc +++ b/chrome/browser/chromeos/android_sms/android_sms_pairing_state_tracker_impl.cc
@@ -94,7 +94,7 @@ } GURL AndroidSmsPairingStateTrackerImpl::GetPairingUrl() { - base::Optional<GURL> app_url = android_sms_app_manager_->GetInstalledAppUrl(); + base::Optional<GURL> app_url = android_sms_app_manager_->GetCurrentAppUrl(); if (app_url) return *app_url;
diff --git a/chrome/browser/chromeos/android_sms/android_sms_urls.cc b/chrome/browser/chromeos/android_sms/android_sms_urls.cc index 3fb6cc0..242bd47e 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_urls.cc +++ b/chrome/browser/chromeos/android_sms/android_sms_urls.cc
@@ -17,10 +17,13 @@ namespace { +const char kGoogleMessagesInstallUrl[] = + "https://messages.google.com/web/authentication"; +const char kGoogleMessagesUrl[] = "https://messages.google.com/web/"; const char kAndroidMessagesUrl[] = "https://messages.android.com/"; -const char kGoogleMessagesUrl[] = "https://messages.google.com/"; -GURL GetAndroidMessagesURL(bool use_google_url_if_applicable) { +GURL GetAndroidMessagesURL(bool use_google_url_if_applicable, + bool use_install_url) { // If a custom URL was passed via a command line argument, use it. std::string url_from_command_line_arg = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( @@ -28,20 +31,25 @@ if (!url_from_command_line_arg.empty()) return GURL(url_from_command_line_arg); - return use_google_url_if_applicable ? GURL(kGoogleMessagesUrl) - : GURL(kAndroidMessagesUrl); + if (use_google_url_if_applicable) { + return use_install_url ? GURL(kGoogleMessagesInstallUrl) + : GURL(kGoogleMessagesUrl); + } + return GURL(kAndroidMessagesUrl); } } // namespace -GURL GetAndroidMessagesURL() { +GURL GetAndroidMessagesURL(bool use_install_url) { return GetAndroidMessagesURL( - base::FeatureList::IsEnabled(features::kUseMessagesGoogleComDomain)); + base::FeatureList::IsEnabled(features::kUseMessagesGoogleComDomain), + use_install_url); } -GURL GetAndroidMessagesURLOld() { +GURL GetAndroidMessagesURLOld(bool use_install_url) { return GetAndroidMessagesURL( - !base::FeatureList::IsEnabled(features::kUseMessagesGoogleComDomain)); + !base::FeatureList::IsEnabled(features::kUseMessagesGoogleComDomain), + use_install_url); } } // namespace android_sms
diff --git a/chrome/browser/chromeos/android_sms/android_sms_urls.h b/chrome/browser/chromeos/android_sms/android_sms_urls.h index b1292fe6..2f887c2 100644 --- a/chrome/browser/chromeos/android_sms/android_sms_urls.h +++ b/chrome/browser/chromeos/android_sms/android_sms_urls.h
@@ -12,14 +12,19 @@ namespace android_sms { // Returns URL to Android Messages for Web page used by AndroidSmsService. -GURL GetAndroidMessagesURL(); +// If |use_install_url| is true, the URL used only for installation and +// uninstallation of the PWA is returned; otherwise, the URL for the service +// worker is returned. +GURL GetAndroidMessagesURL(bool use_install_url = false); // Returns the old URL used for Android Messages. In this context, the "old" URL // refers to the URL used before the last change to the // kUseMessagesGoogleComDomain flag. See go/awm-cros-domain for details. // TODO(https://crbug.com/917855): Remove this function when migration is -// complete. -GURL GetAndroidMessagesURLOld(); +// complete. If |use_install_url| is true, the URL used only for installation +// and uninstallation of the PWA is returned; otherwise, the URL for the service +// worker is returned. +GURL GetAndroidMessagesURLOld(bool use_install_url = false); } // namespace android_sms
diff --git a/chrome/browser/chromeos/android_sms/connection_manager.cc b/chrome/browser/chromeos/android_sms/connection_manager.cc index d7e4357b..34b8039 100644 --- a/chrome/browser/chromeos/android_sms/connection_manager.cc +++ b/chrome/browser/chromeos/android_sms/connection_manager.cc
@@ -163,7 +163,7 @@ // Return the installed app URL if the PWA is installed. base::Optional<GURL> installed_url = - android_sms_app_manager_->GetInstalledAppUrl(); + android_sms_app_manager_->GetCurrentAppUrl(); if (installed_url) return installed_url;
diff --git a/chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.cc b/chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.cc index 32d00f0..75e6a72 100644 --- a/chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.cc +++ b/chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.cc
@@ -23,7 +23,7 @@ NotifyInstalledAppUrlChanged(); } -base::Optional<GURL> FakeAndroidSmsAppManager::GetInstalledAppUrl() { +base::Optional<GURL> FakeAndroidSmsAppManager::GetCurrentAppUrl() { return url_; }
diff --git a/chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.h b/chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.h index 5405716..ba290b4b 100644 --- a/chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.h +++ b/chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.h
@@ -31,7 +31,7 @@ private: // AndroidSmsAppManager: - base::Optional<GURL> GetInstalledAppUrl() override; + base::Optional<GURL> GetCurrentAppUrl() override; base::Optional<GURL> url_;
diff --git a/chrome/browser/chromeos/android_sms/fake_android_sms_app_setup_controller.cc b/chrome/browser/chromeos/android_sms/fake_android_sms_app_setup_controller.cc index 0e56d0a..e81d3be8 100644 --- a/chrome/browser/chromeos/android_sms/fake_android_sms_app_setup_controller.cc +++ b/chrome/browser/chromeos/android_sms/fake_android_sms_app_setup_controller.cc
@@ -27,62 +27,66 @@ FakeAndroidSmsAppSetupController::~FakeAndroidSmsAppSetupController() = default; const FakeAndroidSmsAppSetupController::AppMetadata* -FakeAndroidSmsAppSetupController::GetAppMetadataAtUrl(const GURL& url) const { - const auto it = url_to_metadata_map_.find(url); - if (it == url_to_metadata_map_.end()) +FakeAndroidSmsAppSetupController::GetAppMetadataAtUrl( + const GURL& install_url) const { + const auto it = install_url_to_metadata_map_.find(install_url); + if (it == install_url_to_metadata_map_.end()) return nullptr; return std::addressof(it->second); } void FakeAndroidSmsAppSetupController::SetAppAtUrl( - const GURL& url, + const GURL& install_url, const base::Optional<extensions::ExtensionId>& id_for_app) { if (!id_for_app) { - url_to_metadata_map_.erase(url); + install_url_to_metadata_map_.erase(install_url); return; } - // Create a test Extension and add it to |url_to_metadata_map_|. + // Create a test Extension and add it to |install_url_to_metadata_map_|. base::FilePath path; base::PathService::Get(extensions::DIR_TEST_DATA, &path); - url_to_metadata_map_[url].pwa = + install_url_to_metadata_map_[install_url].pwa = extensions::ExtensionBuilder( - url.spec(), extensions::ExtensionBuilder::Type::PLATFORM_APP) - .SetPath(path.AppendASCII(url.spec())) + install_url.spec(), extensions::ExtensionBuilder::Type::PLATFORM_APP) + .SetPath(path.AppendASCII(install_url.spec())) .SetID(*id_for_app) .Build(); } void FakeAndroidSmsAppSetupController::CompletePendingSetUpAppRequest( - const GURL& expected_url, + const GURL& expected_app_url, + const GURL& expected_install_url, const base::Optional<extensions::ExtensionId>& id_for_app) { DCHECK(!pending_set_up_app_requests_.empty()); auto request = std::move(pending_set_up_app_requests_.front()); pending_set_up_app_requests_.erase(pending_set_up_app_requests_.begin()); - DCHECK_EQ(expected_url, request->first); + DCHECK_EQ(expected_app_url, std::get<0>(*request)); + DCHECK_EQ(expected_install_url, std::get<1>(*request)); if (!id_for_app) { - std::move(request->second).Run(false /* success */); + std::move(std::get<2>(*request)).Run(false /* success */); return; } - SetAppAtUrl(expected_url, *id_for_app); - std::move(request->second).Run(true /* success */); + SetAppAtUrl(expected_install_url, *id_for_app); + std::move(std::get<2>(*request)).Run(true /* success */); } void FakeAndroidSmsAppSetupController::CompletePendingDeleteCookieRequest( - const GURL& expected_url) { + const GURL& expected_app_url, + const GURL& expected_install_url) { DCHECK(!pending_delete_cookie_requests_.empty()); auto request = std::move(pending_delete_cookie_requests_.front()); pending_delete_cookie_requests_.erase( pending_delete_cookie_requests_.begin()); - DCHECK_EQ(expected_url, request->first); + DCHECK_EQ(expected_app_url, request->first); // The app must exist before the cookie is deleted. - auto it = url_to_metadata_map_.find(expected_url); - DCHECK(it != url_to_metadata_map_.end()); + auto it = install_url_to_metadata_map_.find(expected_install_url); + DCHECK(it != install_url_to_metadata_map_.end()); it->second.is_cookie_present = false; @@ -90,45 +94,49 @@ } void FakeAndroidSmsAppSetupController::CompleteRemoveAppRequest( - const GURL& expected_url, + const GURL& expected_app_url, + const GURL& expected_install_url, bool should_succeed) { DCHECK(!pending_remove_app_requests_.empty()); auto request = std::move(pending_remove_app_requests_.front()); pending_remove_app_requests_.erase(pending_remove_app_requests_.begin()); - DCHECK_EQ(expected_url, request->first); + DCHECK_EQ(expected_app_url, std::get<0>(*request)); + DCHECK_EQ(expected_install_url, std::get<1>(*request)); if (should_succeed) - SetAppAtUrl(expected_url, base::nullopt /* id_for_app */); + SetAppAtUrl(expected_install_url, base::nullopt /* id_for_app */); - std::move(request->second).Run(should_succeed); + std::move(std::get<2>(*request)).Run(should_succeed); } -void FakeAndroidSmsAppSetupController::SetUpApp(const GURL& url, +void FakeAndroidSmsAppSetupController::SetUpApp(const GURL& app_url, + const GURL& install_url, SuccessCallback callback) { - pending_set_up_app_requests_.push_back( - std::make_unique<RequestData>(url, std::move(callback))); + pending_set_up_app_requests_.push_back(std::make_unique<AppRequestData>( + app_url, install_url, std::move(callback))); } const extensions::Extension* FakeAndroidSmsAppSetupController::GetPwa( - const GURL& url) { - auto it = url_to_metadata_map_.find(url); - if (it == url_to_metadata_map_.end()) + const GURL& install_url) { + auto it = install_url_to_metadata_map_.find(install_url); + if (it == install_url_to_metadata_map_.end()) return nullptr; return it->second.pwa.get(); } void FakeAndroidSmsAppSetupController::DeleteRememberDeviceByDefaultCookie( - const GURL& url, + const GURL& app_url, SuccessCallback callback) { pending_delete_cookie_requests_.push_back( - std::make_unique<RequestData>(url, std::move(callback))); + std::make_unique<RequestData>(app_url, std::move(callback))); } -void FakeAndroidSmsAppSetupController::RemoveApp(const GURL& url, +void FakeAndroidSmsAppSetupController::RemoveApp(const GURL& app_url, + const GURL& install_url, SuccessCallback callback) { - pending_remove_app_requests_.push_back( - std::make_unique<RequestData>(url, std::move(callback))); + pending_remove_app_requests_.push_back(std::make_unique<AppRequestData>( + app_url, install_url, std::move(callback))); } } // namespace android_sms
diff --git a/chrome/browser/chromeos/android_sms/fake_android_sms_app_setup_controller.h b/chrome/browser/chromeos/android_sms/fake_android_sms_app_setup_controller.h index 05306384..9e9e7ba 100644 --- a/chrome/browser/chromeos/android_sms/fake_android_sms_app_setup_controller.h +++ b/chrome/browser/chromeos/android_sms/fake_android_sms_app_setup_controller.h
@@ -7,6 +7,7 @@ #include <list> #include <memory> +#include <tuple> #include <utility> #include "base/containers/flat_map.h" @@ -39,45 +40,55 @@ bool is_cookie_present = true; }; - // Returns null if no app has been installed at |url|. - const AppMetadata* GetAppMetadataAtUrl(const GURL& url) const; + // Returns null if no app has been installed at |install_url|. + const AppMetadata* GetAppMetadataAtUrl(const GURL& install_url) const; // If |id_for_app| is provided, this function installs an app with the given - // ID at |ur|. Otherwise, this function removes any existing app at that URL. - void SetAppAtUrl(const GURL& url, + // ID at |install_url|. Otherwise, this function removes any existing app at + // that URL. + void SetAppAtUrl(const GURL& install_url, const base::Optional<extensions::ExtensionId>& id_for_app); // Completes a pending setup request (i.e., a previous call to SetUpApp()). // If |id_for_app| is set, the request is successful and the installed app // will have the provided ID; if |id_for_app| is null, the request fails. void CompletePendingSetUpAppRequest( - const GURL& expected_url, + const GURL& expected_app_url, + const GURL& expected_install_url, const base::Optional<extensions::ExtensionId>& id_for_app); // Completes a pending cookie deletion request (i.e., a previous call to // DeleteRememberDeviceByDefaultCookie()). - void CompletePendingDeleteCookieRequest(const GURL& expected_url); + void CompletePendingDeleteCookieRequest(const GURL& expected_app_url, + const GURL& expected_install_url); // Completes a pending app removal request (i.e., a previous call to // RemoveApp()). If |success| is true, the app will be removed; otherwise, the // app will remain in place. - void CompleteRemoveAppRequest(const GURL& expected_url, bool success); + void CompleteRemoveAppRequest(const GURL& expected_app_url, + const GURL& expected_install_url, + bool success); private: // AndroidSmsAppSetupController: - void SetUpApp(const GURL& url, SuccessCallback callback) override; - const extensions::Extension* GetPwa(const GURL& url) override; - void DeleteRememberDeviceByDefaultCookie(const GURL& url, + void SetUpApp(const GURL& app_url, + const GURL& install_url, + SuccessCallback callback) override; + const extensions::Extension* GetPwa(const GURL& install_url) override; + void DeleteRememberDeviceByDefaultCookie(const GURL& app_url, SuccessCallback callback) override; - void RemoveApp(const GURL& url, SuccessCallback callback) override; + void RemoveApp(const GURL& app_url, + const GURL& install_url, + SuccessCallback callback) override; + using AppRequestData = std::tuple<GURL, GURL, SuccessCallback>; using RequestData = std::pair<GURL, SuccessCallback>; - std::list<std::unique_ptr<RequestData>> pending_set_up_app_requests_; std::list<std::unique_ptr<RequestData>> pending_delete_cookie_requests_; - std::list<std::unique_ptr<RequestData>> pending_remove_app_requests_; + std::list<std::unique_ptr<AppRequestData>> pending_set_up_app_requests_; + std::list<std::unique_ptr<AppRequestData>> pending_remove_app_requests_; - base::flat_map<GURL, AppMetadata> url_to_metadata_map_; + base::flat_map<GURL, AppMetadata> install_url_to_metadata_map_; DISALLOW_COPY_AND_ASSIGN(FakeAndroidSmsAppSetupController); };
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc index 367e485..a56d3a4 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
@@ -36,9 +36,14 @@ constexpr char kAcquireBufferQuery[] = "android:onMessageReceived/android:handleMessageInvalidate/" "android:latchBuffer/android:updateTexImage/android:acquireBuffer"; -constexpr char kReleaseBufferQuery[] = +// Android PI+ +constexpr char kReleaseBufferQueryP[] = "android:onMessageReceived/android:handleMessageRefresh/" "android:postComposition/android:releaseBuffer"; +// Android NYC +constexpr char kReleaseBufferQueryN[] = + "android:onMessageReceived/android:handleMessageRefresh/" + "android:releaseBuffer"; constexpr char kDequeueBufferQuery[] = "android:dequeueBuffer"; constexpr char kQueueBufferQuery[] = "android:queueBuffer"; @@ -304,7 +309,9 @@ BufferToEvents per_buffer_surface_flinger_events; ProcessSurfaceFlingerEvents(common_model, kAcquireBufferQuery, &per_buffer_surface_flinger_events); - ProcessSurfaceFlingerEvents(common_model, kReleaseBufferQuery, + ProcessSurfaceFlingerEvents(common_model, kReleaseBufferQueryP, + &per_buffer_surface_flinger_events); + ProcessSurfaceFlingerEvents(common_model, kReleaseBufferQueryN, &per_buffer_surface_flinger_events); ProcessSurfaceFlingerEvents(common_model, kQueueBufferQuery, &per_buffer_surface_flinger_events);
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc index 9b12d6c8..13048d4 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -83,7 +83,6 @@ kDeviceNativePrintersWhitelist, kDeviceQuirksDownloadEnabled, kDeviceUnaffiliatedCrostiniAllowed, - kDeviceWallpaperImage, kDeviceDisplayResolution, kDisplayRotationDefault, kExtensionCacheSize, @@ -630,14 +629,6 @@ policy.quirks_download_enabled().quirks_download_enabled()); } - if (policy.has_device_wallpaper_image() && - policy.device_wallpaper_image().has_device_wallpaper_image()) { - SetJsonDeviceSetting( - kDeviceWallpaperImage, policy::key::kDeviceWallpaperImage, - policy.device_wallpaper_image().device_wallpaper_image(), - new_values_cache); - } - if (policy.has_device_off_hours()) { auto off_hours_policy = policy::off_hours::ConvertOffHoursProtoToValue( policy.device_off_hours());
diff --git a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc index 7ed620c..17e9c94 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
@@ -607,20 +607,6 @@ VerifyLogUploadSettings(false); } -TEST_F(DeviceSettingsProviderTest, SetWallpaperSettings) { - // Invalid format should be ignored. - const std::string invalid_format = "\\\\invalid\\format"; - SetWallpaperSettings(invalid_format); - EXPECT_EQ(nullptr, provider_->Get(kDeviceWallpaperImage)); - - // Set with valid json format. - const std::string valid_format(R"({"url":"foo", "hash": "bar"})"); - SetWallpaperSettings(valid_format); - std::unique_ptr<base::DictionaryValue> expected_value = - base::DictionaryValue::From(base::JSONReader::Read(valid_format)); - EXPECT_EQ(*expected_value, *provider_->Get(kDeviceWallpaperImage)); -} - TEST_F(DeviceSettingsProviderTest, SamlLoginAuthenticationType) { using PolicyProto = em::SamlLoginAuthenticationTypeProto;
diff --git a/chrome/browser/devtools/protocol/cast_handler_unittest.cc b/chrome/browser/devtools/protocol/cast_handler_unittest.cc index 7e9ec8a8..a13f11e 100644 --- a/chrome/browser/devtools/protocol/cast_handler_unittest.cc +++ b/chrome/browser/devtools/protocol/cast_handler_unittest.cc
@@ -78,7 +78,12 @@ EXPECT_CALL(*router_, RegisterMediaRoutesObserver(_)) .WillOnce(SaveArg<0>(&routes_observer_)); EXPECT_CALL(*router_, RegisterMediaSinksObserver(_)) - .WillOnce(DoAll(SaveArg<0>(&sinks_observer_), Return(true))); + .WillRepeatedly( + WithArg<0>([this](media_router::MediaSinksObserver* observer) { + if (observer->source()) + sinks_observer_ = observer; + return true; + })); handler_->Enable(protocol::Maybe<std::string>()); } @@ -99,7 +104,7 @@ EXPECT_CALL(*router_, RegisterMediaSinksObserver(_)) .WillOnce(WithArg<0>( [presentation_url](media_router::MediaSinksObserver* observer) { - EXPECT_EQ(presentation_url, observer->source().id()); + EXPECT_EQ(presentation_url, observer->source()->id()); observer->OnSinksUpdated({sink1, sink2}, {}); return true; }));
diff --git a/chrome/browser/extensions/extension_bindings_apitest.cc b/chrome/browser/extensions/extension_bindings_apitest.cc index c21541c..aa3d6a5 100644 --- a/chrome/browser/extensions/extension_bindings_apitest.cc +++ b/chrome/browser/extensions/extension_bindings_apitest.cc
@@ -18,6 +18,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_host.h" #include "extensions/browser/process_manager.h" @@ -637,6 +638,78 @@ } } +// Tests that bindings are properly instantiated for a window navigated to an +// extension URL after being opened with an undefined URL. +// Regression test for https://crbug.com/925118. +IN_PROC_BROWSER_TEST_P(ExtensionBindingsApiTest, + TestBindingsAvailableWithNavigatedBlankWindow) { + constexpr char kManifest[] = + R"({ + "name": "chrome.runtime bug checker", + "description": "test case for crbug.com/925118", + "version": "0", + "manifest_version": 2 + })"; + constexpr char kOpenerHTML[] = + R"(<!DOCTYPE html> + <html> + <head> + <script src='opener.js'></script> + </head> + <body> + </body> + </html>)"; + // opener.js opens a blank window and then navigates it to an extension URL + // (where extension APIs should be available). + constexpr char kOpenerJS[] = + R"(const url = chrome.runtime.getURL('/page.html'); + const win = window.open(undefined, ''); + win.location = url; + chrome.test.notifyPass())"; + constexpr char kPageHTML[] = + R"(<!DOCTYPE html> + <html> + This space intentionally left blank. + </html>)"; + TestExtensionDir extension_dir; + extension_dir.WriteManifest(kManifest); + extension_dir.WriteFile(FILE_PATH_LITERAL("opener.html"), kOpenerHTML); + extension_dir.WriteFile(FILE_PATH_LITERAL("opener.js"), kOpenerJS); + extension_dir.WriteFile(FILE_PATH_LITERAL("page.html"), kPageHTML); + + const Extension* extension = LoadExtension(extension_dir.UnpackedPath()); + const GURL target_url = extension->GetResourceURL("page.html"); + + ResultCatcher catcher; + content::TestNavigationObserver observer(target_url); + observer.StartWatchingNewWebContents(); + ui_test_utils::NavigateToURL(browser(), + extension->GetResourceURL("opener.html")); + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + observer.Wait(); + EXPECT_TRUE(observer.last_navigation_succeeded()); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_EQ(target_url, web_contents->GetLastCommittedURL()); + + // Check whether bindings are available. They should be. + constexpr char kScript[] = + R"(let message; + if (!chrome.runtime) + message = 'Runtime not defined'; + else if (!chrome.tabs) + message = 'Tabs not defined'; + else + message = 'success'; + domAutomationController.send(message);)"; + std::string result; + // Note: Can't use EvalJs() because of CSP in extension pages. + EXPECT_TRUE( + content::ExecuteScriptAndExtractString(web_contents, kScript, &result)); + EXPECT_EQ("success", result); +} + // Run core bindings API tests with both native and JS-based bindings. This // ensures we have some minimum level of coverage while in the experimental // phase, when native bindings may be enabled on trunk but not at 100% stable.
diff --git a/chrome/browser/first_run/upgrade_util_win.cc b/chrome/browser/first_run/upgrade_util_win.cc index 9c30b37..8d77b39 100644 --- a/chrome/browser/first_run/upgrade_util_win.cc +++ b/chrome/browser/first_run/upgrade_util_win.cc
@@ -11,6 +11,7 @@ #include <wrl/client.h> #include <algorithm> +#include <ios> #include <string> #include "base/base_paths.h" @@ -53,24 +54,41 @@ bool InvokeGoogleUpdateForRename() { #if defined(GOOGLE_CHROME_BUILD) Microsoft::WRL::ComPtr<IProcessLauncher> ipl; - if (!FAILED(::CoCreateInstance(__uuidof(ProcessLauncherClass), nullptr, - CLSCTX_ALL, IID_PPV_ARGS(&ipl)))) { - ULONG_PTR phandle = NULL; - DWORD id = GetCurrentProcessId(); - if (!FAILED(ipl->LaunchCmdElevated(install_static::GetAppGuid(), - google_update::kRegRenameCmdField, id, - &phandle))) { - HANDLE handle = HANDLE(phandle); - WaitForSingleObject(handle, INFINITE); - DWORD exit_code; - ::GetExitCodeProcess(handle, &exit_code); - ::CloseHandle(handle); - if (exit_code == installer::RENAME_SUCCESSFUL) - return true; - } + HRESULT hr = ::CoCreateInstance(__uuidof(ProcessLauncherClass), nullptr, + CLSCTX_ALL, IID_PPV_ARGS(&ipl)); + if (FAILED(hr)) { + LOG(ERROR) << "CoCreate ProcessLauncherClass failed; hr = " << std::hex + << hr; + return false; } -#endif // GOOGLE_CHROME_BUILD + + ULONG_PTR process_handle; + hr = ipl->LaunchCmdElevated(install_static::GetAppGuid(), + google_update::kRegRenameCmdField, + ::GetCurrentProcessId(), &process_handle); + if (FAILED(hr)) { + LOG(ERROR) << "IProcessLauncher::LaunchCmdElevated failed; hr = " + << std::hex << hr; + return false; + } + + base::Process rename_process( + reinterpret_cast<base::ProcessHandle>(process_handle)); + int exit_code; + if (!rename_process.WaitForExit(&exit_code)) { + PLOG(ERROR) << "WaitForExit of rename process failed"; + return false; + } + + if (exit_code != installer::RENAME_SUCCESSFUL) { + LOG(ERROR) << "Rename process failed with exit code " << exit_code; + return false; + } + + return true; +#else // GOOGLE_CHROME_BUILD return false; +#endif // GOOGLE_CHROME_BUILD } } // namespace @@ -118,25 +136,45 @@ // If this is a user-level install, directly launch a process to rename Chrome // executables. Obtain the command to launch the process from the registry. base::win::RegKey key; - if (key.Open(HKEY_CURRENT_USER, install_static::GetClientsKeyPath().c_str(), - KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) { - std::wstring rename_cmd; - if (key.ReadValue(google_update::kRegRenameCmdField, - &rename_cmd) == ERROR_SUCCESS) { - base::LaunchOptions options; - options.wait = true; - options.start_hidden = true; - base::Process process = base::LaunchProcess(rename_cmd, options); - if (process.IsValid()) { - DWORD exit_code; - ::GetExitCodeProcess(process.Handle(), &exit_code); - if (exit_code == installer::RENAME_SUCCESSFUL) - return true; - } - } + auto result = + key.Open(HKEY_CURRENT_USER, install_static::GetClientsKeyPath().c_str(), + KEY_QUERY_VALUE | KEY_WOW64_32KEY); + if (result != ERROR_SUCCESS) { + ::SetLastError(result); + PLOG(ERROR) << "Open Clients key failed"; + return false; } - return false; + std::wstring rename_cmd; + result = key.ReadValue(google_update::kRegRenameCmdField, &rename_cmd); + if (result != ERROR_SUCCESS) { + ::SetLastError(result); + PLOG(ERROR) << "Read rename command failed"; + return false; + } + + base::LaunchOptions options; + options.wait = true; + options.start_hidden = true; + ::SetLastError(ERROR_SUCCESS); + base::Process process = base::LaunchProcess(rename_cmd, options); + if (!process.IsValid()) { + PLOG(ERROR) << "Launch rename process failed"; + return false; + } + + DWORD exit_code; + if (!::GetExitCodeProcess(process.Handle(), &exit_code)) { + PLOG(ERROR) << "GetExitCodeProcess of rename process failed"; + return false; + } + + if (exit_code != installer::RENAME_SUCCESSFUL) { + LOG(ERROR) << "Rename process failed with exit code " << exit_code; + return false; + } + + return true; } bool IsRunningOldChrome() {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index d624898..fcf85e21 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -221,6 +221,11 @@ "expiry_milestone": 74 }, { + "name": "autofill-assistant-chrome-entry", + "owners": [ "gogerald,wuandy" ], + "expiry_milestone": 79 + }, + { "name": "autofill-cache-query-responses", "owners": [ "rogerm" ], "expiry_milestone": 72 @@ -1729,7 +1734,7 @@ }, { "name": "enable-query-in-omnibox", - // "owners": [ "your-team" ], + "owners": [ "tommycli", "chrome-omnibox-team" ], "expiry_milestone": 76 }, { @@ -2713,77 +2718,82 @@ }, { "name": "omnibox-display-title-for-current-url", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-drive-suggestions", - // "owners": [ "your-team" ], + "owners": [ "skare", "chrome-omnibox-team" ], + "expiry_milestone": 76 + }, + { + "name": "omnibox-experimental-keyword-mode", + "owners": [ "krb", "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-new-answer-layout", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-pedal-suggestions", - // "owners": [ "your-team" ], + "owners": [ "orinj", "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-reverse-answers", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-rich-entity-suggestions", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-spare-renderer", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-tab-switch-suggestions", - // "owners": [ "your-team" ], + "owners": [ "krb", "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-tail-suggestions", - // "owners": [ "your-team" ], + "owners": [ "krb", "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-ui-hide-steady-state-url-path-query-and-ref", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-ui-hide-steady-state-url-scheme", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-ui-hide-steady-state-url-trivial-subdomains", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-ui-max-autocomplete-matches", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-ui-one-click-unelide", - "owners": [ "tommycli" ], + "owners": [ "tommycli", "chrome-omnibox-team" ], "expiry_milestone": 76 }, { "name": "omnibox-ui-swap-title-and-url", - // "owners": [ "your-team" ], + "owners": [ "chrome-omnibox-team" ], "expiry_milestone": 76 }, {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b57c0ec..c98b39a4 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -103,6 +103,11 @@ extern const char kAutofillAlwaysShowServerCardsInSyncTransportDescription[] = "Always show server cards when in sync transport mode for wallet data"; +extern const char kAutofillAssistantChromeEntryName[] = + "AutofillAssistantChromeEntry"; +extern const char kAutofillAssistantChromeEntryDescription[] = + "Initiate autofill assistant from within Chrome."; + const char kAutofillCacheQueryResponsesName[] = "Cache Autofill Query Responses"; const char kAutofillCacheQueryResponsesDescription[] = @@ -1267,11 +1272,6 @@ "version, currently under development. WARNING: when enabled, Password " "Manager might stop working"; -const char kNewRemotePlaybackPipelineName[] = - "Enable the new remote playback pipeline."; -const char kNewRemotePlaybackPipelineDescription[] = - "Enable the new pipeline for playing media element remotely via " - "RemotePlayback API or native controls."; const char kUseSurfaceLayerForVideoName[] = "Enable the use of SurfaceLayer objects for videos."; const char kUseSurfaceLayerForVideoDescription[] = @@ -2836,6 +2836,12 @@ "Display suggestions for Google Drive documents in the omnibox when Google " "is the default search engine."; +const char kOmniboxExperimentalKeywordModeName[] = + "Omnibox Experimental Keyword Mode"; +const char kOmniboxExperimentalKeywordModeDescription[] = + "Enables various experimental features related to keyword mode, its " + "suggestions and layout"; + const char kOmniboxPedalSuggestionsName[] = "Omnibox Pedal suggestions"; const char kOmniboxPedalSuggestionsDescription[] = "Enable omnibox Pedal suggestions using either a side button in suggestion "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index d21bc7b..dbfbb030 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -94,6 +94,9 @@ extern const char kAutofillAlwaysShowServerCardsInSyncTransportName[]; extern const char kAutofillAlwaysShowServerCardsInSyncTransportDescription[]; +extern const char kAutofillAssistantChromeEntryName[]; +extern const char kAutofillAssistantChromeEntryDescription[]; + extern const char kAutofillCacheQueryResponsesName[]; extern const char kAutofillCacheQueryResponsesDescription[]; @@ -766,9 +769,6 @@ extern const char kNewPasswordFormParsingForSavingName[]; extern const char kNewPasswordFormParsingForSavingDescription[]; -extern const char kNewRemotePlaybackPipelineName[]; -extern const char kNewRemotePlaybackPipelineDescription[]; - extern const char kOnlyNewPasswordFormParsingName[]; extern const char kOnlyNewPasswordFormParsingDescription[]; @@ -1681,6 +1681,9 @@ extern const char kOmniboxDriveSuggestionsName[]; extern const char kOmniboxDriveSuggestionsDescriptions[]; +extern const char kOmniboxExperimentalKeywordModeName[]; +extern const char kOmniboxExperimentalKeywordModeDescription[]; + extern const char kOmniboxPedalSuggestionsName[]; extern const char kOmniboxPedalSuggestionsDescription[];
diff --git a/chrome/browser/generic_sensor/sensor_permission_context.cc b/chrome/browser/generic_sensor/sensor_permission_context.cc index 9d0df83..b946135 100644 --- a/chrome/browser/generic_sensor/sensor_permission_context.cc +++ b/chrome/browser/generic_sensor/sensor_permission_context.cc
@@ -39,29 +39,6 @@ content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_SENSORS); } -ContentSetting SensorPermissionContext::GetPermissionStatusInternal( - content::RenderFrameHost* render_frame_host, - const GURL& requesting_origin, - const GURL& embedding_origin) const { - // TODO(juncai): We may need to add cross-origin iframes check here when we - // can grant permission for certain sensor types. Currently this function - // doesn't have any information of which sensor type requests permission. - // The Generic Sensor API is not allowed in cross-origin iframes and - // this is enforced by the renderer. - // https://crbug.com/787019 - - // This is to allow DeviceMotion and DeviceOrientation Event to be - // able to access sensors (which are provided by generic sensor) in - // cross-origin iframes. The Generic Sensor API is not allowed in - // cross-origin iframes and this is enforced by the renderer. - - // Sensors are allowed by default in content_settings_registry.cc. - // If cross-origin access check is required, comparison between requesting - // and embedding origin must be performed. - return PermissionContextBase::GetPermissionStatusInternal( - render_frame_host, requesting_origin, embedding_origin); -} - bool SensorPermissionContext::IsRestrictedToSecureOrigins() const { // This is to allow non-secure origins that use DeviceMotion and // DeviceOrientation Event to be able to access sensors that are provided
diff --git a/chrome/browser/generic_sensor/sensor_permission_context.h b/chrome/browser/generic_sensor/sensor_permission_context.h index dcf6d81..10ae0f77 100644 --- a/chrome/browser/generic_sensor/sensor_permission_context.h +++ b/chrome/browser/generic_sensor/sensor_permission_context.h
@@ -19,10 +19,6 @@ void UpdateTabContext(const PermissionRequestID& id, const GURL& requesting_frame, bool allowed) override; - ContentSetting GetPermissionStatusInternal( - content::RenderFrameHost* render_frame_host, - const GURL& requesting_origin, - const GURL& embedding_origin) const override; bool IsRestrictedToSecureOrigins() const override; DISALLOW_COPY_AND_ASSIGN(SensorPermissionContext);
diff --git a/chrome/browser/media/android/router/media_router_android.cc b/chrome/browser/media/android/router/media_router_android.cc index 173f750..6f0c1d9 100644 --- a/chrome/browser/media/android/router/media_router_android.cc +++ b/chrome/browser/media/android/router/media_router_android.cc
@@ -205,7 +205,7 @@ bool MediaRouterAndroid::RegisterMediaSinksObserver( MediaSinksObserver* observer) { - const std::string& source_id = observer->source().id(); + const std::string& source_id = observer->source()->id(); auto& observer_list = sinks_observers_[source_id]; if (!observer_list) { observer_list = std::make_unique<MediaSinksObserverList>(); @@ -219,7 +219,7 @@ void MediaRouterAndroid::UnregisterMediaSinksObserver( MediaSinksObserver* observer) { - const std::string& source_id = observer->source().id(); + const std::string& source_id = observer->source()->id(); auto it = sinks_observers_.find(source_id); if (it == sinks_observers_.end() || !it->second->HasObserver(observer)) return;
diff --git a/chrome/browser/media/router/media_sinks_observer.cc b/chrome/browser/media/router/media_sinks_observer.cc index e7276fe5..47f91ae 100644 --- a/chrome/browser/media/router/media_sinks_observer.cc +++ b/chrome/browser/media/router/media_sinks_observer.cc
@@ -21,6 +21,11 @@ DCHECK(router_); } +MediaSinksObserver::MediaSinksObserver(MediaRouter* router) + : router_(router), initialized_(false) { + DCHECK(router_); +} + MediaSinksObserver::~MediaSinksObserver() { #if DCHECK_IS_ON() DCHECK(!in_on_sinks_updated_);
diff --git a/chrome/browser/media/router/media_sinks_observer.h b/chrome/browser/media/router/media_sinks_observer.h index 8740520..0c95c035 100644 --- a/chrome/browser/media/router/media_sinks_observer.h +++ b/chrome/browser/media/router/media_sinks_observer.h
@@ -29,6 +29,8 @@ MediaSinksObserver(MediaRouter* router, const MediaSource& source, const url::Origin& origin); + // Constructs an observer for all sinks known to |router|. + explicit MediaSinksObserver(MediaRouter* router); virtual ~MediaSinksObserver(); // Registers with MediaRouter to start observing. Must be called before the @@ -37,7 +39,8 @@ bool Init(); // This function is invoked when the list of sinks compatible with |source_| - // has been updated. The result also contains the list of valid origins. + // has been updated, unless |source_| is nullopt, in which case it is invoked + // with all sinks. The result also contains the list of valid origins. // If |origins| is empty or contains |origin_|, then |OnSinksReceived(sinks)| // will be invoked with |sinks|. Otherwise, it will be invoked with an empty // list. @@ -45,7 +48,7 @@ virtual void OnSinksUpdated(const std::vector<MediaSink>& sinks, const std::vector<url::Origin>& origins); - const MediaSource& source() const { return source_; } + const base::Optional<const MediaSource>& source() const { return source_; } protected: // This function is invoked from |OnSinksUpdated(sinks, origins)|. @@ -55,7 +58,7 @@ virtual void OnSinksReceived(const std::vector<MediaSink>& sinks) = 0; private: - const MediaSource source_; + const base::Optional<const MediaSource> source_; const url::Origin origin_; MediaRouter* const router_; bool initialized_;
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc index ad85828..41e15ad8 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -666,7 +666,8 @@ // Create an observer list for the media source and add |observer| // to it. Fail if |observer| is already registered. - const std::string& source_id = observer->source().id(); + const std::string& source_id = + observer->source() ? observer->source()->id() : ""; std::unique_ptr<MediaSinksQuery>& sinks_query = sinks_queries_[source_id]; bool is_new_query = false; if (!sinks_query) { @@ -693,7 +694,8 @@ MediaSinksObserver* observer) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - const MediaSource::Id& source_id = observer->source().id(); + const std::string& source_id = + observer->source() ? observer->source()->id() : ""; auto it = sinks_queries_.find(source_id); if (it == sinks_queries_.end() || !it->second->HasObserver(observer)) return;
diff --git a/chrome/browser/media/router/presentation/presentation_media_sinks_observer.cc b/chrome/browser/media/router/presentation/presentation_media_sinks_observer.cc index 625e769..bc70c0b 100644 --- a/chrome/browser/media/router/presentation/presentation_media_sinks_observer.cc +++ b/chrome/browser/media/router/presentation/presentation_media_sinks_observer.cc
@@ -30,8 +30,9 @@ result.empty() ? blink::mojom::ScreenAvailability::UNAVAILABLE : blink::mojom::ScreenAvailability::AVAILABLE; - DVLOG(1) << "PresentationMediaSinksObserver::OnSinksReceived: " << source() - << " " << (result.empty() ? "unavailable" : "available"); + DVLOG(1) << "PresentationMediaSinksObserver::OnSinksReceived: " + << (source() ? source()->id() : "Any source") << " " + << (result.empty() ? "unavailable" : "available"); // Don't send if new result is same as previous. if (previous_availability_ == current_availability)
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc index d5f56216..2086ca9 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc
@@ -63,6 +63,7 @@ binding_.Bind(std::move(request)); media_router_.Bind(std::move(media_router)); + media_sink_service_->AddObserver(this); // |activity_manager_| might have already been set in tests. if (!activity_manager_) @@ -81,6 +82,7 @@ DialMediaRouteProvider::~DialMediaRouteProvider() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(media_sink_queries_.empty()); + media_sink_service_->RemoveObserver(this); } void DialMediaRouteProvider::CreateRoute(const std::string& media_source, @@ -397,6 +399,13 @@ void DialMediaRouteProvider::StartObservingMediaSinks( const std::string& media_source) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (media_source.empty()) { + std::vector<MediaSinkInternal> sinks; + for (const auto& sink_it : media_sink_service_->GetSinks()) + sinks.push_back(sink_it.second); + OnSinksDiscovered(sinks); + return; + } MediaSource dial_source(media_source); if (!IsDialMediaSource(dial_source)) @@ -429,7 +438,7 @@ MediaSource dial_source(media_source); std::string app_name = AppNameFromDialMediaSource(dial_source); - if (app_name.empty()) + if (!dial_source.id().empty() && app_name.empty()) return; const auto& sink_query_it = media_sink_queries_.find(app_name); @@ -508,6 +517,13 @@ activity_manager_ = std::move(activity_manager); } +void DialMediaRouteProvider::OnSinksDiscovered( + const std::vector<MediaSinkInternal>& sinks) { + // Send a list of all available sinks to Media Router as sinks not associated + // with any particular source. + NotifyOnSinksReceived(MediaSource::Id(), sinks, {}); +} + void DialMediaRouteProvider::OnAvailableSinksUpdated( const std::string& app_name) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h index d79afb9..9540136 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h
@@ -45,7 +45,8 @@ // DialMediaRouteProvider will initiate the app launch on the device. // 4) Once the app is launched, the workflow is complete. The webpage will then // communicate with the app on the device via its own mechanism. -class DialMediaRouteProvider : public mojom::MediaRouteProvider { +class DialMediaRouteProvider : public mojom::MediaRouteProvider, + public MediaSinkServiceBase::Observer { public: // |request|: Request to bind to |this|. // |media_router|: Pointer to MediaRouter. @@ -138,6 +139,9 @@ DISALLOW_COPY_AND_ASSIGN(MediaSinkQuery); }; + // MediaSinkServiceBase::Observer: + void OnSinksDiscovered(const std::vector<MediaSinkInternal>& sinks) override; + // Binds the message pipes |request| and |media_router| to |this|. void Init(mojom::MediaRouteProviderRequest request, mojom::MediaRouterPtrInfo media_router);
diff --git a/chrome/browser/no_best_effort_tasks_browsertest.cc b/chrome/browser/no_best_effort_tasks_browsertest.cc index 35696c8..882aa79 100644 --- a/chrome/browser/no_best_effort_tasks_browsertest.cc +++ b/chrome/browser/no_best_effort_tasks_browsertest.cc
@@ -134,6 +134,9 @@ // Verify that an extension can be loaded and perform basic messaging without // running BEST_EFFORT tasks. Regression test for http://crbug.com/177163#c112. +// +// NOTE: If this test times out, it might help to look at how +// http://crbug.com/924416 was resolved. #if BUILDFLAG(ENABLE_EXTENSIONS) IN_PROC_BROWSER_TEST_F(NoBestEffortTasksTest, LoadExtensionAndSendMessages) { ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/chrome/browser/page_load_metrics/observers/foreground_duration_ukm_observer.cc b/chrome/browser/page_load_metrics/observers/foreground_duration_ukm_observer.cc index 92645b8..e8821960 100644 --- a/chrome/browser/page_load_metrics/observers/foreground_duration_ukm_observer.cc +++ b/chrome/browser/page_load_metrics/observers/foreground_duration_ukm_observer.cc
@@ -41,7 +41,7 @@ ForegroundDurationUKMObserver::FlushMetricsOnAppEnterBackground( const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { - RecordUkmIfInForeground(); + RecordUkmIfInForeground(base::TimeTicks::Now()); return CONTINUE_OBSERVING; } @@ -49,7 +49,7 @@ ForegroundDurationUKMObserver::OnHidden( const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { - RecordUkmIfInForeground(); + RecordUkmIfInForeground(base::TimeTicks::Now()); return CONTINUE_OBSERVING; } page_load_metrics::PageLoadMetricsObserver::ObservePolicy @@ -64,14 +64,22 @@ void ForegroundDurationUKMObserver::OnComplete( const page_load_metrics::mojom::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { - RecordUkmIfInForeground(); + // If we have a page_end_time, use it as our end time, else fall back to the + // current time. Note that we expect page_end_time.has_value() to always be + // true in OnComplete (the PageLoadTracker destructor is supposed to guarantee + // it), but we use Now() as a graceful fallback just in case. + base::TimeTicks end_time = + info.page_end_time.has_value() + ? info.navigation_start + info.page_end_time.value() + : base::TimeTicks::Now(); + RecordUkmIfInForeground(end_time); } -void ForegroundDurationUKMObserver::RecordUkmIfInForeground() { +void ForegroundDurationUKMObserver::RecordUkmIfInForeground( + base::TimeTicks end_time) { if (!currently_in_foreground_) return; - base::TimeDelta foreground_duration = - base::TimeTicks::Now() - last_time_shown_; + base::TimeDelta foreground_duration = end_time - last_time_shown_; ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get(); ukm::builders::PageForegroundSession(source_id_) .SetForegroundDuration(foreground_duration.InMilliseconds())
diff --git a/chrome/browser/page_load_metrics/observers/foreground_duration_ukm_observer.h b/chrome/browser/page_load_metrics/observers/foreground_duration_ukm_observer.h index 63b9c85..2ab8c48 100644 --- a/chrome/browser/page_load_metrics/observers/foreground_duration_ukm_observer.h +++ b/chrome/browser/page_load_metrics/observers/foreground_duration_ukm_observer.h
@@ -37,7 +37,7 @@ bool currently_in_foreground_ = false; base::TimeTicks last_time_shown_; ukm::SourceId source_id_ = ukm::kInvalidSourceId; - void RecordUkmIfInForeground(); + void RecordUkmIfInForeground(base::TimeTicks end_time); DISALLOW_COPY_AND_ASSIGN(ForegroundDurationUKMObserver); };
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc index 730676e..a5c48e0 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer_unittest.cc
@@ -288,7 +288,11 @@ std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries = test_ukm_recorder().GetMergedEntriesByName(PageLoad::kEntryName); - EXPECT_EQ(0ul, merged_entries.size()); + for (const auto& kv : merged_entries) { + EXPECT_FALSE(test_ukm_recorder().EntryHasMetric( + kv.second.get(), + PageLoad::kExperimental_PaintTiming_NavigationToLargestImagePaintName)); + } } TEST_F(UkmPageLoadMetricsObserverTest, LastImagePaint) { @@ -342,7 +346,11 @@ std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> merged_entries = test_ukm_recorder().GetMergedEntriesByName(PageLoad::kEntryName); - EXPECT_EQ(0ul, merged_entries.size()); + for (const auto& kv : merged_entries) { + EXPECT_FALSE(test_ukm_recorder().EntryHasMetric( + kv.second.get(), + PageLoad::kExperimental_PaintTiming_NavigationToLargestImagePaintName)); + } } TEST_F(UkmPageLoadMetricsObserverTest, FCPPlusPlus_ReportLastCandidate) {
diff --git a/chrome/browser/payments/chrome_payment_request_delegate.cc b/chrome/browser/payments/chrome_payment_request_delegate.cc index 6f90c7b..56e3421a 100644 --- a/chrome/browser/payments/chrome_payment_request_delegate.cc +++ b/chrome/browser/payments/chrome_payment_request_delegate.cc
@@ -190,4 +190,8 @@ } } +bool ChromePaymentRequestDelegate::IsInteractive() const { + return shown_dialog_ && shown_dialog_->IsInteractive(); +} + } // namespace payments
diff --git a/chrome/browser/payments/chrome_payment_request_delegate.h b/chrome/browser/payments/chrome_payment_request_delegate.h index 4940660..c76e7a1 100644 --- a/chrome/browser/payments/chrome_payment_request_delegate.h +++ b/chrome/browser/payments/chrome_payment_request_delegate.h
@@ -45,12 +45,15 @@ std::string GetAuthenticatedEmail() const override; PrefService* GetPrefService() override; bool IsBrowserWindowActive() const override; + + // ContentPaymentRequestDelegate: scoped_refptr<PaymentManifestWebDataService> GetPaymentManifestWebDataService() const override; PaymentRequestDisplayManager* GetDisplayManager() override; void EmbedPaymentHandlerWindow( const GURL& url, PaymentHandlerOpenWindowCallback callback) override; + bool IsInteractive() const override; protected: // Reference to the dialog so that we can satisfy calls to CloseDialog(). This
diff --git a/chrome/browser/printing/cloud_print/privet_traffic_detector.cc b/chrome/browser/printing/cloud_print/privet_traffic_detector.cc index ca2850c..481743a 100644 --- a/chrome/browser/printing/cloud_print/privet_traffic_detector.cc +++ b/chrome/browser/printing/cloud_print/privet_traffic_detector.cc
@@ -29,18 +29,15 @@ const int kMaxRestartAttempts = 10; -void GetNetworkListInBackground( - base::OnceCallback<void(net::NetworkInterfaceList)> callback) { - net::NetworkInterfaceList networks; - { - base::ScopedBlockingCall scoped_blocking_call( - base::BlockingType::MAY_BLOCK); - if (!GetNetworkList(&networks, net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES)) - return; - } +void OnGetNetworkList( + base::OnceCallback<void(net::NetworkInterfaceList)> callback, + const base::Optional<net::NetworkInterfaceList>& networks) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (!networks.has_value()) + return; net::NetworkInterfaceList ip4_networks; - for (const auto& network : networks) { + for (const auto& network : networks.value()) { net::AddressFamily address_family = net::GetAddressFamily(network.address); if (address_family == net::ADDRESS_FAMILY_IPV4 && network.prefix_length >= 24) { @@ -49,19 +46,23 @@ } net::IPAddress localhost_prefix(127, 0, 0, 0); - ip4_networks.push_back( - net::NetworkInterface("lo", - "lo", - 0, - net::NetworkChangeNotifier::CONNECTION_UNKNOWN, - localhost_prefix, - 8, - net::IP_ADDRESS_ATTRIBUTE_NONE)); + ip4_networks.push_back(net::NetworkInterface( + "lo", "lo", 0, net::NetworkChangeNotifier::CONNECTION_UNKNOWN, + localhost_prefix, 8, net::IP_ADDRESS_ATTRIBUTE_NONE)); + base::PostTaskWithTraits( FROM_HERE, {content::BrowserThread::IO}, base::BindOnce(std::move(callback), std::move(ip4_networks))); } +void GetNetworkListOnUIThread( + base::OnceCallback<void(net::NetworkInterfaceList)> callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + content::GetNetworkService()->GetNetworkList( + net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, + base::BindOnce(&OnGetNetworkList, std::move(callback))); +} + void CreateUDPSocketOnUIThread( content::BrowserContext* profile, network::mojom::UDPSocketRequest request, @@ -134,9 +135,9 @@ ResetConnection(); weak_ptr_factory_.InvalidateWeakPtrs(); base::PostDelayedTaskWithTraits( - FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()}, + FROM_HERE, {content::BrowserThread::UI}, base::BindOnce( - &GetNetworkListInBackground, + &GetNetworkListOnUIThread, base::BindOnce(&Helper::Restart, weak_ptr_factory_.GetWeakPtr())), base::TimeDelta::FromSeconds(3)); }
diff --git a/chrome/browser/profiling_host/memlog_browsertest.cc b/chrome/browser/profiling_host/memlog_browsertest.cc index 09f81a1..a4a9bd9c 100644 --- a/chrome/browser/profiling_host/memlog_browsertest.cc +++ b/chrome/browser/profiling_host/memlog_browsertest.cc
@@ -34,6 +34,7 @@ struct TestParam { Mode mode; mojom::StackMode stack_mode; + bool stream_samples; bool start_profiling_with_command_line_flag; bool should_sample; bool sample_everything; @@ -83,15 +84,10 @@ // Ensure invocations via TracingController can generate a valid JSON file with // expected data. -// TODO(crbug.com/921036): Test is flaky. -#if defined(OS_LINUX) -#define MAYBE_EndToEnd DISABLED_EndToEnd -#else -#define MAYBE_EndToEnd EndToEnd -#endif -IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, MAYBE_EndToEnd) { +IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, EndToEnd) { LOG(INFO) << "Memlog mode: " << static_cast<int>(GetParam().mode); LOG(INFO) << "Memlog stack mode: " << static_cast<int>(GetParam().stack_mode); + LOG(INFO) << "Stream samples: " << GetParam().stream_samples; LOG(INFO) << "Started via command line flag: " << GetParam().start_profiling_with_command_line_flag; LOG(INFO) << "Should sample: " << GetParam().should_sample; @@ -100,6 +96,7 @@ TestDriver::Options options; options.mode = GetParam().mode; options.stack_mode = GetParam().stack_mode; + options.stream_samples = GetParam().stream_samples; options.profiling_already_started = GetParam().start_profiling_with_command_line_flag; options.should_sample = GetParam().should_sample; @@ -123,54 +120,38 @@ stack_modes.push_back(mojom::StackMode::NATIVE_WITHOUT_THREAD_NAMES); stack_modes.push_back(mojom::StackMode::PSEUDO); - for (const auto& mode : dynamic_start_modes) { - for (const auto& stack_mode : stack_modes) { - params.push_back( - {mode, stack_mode, false /* start_profiling_with_command_line_flag */, - false /* should_sample */, false /* sample_everything*/}); + for (bool stream_samples : (bool[]){true, false}) { + for (const auto& mode : dynamic_start_modes) { + for (const auto& stack_mode : stack_modes) { + params.push_back({mode, stack_mode, stream_samples, + false /* start_profiling_with_command_line_flag */, + true /* should_sample */, + false /* sample_everything*/}); + } } - } // For unknown reasons, renderer profiling has become flaky on ChromeOS. This is // likely happening because the renderers are never being given the signal to // start profiling. It's unclear why this happens. https://crbug.com/843843. // https://crbug.com/843467. #if !defined(OS_CHROMEOS) - // Non-browser processes must be profiled with a command line flag, since - // otherwise, profiling will start after the relevant processes have been - // created, thus that process will be not be profiled. - std::vector<Mode> command_line_start_modes; - command_line_start_modes.push_back(Mode::kAll); - command_line_start_modes.push_back(Mode::kAllRenderers); - for (const auto& mode : command_line_start_modes) { - for (const auto& stack_mode : stack_modes) { - params.push_back( - {mode, stack_mode, true /* start_profiling_with_command_line_flag */, - false /* should_sample */, false /* sample_everything*/}); + // Non-browser processes must be profiled with a command line flag, since + // otherwise, profiling will start after the relevant processes have been + // created, thus that process will be not be profiled. + std::vector<Mode> command_line_start_modes; + command_line_start_modes.push_back(Mode::kAll); + command_line_start_modes.push_back(Mode::kAllRenderers); + for (const auto& mode : command_line_start_modes) { + for (const auto& stack_mode : stack_modes) { + params.push_back({mode, stack_mode, stream_samples, + true /* start_profiling_with_command_line_flag */, + true /* should_sample */, + false /* sample_everything*/}); + } } - } #endif // defined(OS_CHROMEOS) + } - // Test sampling all allocations. - params.push_back({Mode::kBrowser, mojom::StackMode::NATIVE_WITH_THREAD_NAMES, - false /* start_profiling_with_command_line_flag */, - true /* should_sample */, true /* sample_everything*/}); - - // Test sampling some allocations. - params.push_back({Mode::kBrowser, mojom::StackMode::PSEUDO, - false /* start_profiling_with_command_line_flag */, - true /* should_sample */, false /* sample_everything*/}); - - // Test thread names for native profiling. - params.push_back( - {Mode::kBrowser, mojom::StackMode::NATIVE_WITH_THREAD_NAMES, false}); - - // Profile all utility processes and the browser process. The main goal is to - // check that there is no deadlock in the profiling process. - params.push_back({Mode::kUtilityAndBrowser, - mojom::StackMode::NATIVE_WITH_THREAD_NAMES, - false /* start_profiling_with_command_line_flag */, - true /* should_sample */, false /* sample_everything*/}); return params; }
diff --git a/chrome/browser/push_messaging/push_messaging_notification_manager.cc b/chrome/browser/push_messaging/push_messaging_notification_manager.cc index fd0a4890..f505b2a 100644 --- a/chrome/browser/push_messaging/push_messaging_notification_manager.cc +++ b/chrome/browser/push_messaging/push_messaging_notification_manager.cc
@@ -334,7 +334,7 @@ } // Check if origin matches current messages url - base::Optional<GURL> app_url = android_sms_app_manager->GetInstalledAppUrl(); + base::Optional<GURL> app_url = android_sms_app_manager->GetCurrentAppUrl(); if (!app_url) app_url = chromeos::android_sms::GetAndroidMessagesURL();
diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.h b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.h index 0741de0..f925c61 100644 --- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.h +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.h
@@ -166,9 +166,9 @@ // This variables defaults to NO for new gestures. BOOL firstScrollUnconsumed_; - // Whether the renderer disables the overscroll effect, e.g. by - // CSSOverscrollBehavior. - BOOL rendererDisabledOverscroll_; + // Whether the overscroll has been triggered by renderer and is not disabled + // by CSSOverscrollBehavior. + BOOL overscrollTriggeredByRenderer_; // Whether we have received a gesture scroll begin and are awiting on the // first gesture scroll update to deteremine of the event was consumed by
diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm index d1f8812..d31c14f0 100644 --- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.mm
@@ -153,9 +153,10 @@ } - (void)onOverscrolled:(const ui::DidOverscrollParams&)params { - rendererDisabledOverscroll_ = params.overscroll_behavior.x != - cc::OverscrollBehavior::OverscrollBehaviorType:: - kOverscrollBehaviorTypeAuto; + overscrollTriggeredByRenderer_ = + params.overscroll_behavior.x == + cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto; } - (void)beginGestureWithEvent:(NSEvent*)event { @@ -217,7 +218,7 @@ gestureStartPointValid_ = NO; gestureTotalY_ = 0; firstScrollUnconsumed_ = NO; - rendererDisabledOverscroll_ = NO; + overscrollTriggeredByRenderer_ = NO; waitingForFirstGestureScroll_ = NO; recognitionState_ = history_swiper::kPending; } @@ -545,8 +546,8 @@ if (!firstScrollUnconsumed_) return NO; - // History swiping should be prevented if the renderer disables it. - if (rendererDisabledOverscroll_) + // History swiping should be prevented if the renderer hasn't triggered it. + if (!overscrollTriggeredByRenderer_) return NO; // Magic mouse and touchpad swipe events are identical except magic mouse
diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm index b27004c..2ad19db0 100644 --- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm
@@ -172,6 +172,12 @@ andReturnValue:OCMOCK_VALUE(timestamp)] timestamp]; [(NSEvent*)[[mock_event stub] andReturnValue:OCMOCK_VALUE(type)] type]; + // We need to assign a locationInWindow for the event so that the wheel + // event happens inside the page. + NSPoint locationInWindow = NSMakePoint(400, 400); + [(NSEvent*)[[mock_event stub] andReturnValue:OCMOCK_VALUE(locationInWindow)] + locationInWindow]; + return mock_event; } @@ -788,3 +794,25 @@ RunQueuedEvents(); ExpectUrlAndOffset(url1_, 0); } + +IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacHistorySwiperTest, + InnerScrollersOverscrollBehaviorPreventsNavigation) { + if (!IsHistorySwipingSupported()) + return; + + const base::FilePath base_path(FILE_PATH_LITERAL("scroll")); + GURL url_overscroll_behavior = ui_test_utils::GetTestUrl( + base_path, base::FilePath(FILE_PATH_LITERAL("overscroll_behavior.html"))); + ui_test_utils::NavigateToURL(browser(), url_overscroll_behavior); + ASSERT_EQ(url_overscroll_behavior, GetWebContents()->GetURL()); + + QueueBeginningEvents(1, 0); + for (int i = 0; i < 10; ++i) { + QueueScrollAndTouchMoved(10, 0); + } + + QueueEndEvents(); + RunQueuedEvents(); + // If navigation was to occur, the URL would be url2_. + ExpectUrlAndOffset(url_overscroll_behavior, 0); +}
diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm index 8147a37..1af449d 100644 --- a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_unit_test.mm
@@ -233,6 +233,8 @@ startGestureInMiddle(); moveGestureInMiddle(); + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); EXPECT_EQ(begin_count_, 0); EXPECT_EQ(end_count_, 0); @@ -259,6 +261,8 @@ startGestureInMiddle(); moveGestureInMiddle(); + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); EXPECT_EQ(begin_count_, 0); EXPECT_EQ(end_count_, 0); @@ -286,6 +290,8 @@ startGestureInMiddle(); moveGestureInMiddle(); + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); moveGestureAtPoint(makePoint(0.45, 0.5)); endGestureAtPoint(makePoint(0.45, 0.5)); EXPECT_EQ(begin_count_, 1); @@ -304,6 +310,8 @@ startGestureInMiddle(); moveGestureInMiddle(); + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); moveGestureInMiddle(); moveGestureAtPoint(makePoint(0.6, 0.59)); endGestureAtPoint(makePoint(0.6, 0.59)); @@ -324,6 +332,8 @@ startGestureInMiddle(); moveGestureInMiddle(); + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); moveGestureAtPoint(makePoint(0.4, 0.5)); moveGestureAtPoint(makePoint(0.4, 0.3)); endGestureAtPoint(makePoint(0.2, 0.2)); @@ -345,6 +355,8 @@ // Send a momentum move gesture. momentumMoveGestureAtPoint(makePoint(0.5, 0.5)); + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); EXPECT_EQ(begin_count_, 0); EXPECT_EQ(end_count_, 0); @@ -371,6 +383,8 @@ // Magic mouse events don't generate 'touches*' callbacks. NSEvent* event = mockEventWithPoint(makePoint(0.5, 0.5), NSEventTypeGesture); [historySwiper_ beginGestureWithEvent:event]; + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseBegan); [historySwiper_ handleEvent:scrollEvent]; @@ -394,6 +408,8 @@ startGestureInMiddle(); moveGestureInMiddle(); + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); // Starts the gesture. moveGestureAtPoint(makePoint(0.44, 0.44)); @@ -418,6 +434,8 @@ // Successfully pass through a gesture. startGestureInMiddle(); moveGestureInMiddle(); + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); moveGestureAtPoint(makePoint(0.8, 0.5)); endGestureAtPoint(makePoint(0.8, 0.5)); EXPECT_TRUE(navigated_right_); @@ -444,6 +462,8 @@ NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseBegan); NSEvent* event = mockEventWithPoint(makePoint(0.5, 0.5), NSEventTypeGesture); [historySwiper_ touchesBeganWithEvent:event]; + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); [historySwiper_ handleEvent:scrollEvent]; rendererACKForBeganEvent(); @@ -483,6 +503,8 @@ startGestureInMiddle(); moveGestureInMiddle(); + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); // Move up, then move down. for (CGFloat y = 0.51; y < 0.6; y += 0.01) @@ -518,6 +540,8 @@ // - endGesture sendBeginGestureEventInMiddle(); [historySwiper_ handleEvent:scrollWheelEventWithPhase(NSEventPhaseBegan)]; + onOverscrolled(cc::OverscrollBehavior::OverscrollBehaviorType:: + kOverscrollBehaviorTypeAuto); // Callback from Blink to set the relevant state for history swiping. rendererACKForBeganEvent(); @@ -556,7 +580,7 @@ EXPECT_FALSE(magic_mouse_history_swipe_); } -// With scroll-boundary-behavior value as contain, the page should not navigate, +// With overscroll-behavior value as contain, the page should not navigate, // nor should the history overlay appear. TEST_F(MacHistorySwiperTest, OverscrollBehaviorContainPreventsNavigation) { // These tests require 10.7+ APIs. @@ -585,7 +609,7 @@ EXPECT_FALSE(navigated_left_); } -// With scroll-boundary-behavior value as none, the page should not navigate, +// With overscroll-behavior value as none, the page should not navigate, // nor should the history overlay appear. TEST_F(MacHistorySwiperTest, OverscrollBehaviorNonePreventsNavigation) { startGestureInMiddle(); @@ -608,3 +632,25 @@ EXPECT_FALSE(navigated_right_); EXPECT_FALSE(navigated_left_); } + +// Without overscroll msg from renderer, the page should not navigate, nor +// should the history overlay appear. +TEST_F(MacHistorySwiperTest, NoNavigationWithoutOverscrollMsg) { + startGestureInMiddle(); + moveGestureInMiddle(); + + EXPECT_EQ(begin_count_, 0); + EXPECT_EQ(end_count_, 0); + + moveGestureAtPoint(makePoint(0.2, 0.5)); + EXPECT_EQ(begin_count_, 0); + EXPECT_EQ(end_count_, 0); + EXPECT_FALSE(navigated_right_); + EXPECT_FALSE(navigated_left_); + + endGestureAtPoint(makePoint(0.2, 0.5)); + EXPECT_EQ(begin_count_, 0); + EXPECT_EQ(end_count_, 0); + EXPECT_FALSE(navigated_right_); + EXPECT_FALSE(navigated_left_); +}
diff --git a/chrome/browser/resources/bookmarks/bookmarks.html b/chrome/browser/resources/bookmarks/bookmarks.html index 80747bd..6b7581da 100644 --- a/chrome/browser/resources/bookmarks/bookmarks.html +++ b/chrome/browser/resources/bookmarks/bookmarks.html
@@ -7,8 +7,6 @@ <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <style> html { - /* Reconcile with cr_toolbar.html and shared_vars_css.html */ - --toolbar-height: 56px; /* Remove 300ms delay for 'click' event, when using touch interface. */ touch-action: manipulation; } @@ -21,13 +19,8 @@ overflow: hidden; } - html:not([dark]).loading { - border-top: var(--toolbar-height) solid var(--md-toolbar-color); - } - - html[dark].loading { - border-top: 1px solid var(--md-toolbar-border-color); - margin-top: var(--toolbar-height); + html.loading { + border-top: 56px solid var(--md-toolbar-color); } </style> </head>
diff --git a/chrome/browser/resources/bookmarks/toolbar.html b/chrome/browser/resources/bookmarks/toolbar.html index df03299..846d53c 100644 --- a/chrome/browser/resources/bookmarks/toolbar.html +++ b/chrome/browser/resources/bookmarks/toolbar.html
@@ -18,12 +18,7 @@ margin: 4px; } - paper-icon-button-light.more-vert-button div { - border-color: white; - } - cr-toolbar { - color: #fff; flex: 1; --cr-toolbar-field-margin: calc(var(--sidebar-width) + var(--splitter-width));
diff --git a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing.css b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing.css index 222ca75..59a7eeac 100644 --- a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing.css +++ b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing.css
@@ -34,19 +34,32 @@ } .arc-events-band-title { + align-items: center; border: none; - display: block; + display: flex; + flex-direction: row; left: 0; outline: none; position: sticky; text-align: start; } +.arc-events-band-title img { + height: 24px; + width: 24px; +} + +.arc-events-band-title span { + flex: 1; + padding-top: 4px; +} + .arc-events-band-title::before { content: '\2212'; float: left; font-weight: bold; margin-inline-end: 4px; + padding-top: 4px; } .hidden.arc-events-band-title::before {
diff --git a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js index 691d955..17c80a4 100644 --- a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js +++ b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js
@@ -144,10 +144,17 @@ * content. */ class EventBandTitle { - constructor(title) { + constructor(title, opt_iconContent) { this.div = document.createElement('div'); this.div.classList.add('arc-events-band-title'); - this.div.appendChild(document.createTextNode(title)); + if (opt_iconContent) { + var icon = document.createElement('img'); + icon.src = 'data:image/png;base64,' + opt_iconContent; + this.div.appendChild(icon); + } + var span = document.createElement('span'); + span.appendChild(document.createTextNode(title)); + this.div.appendChild(span); this.controlledItems = []; this.div.onclick = this.onClick_.bind(this); var parent = $('arc-event-bands'); @@ -416,8 +423,16 @@ for (i = 0; i < model.views.length; i++) { var view = model.views[i]; - var activityTitleText = 'Task #' + view.task_id + ' - ' + view.activity; - var activityTitle = new EventBandTitle(activityTitleText); + var activityTitleText; + var icon; + if (view.task_id in model.tasks) { + activityTitleText = + model.tasks[view.task_id].title + ' - ' + view.activity; + icon = model.tasks[view.task_id].icon; + } else { + activityTitleText = 'Task #' + view.task_id + ' - ' + view.activity; + } + var activityTitle = new EventBandTitle(activityTitleText, icon); for (j = 0; j < view.buffers.length; j++) { var androidBand = new EventBand( activityTitle, 'arc-events-inner-band', model.duration, 14);
diff --git a/chrome/browser/resources/downloads/downloads.html b/chrome/browser/resources/downloads/downloads.html index 19caed5f..2397587 100644 --- a/chrome/browser/resources/downloads/downloads.html +++ b/chrome/browser/resources/downloads/downloads.html
@@ -4,26 +4,16 @@ <head> <meta charset="utf-8"> <title>$i18n{title}</title> + <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <style> html { - --toolbar-height: 56px; - background: rgb(248, 249, 250); + background: var(--md-background-color); /* Remove 300ms delay for 'click' event, when using touch interface. */ touch-action: manipulation; } - html[dark] { - background: rgb(32, 33, 36); /* --google-grey-900 */ - } - - html[dark].loading { - border-top: 1px solid rgb(95, 99, 104); /* --google-grey-refresh-700 */ - margin-top: var(--toolbar-height); - } - - html:not([dark]).loading { - /* --google-blue-700 disguised. Replaced when downloads-toolbar loads. */ - border-top: var(--toolbar-height) solid rgb(51, 103, 214); + html.loading { + border-top: 56px solid var(--md-toolbar-color); } html:not(.loading), @@ -47,7 +37,6 @@ <command id="clear-all-command" shortcut="Alt|c"> <command id="undo-command" shortcut="Ctrl|z"> </if> - <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/polymer.html">
diff --git a/chrome/browser/resources/downloads/toolbar.html b/chrome/browser/resources/downloads/toolbar.html index 9f25666..f9b804f 100644 --- a/chrome/browser/resources/downloads/toolbar.html +++ b/chrome/browser/resources/downloads/toolbar.html
@@ -20,7 +20,6 @@ :host { align-items: center; background: var(--md-toolbar-color); - color: white; display: flex; min-height: 56px; } @@ -29,10 +28,6 @@ flex: 1; } - :host-context([dark]) #toolbar { - color: var(--cr-primary-text-color); - } - #moreActionsContainer { --iron-icon-height: 20px; --iron-icon-width: 20px;
diff --git a/chrome/browser/resources/history/history.html b/chrome/browser/resources/history/history.html index 748d431..ae99c88 100644 --- a/chrome/browser/resources/history/history.html +++ b/chrome/browser/resources/history/history.html
@@ -62,7 +62,6 @@ } html[dark] #loading-toolbar { - border-bottom: 1px solid var(--md-toolbar-border-color); color: rgb(232, 234, 237); /* --google-grey-200 */ }
diff --git a/chrome/browser/resources/history/history_toolbar.html b/chrome/browser/resources/history/history_toolbar.html index 2b7df411..c28d0ce 100644 --- a/chrome/browser/resources/history/history_toolbar.html +++ b/chrome/browser/resources/history/history_toolbar.html
@@ -13,7 +13,6 @@ <template> <style include="shared-style"> :host { - color: #fff; display: flex; position: relative; }
diff --git a/chrome/browser/resources/md_extensions/extensions.html b/chrome/browser/resources/md_extensions/extensions.html index 7b1d039..e02a07a 100644 --- a/chrome/browser/resources/md_extensions/extensions.html +++ b/chrome/browser/resources/md_extensions/extensions.html
@@ -7,51 +7,41 @@ <if expr="not optimize_webui"> <base href="chrome://extensions"> </if> + <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <style> html { - /* All colors are inlined as the equivalent variables live in stylesheets, - * which can slow down the shell by being pasted or loaded externally. */ - --dev-mode-toolbar-height: 52px; - --toolbar-light-color: rgb(51, 103, 214); /* --google-blue-700 */ - --toolbar-height: 56px; - - /* --md-background-color in disguise. */ - background-color: rgb(248, 249, 250); - + background: var(--md-background-color); /* Remove 300ms delay for 'click' event, when using touch interface. */ touch-action: manipulation; } - html[dark] { - background-color: rgb(32, 33, 36); /* --google-grey-900 */ - } - - html:not([dark]).loading { - /* Replaced when manager.html loads. */ - border-top: var(--toolbar-height) solid var(--toolbar-light-color); - } - - html[dark].loading { - border-top: 1px solid rgb(95, 99, 104); /* --google-grey-refresh-700 */ - margin-top: var(--toolbar-height); - } - - /* Mimics the developer mode toolbar until the real one loads. */ - html[dark].loading.in-dev-mode::before { - background-color: rgb(60, 64, 67); /* --google-grey-800 */ + html.loading::before, + html.loading body::before { + box-sizing: border-box; content: ''; display: block; - height: var(--dev-mode-toolbar-height); } - /* Note: .in-dev-mode is applied by i18n{loadTimeClasses}. */ - html:not([dark]).loading.in-dev-mode { - border-image: linear-gradient(to bottom, - var(--toolbar-light-color) var(--toolbar-height), - #fff var(--toolbar-height), - #fff 107px, #e0e0e0 /* --google-grey-300 */ 107px) 108; - border-top: calc(var(--toolbar-height) + var(--dev-mode-toolbar-height)) - solid; + html.loading::before { + background: var(--md-toolbar-color); + height: 56px; + } + + /* Mimics the developer mode toolbar until the real one loads. Note: + * .in-dev-mode is applied by i18n{loadTimeClasses}. */ + html.loading.in-dev-mode body::before { + background-color: #fff; + border-bottom: 1px solid #e0e0e0; /* --google-grey-300 */ + height: 52px; + } + + html[dark].loading.in-dev-mode body::before { + background: none; + } + + html[dark].loading.in-dev-mode::before, + html[dark].loading.in-dev-mode body::before { + border-bottom: 1px solid rgba(255, 255, 255, .1); } html, @@ -66,7 +56,6 @@ </head> <body> <extensions-manager></extensions-manager> - <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="import" href="chrome://extensions/manager.html"> <link rel="import" href="chrome://resources/html/dark_mode.html">
diff --git a/chrome/browser/resources/md_extensions/manager.html b/chrome/browser/resources/md_extensions/manager.html index 797b13e..30bfe07 100644 --- a/chrome/browser/resources/md_extensions/manager.html +++ b/chrome/browser/resources/md_extensions/manager.html
@@ -51,10 +51,6 @@ extensions-item { display: inline-block; } - - extensions-toolbar { - background-color: var(--md-toolbar-color); - } </style> <extensions-drop-overlay drag-enabled="[[inDevMode]]"> </extensions-drop-overlay>
diff --git a/chrome/browser/resources/md_extensions/toolbar.html b/chrome/browser/resources/md_extensions/toolbar.html index 9d44487..8458178c 100644 --- a/chrome/browser/resources/md_extensions/toolbar.html +++ b/chrome/browser/resources/md_extensions/toolbar.html
@@ -20,20 +20,22 @@ <template> <style include="cr-hidden-style paper-button-style"> :host { - /* The constant is the height of the tallest control. */ - --button-row-height: calc(2 * var(--padding-top-bottom) + 36px); - --dev-drawer-background-color: #fff; + --border-bottom-height: 1px; + --button-row-height: calc(2 * var(--padding-top-bottom) + + var(--cr-button-height)); --drawer-transition: 0.3s cubic-bezier(.25, .1, .25, 1); - --padding-top-bottom: 8px; - --toolbar-color: var(--md-toolbar-color); - } - - :host-context([dark]) { - --dev-drawer-background-color: var(--google-grey-800); + --padding-top-bottom: 10px; } cr-toolbar { - background: var(--toolbar-color); + background: var(--md-toolbar-color); + border-bottom: var(--border-bottom-height) solid transparent; + box-sizing: border-box; + transition: border-bottom-color var(--drawer-transition); + } + + :host-context([dark]):host([in-dev-mode]) cr-toolbar { + border-bottom-color: var(--cr-separator-color); } /* This toggle needs special styling because it's on blue background. */ @@ -54,7 +56,8 @@ } #devDrawer { - background: var(--dev-drawer-background-color); + background: #fff; + border-bottom: 1px solid var(--google-grey-300); box-sizing: border-box; height: 0; overflow-x: hidden; @@ -63,12 +66,13 @@ transition: height var(--drawer-transition); } - :host-context(html:not([dark])) #devDrawer { - border-bottom: 1px solid var(--google-grey-300); + :host-context([dark]) #devDrawer { + background: none; + border-bottom-color: var(--cr-separator-color); } #devDrawer[expanded] { - height: var(--button-row-height); + height: calc(var(--button-row-height) + var(--border-bottom-height)); } #buttonStrip {
diff --git a/chrome/browser/resources/md_extensions/toolbar.js b/chrome/browser/resources/md_extensions/toolbar.js index c9ee828..c231c5a 100644 --- a/chrome/browser/resources/md_extensions/toolbar.js +++ b/chrome/browser/resources/md_extensions/toolbar.js
@@ -37,6 +37,7 @@ type: Boolean, value: false, observer: 'onInDevModeChanged_', + reflectToAttribute: true, }, devModeControlledByPolicy: Boolean,
diff --git a/chrome/browser/resources/pdf/elements/viewer-pen-options/viewer-pen-options.js b/chrome/browser/resources/pdf/elements/viewer-pen-options/viewer-pen-options.js index e01a388..68735f1 100644 --- a/chrome/browser/resources/pdf/elements/viewer-pen-options/viewer-pen-options.js +++ b/chrome/browser/resources/pdf/elements/viewer-pen-options/viewer-pen-options.js
@@ -94,18 +94,33 @@ this.selectedColor = e.target.value; }, + /** @private */ toggleExpanded_: function() { this.expanded_ = !this.expanded_; this.updateExpandedState_(); }, - attached() { + /** @private */ + updateExpandedStateAndFinishAnimations_: function() { this.updateExpandedState_(); for (const animation of this.expandAnimations_) { animation.finish(); } }, + /** @override */ + attached: function() { + // TODO (rbpotter): Remove this conditional when the migration to Polymer 2 + // is completed. + if (Polymer.DomIf) { + Polymer.RenderStatus.beforeNextRender(this, () => { + this.updateExpandedStateAndFinishAnimations_(); + }); + } else { + this.updateExpandedStateAndFinishAnimations_(); + } + }, + /** * Updates the state of the UI to reflect the current value of `expanded`. * Starts or reverses animations and enables/disable controls. @@ -169,6 +184,6 @@ * @return {string} */ lookup_: function(strings, name) { - return strings[name]; + return strings ? strings[name] : ''; } }); \ No newline at end of file
diff --git a/chrome/browser/resources/reset_password/reset_password.html b/chrome/browser/resources/reset_password/reset_password.html index ebc277e..b68848f 100644 --- a/chrome/browser/resources/reset_password/reset_password.html +++ b/chrome/browser/resources/reset_password/reset_password.html
@@ -4,7 +4,6 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>$i18n{title}</title> - <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html">
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html index 0a19b70a..89be0f3 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html +++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.html
@@ -29,16 +29,21 @@ } #clearBrowsingDataDialog { + --border-top-color: var(--paper-grey-300); --cr-dialog-top-container-min-height: 42px; --cr-dialog-title: { padding-bottom: 8px; }; --cr-dialog-body-container: { - border-top: 1px solid var(--paper-grey-300); + border-top: 1px solid var(--border-top-color); height: var(--body-container-height); }; } + :host-context([dark]) #clearBrowsingDataDialog { + --border-top-color: var(--cr-separator-color); + } + #clearBrowsingDataDialog:not(.fully-rendered) { visibility: hidden; } @@ -53,6 +58,10 @@ padding: 0; } + :host-context([dark]) #clearBrowsingDataDialog [slot=footer] { + background: rgb(50, 54, 57); /* Custom color from Namrata. */ + } + .row { align-items: center; display: flex;
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.html b/chrome/browser/resources/settings/people_page/sync_account_control.html index 51754fd..cd22d868 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.html +++ b/chrome/browser/resources/settings/people_page/sync_account_control.html
@@ -2,6 +2,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> @@ -17,9 +18,9 @@ <template> <style include="settings-shared"> :host { - --sync-icon-size: 16px; - --sync-icon-border-size: 2px; --shown-avatar-size: 40px; + --sync-icon-border-size: 2px; + --sync-icon-size: 16px; } setting-box.middle { @@ -77,7 +78,13 @@ right: initial; } - #sync-icon-container.sync-problem { + :host-context([dark]) #sync-icon-container { + background: var(--google-green-refresh-300); + border-color: var(--google-grey-900); + } + + #sync-icon-container.sync-problem, + :host-context([dark]) #sync-icon-container.sync-problem { background: var(--settings-error-color); } @@ -85,12 +92,20 @@ background: var(--google-blue-500); } + :host-context([dark]) #sync-icon-container.sync-paused { + background: var(--google-blue-refresh-300); + } + #sync-icon-container.sync-disabled { background: var(--google-grey-400); } + :host-context([dark]) #sync-icon-container.sync-disabled { + background: var(--google-grey-refresh-500); + } + #sync-icon-container iron-icon { - fill: white; + fill: white; /* Same in light and dark modes. */ height: 12px; margin: auto; width: 12px;
diff --git a/chrome/browser/resources/settings/settings.html b/chrome/browser/resources/settings/settings.html index 75e1fc2..60fc7482 100644 --- a/chrome/browser/resources/settings/settings.html +++ b/chrome/browser/resources/settings/settings.html
@@ -7,33 +7,22 @@ <if expr="not optimize_webui"> <base href="chrome://settings"> </if> + <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <style> html { - --toolbar-height: 56px; - background-color: rgb(248, 249, 250); + background: var(--md-background-color); overflow: hidden; /* Remove 300ms delay for 'click' event, when using touch interface. */ touch-action: manipulation; } - html[dark] { - background: rgb(32, 33, 36); /* --google-grey-900 */ - } - - html[dark].loading { - border-top: 1px solid rgb(95, 99, 104); /* --google-grey-refresh-700 */ - margin-top: var(--toolbar-height); - } - - html:not([dark]).loading { - /* --google-blue-700 in disguise. Replaced when settings-ui loads. */ - border-top: var(--toolbar-height) solid rgb(51, 103, 214); + html.loading { + border-top: 56px solid var(--md-toolbar-color); } </style> </head> <body> <settings-ui></settings-ui> - <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="settings_ui/settings_ui.html">
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.html b/chrome/browser/resources/settings/settings_ui/settings_ui.html index cf4382d..dad18a07 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.html +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.html
@@ -38,13 +38,15 @@ cr-toolbar { @apply --layout-center; - --iron-icon-fill-color: white; background-color: var(--md-toolbar-color); - color: white; min-height: 56px; z-index: 2; } + :host-context(html:not([dark])) cr-toolbar { + --iron-icon-fill-color: white; + } + #container { flex: 1; overflow: overlay;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 21ea97e..e2d9585 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2807,6 +2807,8 @@ "views/tabs/tab_controller.h", "views/tabs/tab_drag_controller.cc", "views/tabs/tab_drag_controller.h", + "views/tabs/tab_group_header.cc", + "views/tabs/tab_group_header.h", "views/tabs/tab_hover_card_bubble_view.cc", "views/tabs/tab_hover_card_bubble_view.h", "views/tabs/tab_icon.cc", @@ -3006,7 +3008,6 @@ ] } else { sources += [ - "views/badge_service_delegate_impl.cc", "views/frame/opaque_browser_frame_view.cc", "views/frame/opaque_browser_frame_view.h", "views/frame/opaque_browser_frame_view_layout.cc",
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 05bd4ae7..1a7e770d 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -89,10 +89,6 @@ EDITABLE_FIELD_IS_ACTIVE, }; -#if !defined(OS_CHROMEOS) -class BadgeServiceDelegate; -#endif - //////////////////////////////////////////////////////////////////////////////// // BrowserWindow interface // An interface implemented by the "view" of the Browser window. @@ -316,9 +312,6 @@ bool disable_stay_in_chrome, IntentPickerResponse callback) = 0; virtual void SetIntentPickerViewVisibility(bool visible) = 0; -#else // !defined(OS_CHROMEOS) - // Returns the badge service delegate. - virtual BadgeServiceDelegate* GetBadgeServiceDelegate() const = 0; #endif // defined(OS_CHROMEOS) // Shows the Bookmark bubble. |url| is the URL being bookmarked,
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc index 996d8ce8..5b49549 100644 --- a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc +++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
@@ -331,6 +331,10 @@ return GetExtension()->short_name(); } +std::string HostedAppBrowserController::GetExtensionId() const { + return extension_id_; +} + base::string16 HostedAppBrowserController::GetFormattedUrlOrigin() const { return FormatUrlOrigin(AppLaunchInfo::GetLaunchWebURL(GetExtension())); }
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.h b/chrome/browser/ui/extensions/hosted_app_browser_controller.h index b7b2275..3a6645d 100644 --- a/chrome/browser/ui/extensions/hosted_app_browser_controller.h +++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.h
@@ -92,6 +92,9 @@ // Gets the short name of the app. std::string GetAppShortName() const; + // Returns the extension id for the app. + std::string GetExtensionId() const; + // Gets the origin of the app start url suitable for display (e.g // example.com.au). base::string16 GetFormattedUrlOrigin() const;
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc index b9df8d2..22185ef 100644 --- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc +++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -20,7 +20,9 @@ #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/badging/badge_service_delegate.h" +#include "chrome/browser/badging/badge_manager.h" +#include "chrome/browser/badging/badge_manager_delegate.h" +#include "chrome/browser/badging/badge_manager_factory.h" #include "chrome/browser/banners/app_banner_manager_desktop.h" #include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/extensions/extension_browsertest.h" @@ -978,29 +980,44 @@ app_browser->GetWindowTitleForCurrentTab(false)); } -#if !defined(OS_CHROMEOS) +#if !defined(OS_ANDROID) class HostedAppBadgingTest : public HostedAppTest { public: + // Listens to BadgeManager events and forwards them to the test class. + class TestBadgeManagerDelegate : public badging::BadgeManagerDelegate { + public: + using SetBadgeCallback = + base::RepeatingCallback<void(const std::string&, + base::Optional<uint64_t>)>; + using ClearBadgeCallback = + base::RepeatingCallback<void(const std::string&)>; + + TestBadgeManagerDelegate(Profile* profile, + SetBadgeCallback on_set_badge, + ClearBadgeCallback on_clear_badge) + : badging::BadgeManagerDelegate(profile), + on_set_badge_(on_set_badge), + on_clear_badge_(on_clear_badge) {} + + void OnBadgeSet(const std::string& app_id, + base::Optional<uint64_t> contents) override { + on_set_badge_.Run(app_id, contents); + } + + void OnBadgeCleared(const std::string& app_id) override { + on_clear_badge_.Run(app_id); + } + + private: + SetBadgeCallback on_set_badge_; + ClearBadgeCallback on_clear_badge_; + }; + void SetUpCommandLine(base::CommandLine* command_line) override { HostedAppTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII("enable-blink-features", "Badging"); } - void OnBadgeSet(content::WebContents* web_contents, - base::Optional<uint64_t> badge_content) { - if (badge_content.has_value()) - last_badge_content_ = badge_content; - else - was_flagged_ = true; - - awaiter_->Quit(); - } - - void OnBadgeCleared(content::WebContents* web_contents) { - was_cleared_ = true; - awaiter_->Quit(); - } - void SetUpOnMainThread() override { HostedAppTest::SetUpOnMainThread(); @@ -1010,12 +1027,34 @@ InstallSecurePWA(); awaiter_ = std::make_unique<base::RunLoop>(); - badge_service_delegate_ = app_browser_->window()->GetBadgeServiceDelegate(); - badge_service_delegate_->SetImplForTesting( - base::BindRepeating(&HostedAppBadgingTest::OnBadgeSet, - base::Unretained(this)), - base::BindRepeating(&HostedAppBadgingTest::OnBadgeCleared, - base::Unretained(this))); + + Profile* profile = app_browser_->profile(); + std::unique_ptr<badging::BadgeManagerDelegate> delegate = + std::make_unique<TestBadgeManagerDelegate>( + profile, + base::BindRepeating(&HostedAppBadgingTest::OnBadgeSet, + base::Unretained(this)), + base::BindRepeating(&HostedAppBadgingTest::OnBadgeCleared, + base::Unretained(this))); + badging::BadgeManagerFactory::GetInstance() + ->GetForProfile(profile) + ->SetDelegate(std::move(delegate)); + } + + // BadgeManagerDelegate: + void OnBadgeSet(const std::string& app_id, + base::Optional<uint64_t> badge_content) { + if (badge_content.has_value()) + last_badge_content_ = badge_content; + else + was_flagged_ = true; + + awaiter_->Quit(); + } + + void OnBadgeCleared(const std::string& app_id) { + was_cleared_ = true; + awaiter_->Quit(); } protected: @@ -1035,8 +1074,6 @@ awaiter_->Run(); } - BadgeServiceDelegate* badge_service_delegate_; - bool was_cleared_ = false; bool was_flagged_ = false; base::Optional<uint64_t> last_badge_content_ = base::nullopt;
diff --git a/chrome/browser/ui/login/login_handler.cc b/chrome/browser/ui/login/login_handler.cc index 8f928ad6..5c6b5432 100644 --- a/chrome/browser/ui/login/login_handler.cc +++ b/chrome/browser/ui/login/login_handler.cc
@@ -171,7 +171,7 @@ handler_ = nullptr; } - LoginHandler* handler_; // owned on the UI thread + LoginHandler* handler_ = nullptr; // owned on the UI thread LoginAuthRequiredCallback callback_; };
diff --git a/chrome/browser/ui/media_router/query_result_manager.cc b/chrome/browser/ui/media_router/query_result_manager.cc index d24c989..ff6209c 100644 --- a/chrome/browser/ui/media_router/query_result_manager.cc +++ b/chrome/browser/ui/media_router/query_result_manager.cc
@@ -34,7 +34,7 @@ ~MediaSourceMediaSinksObserver() override {} - // MediaSinksObserver + // MediaSinksObserver: void OnSinksReceived(const std::vector<MediaSink>& result) override { latest_sink_ids_.clear(); for (const MediaSink& sink : result) @@ -44,7 +44,7 @@ result_manager_->NotifyOnResultsUpdated(); } - // Returns the most recent sink IDs that were passed to |OnSinksReceived|. + // Returns the most recent sink IDs that were passed to |OnSinksReceived()|. void GetLatestSinkIds(std::vector<MediaSink::Id>* sink_ids) const { DCHECK(sink_ids); *sink_ids = latest_sink_ids_; @@ -59,8 +59,29 @@ QueryResultManager* const result_manager_; }; +// Observes for all the available sinks. +class QueryResultManager::AnyMediaSinksObserver : public MediaSinksObserver { + public: + AnyMediaSinksObserver(MediaRouter* router, QueryResultManager* result_manager) + : MediaSinksObserver(router), result_manager_(result_manager) {} + + ~AnyMediaSinksObserver() override {} + + // MediaSinksObserver: + void OnSinksReceived(const std::vector<MediaSink>& sinks) override { + result_manager_->UpdateSinkList(sinks); + result_manager_->NotifyOnResultsUpdated(); + } + + private: + QueryResultManager* const result_manager_; +}; + QueryResultManager::QueryResultManager(MediaRouter* router) : router_(router) { DCHECK(router_); + auto observer = std::make_unique<AnyMediaSinksObserver>(router_, this); + observer->Init(); + sinks_observers_[MediaSource()] = std::move(observer); } QueryResultManager::~QueryResultManager() { @@ -175,15 +196,11 @@ // (1) Iterate through current sink set, remove cast mode from those that // do not appear in latest result. - for (auto it = all_sinks_.begin(); it != all_sinks_.end(); /*no-op*/) { + for (auto it = all_sinks_.begin(); it != all_sinks_.end(); ++it) { const MediaSink::Id& sink_id = it->first; CastModesWithMediaSources& sources_for_sink = it->second; if (!base::ContainsKey(new_sink_ids, sink_id)) sources_for_sink.RemoveSource(cast_mode, source); - if (sources_for_sink.IsEmpty()) - all_sinks_.erase(it++); - else - ++it; } // (2) Add / update sinks with latest result. @@ -200,6 +217,25 @@ } } +// A sink is added to |all_sinks_| in SetSinksCompatibleWithSource() when +// MediaSourceMediaSinksObserver receives it, or in UpdateSinkList() when +// AnyMediaSinksObserver receives it, whichever comes first. +// A sink is removed from |all_sinks_| in UpdateSinkList() when +// AnyMediaSinksObserver receives an update that does not contain it. +void QueryResultManager::UpdateSinkList(const std::vector<MediaSink>& sinks) { + // Erase sinks in |all_sinks_| that do not appear in |sinks|. + base::EraseIf(all_sinks_, [&sinks](const auto& sink_pair) { + return std::find_if(sinks.begin(), sinks.end(), + [&sink_pair](const MediaSink& sink) { + return sink.id() == sink_pair.first; + }) == sinks.end(); + }); + for (const MediaSink& sink : sinks) { + if (!base::ContainsKey(all_sinks_, sink.id())) + all_sinks_.emplace(sink.id(), sink); + } +} + std::unique_ptr<MediaSource> QueryResultManager::GetHighestPrioritySourceForCastModeAndSink( MediaCastMode cast_mode,
diff --git a/chrome/browser/ui/media_router/query_result_manager.h b/chrome/browser/ui/media_router/query_result_manager.h index ea341d5d..8f19d56 100644 --- a/chrome/browser/ui/media_router/query_result_manager.h +++ b/chrome/browser/ui/media_router/query_result_manager.h
@@ -112,6 +112,7 @@ private: class MediaSourceMediaSinksObserver; + class AnyMediaSinksObserver; FRIEND_TEST_ALL_PREFIXES(QueryResultManagerTest, Observers); FRIEND_TEST_ALL_PREFIXES(QueryResultManagerTest, StartRoutesDiscovery); @@ -137,6 +138,9 @@ const MediaSource& source, const std::vector<MediaSink>& new_sinks); + // Updates the overall list of sinks to match |sinks|. + void UpdateSinkList(const std::vector<MediaSink>& sinks); + // Returns the highest-priority source for |cast_mode| contained in // |sources_for_sink|. Returns an empty unique_ptr if none exists. std::unique_ptr<MediaSource> GetHighestPrioritySourceForCastModeAndSink(
diff --git a/chrome/browser/ui/media_router/query_result_manager_unittest.cc b/chrome/browser/ui/media_router/query_result_manager_unittest.cc index d87520a..9cd1d44d 100644 --- a/chrome/browser/ui/media_router/query_result_manager_unittest.cc +++ b/chrome/browser/ui/media_router/query_result_manager_unittest.cc
@@ -15,12 +15,11 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +using testing::_; using testing::Eq; using testing::IsEmpty; -using testing::Eq; using testing::Mock; using testing::Return; -using testing::_; namespace media_router { @@ -44,7 +43,7 @@ void DiscoverSinks(MediaCastMode cast_mode, const MediaSource& source) { EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .WillOnce(Return(true)); - EXPECT_CALL(mock_observer_, OnResultsUpdated(_)).Times(1); + EXPECT_CALL(mock_observer_, OnResultsUpdated(_)); query_result_manager_.SetSourcesForCastMode( cast_mode, {source}, url::Origin::Create(GURL(kOrigin))); } @@ -94,12 +93,12 @@ query_result_manager_.AddObserver(&ob1); query_result_manager_.AddObserver(&ob2); - EXPECT_CALL(ob1, OnResultsUpdated(_)).Times(1); - EXPECT_CALL(ob2, OnResultsUpdated(_)).Times(1); + EXPECT_CALL(ob1, OnResultsUpdated(_)); + EXPECT_CALL(ob2, OnResultsUpdated(_)); query_result_manager_.NotifyOnResultsUpdated(); query_result_manager_.RemoveObserver(&ob2); - EXPECT_CALL(ob1, OnResultsUpdated(_)).Times(1); + EXPECT_CALL(ob1, OnResultsUpdated(_)); query_result_manager_.NotifyOnResultsUpdated(); query_result_manager_.RemoveObserver(&ob1); @@ -131,7 +130,7 @@ // Register a different set of sources for the same cast mode. MediaSource another_source( MediaSourceForPresentationUrl(GURL("http://bar.com"))); - EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(1); + EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)); EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .WillOnce(Return(true)); query_result_manager_.SetSourcesForCastMode( @@ -146,7 +145,7 @@ EXPECT_EQ(1u, actual_sources.size()); EXPECT_EQ(another_source, actual_sources[0]); - EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(1); + EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)); query_result_manager_.RemoveSourcesForCastMode(MediaCastMode::PRESENTATION); cast_modes = query_result_manager_.GetSupportedCastModes(); @@ -161,7 +160,6 @@ MediaSink sink2("sinkId2", "Sink 2", SinkIconType::CAST); MediaSink sink3("sinkId3", "Sink 3", SinkIconType::CAST); MediaSink sink4("sinkId4", "Sink 4", SinkIconType::CAST); - MediaSink sink5("sinkId5", "Sink 5", SinkIconType::CAST); MediaSource presentation_source1 = MediaSourceForPresentationUrl(GURL("http://bar.com")); MediaSource presentation_source2 = @@ -173,30 +171,40 @@ DiscoverSinks(MediaCastMode::TAB_MIRROR, tab_source); // Scenario (results in this order): + // Action: (all sinks) -> [1, 2, 3, 4] + // Expected result: + // Sinks: [1 -> {}, 2 -> {}, 3 -> {}, 4 -> {}] + std::vector<MediaSinkWithCastModes> expected_sinks; + expected_sinks.push_back(MediaSinkWithCastModes(sink1)); + expected_sinks.push_back(MediaSinkWithCastModes(sink2)); + expected_sinks.push_back(MediaSinkWithCastModes(sink3)); + expected_sinks.push_back(MediaSinkWithCastModes(sink4)); + + std::vector<MediaSink> sinks_query_result = {sink1, sink2, sink3, sink4}; + + const auto& sinks_observers = query_result_manager_.sinks_observers_; + auto* any_sink_observer = sinks_observers.find(MediaSource())->second.get(); + EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))); + any_sink_observer->OnSinksUpdated(sinks_query_result, {}); + // Action: PRESENTATION -> [1, 2, 3] // Expected result: - // Sinks: [1 -> {PRESENTATION}, 2 -> {PRESENTATION}, 3 -> {PRESENTATION}] - std::vector<MediaSinkWithCastModes> expected_sinks; + // Sinks: [1 -> {PRESENTATION}, 2 -> {PRESENTATION}, 3 -> {PRESENTATION}, + // 4 -> {}] + expected_sinks.clear(); expected_sinks.push_back(MediaSinkWithCastModes(sink1)); expected_sinks.back().cast_modes.insert(MediaCastMode::PRESENTATION); expected_sinks.push_back(MediaSinkWithCastModes(sink2)); expected_sinks.back().cast_modes.insert(MediaCastMode::PRESENTATION); expected_sinks.push_back(MediaSinkWithCastModes(sink3)); expected_sinks.back().cast_modes.insert(MediaCastMode::PRESENTATION); + expected_sinks.push_back(MediaSinkWithCastModes(sink4)); - const auto& sinks_observers = query_result_manager_.sinks_observers_; - auto sinks_observer_it = sinks_observers.find(presentation_source1); - ASSERT_TRUE(sinks_observer_it != sinks_observers.end()); - ASSERT_TRUE(sinks_observer_it->second.get()); - - std::vector<MediaSink> sinks_query_result; - sinks_query_result.push_back(sink1); - sinks_query_result.push_back(sink2); - sinks_query_result.push_back(sink3); - EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))) - .Times(1); - sinks_observer_it->second->OnSinksUpdated(sinks_query_result, - std::vector<url::Origin>()); + sinks_query_result = {sink1, sink2, sink3}; + auto* presentation1_sinks_observer = + sinks_observers.find(presentation_source1)->second.get(); + EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))); + presentation1_sinks_observer->OnSinksUpdated(sinks_query_result, {}); // Action: TAB_MIRROR -> [2, 3, 4] // Expected result: @@ -214,23 +222,17 @@ expected_sinks.push_back(MediaSinkWithCastModes(sink4)); expected_sinks.back().cast_modes.insert(MediaCastMode::TAB_MIRROR); - sinks_query_result.clear(); - sinks_query_result.push_back(sink2); - sinks_query_result.push_back(sink3); - sinks_query_result.push_back(sink4); - - sinks_observer_it = sinks_observers.find(tab_source); - ASSERT_TRUE(sinks_observer_it != sinks_observers.end()); - ASSERT_TRUE(sinks_observer_it->second.get()); - EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))) - .Times(1); - sinks_observer_it->second->OnSinksUpdated( - sinks_query_result, {url::Origin::Create(GURL(kOrigin))}); + sinks_query_result = {sink2, sink3, sink4}; + auto* tab_sinks_observer = sinks_observers.find(tab_source)->second.get(); + EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))); + tab_sinks_observer->OnSinksUpdated(sinks_query_result, + {url::Origin::Create(GURL(kOrigin))}); // Action: Update presentation URL // Expected result: - // Sinks: [2 -> {TAB_MIRROR}, 3 -> {TAB_MIRROR}, 4 -> {TAB_MIRROR}] + // Sinks: [1 -> {}, 2 -> {TAB_MIRROR}, 3 -> {TAB_MIRROR}, 4 -> {TAB_MIRROR}] expected_sinks.clear(); + expected_sinks.push_back(MediaSinkWithCastModes(sink1)); expected_sinks.push_back(MediaSinkWithCastModes(sink2)); expected_sinks.back().cast_modes.insert(MediaCastMode::TAB_MIRROR); expected_sinks.push_back(MediaSinkWithCastModes(sink3)); @@ -239,42 +241,51 @@ expected_sinks.back().cast_modes.insert(MediaCastMode::TAB_MIRROR); // The observer for the old source will be unregistered. - EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(1); + EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)); // The observer for the new source will be registered. EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) .WillOnce(Return(true)); - EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))) - .Times(1); + EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))); query_result_manager_.SetSourcesForCastMode( MediaCastMode::PRESENTATION, {presentation_source2}, url::Origin::Create(GURL(kOrigin))); // Action: PRESENTATION -> [1], origins don't match - // Expected result: [2 -> {TAB_MIRROR}, 3 -> {TAB_MIRROR}, 4 -> {TAB_MIRROR}] - // (No change) - sinks_query_result.clear(); - sinks_query_result.push_back(sink1); - sinks_observer_it = sinks_observers.find(presentation_source2); - ASSERT_TRUE(sinks_observer_it != sinks_observers.end()); - ASSERT_TRUE(sinks_observer_it->second.get()); - EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))) - .Times(1); - sinks_observer_it->second->OnSinksUpdated( + // Expected result: [1 -> {}, 2 -> {TAB_MIRROR}, 3 -> {TAB_MIRROR}, + // 4 -> {TAB_MIRROR}] (No change) + sinks_query_result = {sink1}; + auto* presentation2_sinks_observer = + sinks_observers.find(presentation_source2)->second.get(); + EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))); + presentation2_sinks_observer->OnSinksUpdated( sinks_query_result, {url::Origin::Create(GURL("https://differentOrigin.com"))}); + // Action: (all sinks) -> [2, 3] + // Expected result: [2 -> {TAB_MIRROR}, 3 -> {TAB_MIRROR}] + expected_sinks.clear(); + expected_sinks.push_back(MediaSinkWithCastModes(sink2)); + expected_sinks.back().cast_modes.insert(MediaCastMode::TAB_MIRROR); + expected_sinks.push_back(MediaSinkWithCastModes(sink3)); + expected_sinks.back().cast_modes.insert(MediaCastMode::TAB_MIRROR); + + sinks_query_result = {sink2, sink3}; + EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))); + any_sink_observer->OnSinksUpdated(sinks_query_result, {}); + // Action: Remove TAB_MIRROR observer // Expected result: - // Sinks: [] + // Sinks: [2 -> {}, 3 -> {}] expected_sinks.clear(); - EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))) - .Times(1); - EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(1); + expected_sinks.push_back(MediaSinkWithCastModes(sink2)); + expected_sinks.push_back(MediaSinkWithCastModes(sink3)); + EXPECT_CALL(mock_observer_, OnResultsUpdated(VectorEquals(expected_sinks))); + EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)); query_result_manager_.RemoveSourcesForCastMode(MediaCastMode::TAB_MIRROR); // Remaining observers: PRESENTATION observer, which will be removed on // destruction - EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)).Times(1); + EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)); } TEST_F(QueryResultManagerTest, MultipleUrls) { @@ -393,8 +404,7 @@ MediaSourceForPresentationUrl(GURL("http://url.com"))); EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) - .Times(1) - .WillRepeatedly(Return(true)); + .WillOnce(Return(true)); query_result_manager_.SetSourcesForCastMode( MediaCastMode::PRESENTATION, {source}, url::Origin::Create(GURL(kOrigin)));
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc index 9b24ae0..c737177 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest.cc
@@ -14,7 +14,6 @@ #include "base/test/metrics/user_action_tester.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/sync_test.h"
diff --git a/chrome/browser/ui/views/badge_service_delegate_impl.cc b/chrome/browser/ui/views/badge_service_delegate_impl.cc deleted file mode 100644 index ce72410..0000000 --- a/chrome/browser/ui/views/badge_service_delegate_impl.cc +++ /dev/null
@@ -1,107 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/badging/badge_service_delegate.h" - -#include "base/bind.h" -#include "base/i18n/number_formatting.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" -#include "content/public/browser/web_contents.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/strings/grit/ui_strings.h" - -#if defined(OS_WIN) -#include "chrome/browser/taskbar/taskbar_decorator_win.h" -#elif defined(OS_MACOSX) -#include "chrome/browser/apps/app_shim/app_shim_host_mac.h" -#include "chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h" -#include "chrome/common/mac/app_shim.mojom.h" -#endif - -namespace { - -#if defined(OS_MACOSX) -void SetAppShimBadgeLabel(content::WebContents* contents, - const std::string& badge_label) { - Browser* browser = chrome::FindBrowserWithWebContents(contents); - auto* shim_handler = apps::ExtensionAppShimHandler::Get(); - if (!shim_handler) - return; - - AppShimHost* shim_host = shim_handler->GetHostForBrowser(browser); - if (!shim_host) - return; - - chrome::mojom::AppShim* shim = shim_host->GetAppShim(); - if (!shim) - return; - - shim->SetBadgeLabel(badge_label); -} -#endif - -#if defined(OS_WIN) || defined(OS_MACOSX) -std::string GetBadgeString(base::Optional<uint64_t> badge_content) { - if (!badge_content) - return "•"; - - if (badge_content > 99u) { - return base::UTF16ToUTF8(l10n_util::GetStringFUTF16( - IDS_SATURATED_BADGE_CONTENT, base::FormatNumber(99))); - } - - return base::UTF16ToUTF8(base::FormatNumber(badge_content.value())); -} -#endif - -void SetBadgeImpl(content::WebContents* contents, - base::Optional<uint64_t> badge_content) { -#if defined(OS_WIN) - Browser* browser = chrome::FindBrowserWithWebContents(contents); - auto* window = browser->window()->GetNativeWindow(); - taskbar::DrawTaskbarDecorationString(window, GetBadgeString(badge_content)); -#elif defined(OS_MACOSX) - SetAppShimBadgeLabel(contents, GetBadgeString(badge_content)); -#endif -} - -void ClearBadgeImpl(content::WebContents* contents) { -#if defined(OS_WIN) - Browser* browser = chrome::FindBrowserWithWebContents(contents); - - // Restore the decoration to whatever it is naturally (either nothing or a - // profile picture badge). - taskbar::UpdateTaskbarDecoration(browser->profile(), - browser->window()->GetNativeWindow()); -#elif defined(OS_MACOSX) - SetAppShimBadgeLabel(contents, ""); -#endif -} - -} // namespace - -BadgeServiceDelegate::BadgeServiceDelegate() - : on_set_badge_(base::BindRepeating(&SetBadgeImpl)), - on_clear_badge_(base::BindRepeating(&ClearBadgeImpl)) {} - -BadgeServiceDelegate::~BadgeServiceDelegate() {} - -void BadgeServiceDelegate::SetBadge(content::WebContents* contents, - base::Optional<uint64_t> badge_content) { - on_set_badge_.Run(contents, badge_content); -} - -void BadgeServiceDelegate::ClearBadge(content::WebContents* contents) { - on_clear_badge_.Run(contents); -} - -void BadgeServiceDelegate::SetImplForTesting( - SetBadgeCallback on_set_badge, - ClearBadgeCallback on_clear_badge) { - on_set_badge_ = on_set_badge; - on_clear_badge_ = on_clear_badge; -}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc index 972e9edb..57cccf34 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_editor_view.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/views/bookmarks/bookmark_editor_view.h" +#include <set> #include <string> #include "base/logging.h" @@ -402,12 +403,6 @@ layout->AddView(tree_view_->CreateParentIfNecessary()); } - if (provider->UseExtraDialogPadding()) { - layout->AddPaddingRow( - views::GridLayout::kFixedSize, - provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)); - } - if (!show_tree_ || bb_model_->loaded()) Reset(); }
diff --git a/chrome/browser/ui/views/chrome_layout_provider.cc b/chrome/browser/ui/views/chrome_layout_provider.cc index b07eac5f..65eccce 100644 --- a/chrome/browser/ui/views/chrome_layout_provider.cc +++ b/chrome/browser/ui/views/chrome_layout_provider.cc
@@ -186,10 +186,6 @@ return views::GridLayout::LEADING; } -bool ChromeLayoutProvider::UseExtraDialogPadding() const { - return false; -} - bool ChromeLayoutProvider::ShouldShowWindowIcon() const { return false; }
diff --git a/chrome/browser/ui/views/chrome_layout_provider.h b/chrome/browser/ui/views/chrome_layout_provider.h index b92ec0d..d023093 100644 --- a/chrome/browser/ui/views/chrome_layout_provider.h +++ b/chrome/browser/ui/views/chrome_layout_provider.h
@@ -91,10 +91,6 @@ // This value controls the alignment used for "Label 1" and "Label 2". virtual views::GridLayout::Alignment GetControlLabelGridAlignment() const; - // Returns whether to use extra padding on dialogs. If this is false, content - // Views for dialogs should not insert extra padding at their own edges. - virtual bool UseExtraDialogPadding() const; - // Returns whether to show the icon next to the title text on a dialog. virtual bool ShouldShowWindowIcon() const;
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc index ce8a862..071696d 100644 --- a/chrome/browser/ui/views/collected_cookies_views.cc +++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -4,7 +4,9 @@ #include "chrome/browser/ui/views/collected_cookies_views.h" +#include <map> #include <memory> +#include <utility> #include "base/macros.h" #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h" @@ -60,10 +62,6 @@ const int kTreeViewWidth = 400; const int kTreeViewHeight = 125; -// Spacing constants used with non-Harmony dialogs. -const int kTabbedPaneTopPadding = 14; -const int kCookieInfoBottomPadding = 4; - // Adds a ColumnSet to |layout| to hold two buttons with padding between. // Starts a new row with the added ColumnSet. void StartNewButtonColumnSet(views::GridLayout* layout, @@ -401,10 +399,13 @@ views::GridLayout* layout = SetLayoutManager(std::make_unique<views::GridLayout>(this)); ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); - if (provider->UseExtraDialogPadding()) { - SetBorder( - views::CreateEmptyBorder(gfx::Insets(kTabbedPaneTopPadding, 0, 0, 0))); - } + + // Add margin above the content. The left, right, and bottom margins are added + // by the content itself. + set_margins( + gfx::Insets(provider->GetDistanceMetric( + views::DISTANCE_DIALOG_CONTENT_MARGIN_TOP_CONTROL), + 0, 0, 0)); const int single_column_layout_id = 0; views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id); @@ -424,18 +425,10 @@ tabbed_pane->AddTab(label_blocked, CreateBlockedPane()); tabbed_pane->SelectTabAt(0); tabbed_pane->set_listener(this); - if (ChromeLayoutProvider::Get()->UseExtraDialogPadding()) { - layout->AddPaddingRow( - views::GridLayout::kFixedSize, - provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)); - } layout->StartRow(views::GridLayout::kFixedSize, single_column_layout_id); cookie_info_view_ = new CookieInfoView(); layout->AddView(cookie_info_view_); - if (provider->UseExtraDialogPadding()) - layout->AddPaddingRow(views::GridLayout::kFixedSize, - kCookieInfoBottomPadding); layout->StartRow(views::GridLayout::kFixedSize, single_column_layout_id); infobar_ = new InfobarView();
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 9299322..7311cb0 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -169,7 +169,6 @@ #include "chrome/grit/chrome_unscaled_resources.h" #include "ui/base/ui_base_features.h" #else -#include "chrome/browser/badging/badge_service_delegate.h" #include "chrome/browser/ui/signin_view_controller.h" #include "chrome/browser/ui/views/profiles/profile_chooser_view.h" #endif // !defined(OS_CHROMEOS) @@ -535,9 +534,6 @@ browser_ = std::move(browser); browser_->tab_strip_model()->AddObserver(this); immersive_mode_controller_.reset(chrome::CreateImmersiveModeController()); -#if !defined(OS_CHROMEOS) - badge_service_delegate_ = std::make_unique<BadgeServiceDelegate>(); -#endif } // static @@ -1352,10 +1348,6 @@ location_bar->Layout(); } } -#else // !defined(OS_CHROMEOS) -BadgeServiceDelegate* BrowserView::GetBadgeServiceDelegate() const { - return badge_service_delegate_.get(); -} #endif // defined(OS_CHROMEOS) void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) {
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 4d0878e..bf8bfc65 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -367,8 +367,6 @@ bool disable_stay_in_chrome, IntentPickerResponse callback) override; void SetIntentPickerViewVisibility(bool visible) override; -#else // !defined(OS_CHROMEOS) - BadgeServiceDelegate* GetBadgeServiceDelegate() const override; #endif // defined(OS_CHROMEOS) void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) override; autofill::SaveCardBubbleView* ShowSaveCreditCardBubble( @@ -831,11 +829,6 @@ std::unique_ptr<FullscreenControlHost> fullscreen_control_host_; -#if !defined(OS_CHROMEOS) - // The badge service delegate for this window. - std::unique_ptr<BadgeServiceDelegate> badge_service_delegate_; -#endif // !defined(OS_CHROMEOS) - #if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP) std::unique_ptr<ReopenTabPromoController> reopen_tab_promo_controller_; #endif
diff --git a/chrome/browser/ui/views/login_view.cc b/chrome/browser/ui/views/login_view.cc index fe7d447..3f3092e 100644 --- a/chrome/browser/ui/views/login_view.cc +++ b/chrome/browser/ui/views/login_view.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/views/login_view.h" +#include <memory> + #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/textfield_layout.h" @@ -70,12 +72,6 @@ kFieldsColumnSetId); password_field_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD); - if (provider->UseExtraDialogPadding()) { - layout->AddPaddingRow(views::GridLayout::kFixedSize, - provider->GetDistanceMetric( - views::DISTANCE_UNRELATED_CONTROL_VERTICAL)); - } - if (login_model_data) { login_model_->AddObserverAndDeliverCredentials(this, login_model_data->form);
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index 5f5d5527..3c9c323 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -42,9 +42,7 @@ #if defined(OS_CHROMEOS) #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/window_properties.h" // nogncheck -#include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" -#include "ui/base/ui_base_features.h" #endif // static @@ -230,12 +228,6 @@ #if defined(OS_CHROMEOS) GetNativeWindow()->SetProperty(ash::kWindowPipTypeKey, true); - if (features::IsUsingWindowService()) { - aura::Window* window = GetNativeWindow()->GetRootWindow(); - window->SetProperty(aura::client::kMinimumSize, - new gfx::Size(kMinWindowSize)); - window->SetProperty(aura::client::kMaximumSize, new gfx::Size(max_size_)); - } #endif // defined(OS_CHROMEOS) is_initialized_ = true; @@ -256,12 +248,6 @@ // Lower bound size of the window is a fixed value to allow for minimal sizes // on UI affordances, such as buttons. min_size_ = kMinWindowSize; -#if defined(OS_CHROMEOS) - if (features::IsUsingWindowService() && is_initialized_) { - GetNativeWindow()->GetRootWindow()->SetProperty(aura::client::kMaximumSize, - new gfx::Size(max_size_)); - } -#endif gfx::Size window_size = window_bounds_.size(); if (!has_been_shown_) {
diff --git a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc index d817e6fe..f4c38cd 100644 --- a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc +++ b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc
@@ -311,8 +311,6 @@ } unmask_delegate_->OnUnmaskResponse(response); } - - dialog()->ShowProcessingSpinner(); } void CvcUnmaskViewController::DisplayError(base::string16 error) {
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.cc b/chrome/browser/ui/views/tabs/tab_group_header.cc new file mode 100644 index 0000000..0b635160 --- /dev/null +++ b/chrome/browser/ui/views/tabs/tab_group_header.cc
@@ -0,0 +1,53 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/tabs/tab_group_header.h" + +#include <memory> + +#include "base/strings/utf_string_conversions.h" +#include "chrome/app/vector_icons/vector_icons.h" +#include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkPath.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/geometry/insets.h" +#include "ui/views/border.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/button/image_button_factory.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/flex_layout.h" +#include "ui/views/layout/flex_layout_types.h" + +TabGroupHeader::TabGroupHeader() { + // TODO(crbug.com/905491): Call TabStyle::GetContentsInsets. + constexpr gfx::Insets kPlaceholderInsets = gfx::Insets(2, 10); + SetBorder(views::CreateEmptyBorder(kPlaceholderInsets)); + + views::FlexLayout* layout = + SetLayoutManager(std::make_unique<views::FlexLayout>()); + layout->SetOrientation(views::LayoutOrientation::kHorizontal) + .SetCollapseMargins(true) + .SetMainAxisAlignment(views::LayoutAlignment::kStart) + .SetCrossAxisAlignment(views::LayoutAlignment::kCenter); + + // TODO(crbug.com/905491): Get title from TabGroupData::title(). + auto* title = new views::Label(base::ASCIIToUTF16("Placeholder Title")); + title->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); + title->SetElideBehavior(gfx::FADE_TAIL); + AddChildView(title); + layout->SetFlexForView(title, views::FlexSpecification::ForSizeRule( + views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kUnbounded)); + + auto* group_menu_button = + views::CreateVectorImageButton(/*listener*/ nullptr); + views::SetImageFromVectorIcon(group_menu_button, kBrowserToolsIcon); + AddChildView(group_menu_button); +} + +void TabGroupHeader::OnPaint(gfx::Canvas* canvas) { + // TODO(crbug.com/905491): Call TabStyle::PaintTab. + constexpr SkColor kPlaceholderColor = SkColorSetRGB(0xAA, 0xBB, 0xCC); + canvas->FillRect(GetLocalBounds(), kPlaceholderColor); +}
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.h b/chrome/browser/ui/views/tabs/tab_group_header.h new file mode 100644 index 0000000..01d111e9 --- /dev/null +++ b/chrome/browser/ui/views/tabs/tab_group_header.h
@@ -0,0 +1,28 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_HEADER_H_ +#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_HEADER_H_ + +#include "ui/views/view.h" + +namespace gfx { +class Canvas; +} + +// View for tab group headers in the tab strip, which are tab-shaped markers of +// group boundaries. There is one header for each group, which is included in +// the tab strip flow and positioned left of the leftmost tab in the group. +class TabGroupHeader : public views::View { + public: + TabGroupHeader(); + + // views::View: + void OnPaint(gfx::Canvas* canvas) override; + + private: + DISALLOW_COPY_AND_ASSIGN(TabGroupHeader); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_GROUP_HEADER_H_
diff --git a/chrome/browser/ui/views/touch_selection_menu_runner_chromeos.cc b/chrome/browser/ui/views/touch_selection_menu_runner_chromeos.cc index e7d67805..7edd923 100644 --- a/chrome/browser/ui/views/touch_selection_menu_runner_chromeos.cc +++ b/chrome/browser/ui/views/touch_selection_menu_runner_chromeos.cc
@@ -7,6 +7,8 @@ #include <utility> #include "base/bind.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/views/touch_selection_menu_chromeos.h" #include "components/arc/arc_bridge_service.h" @@ -79,6 +81,7 @@ const display::Screen* screen = display::Screen::GetScreen(); DCHECK(screen); + base::RecordAction(base::UserMetricsAction("Arc.SmartTextSelection.Request")); // Fetch actions for selected text and then show quick menu. instance->RequestTextSelectionActions( converted_text,
diff --git a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc index 196f4c1e..6aaa395 100644 --- a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc +++ b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
@@ -4,21 +4,78 @@ #include "chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h" +#include <map> #include <string> +#include "ash/public/cpp/shell_window_ids.h" +#include "base/base64.h" #include "base/bind.h" #include "base/memory/ref_counted_memory.h" #include "base/task/post_task.h" #include "base/values.h" #include "chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h" #include "chrome/browser/chromeos/arc/tracing/arc_tracing_model.h" +#include "components/exo/shell_surface_util.h" +#include "components/exo/wm_helper_chromeos.h" #include "content/public/browser/tracing_controller.h" #include "content/public/browser/web_ui.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/base/ui_base_features.h" +#include "ui/gfx/codec/png_codec.h" namespace chromeos { namespace { +constexpr char kKeyIcon[] = "icon"; +constexpr char kKeyTitle[] = "title"; +constexpr char kKeyTasks[] = "tasks"; +constexpr char kTaskIdPrefix[] = "org.chromium.arc."; + +// Scans for all ARC windows and and extracts the title and optionally icon. +void CreateTaskMap(aura::Window* window, base::DictionaryValue* tasks) { + if (!window->IsVisible()) + return; + + // ARC window is top level window, all its parents have type not set. + if (window->type() == aura::client::WINDOW_TYPE_UNKNOWN) { + for (aura::Window* child_window : window->children()) + CreateTaskMap(child_window, tasks); + return; + } + + // Verifies if this is top-level ARC window. + const std::string* arc_app_id = exo::GetShellApplicationId(window); + if (!arc_app_id) + return; + + // Root surface may not have task id. + const size_t prefix_pos = arc_app_id->find(kTaskIdPrefix); + if (prefix_pos) + return; + + base::DictionaryValue task_information; + task_information.SetKey(kKeyTitle, base::Value(window->GetTitle())); + + const gfx::ImageSkia* app_icon = + window->GetProperty(aura::client::kAppIconKey); + if (app_icon) { + std::vector<unsigned char> png_data; + if (gfx::PNGCodec::EncodeBGRASkBitmap( + app_icon->GetRepresentation(1.0f).GetBitmap(), + false /* discard_transparency */, &png_data)) { + const std::string png_data_as_string( + reinterpret_cast<const char*>(&png_data[0]), png_data.size()); + std::string icon_content; + base::Base64Encode(png_data_as_string, &icon_content); + task_information.SetKey(kKeyIcon, base::Value(icon_content)); + } + } + + tasks->SetKey(arc_app_id->c_str() + strlen(kTaskIdPrefix), + std::move(task_information)); +} + std::unique_ptr<base::Value> BuildGraphicsModel(const std::string& data) { arc::ArcTracingModel common_model; if (!common_model.Build(data)) { @@ -32,7 +89,19 @@ return nullptr; } - return graphics_model.Serialize(); + std::unique_ptr<base::DictionaryValue> model = graphics_model.Serialize(); + base::DictionaryValue tasks; + // Scan for ARC++ windows + // TODO(https://crbug.com/887156): Fix the mash. + if (!features::IsMultiProcessMash()) { + CreateTaskMap( + exo::WMHelperChromeOS::GetInstance()->GetPrimaryDisplayContainer( + ash::kShellWindowId_DefaultContainer), + &tasks); + } + model->SetKey(kKeyTasks, std::move(tasks)); + + return model; } } // namespace
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc index 00d7313..c2fa4ac 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc
@@ -27,7 +27,6 @@ #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.h" #include "chrome/common/chrome_constants.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc index a4f0faf..31a5128 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc
@@ -294,7 +294,7 @@ MultideviceHandler::GenerateAndroidSmsInfo() { base::Optional<GURL> app_url; if (android_sms_app_manager_) - app_url = android_sms_app_manager_->GetInstalledAppUrl(); + app_url = android_sms_app_manager_->GetCurrentAppUrl(); if (!app_url) app_url = android_sms::GetAndroidMessagesURL();
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc index bec01db..e889966 100644 --- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc
@@ -382,9 +382,9 @@ TEST_F(MultideviceHandlerTest, GetAndroidSmsInfo) { // Check that getAndroidSmsInfo returns correct value. - CallGetAndroidSmsInfo( - false /* expected_enabled */, - android_sms::GetAndroidMessagesURL() /* expected_url */); + CallGetAndroidSmsInfo(false /* expected_enabled */, + android_sms::GetAndroidMessagesURL( + true /* use_install_url */) /* expected_url */); // Change messages feature state and assert that the change // callback is fired. @@ -401,20 +401,19 @@ EXPECT_EQ("settings.onAndroidSmsInfoChange", call_data_1.arg1()->GetString()); // Check that getAndroidSmsInfo returns update value. - CallGetAndroidSmsInfo( - true /* enabled */, - android_sms::GetAndroidMessagesURL() /* expected_url */); + CallGetAndroidSmsInfo(true /* enabled */, android_sms::GetAndroidMessagesURL( + true) /* expected_url */); // Now, update the installed URL. This should have resulted in another call. fake_android_sms_app_manager()->SetInstalledAppUrl( - android_sms::GetAndroidMessagesURLOld()); + android_sms::GetAndroidMessagesURLOld(true)); const content::TestWebUI::CallData& call_data_2 = CallDataAtIndex(call_data_count_before_call + 4); EXPECT_EQ("cr.webUIListenerCallback", call_data_2.function_name()); EXPECT_EQ("settings.onAndroidSmsInfoChange", call_data_2.arg1()->GetString()); CallGetAndroidSmsInfo( true /* enabled */, - android_sms::GetAndroidMessagesURLOld() /* expected_url */); + android_sms::GetAndroidMessagesURLOld(true) /* expected_url */); } } // namespace settings
diff --git a/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc b/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc index db57f7a..c25759c 100644 --- a/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc +++ b/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc
@@ -10,9 +10,7 @@ #include "chrome/browser/profiles/profile_attributes_entry.h" #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_avatar_icon_util.h" -#include "chrome/browser/signin/fake_signin_manager_builder.h" #include "chrome/browser/signin/signin_error_controller_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_util.h" #include "chrome/browser/ui/webui/signin/signin_utils.h" #include "chrome/common/buildflags.h" @@ -120,13 +118,8 @@ return handler_.get(); } - FakeSigninManagerForTesting* signin_manager() { - return fake_signin_manager_; - } - private: std::unique_ptr<content::TestWebUI> web_ui_; - FakeSigninManagerForTesting* fake_signin_manager_; std::unique_ptr<TestSigninCreateProfileHandler> handler_; };
diff --git a/chrome/common/media_router/discovery/media_sink_service_base.cc b/chrome/common/media_router/discovery/media_sink_service_base.cc index 1f87e73..009517d7 100644 --- a/chrome/common/media_router/discovery/media_sink_service_base.cc +++ b/chrome/common/media_router/discovery/media_sink_service_base.cc
@@ -116,6 +116,8 @@ for (const auto& sink_it : sinks_) sinks.push_back(sink_it.second); + for (auto& observer : observers_) + observer.OnSinksDiscovered(sinks); on_sinks_discovered_cb_.Run(std::move(sinks)); previous_sinks_ = sinks_; }
diff --git a/chrome/common/media_router/discovery/media_sink_service_base.h b/chrome/common/media_router/discovery/media_sink_service_base.h index 571d682..df9547f 100644 --- a/chrome/common/media_router/discovery/media_sink_service_base.h +++ b/chrome/common/media_router/discovery/media_sink_service_base.h
@@ -6,6 +6,7 @@ #define CHROME_COMMON_MEDIA_ROUTER_DISCOVERY_MEDIA_SINK_SERVICE_BASE_H_ #include <memory> +#include <vector> #include "base/containers/flat_map.h" #include "base/gtest_prod_util.h" @@ -38,15 +39,19 @@ public: virtual ~Observer() = default; + // Invoked when the list of discovered sinks changes. + virtual void OnSinksDiscovered( + const std::vector<MediaSinkInternal>& sinks) {} + // Invoked when |sink| is added or updated. - virtual void OnSinkAddedOrUpdated(const MediaSinkInternal& sink) = 0; + virtual void OnSinkAddedOrUpdated(const MediaSinkInternal& sink) {} // Invoked when |sink| is removed. - virtual void OnSinkRemoved(const MediaSinkInternal& sink) = 0; + virtual void OnSinkRemoved(const MediaSinkInternal& sink) {} }; - // |callback|: Callback to invoke inform MediaRouter of discovered sinks - // updates. + // |callback|: Callback to inform the MediaRouter extension of discovered + // sinks updates. Other uses should implement Observer::OnSinksDiscovered(). explicit MediaSinkServiceBase(const OnSinksDiscoveredCallback& callback); virtual ~MediaSinkServiceBase();
diff --git a/chrome/common/media_router/mojo/media_router.mojom b/chrome/common/media_router/mojo/media_router.mojom index 405d374..de758c6 100644 --- a/chrome/common/media_router/mojo/media_router.mojom +++ b/chrome/common/media_router/mojo/media_router.mojom
@@ -395,7 +395,8 @@ // If the operation was successful, |sent| is true; otherwise it is false. SendRouteBinaryMessage(string media_route_id, array<uint8> data); - // Starts querying for sinks capable of displaying |media_source|. + // Starts querying for sinks capable of displaying |media_source|. If + // |media_source| is empty, queries for all available sinks. StartObservingMediaSinks(string media_source); // Stops querying sinks for |media_source|.
diff --git a/chrome/test/base/in_process_browser_test_browsertest.cc b/chrome/test/base/in_process_browser_test_browsertest.cc index 79e3260..83dc373 100644 --- a/chrome/test/base/in_process_browser_test_browsertest.cc +++ b/chrome/test/base/in_process_browser_test_browsertest.cc
@@ -97,7 +97,9 @@ // On Mac this crashes inside cc::SingleThreadProxy::SetNeedsCommit. See // https://ci.chromium.org/b/8923336499994443392 -#if !defined(OS_MACOSX) +// On ChromeOS this crashes because ProfileIOData and NetworkContext both try +// to set up NSS on different threads, which it doesn't like. +#if !defined(OS_MACOSX) && !defined(OS_CHROMEOS) class SingleProcessBrowserTest : public InProcessBrowserTest { public: void SetUpCommandLine(base::CommandLine* command_line) override {
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc index 9320c7dc..568caec 100644 --- a/chrome/test/base/test_browser_window.cc +++ b/chrome/test/base/test_browser_window.cc
@@ -175,12 +175,6 @@ return false; } -#if !defined(OS_CHROMEOS) -BadgeServiceDelegate* TestBrowserWindow::GetBadgeServiceDelegate() const { - return nullptr; -} -#endif - ShowTranslateBubbleResult TestBrowserWindow::ShowTranslateBubble( content::WebContents* contents, translate::TranslateStep step,
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 37a129b..e07533a 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -118,8 +118,6 @@ bool disable_stay_in_chrome, IntentPickerResponse callback) override {} void SetIntentPickerViewVisibility(bool visible) override {} -#else // !defined(OS_CHROMEOS) - BadgeServiceDelegate* GetBadgeServiceDelegate() const override; #endif autofill::SaveCardBubbleView* ShowSaveCreditCardBubble( content::WebContents* contents,
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 41d864ab..cf2d415 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -41,7 +41,13 @@ ] _OS_NEGATIVE_FILTER['mac'] = [ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2663 - 'WindowTest.testSetsThePositionOfTheCurrentWindow', + 'WindowTest.canFullscreenTheWindow', + 'WindowTest.testSetsTheSizeOfTheCurrentWindowFromIframe', + 'WindowTest.testSetsTheSizeOfTheCurrentWindowFromFrame', + 'WindowTest.canFullscreenTheWindowFromFrame', + 'WindowTest.canFullscreenTheWindowFromIframe', + 'WindowTest.testSetsTheSizeOfTheCurrentWindow', + 'BasicMouseInterfaceTest.testMovingMouseByRelativeOffset', ] _SPECIFIC_OS_REVISION_NEGATIVE_FILTER = {}
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/test_page.html b/chrome/test/data/extensions/api_test/mime_handler_view/test_page.html index 3dbe2d5..ef0a3d2 100644 --- a/chrome/test/data/extensions/api_test/mime_handler_view/test_page.html +++ b/chrome/test/data/extensions/api_test/mime_handler_view/test_page.html
@@ -7,6 +7,7 @@ const token = "?next="; if (!query.startsWith(token)) return false; + let query_index = query.indexOf(token); window.location.href = query.substr(query_index + token.length); return true; }
diff --git a/chrome/test/data/extensions/no_best_effort_tasks_test_extension/background.js b/chrome/test/data/extensions/no_best_effort_tasks_test_extension/background.js index ee7ee7d..de7e188 100644 --- a/chrome/test/data/extensions/no_best_effort_tasks_test_extension/background.js +++ b/chrome/test/data/extensions/no_best_effort_tasks_test_extension/background.js
@@ -8,3 +8,1099 @@ sendResponse({pong: true}); } }); + +/* +What follows is garbage to make the total size of this file more than 64 +kilobytes. This is to test the case where the NetworkService has to schedule +multiple tasks to feed this file through a mojo data pipe (when the extension +loads this background.js file resource). + +See http://crbug.com/924416 for further details. + + +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| _ _ | +|( ) _ ( ) _ | +|| | ( ) | | __ _ _ _ __ _ ___ ___ (_) ___ __ | +|| | | | | | /'__`\ ( '_`\ ( '__)/'_`\ /' _ ` _ `\| |/',__) /'__`\ | +|| (_/ \_) |( ___/ | (_) )| | ( (_) )| ( ) ( ) || |\__, \( ___/ | +|`\___x___/'`\____) | ,__/'(_) `\___/'(_) (_) (_)(_)(____/`\____) | +| | | | +| (_) | +| _ _ | +|( )_ ( )_ | +|| ,_) _ ___ | ,_) _ _ _ | +|| | /'_`\ /',__)| | /'_`\ ( '_`\ | +|| |_ ( (_) ) \__, \| |_ ( (_) )| (_) ) | +|`\__)`\___/' (____/`\__)`\___/'| ,__/' | +| | | | +| (_) | +| _ ___ _ _ | +| _ ( )_ _ ( _`\ ( ) ( ) | +| _ _ _ _ __ (_)| ,_)(_) ___ __ | ( (_)__| |__ __| |__ | +|( ) ( ) ( )( '__)| || | | |/' _ `\ /'_ `\ | | _(__ __)(__ __) | +|| \_/ \_/ || | | || |_ | || ( ) |( (_) | | (_( ) | | | | | +|`\___x___/'(_) (_)`\__)(_)(_) (_)`\__ | (____/' (_) (_) | +| ( )_) | | +| \___/' | +| _ _ _____ | +|(_ ) _ ( ) (___ ) | +| | | (_)| |/') __ | | _ _ _ _ _ _ | +| | | | || , < /'__`\ _ | | /'_` )( ) ( ) /'_` ) | +| | | | || |\`\ ( ___/ ( )_| |( (_| || \_/ |( (_| | _ | +|(___)(_)(_) (_)`\____) `\___/'`\__,_)`\___/'`\__,_)(_) | +| | +| | +| | +| | +| | +| | +| | +| | +| | +| | +*/
diff --git a/chrome/test/data/pdf/annotations_feature_enabled_test.js b/chrome/test/data/pdf/annotations_feature_enabled_test.js index 181765b..1413030 100644 --- a/chrome/test/data/pdf/annotations_feature_enabled_test.js +++ b/chrome/test/data/pdf/annotations_feature_enabled_test.js
@@ -84,17 +84,18 @@ inkHost.ink_.setAnnotationTool = value => tool = value; // Pen defaults. - document.querySelector('* /deep/ #pen').click(); + const viewerPdfToolbar = document.querySelector('viewer-pdf-toolbar'); + const pen = viewerPdfToolbar.$$('#pen'); + pen.click(); chrome.test.assertEq('pen', tool.tool); chrome.test.assertEq(0.1429, tool.size); chrome.test.assertEq('#000000', tool.color); // Selected size and color. - document.querySelector( - '* /deep/ #pen /deep/ #sizes [value="1"]').click(); - document.querySelector( - '* /deep/ #pen /deep/ #colors [value="#00b0ff"]').click(); + const penOptions = viewerPdfToolbar.$$('#pen viewer-pen-options'); + penOptions.$$('#sizes [value="1"]').click(); + penOptions.$$('#colors [value="#00b0ff"]').click(); await animationFrame(); chrome.test.assertEq('pen', tool.tool); chrome.test.assertEq(1, tool.size); @@ -102,38 +103,36 @@ // Eraser defaults. - document.querySelector('* /deep/ #eraser').click(); + viewerPdfToolbar.$$('#eraser').click(); chrome.test.assertEq('eraser', tool.tool); chrome.test.assertEq(1, tool.size); chrome.test.assertEq(null, tool.color); // Pen keeps previous settings. - document.querySelector('* /deep/ #pen').click(); + pen.click(); chrome.test.assertEq('pen', tool.tool); chrome.test.assertEq(1, tool.size); chrome.test.assertEq('#00b0ff', tool.color); // Highlighter defaults. - document.querySelector('* /deep/ #highlighter').click(); + viewerPdfToolbar.$$('#highlighter').click(); chrome.test.assertEq('highlighter', tool.tool); chrome.test.assertEq(0.7143, tool.size); chrome.test.assertEq('#ffbc00', tool.color); // Need to expand to use this color. - document.querySelector( - '* /deep/ #highlighter /deep/ #colors [value="#d1c4e9"]').click(); + const highlighterOptions = + viewerPdfToolbar.$$('#highlighter viewer-pen-options'); + highlighterOptions.$$('#colors [value="#d1c4e9"]').click(); chrome.test.assertEq('#ffbc00', tool.color); // Selected size and expanded color. - document.querySelector( - '* /deep/ #highlighter /deep/ #sizes [value="1"]').click(); - document.querySelector( - '* /deep/ #highlighter /deep/ #colors #expand').click(); - document.querySelector( - '* /deep/ #highlighter /deep/ #colors [value="#d1c4e9"]').click(); + highlighterOptions.$$('#sizes [value="1"]').click(); + highlighterOptions.$$('#colors #expand').click(); + highlighterOptions.$$('#colors [value="#d1c4e9"]').click(); chrome.test.assertEq('highlighter', tool.tool); chrome.test.assertEq(1, tool.size); chrome.test.assertEq('#d1c4e9', tool.color);
diff --git a/chrome/test/data/scroll/overscroll_behavior.html b/chrome/test/data/scroll/overscroll_behavior.html new file mode 100644 index 0000000..1829fa5 --- /dev/null +++ b/chrome/test/data/scroll/overscroll_behavior.html
@@ -0,0 +1,18 @@ +<style> +body { + margin: 0px; +} +#scroller { + overflow: scroll; + overscroll-behavior: none; + width: 800px; + height: 800px; +} +#space { + height: 800px; + width: 2000px; +} +</style> +<div id="scroller"> + <div id="space"></div> +</div> \ No newline at end of file
diff --git a/chromecast/browser/cast_network_contexts.cc b/chromecast/browser/cast_network_contexts.cc index c2e42eb..e7b0c0ca 100644 --- a/chromecast/browser/cast_network_contexts.cc +++ b/chromecast/browser/cast_network_contexts.cc
@@ -10,9 +10,15 @@ #include "base/bind.h" #include "base/task/post_task.h" +#include "chromecast/browser/cast_browser_context.h" +#include "chromecast/browser/cast_browser_process.h" +#include "chromecast/browser/cast_http_user_agent_settings.h" #include "chromecast/browser/url_request_context_factory.h" +#include "chromecast/common/cast_content_client.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/network_service_instance.h" +#include "content/public/browser/storage_partition.h" #include "services/network/network_context.h" #include "services/network/public/cpp/cross_thread_shared_url_loader_factory_info.h" #include "services/network/public/cpp/features.h" @@ -209,11 +215,30 @@ CreateSystemNetworkContextParams()); } +void CastNetworkContexts::OnLocaleUpdate() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) + return; + + auto accept_language = CastHttpUserAgentSettings::AcceptLanguage(); + + GetSystemContext()->SetAcceptLanguage(accept_language); + + auto* browser_context = CastBrowserProcess::GetInstance()->browser_context(); + content::BrowserContext::GetDefaultStoragePartition(browser_context) + ->GetNetworkContext() + ->SetAcceptLanguage(accept_language); +} + network::mojom::NetworkContextParamsPtr CastNetworkContexts::CreateDefaultNetworkContextParams() { network::mojom::NetworkContextParamsPtr network_context_params = network::mojom::NetworkContextParams::New(); + network_context_params->user_agent = GetUserAgent(); + network_context_params->accept_language = + CastHttpUserAgentSettings::AcceptLanguage(); + return network_context_params; }
diff --git a/chromecast/browser/cast_network_contexts.h b/chromecast/browser/cast_network_contexts.h index de68895..ed3fcba 100644 --- a/chromecast/browser/cast_network_contexts.h +++ b/chromecast/browser/cast_network_contexts.h
@@ -70,6 +70,9 @@ bool in_memory, const base::FilePath& relative_partition_path); + // Called when the locale has changed. + void OnLocaleUpdate(); + private: class SystemNetworkContextOwner; class URLLoaderFactoryForSystem;
diff --git a/chromecast/cast_shell_sandbox_policy b/chromecast/cast_shell_sandbox_policy index 2555134..5a31e2bf 100644 --- a/chromecast/cast_shell_sandbox_policy +++ b/chromecast/cast_shell_sandbox_policy
@@ -9,6 +9,7 @@ "fuchsia.media.Audio", "fuchsia.mediacodec.CodecFactory", "fuchsia.net.LegacySocketProvider", + "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.process.Launcher", "fuchsia.sys.Launcher",
diff --git a/chromeos/dbus/update_engine_client.cc b/chromeos/dbus/update_engine_client.cc index 0bc947d8..d6e05b3 100644 --- a/chromeos/dbus/update_engine_client.cc +++ b/chromeos/dbus/update_engine_client.cc
@@ -246,7 +246,7 @@ const std::string& update_version, int64_t update_size, const UpdateOverCellularOneTimePermissionCallback& callback) override { - // TODO(weidongg): Change 'kSetUpdateOverCellularTarget' to + // TODO(https://crbug.com/927439): Change 'kSetUpdateOverCellularTarget' to // 'kSetUpdateOverCellularOneTimePermission' dbus::MethodCall method_call(update_engine::kUpdateEngineInterface, update_engine::kSetUpdateOverCellularTarget);
diff --git a/chromeos/services/device_sync/BUILD.gn b/chromeos/services/device_sync/BUILD.gn index a4b6fa2..b252301f 100644 --- a/chromeos/services/device_sync/BUILD.gn +++ b/chromeos/services/device_sync/BUILD.gn
@@ -30,8 +30,6 @@ "cryptauth_enrollment_result.h", "cryptauth_enrollment_scheduler.cc", "cryptauth_enrollment_scheduler.h", - "cryptauth_enrollment_scheduler_impl.cc", - "cryptauth_enrollment_scheduler_impl.h", "cryptauth_gcm_manager.cc", "cryptauth_gcm_manager.h", "cryptauth_gcm_manager_impl.cc", @@ -54,6 +52,8 @@ "device_sync_type_converters.h", "network_request_error.cc", "network_request_error.h", + "persistent_enrollment_scheduler.cc", + "persistent_enrollment_scheduler.h", "pref_names.cc", "pref_names.h", "remote_device_loader.cc", @@ -155,12 +155,12 @@ "cryptauth_device_manager_impl_unittest.cc", "cryptauth_enroller_impl_unittest.cc", "cryptauth_enrollment_manager_impl_unittest.cc", - "cryptauth_enrollment_scheduler_impl_unittest.cc", "cryptauth_gcm_manager_impl_unittest.cc", "cryptauth_key_bundle_unittest.cc", "cryptauth_key_registry_impl_unittest.cc", "cryptauth_key_unittest.cc", "device_sync_service_unittest.cc", + "persistent_enrollment_scheduler_unittest.cc", "remote_device_loader_unittest.cc", "remote_device_provider_impl_unittest.cc", "software_feature_manager_impl_unittest.cc",
diff --git a/chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl.h b/chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl.h deleted file mode 100644 index cff85a2..0000000 --- a/chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl.h +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_ENROLLMENT_SCHEDULER_IMPL_H_ -#define CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_ENROLLMENT_SCHEDULER_IMPL_H_ - -#include "chromeos/services/device_sync/cryptauth_enrollment_scheduler.h" - -#include <memory> - -#include "base/macros.h" -#include "chromeos/services/device_sync/proto/cryptauth_directive.pb.h" - -class PrefRegistrySimple; -class PrefService; - -namespace base { -class Clock; -class OneShotTimer; -} // namespace base - -namespace chromeos { - -namespace device_sync { - -// Implementation of CryptAuthEnrollmentScheduler. -class CryptAuthEnrollmentSchedulerImpl : public CryptAuthEnrollmentScheduler { - public: - class Factory { - public: - static Factory* Get(); - static void SetFactoryForTesting(Factory* test_factory); - virtual std::unique_ptr<CryptAuthEnrollmentScheduler> BuildInstance( - Delegate* delegate, - PrefService* pref_service, - base::Clock* clock, - std::unique_ptr<base::OneShotTimer> timer); - - private: - static Factory* test_factory_; - }; - - // Registers the prefs used by this class to the given |registry|. - static void RegisterPrefs(PrefRegistrySimple* registry); - - ~CryptAuthEnrollmentSchedulerImpl() override; - - private: - CryptAuthEnrollmentSchedulerImpl(Delegate* delegate, - PrefService* pref_service, - base::Clock* clock, - std::unique_ptr<base::OneShotTimer> timer); - - // CryptAuthEnrollmentScheduler: - void RequestEnrollmentNow() override; - void HandleEnrollmentResult( - const CryptAuthEnrollmentResult& enrollment_result) override; - base::Optional<base::Time> GetLastSuccessfulEnrollmentTime() const override; - base::TimeDelta GetRefreshPeriod() const override; - base::TimeDelta GetTimeToNextEnrollmentRequest() const override; - bool IsWaitingForEnrollmentResult() const override; - size_t GetNumConsecutiveFailures() const override; - - // Calculates the time period between the previous enrollment attempt and the - // next enrollment attempt, taking failures into consideration. - base::TimeDelta CalculateTimeBetweenEnrollmentRequests() const; - - // Starts a new timer that will fire when an enrollment is ready to be - // attempted. - void ScheduleNextEnrollment(); - - // Get the ClientDirective's PolicyReference. If one has not been set, returns - // base::nullopt. - base::Optional<cryptauthv2::PolicyReference> GetPolicyReference() const; - - PrefService* pref_service_; - base::Clock* clock_; - std::unique_ptr<base::OneShotTimer> timer_; - cryptauthv2::ClientDirective client_directive_; - - DISALLOW_COPY_AND_ASSIGN(CryptAuthEnrollmentSchedulerImpl); -}; - -} // namespace device_sync - -} // namespace chromeos - -#endif // CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_ENROLLMENT_SCHEDULER_IMPL_H_
diff --git a/chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl.cc b/chromeos/services/device_sync/persistent_enrollment_scheduler.cc similarity index 78% rename from chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl.cc rename to chromeos/services/device_sync/persistent_enrollment_scheduler.cc index 1f878b2..dae6082 100644 --- a/chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl.cc +++ b/chromeos/services/device_sync/persistent_enrollment_scheduler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl.h" +#include "chromeos/services/device_sync/persistent_enrollment_scheduler.h" #include <algorithm> #include <string> @@ -12,8 +12,6 @@ #include "base/memory/ptr_util.h" #include "base/no_destructor.h" #include "base/optional.h" -#include "base/time/clock.h" -#include "base/timer/timer.h" #include "chromeos/components/multidevice/logging/logging.h" #include "chromeos/services/device_sync/pref_names.h" #include "components/prefs/pref_registry_simple.h" @@ -107,37 +105,38 @@ } // namespace // static -CryptAuthEnrollmentSchedulerImpl::Factory* - CryptAuthEnrollmentSchedulerImpl::Factory::test_factory_ = nullptr; +PersistentEnrollmentScheduler::Factory* + PersistentEnrollmentScheduler::Factory::test_factory_ = nullptr; // static -CryptAuthEnrollmentSchedulerImpl::Factory* -CryptAuthEnrollmentSchedulerImpl::Factory::Get() { +PersistentEnrollmentScheduler::Factory* +PersistentEnrollmentScheduler::Factory::Get() { if (test_factory_) return test_factory_; - static base::NoDestructor<CryptAuthEnrollmentSchedulerImpl::Factory> factory; + static base::NoDestructor<PersistentEnrollmentScheduler::Factory> factory; return factory.get(); } // static -void CryptAuthEnrollmentSchedulerImpl::Factory::SetFactoryForTesting( +void PersistentEnrollmentScheduler::Factory::SetFactoryForTesting( Factory* test_factory) { test_factory_ = test_factory; } std::unique_ptr<CryptAuthEnrollmentScheduler> -CryptAuthEnrollmentSchedulerImpl::Factory::BuildInstance( +PersistentEnrollmentScheduler::Factory::BuildInstance( Delegate* delegate, PrefService* pref_service, base::Clock* clock, - std::unique_ptr<base::OneShotTimer> timer) { - return base::WrapUnique(new CryptAuthEnrollmentSchedulerImpl( - delegate, pref_service, clock, std::move(timer))); + std::unique_ptr<base::OneShotTimer> timer, + scoped_refptr<base::TaskRunner> task_runner) { + return base::WrapUnique(new PersistentEnrollmentScheduler( + delegate, pref_service, clock, std::move(timer), task_runner)); } // static -void CryptAuthEnrollmentSchedulerImpl::RegisterPrefs( +void PersistentEnrollmentScheduler::RegisterPrefs( PrefRegistrySimple* registry) { registry->RegisterStringPref( prefs::kCryptAuthEnrollmentSchedulerClientDirective, std::string()); @@ -151,16 +150,18 @@ prefs::kCryptAuthEnrollmentSchedulerNumConsecutiveFailures, 0); } -CryptAuthEnrollmentSchedulerImpl::CryptAuthEnrollmentSchedulerImpl( +PersistentEnrollmentScheduler::PersistentEnrollmentScheduler( Delegate* delegate, PrefService* pref_service, base::Clock* clock, - std::unique_ptr<base::OneShotTimer> timer) + std::unique_ptr<base::OneShotTimer> timer, + scoped_refptr<base::TaskRunner> task_runner) : CryptAuthEnrollmentScheduler(delegate), pref_service_(pref_service), clock_(clock), timer_(std::move(timer)), - client_directive_(BuildClientDirective(pref_service)) { + client_directive_(BuildClientDirective(pref_service)), + weak_ptr_factory_(this) { DCHECK(pref_service); DCHECK(clock); DCHECK(IsClientDirectiveValid(client_directive_)); @@ -173,17 +174,23 @@ prefs::kCryptAuthEnrollmentSchedulerNumConsecutiveFailures, 1); } - ScheduleNextEnrollment(); + // Schedule the next enrollment as part of a new task. This ensures that the + // delegate can complete its initialization before handling an enrollment + // request. + task_runner->PostTask( + FROM_HERE, + base::BindOnce(&PersistentEnrollmentScheduler::ScheduleNextEnrollment, + weak_ptr_factory_.GetWeakPtr())); } -CryptAuthEnrollmentSchedulerImpl::~CryptAuthEnrollmentSchedulerImpl() = default; +PersistentEnrollmentScheduler::~PersistentEnrollmentScheduler() = default; -void CryptAuthEnrollmentSchedulerImpl::RequestEnrollmentNow() { +void PersistentEnrollmentScheduler::RequestEnrollmentNow() { timer_->Stop(); NotifyEnrollmentRequested(GetPolicyReference()); } -void CryptAuthEnrollmentSchedulerImpl::HandleEnrollmentResult( +void PersistentEnrollmentScheduler::HandleEnrollmentResult( const CryptAuthEnrollmentResult& enrollment_result) { DCHECK(!timer_->IsRunning()); @@ -217,7 +224,7 @@ } base::Optional<base::Time> -CryptAuthEnrollmentSchedulerImpl::GetLastSuccessfulEnrollmentTime() const { +PersistentEnrollmentScheduler::GetLastSuccessfulEnrollmentTime() const { base::Time time = pref_service_->GetTime( prefs::kCryptAuthEnrollmentSchedulerLastSuccessfulEnrollmentTime); if (time.is_null()) @@ -226,31 +233,30 @@ return time; } -base::TimeDelta CryptAuthEnrollmentSchedulerImpl::GetRefreshPeriod() const { +base::TimeDelta PersistentEnrollmentScheduler::GetRefreshPeriod() const { return base::TimeDelta::FromMilliseconds( client_directive_.checkin_delay_millis()); } -base::TimeDelta -CryptAuthEnrollmentSchedulerImpl::GetTimeToNextEnrollmentRequest() const { +base::TimeDelta PersistentEnrollmentScheduler::GetTimeToNextEnrollmentRequest() + const { if (IsWaitingForEnrollmentResult()) return base::TimeDelta::FromMilliseconds(0); return timer_->GetCurrentDelay(); } -bool CryptAuthEnrollmentSchedulerImpl::IsWaitingForEnrollmentResult() const { +bool PersistentEnrollmentScheduler::IsWaitingForEnrollmentResult() const { return !timer_->IsRunning(); } -size_t CryptAuthEnrollmentSchedulerImpl::GetNumConsecutiveFailures() const { +size_t PersistentEnrollmentScheduler::GetNumConsecutiveFailures() const { return pref_service_->GetUint64( prefs::kCryptAuthEnrollmentSchedulerNumConsecutiveFailures); } base::TimeDelta -CryptAuthEnrollmentSchedulerImpl::CalculateTimeBetweenEnrollmentRequests() - const { +PersistentEnrollmentScheduler::CalculateTimeBetweenEnrollmentRequests() const { size_t num_consecutive_failures = GetNumConsecutiveFailures(); if (num_consecutive_failures == 0) return GetRefreshPeriod(); @@ -262,7 +268,7 @@ client_directive_.retry_period_millis()); } -void CryptAuthEnrollmentSchedulerImpl::ScheduleNextEnrollment() { +void PersistentEnrollmentScheduler::ScheduleNextEnrollment() { DCHECK(!timer_->IsRunning()); base::Time last_attempt_time = pref_service_->GetTime( @@ -279,13 +285,12 @@ timer_->Start( FROM_HERE, time_until_next_request, - base::BindOnce( - &CryptAuthEnrollmentSchedulerImpl::NotifyEnrollmentRequested, - base::Unretained(this), GetPolicyReference())); + base::BindOnce(&PersistentEnrollmentScheduler::NotifyEnrollmentRequested, + base::Unretained(this), GetPolicyReference())); } base::Optional<cryptauthv2::PolicyReference> -CryptAuthEnrollmentSchedulerImpl::GetPolicyReference() const { +PersistentEnrollmentScheduler::GetPolicyReference() const { if (client_directive_.has_policy_reference()) return client_directive_.policy_reference();
diff --git a/chromeos/services/device_sync/persistent_enrollment_scheduler.h b/chromeos/services/device_sync/persistent_enrollment_scheduler.h new file mode 100644 index 0000000..3ea6b36 --- /dev/null +++ b/chromeos/services/device_sync/persistent_enrollment_scheduler.h
@@ -0,0 +1,98 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_DEVICE_SYNC_PERSISTENT_ENROLLMENT_SCHEDULER_H_ +#define CHROMEOS_SERVICES_DEVICE_SYNC_PERSISTENT_ENROLLMENT_SCHEDULER_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/default_clock.h" +#include "base/timer/timer.h" +#include "chromeos/services/device_sync/cryptauth_enrollment_scheduler.h" +#include "chromeos/services/device_sync/proto/cryptauth_directive.pb.h" + +class PrefRegistrySimple; +class PrefService; + +namespace chromeos { + +namespace device_sync { + +// CryptAuthEnrollmentScheduler implementation which stores scheduling metadata +// persistently so that the enrollment schedule is saved across device reboots. +// If this class is instantiated before at least one enrollment has been +// completed successfully, it requests enrollment immediately. Once enrollment +// has been completed successfully, this class schedules the next enrollment +// attempt at a time provided by the server via a ClientDirective proto. +class PersistentEnrollmentScheduler : public CryptAuthEnrollmentScheduler { + public: + class Factory { + public: + static Factory* Get(); + static void SetFactoryForTesting(Factory* test_factory); + virtual std::unique_ptr<CryptAuthEnrollmentScheduler> BuildInstance( + Delegate* delegate, + PrefService* pref_service, + base::Clock* clock = base::DefaultClock::GetInstance(), + std::unique_ptr<base::OneShotTimer> timer = + std::make_unique<base::OneShotTimer>(), + scoped_refptr<base::TaskRunner> task_runner = + base::ThreadTaskRunnerHandle::Get()); + + private: + static Factory* test_factory_; + }; + + // Registers the prefs used by this class to the given |registry|. + static void RegisterPrefs(PrefRegistrySimple* registry); + + ~PersistentEnrollmentScheduler() override; + + private: + PersistentEnrollmentScheduler(Delegate* delegate, + PrefService* pref_service, + base::Clock* clock, + std::unique_ptr<base::OneShotTimer> timer, + scoped_refptr<base::TaskRunner> task_runner); + + // CryptAuthEnrollmentScheduler: + void RequestEnrollmentNow() override; + void HandleEnrollmentResult( + const CryptAuthEnrollmentResult& enrollment_result) override; + base::Optional<base::Time> GetLastSuccessfulEnrollmentTime() const override; + base::TimeDelta GetRefreshPeriod() const override; + base::TimeDelta GetTimeToNextEnrollmentRequest() const override; + bool IsWaitingForEnrollmentResult() const override; + size_t GetNumConsecutiveFailures() const override; + + // Calculates the time period between the previous enrollment attempt and the + // next enrollment attempt, taking failures into consideration. + base::TimeDelta CalculateTimeBetweenEnrollmentRequests() const; + + // Starts a new timer that will fire when an enrollment is ready to be + // attempted. + void ScheduleNextEnrollment(); + + // Get the ClientDirective's PolicyReference. If one has not been set, returns + // base::nullopt. + base::Optional<cryptauthv2::PolicyReference> GetPolicyReference() const; + + PrefService* pref_service_; + base::Clock* clock_; + std::unique_ptr<base::OneShotTimer> timer_; + cryptauthv2::ClientDirective client_directive_; + base::WeakPtrFactory<PersistentEnrollmentScheduler> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PersistentEnrollmentScheduler); +}; + +} // namespace device_sync + +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_DEVICE_SYNC_PERSISTENT_ENROLLMENT_SCHEDULER_H_
diff --git a/chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl_unittest.cc b/chromeos/services/device_sync/persistent_enrollment_scheduler_unittest.cc similarity index 91% rename from chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl_unittest.cc rename to chromeos/services/device_sync/persistent_enrollment_scheduler_unittest.cc index c81f885..7df7acb 100644 --- a/chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl_unittest.cc +++ b/chromeos/services/device_sync/persistent_enrollment_scheduler_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/services/device_sync/cryptauth_enrollment_scheduler_impl.h" +#include "chromeos/services/device_sync/persistent_enrollment_scheduler.h" #include <memory> #include <string> @@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/test/simple_test_clock.h" +#include "base/test/test_simple_task_runner.h" #include "base/timer/mock_timer.h" #include "chromeos/services/device_sync/pref_names.h" #include "components/prefs/testing_pref_service.h" @@ -93,9 +94,9 @@ } // namespace -class CryptAuthEnrollmentSchedulerImplTest : public testing::Test { +class DeviceSyncPersistentEnrollmentSchedulerTest : public testing::Test { protected: - CryptAuthEnrollmentSchedulerImplTest() { + DeviceSyncPersistentEnrollmentSchedulerTest() { fake_client_directive_.mutable_policy_reference()->set_name( kFakePolicyName); fake_client_directive_.mutable_policy_reference()->set_version( @@ -107,10 +108,10 @@ fake_client_directive_.set_retry_attempts(kFakeMaxImmediateRetries); }; - ~CryptAuthEnrollmentSchedulerImplTest() override = default; + ~DeviceSyncPersistentEnrollmentSchedulerTest() override = default; void SetUp() override { - CryptAuthEnrollmentSchedulerImpl::RegisterPrefs(pref_service_.registry()); + PersistentEnrollmentScheduler::RegisterPrefs(pref_service_.registry()); } void CreateScheduler() { @@ -119,10 +120,14 @@ auto mock_timer = std::make_unique<base::MockOneShotTimer>(); mock_timer_ = mock_timer.get(); - scheduler_ = - CryptAuthEnrollmentSchedulerImpl::Factory::Get()->BuildInstance( - &fake_delegate_, &pref_service_, &test_clock_, - std::move(mock_timer)); + + auto test_task_runner = base::MakeRefCounted<base::TestSimpleTaskRunner>(); + + scheduler_ = PersistentEnrollmentScheduler::Factory::Get()->BuildInstance( + &fake_delegate_, &pref_service_, &test_clock_, std::move(mock_timer), + test_task_runner); + + test_task_runner->RunUntilIdle(); } FakeDelegate* delegate() { return &fake_delegate_; } @@ -156,10 +161,11 @@ std::unique_ptr<CryptAuthEnrollmentScheduler> scheduler_; - DISALLOW_COPY_AND_ASSIGN(CryptAuthEnrollmentSchedulerImplTest); + DISALLOW_COPY_AND_ASSIGN(DeviceSyncPersistentEnrollmentSchedulerTest); }; -TEST_F(CryptAuthEnrollmentSchedulerImplTest, HandleSuccessfulEnrollmentResult) { +TEST_F(DeviceSyncPersistentEnrollmentSchedulerTest, + HandleSuccessfulEnrollmentResult) { clock()->SetNow(kFakeTimeNow); CreateScheduler(); @@ -200,7 +206,7 @@ 2, fake_client_directive().policy_reference()); } -TEST_F(CryptAuthEnrollmentSchedulerImplTest, +TEST_F(DeviceSyncPersistentEnrollmentSchedulerTest, NotDueForRefresh_RequestImmediateEnrollment) { pref_service()->SetString( prefs::kCryptAuthEnrollmentSchedulerClientDirective, @@ -234,7 +240,8 @@ EXPECT_EQ(1u, delegate()->policy_reference_history().size()); } -TEST_F(CryptAuthEnrollmentSchedulerImplTest, DueForRefreshBeforeConstructed) { +TEST_F(DeviceSyncPersistentEnrollmentSchedulerTest, + DueForRefreshBeforeConstructed) { pref_service()->SetString( prefs::kCryptAuthEnrollmentSchedulerClientDirective, ClientDirectiveToPrefString(fake_client_directive())); @@ -255,7 +262,7 @@ scheduler()->GetTimeToNextEnrollmentRequest()); } -TEST_F(CryptAuthEnrollmentSchedulerImplTest, HandleFailures) { +TEST_F(DeviceSyncPersistentEnrollmentSchedulerTest, HandleFailures) { clock()->SetNow(kFakeTimeNow); CreateScheduler(); @@ -325,7 +332,7 @@ VerifyLastEnrollmentAttemptTimePref(kFakeTimeLaterAfterRetryPeriod); } -TEST_F(CryptAuthEnrollmentSchedulerImplTest, HandlePersistedFailures) { +TEST_F(DeviceSyncPersistentEnrollmentSchedulerTest, HandlePersistedFailures) { // Seed the preferences to simulate the previous scheduler using all of its // immediate retry attempts and making 10 periodic retry attempts. pref_service()->SetString(
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc index b7ab45f..8eb5d22 100644 --- a/chromeos/settings/cros_settings_names.cc +++ b/chromeos/settings/cros_settings_names.cc
@@ -268,10 +268,6 @@ const char kDeviceLoginScreenAppInstallList[] = "cros.device.login_screen_app_install_list"; -// A string pref storing the url and cryptographic hash of the image in JSON -// format allowed to set a device-level wallpaper before any user logs in. -const char kDeviceWallpaperImage[] = "cros.device_wallpaper_image"; - // A list pref specifying the locales allowed on the login screen. Currently // only the first value is used, as the single locale allowed on the login // screen.
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h index 583cc24..c9caaf4b 100644 --- a/chromeos/settings/cros_settings_names.h +++ b/chromeos/settings/cros_settings_names.h
@@ -164,8 +164,6 @@ COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kDeviceLoginScreenAppInstallList[]; -COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kDeviceWallpaperImage[]; - COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kDeviceLoginScreenLocales[]; COMPONENT_EXPORT(CHROMEOS_SETTINGS)
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index 9e69040..bfbd58c 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -81,6 +81,8 @@ "details.h", "element_area.cc", "element_area.h", + "features.cc", + "features.h", "metrics.cc", "metrics.h", "payment_information.h",
diff --git a/components/autofill_assistant/browser/features.cc b/components/autofill_assistant/browser/features.cc new file mode 100644 index 0000000..845b393 --- /dev/null +++ b/components/autofill_assistant/browser/features.cc
@@ -0,0 +1,20 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill_assistant/browser/features.h" + +#include "base/feature_list.h" + +namespace autofill_assistant { +namespace features { + +const base::Feature kAutofillAssistant{"AutofillAssistant", + base::FEATURE_ENABLED_BY_DEFAULT}; + +// Controls whether to query backend service to start any assisted actions. +const base::Feature kAutofillAssistantChromeEntry{ + "AutofillAssistantChromeEntry", base::FEATURE_DISABLED_BY_DEFAULT}; + +} // namespace features +} // namespace autofill_assistant \ No newline at end of file
diff --git a/components/autofill_assistant/browser/features.h b/components/autofill_assistant/browser/features.h new file mode 100644 index 0000000..eedd49e --- /dev/null +++ b/components/autofill_assistant/browser/features.h
@@ -0,0 +1,21 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_FEATURES_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_FEATURES_H_ + +namespace base { +struct Feature; +} + +namespace autofill_assistant { +namespace features { +// All features in alphabetical order. +extern const base::Feature kAutofillAssistant; +extern const base::Feature kAutofillAssistantChromeEntry; + +} // namespace features +} // namespace autofill_assistant + +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_FEATURES_H_
diff --git a/components/crash/android/java/src/org/chromium/components/crash/browser/PackagePaths.java b/components/crash/android/java/src/org/chromium/components/crash/browser/PackagePaths.java index d43b244..9b621c48 100644 --- a/components/crash/android/java/src/org/chromium/components/crash/browser/PackagePaths.java +++ b/components/crash/android/java/src/org/chromium/components/crash/browser/PackagePaths.java
@@ -53,13 +53,17 @@ } List<String> libPaths = new ArrayList<>(10); - libPaths.add(pi.applicationInfo.nativeLibraryDir); + File parent = new File(pi.applicationInfo.nativeLibraryDir).getParentFile(); + if (parent != null) { + libPaths.add(new File(parent, arch).getPath()); + } for (String zip : zipPaths) { if (zip.endsWith(".apk")) { libPaths.add(zip + "!/lib/" + arch); } } libPaths.add(System.getProperty("java.library.path")); + libPaths.add(pi.applicationInfo.nativeLibraryDir); return new String[] {TextUtils.join(File.pathSeparator, zipPaths), TextUtils.join(File.pathSeparator, libPaths)};
diff --git a/components/gwp_asan/client/guarded_page_allocator.cc b/components/gwp_asan/client/guarded_page_allocator.cc index a50d076..798583809 100644 --- a/components/gwp_asan/client/guarded_page_allocator.cc +++ b/components/gwp_asan/client/guarded_page_allocator.cc
@@ -17,7 +17,6 @@ #include "components/crash/core/common/crash_key.h" #include "components/gwp_asan/common/allocator_state.h" #include "components/gwp_asan/common/crash_key_name.h" -#include "components/gwp_asan/common/pack_stack_trace.h" namespace gwp_asan { namespace internal { @@ -175,13 +174,10 @@ slots_[slot].alloc_size = size; slots_[slot].alloc_ptr = reinterpret_cast<uintptr_t>(ptr); - void* trace[AllocatorState::kMaxStackFrames]; - size_t len = - base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames); - slots_[slot].alloc.trace_len = Pack(reinterpret_cast<uintptr_t*>(trace), len, - slots_[slot].alloc.packed_trace, - sizeof(slots_[slot].alloc.packed_trace)); slots_[slot].alloc.tid = base::PlatformThread::CurrentId(); + slots_[slot].alloc.trace_len = base::debug::CollectStackTrace( + reinterpret_cast<void**>(&slots_[slot].alloc.trace), + AllocatorState::kMaxStackFrames); slots_[slot].alloc.trace_collected = true; slots_[slot].dealloc.tid = base::kInvalidThreadId; @@ -191,14 +187,10 @@ } void GuardedPageAllocator::RecordDeallocationInSlot(size_t slot) { - void* trace[AllocatorState::kMaxStackFrames]; - size_t len = - base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames); - slots_[slot].dealloc.trace_len = - Pack(reinterpret_cast<uintptr_t*>(trace), len, - slots_[slot].dealloc.packed_trace, - sizeof(slots_[slot].dealloc.packed_trace)); slots_[slot].dealloc.tid = base::PlatformThread::CurrentId(); + slots_[slot].dealloc.trace_len = base::debug::CollectStackTrace( + reinterpret_cast<void**>(&slots_[slot].dealloc.trace), + AllocatorState::kMaxStackFrames); slots_[slot].dealloc.trace_collected = true; }
diff --git a/components/gwp_asan/common/allocator_state.cc b/components/gwp_asan/common/allocator_state.cc index 8aa839f..ccd2a7d 100644 --- a/components/gwp_asan/common/allocator_state.cc +++ b/components/gwp_asan/common/allocator_state.cc
@@ -15,7 +15,6 @@ // TODO: Delete out-of-line constexpr defininitons once C++17 is in use. constexpr size_t AllocatorState::kGpaMaxPages; constexpr size_t AllocatorState::kMaxStackFrames; -constexpr size_t AllocatorState::kMaxPackedTraceLength; AllocatorState::AllocatorState() {}
diff --git a/components/gwp_asan/common/allocator_state.h b/components/gwp_asan/common/allocator_state.h index 2f1f88b..d393749 100644 --- a/components/gwp_asan/common/allocator_state.h +++ b/components/gwp_asan/common/allocator_state.h
@@ -40,9 +40,6 @@ static constexpr size_t kGpaMaxPages = 256; // Maximum number of stack trace frames to collect. static constexpr size_t kMaxStackFrames = 60; - // Number of bytes to allocate for packed stack traces. This can hold - // approximately kMaxStackFrames under normal conditions. - static constexpr size_t kMaxPackedTraceLength = 200; enum class ErrorType { kUseAfterFree = 0, @@ -68,9 +65,9 @@ // (De)allocation thread id or base::kInvalidThreadId if no (de)allocation // occurred. base::PlatformThreadId tid = base::kInvalidThreadId; - // Packed stack trace. - uint8_t packed_trace[kMaxPackedTraceLength]; - // Length used to encode the packed stack trace. + // Stack trace contents. + uintptr_t trace[kMaxStackFrames]; + // Stack trace length. size_t trace_len = 0; // Whether a stack trace has been collected for this (de)allocation. bool trace_collected = false;
diff --git a/components/gwp_asan/common/pack_stack_trace_differential_fuzzer.cc b/components/gwp_asan/common/pack_stack_trace_differential_fuzzer.cc index f964385..e2a1da8 100644 --- a/components/gwp_asan/common/pack_stack_trace_differential_fuzzer.cc +++ b/components/gwp_asan/common/pack_stack_trace_differential_fuzzer.cc
@@ -6,6 +6,7 @@ #include <string.h> #include <algorithm> +#include <memory> // Tests that whatever we give to Pack() is the same as what comes out of // Unpack(). @@ -24,16 +25,16 @@ // We don't need a buffer large than Size*10 as the longest variable length // encoding of a 64-bit integer is 10 bytes long.) size_t array_size = std::min(Size * 10, packed_max_size); - uint8_t packed[array_size]; + std::unique_ptr<uint8_t[]> packed(new uint8_t[array_size]); size_t packed_size = gwp_asan::internal::Pack(reinterpret_cast<const uintptr_t*>(Data), - entries, packed, packed_max_size); - if (packed_size > sizeof(packed)) + entries, packed.get(), packed_max_size); + if (packed_size > array_size) __builtin_trap(); - uintptr_t unpacked[std::min(unpacked_max_size, Size)]; + uintptr_t unpacked[std::min(unpacked_max_size, entries)]; size_t unpacked_size = gwp_asan::internal::Unpack( - packed, packed_size, unpacked, unpacked_max_size); + packed.get(), packed_size, unpacked, unpacked_max_size); // We can only be sure there was enough room to pack the entire input when // packed_max_size was larger than Size*10. if (packed_max_size > array_size &&
diff --git a/components/gwp_asan/crash_handler/crash_analyzer.cc b/components/gwp_asan/crash_handler/crash_analyzer.cc index 95f1223..04e70d1 100644 --- a/components/gwp_asan/crash_handler/crash_analyzer.cc +++ b/components/gwp_asan/crash_handler/crash_analyzer.cc
@@ -14,7 +14,6 @@ #include "build/build_config.h" #include "components/gwp_asan/common/allocator_state.h" #include "components/gwp_asan/common/crash_key_name.h" -#include "components/gwp_asan/common/pack_stack_trace.h" #include "components/gwp_asan/crash_handler/crash.pb.h" #include "third_party/crashpad/crashpad/client/annotation.h" #include "third_party/crashpad/crashpad/snapshot/cpu_context.h" @@ -159,21 +158,12 @@ return; } - uintptr_t unpacked_stack_trace[AllocatorState::kMaxPackedTraceLength]; - size_t unpacked_len = - Unpack(slot_info.packed_trace, slot_info.trace_len, unpacked_stack_trace, - AllocatorState::kMaxPackedTraceLength); - if (!unpacked_len) { - DLOG(ERROR) << "Failed to unpack stack trace."; - return; - } - - // On 32-bit platforms we can't copy directly into + // On 32-bit platforms we can't copy directly to // proto_info->mutable_stack_trace()->mutable_data(). - proto_info->mutable_stack_trace()->Resize(unpacked_len, 0); + proto_info->mutable_stack_trace()->Resize(slot_info.trace_len, 0); uint64_t* output = proto_info->mutable_stack_trace()->mutable_data(); - for (size_t i = 0; i < unpacked_len; i++) - output[i] = unpacked_stack_trace[i]; + for (size_t i = 0; i < slot_info.trace_len; i++) + output[i] = slot_info.trace[i]; } } // namespace internal
diff --git a/components/heap_profiling/heap_profiling_test_shim.cc b/components/heap_profiling/heap_profiling_test_shim.cc index ca6efeb9..bae0523 100644 --- a/components/heap_profiling/heap_profiling_test_shim.cc +++ b/components/heap_profiling/heap_profiling_test_shim.cc
@@ -19,8 +19,7 @@ } HeapProfilingTestShim::HeapProfilingTestShim(JNIEnv* env, jobject obj) {} - -HeapProfilingTestShim::~HeapProfilingTestShim() {} +HeapProfilingTestShim::~HeapProfilingTestShim() = default; void HeapProfilingTestShim::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { @@ -33,6 +32,7 @@ const base::android::JavaParamRef<jstring>& mode, jboolean dynamically_start_profiling, const base::android::JavaParamRef<jstring>& stack_mode, + jboolean stream_samples, jboolean should_sample, jboolean sample_everything) { heap_profiling::TestDriver driver; @@ -42,6 +42,7 @@ options.stack_mode = heap_profiling::ConvertStringToStackMode( base::android::ConvertJavaStringToUTF8(stack_mode)); options.profiling_already_started = !dynamically_start_profiling; + options.stream_samples = stream_samples; options.should_sample = should_sample; options.sample_everything = sample_everything; return driver.RunTest(options);
diff --git a/components/heap_profiling/heap_profiling_test_shim.h b/components/heap_profiling/heap_profiling_test_shim.h index 134d548..558933c 100644 --- a/components/heap_profiling/heap_profiling_test_shim.h +++ b/components/heap_profiling/heap_profiling_test_shim.h
@@ -23,6 +23,7 @@ const base::android::JavaParamRef<jstring>& mode, jboolean dynamically_start_profiling, const base::android::JavaParamRef<jstring>& stack_mode, + jboolean stream_samples, jboolean should_sample, jboolean sample_everything);
diff --git a/components/heap_profiling/javatests/src/org/chromium/components/heap_profiling/HeapProfilingTestShim.java b/components/heap_profiling/javatests/src/org/chromium/components/heap_profiling/HeapProfilingTestShim.java index f55ceaf8..c7f788e 100644 --- a/components/heap_profiling/javatests/src/org/chromium/components/heap_profiling/HeapProfilingTestShim.java +++ b/components/heap_profiling/javatests/src/org/chromium/components/heap_profiling/HeapProfilingTestShim.java
@@ -23,9 +23,9 @@ * rather than native stacks. */ public boolean runTestForMode(String mode, boolean dynamicallyStartProfiling, String stackMode, - boolean shouldSample, boolean sampleEverything) { + boolean streamSamples, boolean shouldSample, boolean sampleEverything) { return nativeRunTestForMode(mNativeHeapProfilingTestShim, mode, dynamicallyStartProfiling, - stackMode, shouldSample, sampleEverything); + stackMode, streamSamples, shouldSample, sampleEverything); } /** @@ -43,6 +43,6 @@ private native long nativeInit(); private native void nativeDestroy(long nativeHeapProfilingTestShim); private native boolean nativeRunTestForMode(long nativeHeapProfilingTestShim, String mode, - boolean dynamicallyStartProfiling, String stackMode, boolean shouldSample, - boolean sampleEverything); + boolean dynamicallyStartProfiling, String stackMode, boolean streamSamples, + boolean shouldSample, boolean sampleEverything); }
diff --git a/components/heap_profiling/supervisor.cc b/components/heap_profiling/supervisor.cc index 70afb5f..987902b3 100644 --- a/components/heap_profiling/supervisor.cc +++ b/components/heap_profiling/supervisor.cc
@@ -60,24 +60,27 @@ void Supervisor::Start(content::ServiceManagerConnection* connection, base::OnceClosure closure) { + // TODO(alph): Obtain stream_samples from the command line / Finch. Start(connection, GetModeForStartup(), GetStackModeForStartup(), - GetSamplingRateForStartup(), std::move(closure)); + true /* stream_samples */, GetSamplingRateForStartup(), + std::move(closure)); } void Supervisor::Start(content::ServiceManagerConnection* connection, Mode mode, mojom::StackMode stack_mode, + bool stream_samples, uint32_t sampling_rate, base::OnceClosure closure) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); DCHECK(!started_); base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO}) - ->PostTask(FROM_HERE, - base::BindOnce(&Supervisor::StartServiceOnIOThread, - base::Unretained(this), - connection->GetConnector()->Clone(), mode, - stack_mode, sampling_rate, std::move(closure))); + ->PostTask(FROM_HERE, base::BindOnce(&Supervisor::StartServiceOnIOThread, + base::Unretained(this), + connection->GetConnector()->Clone(), + mode, stack_mode, stream_samples, + sampling_rate, std::move(closure))); } Mode Supervisor::GetMode() { @@ -180,12 +183,13 @@ std::unique_ptr<service_manager::Connector> connector, Mode mode, mojom::StackMode stack_mode, + bool stream_samples, uint32_t sampling_rate, base::OnceClosure closure) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - controller_.reset( - new Controller(std::move(connector), stack_mode, sampling_rate)); + controller_.reset(new Controller(std::move(connector), stack_mode, + stream_samples, sampling_rate)); base::WeakPtr<Controller> controller_weak_ptr = controller_->GetWeakPtr(); base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::UI})
diff --git a/components/heap_profiling/supervisor.h b/components/heap_profiling/supervisor.h index b4b8515..592b72e 100644 --- a/components/heap_profiling/supervisor.h +++ b/components/heap_profiling/supervisor.h
@@ -72,6 +72,7 @@ void Start(content::ServiceManagerConnection* connection, Mode mode, mojom::StackMode stack_mode, + bool stream_samples, uint32_t sampling_rate, base::OnceClosure callback); @@ -116,6 +117,7 @@ std::unique_ptr<service_manager::Connector> connector, Mode mode, mojom::StackMode stack_mode, + bool stream_samples, uint32_t sampling_rate, base::OnceClosure callback);
diff --git a/components/heap_profiling/test_driver.cc b/components/heap_profiling/test_driver.cc index 7a6decc..6799497c 100644 --- a/components/heap_profiling/test_driver.cc +++ b/components/heap_profiling/test_driver.cc
@@ -559,7 +559,7 @@ base::WaitableEvent::InitialState::NOT_SIGNALED) { partition_allocator_.init(); } -TestDriver::~TestDriver() {} +TestDriver::~TestDriver() = default; bool TestDriver::RunTest(const Options& options) { options_ = options; @@ -723,8 +723,8 @@ ? (options_.sample_everything ? 2 : kSampleRate) : 1; Supervisor::GetInstance()->Start(connection, options_.mode, - options_.stack_mode, sampling_rate, - std::move(start_callback)); + options_.stack_mode, options_.stream_samples, + sampling_rate, std::move(start_callback)); return true; } @@ -776,8 +776,8 @@ ? (options_.sample_everything ? 2 : kSampleRate) : 1; Supervisor::GetInstance()->Start(connection, options_.mode, - options_.stack_mode, sampling_rate, - std::move(start_callback)); + options_.stack_mode, options_.stream_samples, + sampling_rate, std::move(start_callback)); run_loop->Run();
diff --git a/components/heap_profiling/test_driver.h b/components/heap_profiling/test_driver.h index f897c672..03e447b 100644 --- a/components/heap_profiling/test_driver.h +++ b/components/heap_profiling/test_driver.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted_memory.h" #include "base/synchronization/waitable_event.h" +#include "components/services/heap_profiling/public/cpp/settings.h" #include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h" namespace base { @@ -19,8 +20,6 @@ namespace heap_profiling { -enum class Mode; - // This class runs tests for the Heap Profiling Service, a cross-platform, // multi-process component. // @@ -45,23 +44,28 @@ public: struct Options { // The profiling mode to test. - Mode mode; + Mode mode = Mode::kBrowser; // The stack profiling mode to test. - mojom::StackMode stack_mode; + mojom::StackMode stack_mode = mojom::StackMode::NATIVE_WITHOUT_THREAD_NAMES; + + // Whether the client should stream samples as they are collected through + // the provided pipe. When false the samples are accumulated on the client + // side and can be retrieved later. + bool stream_samples = true; // Whether the caller has already started profiling with the given mode. // When false, the test driver is responsible for starting profiling. - bool profiling_already_started; + bool profiling_already_started = false; // Whether to test sampling. - bool should_sample; + bool should_sample = true; // When set to true, the internal sampling_rate is set to 2. While this // doesn't record all allocations, it should record all test allocations // made in this file with exponentially high probability. // When set to false, the internal sampling rate is set to 10000. - bool sample_everything; + bool sample_everything = false; }; TestDriver();
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index b3ff4f5..7a2f65a6 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -134,7 +134,7 @@ // Feature used to enable various experiments on keyword mode, UI and // suggestions. -const base::Feature kExperimentalKeywordMode{"ExperimentalKeywordMode", +const base::Feature kExperimentalKeywordMode{"OmniboxExperimentalKeywordMode", base::FEATURE_DISABLED_BY_DEFAULT}; // Feature used to enable Pedal suggestions as either in-suggestion side button
diff --git a/components/omnibox/browser/vector_icons/drive_sheets.icon b/components/omnibox/browser/vector_icons/drive_sheets.icon index 64e369d..4ca6f953 100644 --- a/components/omnibox/browser/vector_icons/drive_sheets.icon +++ b/components/omnibox/browser/vector_icons/drive_sheets.icon
@@ -2,29 +2,32 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 18, +CANVAS_DIMENSIONS, 16, PATH_COLOR_ARGB, 0xFF, 0x0F, 0x9D, 0x58, -MOVE_TO, 16, 0, +MOVE_TO, 14, 0, H_LINE_TO, 2, -CUBIC_TO, 0.9f, 0, 0.01f, 0.9f, 0.01f, 2, -LINE_TO, 0, 5, -R_V_LINE_TO, 11, +CUBIC_TO, 0.9f, 0, 0, 0.9f, 0, 2, +R_V_LINE_TO, 12, R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2, -R_H_LINE_TO, 14, +R_H_LINE_TO, 12, R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2, V_LINE_TO, 2, -CUBIC_TO, 18, 0.9f, 17.1f, 0, 16, 0, +R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2, CLOSE, -R_MOVE_TO, 0, 8, -H_LINE_TO, 8, -R_V_LINE_TO, 8, -H_LINE_TO, 6, -V_LINE_TO, 8, +// The white cross is drawn in one horizontal and two vertical sections to +// avoid inverting the color in the intersection. +MOVE_TO, 2, 5, +H_LINE_TO, 14, +R_V_LINE_TO, 2, H_LINE_TO, 2, -V_LINE_TO, 6, -H_LINE_TO, 6, -V_LINE_TO, 2, + +MOVE_TO, 5, 2, R_H_LINE_TO, 2, -R_V_LINE_TO, 4, -R_H_LINE_TO, 8, +V_LINE_TO, 5, +R_H_LINE_TO, -2, + +MOVE_TO, 5, 7, +R_H_LINE_TO, 2, +V_LINE_TO, 14, +R_H_LINE_TO, -2, CLOSE
diff --git a/components/omnibox/browser/vector_icons/drive_slides.icon b/components/omnibox/browser/vector_icons/drive_slides.icon index 24c6176..4ee7ffec 100644 --- a/components/omnibox/browser/vector_icons/drive_slides.icon +++ b/components/omnibox/browser/vector_icons/drive_slides.icon
@@ -2,20 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 18, +CANVAS_DIMENSIONS, 16, PATH_COLOR_ARGB, 0xFF, 0xFC, 0xB7, 0x00, -MOVE_TO, 16, 0, -R_H_LINE_TO, -14, +MOVE_TO, 14, 0, +H_LINE_TO, 2, CUBIC_TO, 0.9f, 0, 0, 0.9f, 0, 2, -R_V_LINE_TO, 14, +R_V_LINE_TO, 12, R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2, -R_H_LINE_TO, 14, +R_H_LINE_TO, 12, R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2, V_LINE_TO, 2, R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2, CLOSE, -R_MOVE_TO, 0, 13, -R_H_LINE_TO, -14, -V_LINE_TO, 5, -R_H_LINE_TO, 14, +// Padding for the white 'content' area is {4, 2, 4, 2} +MOVE_TO, 2, 4, +H_LINE_TO, 14, +V_LINE_TO, 12, +H_LINE_TO, 2, CLOSE
diff --git a/components/payments/content/content_payment_request_delegate.h b/components/payments/content/content_payment_request_delegate.h index efa368a..ac5c967 100644 --- a/components/payments/content/content_payment_request_delegate.h +++ b/components/payments/content/content_payment_request_delegate.h
@@ -36,6 +36,10 @@ virtual void EmbedPaymentHandlerWindow( const GURL& url, PaymentHandlerOpenWindowCallback callback) = 0; + + // Returns whether user interaction is enabled. (False when showing a + // spinner.) + virtual bool IsInteractive() const = 0; }; } // namespace payments
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc index 967a875e..6b853dc 100644 --- a/components/payments/content/payment_request.cc +++ b/components/payments/content/payment_request.cc
@@ -456,6 +456,13 @@ return; } + // If currently interactive, show the processing spinner. Autofill payment + // instruments request a CVC, so they are always interactive at this point. A + // payment handler may elect to be non-interactive by not showing a + // confirmation page to the user. + if (delegate_->IsInteractive()) + delegate_->ShowProcessingSpinner(); + client_->OnPaymentResponse(std::move(response)); }
diff --git a/components/payments/content/test_content_payment_request_delegate.cc b/components/payments/content/test_content_payment_request_delegate.cc index 2b76cd4..aaeabd5 100644 --- a/components/payments/content/test_content_payment_request_delegate.cc +++ b/components/payments/content/test_content_payment_request_delegate.cc
@@ -103,6 +103,10 @@ const GURL& url, PaymentHandlerOpenWindowCallback callback) {} +bool TestContentPaymentRequestDelegate::IsInteractive() const { + return true; +} + autofill::TestAddressNormalizer* TestContentPaymentRequestDelegate::test_address_normalizer() { return core_delegate_.test_address_normalizer();
diff --git a/components/payments/content/test_content_payment_request_delegate.h b/components/payments/content/test_content_payment_request_delegate.h index dae7dbc..10ee9d93 100644 --- a/components/payments/content/test_content_payment_request_delegate.h +++ b/components/payments/content/test_content_payment_request_delegate.h
@@ -48,6 +48,7 @@ void EmbedPaymentHandlerWindow( const GURL& url, PaymentHandlerOpenWindowCallback callback) override; + bool IsInteractive() const override; autofill::TestAddressNormalizer* test_address_normalizer(); void DelayFullCardRequestCompletion();
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 74f903b4..28f9fb93 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -7545,6 +7545,8 @@ 'tags': [], 'desc': '''The Safe Browsing service shows a warning page when users navigate to sites that are flagged as potentially malicious. Enabling this setting prevents users from proceeding anyway from the warning page to the malicious site. + This policy only prevents users from proceeding on Safe Browsing warnings (e.g. malware and phishing) not for SSL certificate related issues like invalid or expired certificates. + If this setting is disabled or not configured then users can choose to proceed to the flagged site after being shown the warning. See https://developers.google.com/safe-browsing for more info on Safe Browsing.''',
diff --git a/components/services/heap_profiling/connection_manager.cc b/components/services/heap_profiling/connection_manager.cc index 2a115e1..9fee87a 100644 --- a/components/services/heap_profiling/connection_manager.cc +++ b/components/services/heap_profiling/connection_manager.cc
@@ -5,6 +5,7 @@ #include "components/services/heap_profiling/connection_manager.h" #include "base/bind.h" +#include "base/json/string_escape.h" #include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_current.h" #include "base/metrics/histogram_macros.h" @@ -74,13 +75,15 @@ scoped_refptr<ReceiverPipe> p, mojom::ProcessType process_type, uint32_t sampling_rate, - mojom::StackMode stack_mode) + mojom::StackMode stack_mode, + bool stream_samples) : thread(base::StringPrintf("Sender %lld thread", static_cast<long long>(pid))), client(std::move(client)), pipe(p), process_type(process_type), stack_mode(stack_mode), + stream_samples(stream_samples), tracker(std::move(complete_cb), backtrace_storage), sampling_rate(sampling_rate) {} @@ -103,6 +106,7 @@ scoped_refptr<StreamParser> parser; mojom::ProcessType process_type; mojom::StackMode stack_mode; + bool stream_samples; // Danger: This lives on the |thread| member above. The connection manager // lives on the I/O thread, so accesses to the variable must be synchronized. @@ -159,7 +163,8 @@ auto connection = std::make_unique<Connection>( std::move(complete_cb), &backtrace_storage_, pid, std::move(client), - new_pipe, process_type, params->sampling_rate, params->stack_mode); + new_pipe, process_type, params->sampling_rate, params->stack_mode, + params->stream_samples); base::Thread::Options options; options.message_loop_type = base::MessageLoop::TYPE_IO; @@ -254,6 +259,13 @@ for (auto& it : connections_) { base::ProcessId pid = it.first; Connection* connection = it.second.get(); + if (!connection->stream_samples) { + connection->client->RetrieveHeapProfile(base::BindOnce( + &ConnectionManager::HeapProfileRetrieved, weak_factory_.GetWeakPtr(), + tracking, pid, connection->process_type, keep_small_allocations, + strip_path_from_mapped_files, connection->sampling_rate)); + continue; + } int barrier_id = next_barrier_id_++; // Register for callback before requesting the dump so we don't race for the @@ -270,6 +282,66 @@ } } +void ConnectionManager::HeapProfileRetrieved( + scoped_refptr<DumpProcessesForTracingTracking> tracking, + base::ProcessId pid, + mojom::ProcessType process_type, + bool keep_small_allocations, + bool strip_path_from_mapped_files, + uint32_t sampling_rate, + mojom::HeapProfilePtr profile) { + AllocationCountMap counts; + AllocationTracker::ContextMap context_map; + AllocationTracker::AddressToStringMap string_map; + BacktraceStorage backtrace_storage; + BacktraceStorage::Lock backtrace_storage_lock(&backtrace_storage); + + bool success = true; + for (const mojom::HeapProfileSamplePtr& sample : profile->samples) { + int context_id = 0; + if (sample->context_id) { + auto it = profile->strings.find(sample->context_id); + if (it == profile->strings.end()) { + success = false; + break; + } + const std::string& context = it->second; + // Escape the strings early, to simplify exporting a heap dump. + std::string escaped_context; + base::EscapeJSONString(context, false /* put_in_quotes */, + &escaped_context); + context_id = context_map + .emplace(std::move(escaped_context), + static_cast<int>(context_map.size() + 1)) + .first->second; + } + const Backtrace* backtrace = backtrace_storage.Insert( + std::vector<Address>(sample->stack.begin(), sample->stack.end())); + AllocatorType allocator = static_cast<AllocatorType>(sample->allocator); + if (allocator >= AllocatorType::kCount) { + success = false; + break; + } + AllocationEvent alloc(allocator, Address(0), sample->size, backtrace, + context_id); + ++counts[alloc]; + } + + for (const auto& str : profile->strings) { + std::string quoted_string; + // Escape the strings before saving them, to simplify exporting a heap dump. + base::EscapeJSONString(str.second, false /* put_in_quotes */, + "ed_string); + string_map.emplace(str.first, std::move(quoted_string)); + } + + DCHECK(success); + DoDumpOneProcessForTracing( + tracking, pid, process_type, keep_small_allocations, + strip_path_from_mapped_files, sampling_rate, success, std::move(counts), + std::move(context_map), std::move(string_map)); +} + void ConnectionManager::DoDumpOneProcessForTracing( scoped_refptr<DumpProcessesForTracingTracking> tracking, base::ProcessId pid,
diff --git a/components/services/heap_profiling/connection_manager.h b/components/services/heap_profiling/connection_manager.h index 6c746b3..6571f9f 100644 --- a/components/services/heap_profiling/connection_manager.h +++ b/components/services/heap_profiling/connection_manager.h
@@ -88,6 +88,15 @@ struct Connection; struct DumpProcessesForTracingTracking; + void HeapProfileRetrieved( + scoped_refptr<DumpProcessesForTracingTracking> tracking, + base::ProcessId pid, + mojom::ProcessType process_type, + bool keep_small_allocations, + bool strip_path_from_mapped_files, + uint32_t sampling_rate, + mojom::HeapProfilePtr profile); + void DoDumpOneProcessForTracing( scoped_refptr<DumpProcessesForTracingTracking> tracking, base::ProcessId pid,
diff --git a/components/services/heap_profiling/public/cpp/client.cc b/components/services/heap_profiling/public/cpp/client.cc index 020ef5e..39cd6c1d 100644 --- a/components/services/heap_profiling/public/cpp/client.cc +++ b/components/services/heap_profiling/public/cpp/client.cc
@@ -128,6 +128,10 @@ SamplingProfilerWrapper::FlushPipe(barrier_id); } +void Client::RetrieveHeapProfile(RetrieveHeapProfileCallback callback) { + std::move(callback).Run(sampling_profiler_->RetrieveHeapProfile()); +} + void Client::StartProfilingInternal(mojom::ProfilingParamsPtr params) { sampling_profiler_->StartProfiling(sender_pipe_.get(), std::move(params)); }
diff --git a/components/services/heap_profiling/public/cpp/client.h b/components/services/heap_profiling/public/cpp/client.h index e06103c7..23abac2 100644 --- a/components/services/heap_profiling/public/cpp/client.h +++ b/components/services/heap_profiling/public/cpp/client.h
@@ -27,6 +27,7 @@ // mojom::ProfilingClient overrides: void StartProfiling(mojom::ProfilingParamsPtr params) override; void FlushMemlogPipe(uint32_t barrier_id) override; + void RetrieveHeapProfile(RetrieveHeapProfileCallback callback) override; void BindToInterface(mojom::ProfilingClientRequest request);
diff --git a/components/services/heap_profiling/public/cpp/controller.cc b/components/services/heap_profiling/public/cpp/controller.cc index afb48330..8ab69c5 100644 --- a/components/services/heap_profiling/public/cpp/controller.cc +++ b/components/services/heap_profiling/public/cpp/controller.cc
@@ -16,10 +16,12 @@ Controller::Controller(std::unique_ptr<service_manager::Connector> connector, mojom::StackMode stack_mode, + bool stream_samples, uint32_t sampling_rate) : connector_(std::move(connector)), sampling_rate_(sampling_rate), stack_mode_(stack_mode), + stream_samples_(stream_samples), weak_factory_(this) { DCHECK_NE(sampling_rate, 0u); @@ -50,6 +52,7 @@ mojom::ProfilingParamsPtr params = mojom::ProfilingParams::New(); params->sampling_rate = sampling_rate_; + params->stream_samples = stream_samples_; params->sender_pipe = mojo::WrapPlatformHandle(pipes.PassSender()); params->stack_mode = stack_mode_; heap_profiling_service_->AddProfilingClient(
diff --git a/components/services/heap_profiling/public/cpp/controller.h b/components/services/heap_profiling/public/cpp/controller.h index ab077b0d..969f89e 100644 --- a/components/services/heap_profiling/public/cpp/controller.h +++ b/components/services/heap_profiling/public/cpp/controller.h
@@ -42,6 +42,7 @@ // named |sampling_interval|. Controller(std::unique_ptr<service_manager::Connector> connector, mojom::StackMode stack_mode, + bool stream_samples, uint32_t sampling_rate); ~Controller(); @@ -71,6 +72,7 @@ // The same sampling rate and stack mode is used for each client. const uint32_t sampling_rate_ = 1; const mojom::StackMode stack_mode_; + const bool stream_samples_; SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<Controller> weak_factory_;
diff --git a/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.cc b/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.cc index b97ec3c5..05b88f1 100644 --- a/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.cc +++ b/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.cc
@@ -4,6 +4,8 @@ #include "components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h" +#include <utility> + #include "base/allocator/buildflags.h" #include "base/atomicops.h" #include "base/bind.h" @@ -424,8 +426,12 @@ *context = allocation_context.type_name; } -void SerializeFramesFromBacktrace(FrameSerializer* serializer, - const char** context) { +// Captures up to |max_entries| stack frames using the buffer pointed by +// |frames|. Puts the number of captured frames into the |count| output +// parameters. Returns the pointer to the topmost frame. +const void** CaptureStackTrace(const void** frames, + size_t max_entries, + size_t* count) { // Skip 3 top frames related to the profiler itself, e.g.: // base::debug::StackTrace::StackTrace // heap_profiling::RecordAndSendAlloc @@ -433,26 +439,33 @@ size_t skip_frames = 3; #if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \ defined(OFFICIAL_BUILD) - const void* frames[kMaxStackEntries - 1]; size_t frame_count = base::trace_event::CFIBacktraceAndroid::GetInitializedInstance()->Unwind( - frames, kMaxStackEntries - 1); + frames, max_entries); #elif BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) - const void* frames[kMaxStackEntries - 1]; - size_t frame_count = base::debug::TraceStackFramePointers( - frames, kMaxStackEntries - 1, skip_frames); + size_t frame_count = + base::debug::TraceStackFramePointers(frames, max_entries, skip_frames); skip_frames = 0; #else - // Fall-back to capturing the stack with base::debug::StackTrace, + // Fall-back to capturing the stack with base::debug::CollectStackTrace, // which is likely slower, but more reliable. - base::debug::StackTrace stack_trace(kMaxStackEntries - 1); - size_t frame_count = 0u; - const void* const* frames = stack_trace.Addresses(&frame_count); + // TODO(alph): Make CollectStackTrace accept const void** pointer. + size_t frame_count = + base::debug::CollectStackTrace(const_cast<void**>(frames), max_entries); #endif skip_frames = std::min(skip_frames, frame_count); - serializer->AddAllInstructionPointers(frame_count - skip_frames, - frames + skip_frames); + *count = frame_count - skip_frames; + return frames + skip_frames; +} + +void SerializeFramesFromBacktrace(FrameSerializer* serializer, + const char** context) { + const void* frames[kMaxStackEntries]; + size_t frames_count; + const void** first_frame = + CaptureStackTrace(frames, kMaxStackEntries - 1, &frames_count); + serializer->AddAllInstructionPointers(frames_count, first_frame); // Both thread name and task context require access to TLS. if (ScopedAllowAlloc::HasTLSBeenDestroyed()) @@ -605,9 +618,14 @@ base::PoissonAllocationSampler::Get()->RemoveSamplesObserver(this); } +SamplingProfilerWrapper::Sample::Sample() = default; +SamplingProfilerWrapper::Sample::Sample(Sample&&) = default; +SamplingProfilerWrapper::Sample::~Sample() = default; + void SamplingProfilerWrapper::StartProfiling(SenderPipe* sender_pipe, mojom::ProfilingParamsPtr params) { size_t sampling_rate = params->sampling_rate; + stream_samples_ = params->stream_samples; InitAllocationRecorder(sender_pipe, std::move(params)); auto* sampler = base::PoissonAllocationSampler::Get(); sampler->SetSamplingInterval(sampling_rate); @@ -619,17 +637,126 @@ base::PoissonAllocationSampler::Get()->Stop(); } +mojom::HeapProfilePtr SamplingProfilerWrapper::RetrieveHeapProfile() { + base::PoissonAllocationSampler::ScopedMuteThreadSamples no_samples_scope; + base::AutoLock lock(mutex_); + mojom::HeapProfilePtr profile = mojom::HeapProfile::New(); + profile->samples.reserve(samples_.size()); + for (const auto& pair : samples_) { + auto mojo_sample = mojom::HeapProfileSample::New(); + mojo_sample->allocator = static_cast<uint32_t>(pair.second.allocator); + mojo_sample->size = pair.second.size; + mojo_sample->context_id = reinterpret_cast<uintptr_t>(pair.second.context); + mojo_sample->stack = pair.second.stack; + profile->samples.push_back(std::move(mojo_sample)); + } + profile->strings.reserve(strings_.size()); + for (const char* string : strings_) + profile->strings.emplace(reinterpret_cast<uintptr_t>(string), string); + return profile; +} + +// The PoissonAllocationSampler that invokes this method guarantees +// non-reentrancy, i.e. no allocations made within the scope of SampleAdded +// will produce a sample. void SamplingProfilerWrapper::SampleAdded( void* address, size_t size, size_t total, base::PoissonAllocationSampler::AllocatorType type, const char* context) { - RecordAndSendAlloc(ConvertType(type), address, size, context); + DCHECK(base::PoissonAllocationSampler::ScopedMuteThreadSamples::IsMuted()); + if (stream_samples_) { + RecordAndSendAlloc(ConvertType(type), address, size, context); + return; + } + base::AutoLock lock(mutex_); + Sample sample; + sample.allocator = ConvertType(type); + sample.size = size; + CaptureMode capture_mode = AllocationContextTracker::capture_mode(); + if (capture_mode == CaptureMode::PSEUDO_STACK || + capture_mode == CaptureMode::MIXED_STACK) { + CaptureMixedStack(context, &sample); + } else { + CaptureNativeStack(context, &sample); + } + RecordString(sample.context); + samples_.emplace(address, std::move(sample)); +} + +void SamplingProfilerWrapper::CaptureMixedStack(const char* context, + Sample* sample) { + // Allocation context is tracked in TLS. Return nothing if TLS was destroyed. + if (ScopedAllowAlloc::HasTLSBeenDestroyed()) + return; + auto* tracker = AllocationContextTracker::GetInstanceForCurrentThread(); + if (!tracker) + return; + + AllocationContext allocation_context; + if (!tracker->GetContextSnapshot(&allocation_context)) + return; + + const base::trace_event::Backtrace& backtrace = allocation_context.backtrace; + CHECK_LE(backtrace.frame_count, kMaxStackEntries); + std::vector<uint64_t> stack; + stack.reserve(backtrace.frame_count); + for (int i = base::checked_cast<int>(backtrace.frame_count) - 1; i >= 0; + --i) { + const base::trace_event::StackFrame& frame = backtrace.frames[i]; + if (frame.type != base::trace_event::StackFrame::Type::PROGRAM_COUNTER) + RecordString(static_cast<const char*>(frame.value)); + stack.push_back(reinterpret_cast<uintptr_t>(frame.value)); + } + sample->stack = std::move(stack); + if (!context) + context = allocation_context.type_name; + sample->context = context; +} + +void SamplingProfilerWrapper::CaptureNativeStack(const char* context, + Sample* sample) { + const void* stack[kMaxStackEntries]; + size_t frame_count; + // One frame is reserved for the thread name. + const void** first_frame = + CaptureStackTrace(stack, kMaxStackEntries - 1, &frame_count); + DCHECK_LT(frame_count, kMaxStackEntries); + sample->stack.reserve(frame_count + (g_include_thread_names ? 1 : 0)); + sample->stack.insert(sample->stack.end(), + reinterpret_cast<uintptr_t*>(first_frame), + reinterpret_cast<uintptr_t*>(first_frame + frame_count)); + + // Both thread name and task context require access to TLS. + if (ScopedAllowAlloc::HasTLSBeenDestroyed()) + return; + + if (g_include_thread_names) { + sample->stack.push_back( + reinterpret_cast<uintptr_t>(RecordString(GetOrSetThreadName()))); + } + if (!context) { + const auto* tracker = + AllocationContextTracker::GetInstanceForCurrentThread(); + if (tracker) + context = tracker->TaskContext(); + } + sample->context = context; +} + +const char* SamplingProfilerWrapper::RecordString(const char* string) { + return string ? *strings_.insert(string).first : nullptr; } void SamplingProfilerWrapper::SampleRemoved(void* address) { - RecordAndSendFree(address); + DCHECK(base::PoissonAllocationSampler::ScopedMuteThreadSamples::IsMuted()); + if (stream_samples_) { + RecordAndSendFree(address); + return; + } + base::AutoLock lock(mutex_); + samples_.erase(address); } } // namespace heap_profiling
diff --git a/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h b/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h index bee5c72..19d5a29c 100644 --- a/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h +++ b/components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h
@@ -5,6 +5,10 @@ #ifndef COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_SAMPLING_PROFILER_WRAPPER_H_ #define COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_SAMPLING_PROFILER_WRAPPER_H_ +#include <unordered_map> +#include <unordered_set> +#include <vector> + #include "base/sampling_heap_profiler/poisson_allocation_sampler.h" #include "components/services/heap_profiling/public/cpp/sender_pipe.h" #include "components/services/heap_profiling/public/cpp/stream.h" @@ -44,7 +48,24 @@ // logging process so it knows when this operation is complete. static void FlushPipe(uint32_t barrier_id); + mojom::HeapProfilePtr RetrieveHeapProfile(); + private: + struct Sample { + Sample(); + Sample(Sample&& sample); + ~Sample(); + + Sample& operator=(Sample&&) = default; + + AllocatorType allocator; + size_t size; + const char* context = nullptr; + std::vector<uint64_t> stack; + + DISALLOW_COPY_AND_ASSIGN(Sample); + }; + // base::PoissonAllocationSampler::SamplesObserver void SampleAdded(void* address, size_t size, @@ -52,6 +73,26 @@ base::PoissonAllocationSampler::AllocatorType, const char* context) override; void SampleRemoved(void* address) override; + + void CaptureMixedStack(const char* context, Sample* sample); + void CaptureNativeStack(const char* context, Sample* sample); + const char* RecordString(const char* string); + + bool stream_samples_ = false; + + // Mutex to access |samples_| and |strings_|. + base::Lock mutex_; + + // Samples of the currently live allocations. + std::unordered_map<void*, Sample> samples_; + + // When CaptureMode::PSEUDO_STACK or CaptureMode::MIXED_STACK is enabled + // the call stack contents of samples may contain strings besides + // PC addresses. + // In this case each string pointer is also added to the |strings_| set. + // The set does only contain pointers to static strings that are never + // deleted. + std::unordered_set<const char*> strings_; }; } // namespace heap_profiling
diff --git a/components/services/heap_profiling/public/mojom/heap_profiling_client.mojom b/components/services/heap_profiling/public/mojom/heap_profiling_client.mojom index 8b98d691..6a9607776 100644 --- a/components/services/heap_profiling/public/mojom/heap_profiling_client.mojom +++ b/components/services/heap_profiling/public/mojom/heap_profiling_client.mojom
@@ -23,6 +23,12 @@ // A wrapper for parameters that affect each client's implementation of // profiling. struct ProfilingParams { + // When |stream_samples| is true the samples are streamed through the + // provided |sender_pipe|. Otherwise, the samples are stored on + // the client side during recording and can be retrieved using + // |ProfilingClient.RetrieveHeapProfile| method. + bool stream_samples; + // The client should record allocations into |memlog_sender_pipe|. handle sender_pipe; @@ -37,17 +43,48 @@ uint32 sampling_rate; }; +// A single memory allocation sample. +struct HeapProfileSample { + // Allocator type. + uint32 allocator; + + // The size in bytes accounted for the sample. + uint64 size; + + // Id of the context string. + uint64 context_id; + + // Program stack in top to bottom order recorded for the allocation. + // Each element of the |stack| is either a PC memory address or a string + // if it is among the |strings| map items of |HeapProfile|. + array<uint64> stack; +}; + +// Heap profile data. Can be retrieved from the client with +// |RetrieveHeapProfile| method. +struct HeapProfile { + // Samples recorded for the profile. + array<HeapProfileSample> samples; + + // Strings used within the profile. + map<uint64, string> strings; +}; + // This interface is implemented by "memlog clients" (profiled processes that // can send memory allocation events to the profiling process). These functions // are called by the profiling process to control the senders. interface ProfilingClient { - // Start recording allocations and sending them to the profiling process via - // |params.sender_pipe|. There is currently no mechanism to stop recording - // allocations. + // Start recording allocations. + // Collected allocations are either streamed to the profiling process via + // |params.sender_pipe|, or accumulated in the profiled process depending on + // the |params.use_in_process_storage|. + // There is currently no mechanism to stop recording allocations. StartProfiling(ProfilingParams params); // Flushes the memlog pipe associated with this client. A barrier packet is // set over the memlog pipe with the given identifier. This allows the // receiver to synchronize with the flush. FlushMemlogPipe(uint32 barrier_id); + + RetrieveHeapProfile() => (HeapProfile profile); };
diff --git a/components/signin/ios/browser/BUILD.gn b/components/signin/ios/browser/BUILD.gn index 088e53e..8aafb19 100644 --- a/components/signin/ios/browser/BUILD.gn +++ b/components/signin/ios/browser/BUILD.gn
@@ -8,8 +8,6 @@ "account_consistency_service.h", "account_consistency_service.mm", "manage_accounts_delegate.h", - "merge_session_observer_bridge.h", - "merge_session_observer_bridge.mm", "profile_oauth2_token_service_ios_delegate.h", "profile_oauth2_token_service_ios_delegate.mm", "profile_oauth2_token_service_ios_provider.h",
diff --git a/components/signin/ios/browser/merge_session_observer_bridge.h b/components/signin/ios/browser/merge_session_observer_bridge.h deleted file mode 100644 index ec9b104..0000000 --- a/components/signin/ios/browser/merge_session_observer_bridge.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_SIGNIN_IOS_BROWSER_MERGE_SESSION_OBSERVER_BRIDGE_H_ -#define COMPONENTS_SIGNIN_IOS_BROWSER_MERGE_SESSION_OBSERVER_BRIDGE_H_ - -#import <Foundation/Foundation.h> - -#include <string> - -#include "base/macros.h" -#include "components/signin/core/browser/gaia_cookie_manager_service.h" - -class GoogleServiceAuthError; - -@protocol MergeSessionObserverBridgeDelegate - -// Informs the delegate that the merge session operation for |account_id| has -// finished. If there was an error, it will be described in |error|. -- (void)onMergeSessionCompleted:(const std::string&)account_id - error:(const GoogleServiceAuthError&)error; - -@end - -// C++ class to monitor merge session status in Objective C type. -class MergeSessionObserverBridge : public GaiaCookieManagerService::Observer { - public: - MergeSessionObserverBridge(id<MergeSessionObserverBridgeDelegate> delegate, - GaiaCookieManagerService* cookie_manager_service); - ~MergeSessionObserverBridge() override; - - void OnAddAccountToCookieCompleted( - const std::string& account_id, - const GoogleServiceAuthError& error) override; - - private: - __weak id<MergeSessionObserverBridgeDelegate> delegate_; - GaiaCookieManagerService* cookie_manager_service_; - - DISALLOW_COPY_AND_ASSIGN(MergeSessionObserverBridge); -}; - -#endif // COMPONENTS_SIGNIN_IOS_BROWSER_MERGE_SESSION_OBSERVER_BRIDGE_H_
diff --git a/components/signin/ios/browser/merge_session_observer_bridge.mm b/components/signin/ios/browser/merge_session_observer_bridge.mm deleted file mode 100644 index ee30039..0000000 --- a/components/signin/ios/browser/merge_session_observer_bridge.mm +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/signin/ios/browser/merge_session_observer_bridge.h" - -#include "base/logging.h" -#include "google_apis/gaia/google_service_auth_error.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -MergeSessionObserverBridge::MergeSessionObserverBridge( - id<MergeSessionObserverBridgeDelegate> delegate, - GaiaCookieManagerService* cookie_manager_service) - : delegate_(delegate), cookie_manager_service_(cookie_manager_service) { - DCHECK(delegate); - DCHECK(cookie_manager_service); - cookie_manager_service_->AddObserver(this); -} - -MergeSessionObserverBridge::~MergeSessionObserverBridge() { - cookie_manager_service_->RemoveObserver(this); -} - -void MergeSessionObserverBridge::OnAddAccountToCookieCompleted( - const std::string& account_id, - const GoogleServiceAuthError& error) { - [delegate_ onMergeSessionCompleted:account_id error:error]; -}
diff --git a/components/translate/core/browser/BUILD.gn b/components/translate/core/browser/BUILD.gn index aea0ed1..5ee75683 100644 --- a/components/translate/core/browser/BUILD.gn +++ b/components/translate/core/browser/BUILD.gn
@@ -84,12 +84,6 @@ testonly = true sources = [ "language_state_unittest.cc", - "mock_translate_client.cc", - "mock_translate_client.h", - "mock_translate_driver.cc", - "mock_translate_driver.h", - "mock_translate_ranker.cc", - "mock_translate_ranker.h", "translate_accept_languages_unittest.cc", "translate_browser_metrics_unittest.cc", "translate_language_list_unittest.cc", @@ -102,6 +96,7 @@ ] deps = [ ":browser", + ":test_support", "//base", "//components/assist_ranker", "//components/assist_ranker/proto", @@ -120,8 +115,38 @@ "//services/metrics/public/cpp:ukm_builders", "//services/network:test_support", "//services/network/public/cpp:cpp", - "//testing/gtest", - "//third_party/metrics_proto", "//ui/base", ] } + +source_set("test_support") { + testonly = true + sources = [ + "mock_translate_client.cc", + "mock_translate_client.h", + "mock_translate_driver.cc", + "mock_translate_driver.h", + "mock_translate_ranker.cc", + "mock_translate_ranker.h", + ] + deps = [ + "//base", + "//components/infobars/core", + "//components/language/core/browser", + "//components/sync_preferences", + "//components/sync_preferences:test_support", + "//components/translate/core/browser", + "//components/translate/core/common", + "//testing/gmock", + "//testing/gtest", + "//third_party/metrics_proto:metrics_proto", + "//url", + ] + + if (is_ios || is_android) { + sources += [ + "mock_translate_infobar_delegate.cc", + "mock_translate_infobar_delegate.h", + ] + } +}
diff --git a/components/translate/core/browser/mock_translate_infobar_delegate.cc b/components/translate/core/browser/mock_translate_infobar_delegate.cc new file mode 100644 index 0000000..9b67068 --- /dev/null +++ b/components/translate/core/browser/mock_translate_infobar_delegate.cc
@@ -0,0 +1,59 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/translate/core/browser/mock_translate_infobar_delegate.h" + +namespace translate { + +namespace testing { + +std::vector<MockLanguageModel::LanguageDetails> +MockLanguageModel::GetLanguages() { + return {MockLanguageModel::LanguageDetails("en", 1.0)}; +} + +MockTranslateInfoBarDelegate::MockTranslateInfoBarDelegate( + const base::WeakPtr<translate::TranslateManager>& translate_manager, + bool is_off_the_record, + translate::TranslateStep step, + const std::string& original_language, + const std::string& target_language, + translate::TranslateErrors::Type error_type, + bool triggered_from_menu) + : translate::TranslateInfoBarDelegate(translate_manager, + is_off_the_record, + step, + original_language, + target_language, + error_type, + triggered_from_menu) {} + +MockTranslateInfoBarDelegate::~MockTranslateInfoBarDelegate() {} + +MockTranslateInfoBarDelegateFactory::MockTranslateInfoBarDelegateFactory( + const std::string& original_language, + const std::string& target_language) { + pref_service_ = + std::make_unique<sync_preferences::TestingPrefServiceSyncable>(); + translate::TranslatePrefs::RegisterProfilePrefs(pref_service_->registry()); + pref_service_->registry()->RegisterBooleanPref(prefs::kOfferTranslateEnabled, + true); + client_ = + std::make_unique<MockTranslateClient>(&driver_, pref_service_.get()); + ranker_ = std::make_unique<MockTranslateRanker>(); + language_model_ = std::make_unique<MockLanguageModel>(); + manager_ = std::make_unique<translate::TranslateManager>( + client_.get(), ranker_.get(), language_model_.get()); + delegate_ = std::make_unique<MockTranslateInfoBarDelegate>( + manager_->GetWeakPtr(), false, + translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE, + original_language, target_language, + translate::TranslateErrors::Type::NONE, false); +} + +MockTranslateInfoBarDelegateFactory::~MockTranslateInfoBarDelegateFactory() {} + +} // namespace testing + +} // namespace translate
diff --git a/components/translate/core/browser/mock_translate_infobar_delegate.h b/components/translate/core/browser/mock_translate_infobar_delegate.h new file mode 100644 index 0000000..3f736f90 --- /dev/null +++ b/components/translate/core/browser/mock_translate_infobar_delegate.h
@@ -0,0 +1,78 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_TRANSLATE_CORE_BROWSER_MOCK_TRANSLATE_INFOBAR_DELEGATE_H_ +#define COMPONENTS_TRANSLATE_CORE_BROWSER_MOCK_TRANSLATE_INFOBAR_DELEGATE_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "components/language/core/browser/language_model.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "components/translate/core/browser/mock_translate_client.h" +#include "components/translate/core/browser/mock_translate_driver.h" +#include "components/translate/core/browser/mock_translate_ranker.h" +#include "components/translate/core/browser/translate_infobar_delegate.h" +#include "components/translate/core/browser/translate_manager.h" +#include "components/translate/core/browser/translate_pref_names.h" +#include "components/translate/core/browser/translate_prefs.h" +#include "testing/gmock/include/gmock/gmock.h" + +using testing::_; + +namespace translate { + +namespace testing { + +class MockLanguageModel : public language::LanguageModel { + std::vector<LanguageDetails> GetLanguages() override; +}; + +class MockTranslateInfoBarDelegate + : public translate::TranslateInfoBarDelegate { + public: + MockTranslateInfoBarDelegate( + const base::WeakPtr<translate::TranslateManager>& translate_manager, + bool is_off_the_record, + translate::TranslateStep step, + const std::string& original_language, + const std::string& target_language, + translate::TranslateErrors::Type error_type, + bool triggered_from_menu); + ~MockTranslateInfoBarDelegate() override; + + MOCK_CONST_METHOD0(num_languages, size_t()); + MOCK_CONST_METHOD1(language_code_at, std::string(size_t index)); + MOCK_CONST_METHOD1(language_name_at, base::string16(size_t index)); + MOCK_CONST_METHOD0(original_language_name, base::string16()); + MOCK_CONST_METHOD0(ShouldAlwaysTranslate, bool()); + MOCK_METHOD1(SetObserver, void(Observer* observer)); +}; + +class MockTranslateInfoBarDelegateFactory { + public: + MockTranslateInfoBarDelegateFactory(const std::string& original_language, + const std::string& target_language); + ~MockTranslateInfoBarDelegateFactory(); + + MockTranslateInfoBarDelegate* GetMockTranslateInfoBarDelegate() { + return delegate_.get(); + } + + private: + MockTranslateDriver driver_; + std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> pref_service_; + std::unique_ptr<MockTranslateClient> client_; + std::unique_ptr<MockTranslateRanker> ranker_; + std::unique_ptr<MockLanguageModel> language_model_; + std::unique_ptr<translate::TranslateManager> manager_; + std::unique_ptr<MockTranslateInfoBarDelegate> delegate_; +}; + +} // namespace testing + +} // namespace translate + +#endif // COMPONENTS_TRANSLATE_CORE_BROWSER_MOCK_TRANSLATE_INFOBAR_DELEGATE_H_
diff --git a/components/translate/core/browser/translate_infobar_delegate.cc b/components/translate/core/browser/translate_infobar_delegate.cc index aa2cb72..68d4a1a 100644 --- a/components/translate/core/browser/translate_infobar_delegate.cc +++ b/components/translate/core/browser/translate_infobar_delegate.cc
@@ -103,10 +103,26 @@ infobar_manager->AddInfoBar(std::move(infobar)); } +size_t TranslateInfoBarDelegate::num_languages() const { + return ui_delegate_.GetNumberOfLanguages(); +} + +std::string TranslateInfoBarDelegate::language_code_at(size_t index) const { + return ui_delegate_.GetLanguageCodeAt(index); +} + +base::string16 TranslateInfoBarDelegate::language_name_at(size_t index) const { + return ui_delegate_.GetLanguageNameAt(index); +} + void TranslateInfoBarDelegate::SetObserver(Observer* observer) { observer_ = observer; } +base::string16 TranslateInfoBarDelegate::original_language_name() const { + return language_name_at(ui_delegate_.GetOriginalLanguageIndex()); +} + void TranslateInfoBarDelegate::UpdateOriginalLanguage( const std::string& language_code) { ui_delegate_.UpdateOriginalLanguage(language_code);
diff --git a/components/translate/core/browser/translate_infobar_delegate.h b/components/translate/core/browser/translate_infobar_delegate.h index dc16ed9..47c1c91 100644 --- a/components/translate/core/browser/translate_infobar_delegate.h +++ b/components/translate/core/browser/translate_infobar_delegate.h
@@ -77,17 +77,13 @@ bool triggered_from_menu); // Returns the number of languages supported. - size_t num_languages() const { return ui_delegate_.GetNumberOfLanguages(); } + virtual size_t num_languages() const; // Returns the ISO code for the language at |index|. - std::string language_code_at(size_t index) const { - return ui_delegate_.GetLanguageCodeAt(index); - } + virtual std::string language_code_at(size_t index) const; // Returns the displayable name for the language at |index|. - base::string16 language_name_at(size_t index) const { - return ui_delegate_.GetLanguageNameAt(index); - } + virtual base::string16 language_name_at(size_t index) const; translate::TranslateStep translate_step() const { return step_; } @@ -99,9 +95,7 @@ return ui_delegate_.GetOriginalLanguageCode(); } - base::string16 original_language_name() const { - return language_name_at(ui_delegate_.GetOriginalLanguageIndex()); - } + virtual base::string16 original_language_name() const; void UpdateOriginalLanguage(const std::string& language_code);
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 92632c3..81ecaf42 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -134,7 +134,8 @@ backend_format, size_.width(), size_.height(), mipmap_, kTopLeft_GrSurfaceOrigin /* origin */, color_type, alpha_type_, color_space_, PromiseTextureHelper::Fulfill, - PromiseTextureHelper::Release, PromiseTextureHelper::Done, this); + PromiseTextureHelper::Release, PromiseTextureHelper::Done, this, + SkDeferredDisplayListRecorder::DelayReleaseCallback::kYes); } static sk_sp<SkPromiseImageTexture> Fulfill(void* texture_context) { @@ -267,7 +268,8 @@ yuv_color_space, formats, yuva_sizes, indices, yuva_sizes[0].width(), yuva_sizes[0].height(), kTopLeft_GrSurfaceOrigin, nullptr /* color_space */, PromiseTextureHelper::Fulfill, - PromiseTextureHelper::Release, PromiseTextureHelper::Done, contexts); + PromiseTextureHelper::Release, PromiseTextureHelper::Done, contexts, + SkDeferredDisplayListRecorder::DelayReleaseCallback::kYes); return image; }
diff --git a/content/browser/child_process_launcher_helper_fuchsia.cc b/content/browser/child_process_launcher_helper_fuchsia.cc index 06e1067..413ff43 100644 --- a/content/browser/child_process_launcher_helper_fuchsia.cc +++ b/content/browser/child_process_launcher_helper_fuchsia.cc
@@ -18,8 +18,8 @@ base::Process process, const ChildProcessLauncherPriority& priority) { DCHECK(CurrentlyOnProcessLauncherTaskRunner()); - // TODO(fuchsia): Implement this. (crbug.com/707031) - NOTIMPLEMENTED(); + // TODO(https://crbug.com/926583): Fuchsia does not currently support this. + NOTIMPLEMENTED_LOG_ONCE(); } ChildProcessTerminationInfo ChildProcessLauncherHelper::GetTerminationInfo( @@ -41,14 +41,11 @@ void ChildProcessLauncherHelper::SetRegisteredFilesForService( const std::string& service_name, std::map<std::string, base::FilePath> required_files) { - // TODO(fuchsia): Implement this. (crbug.com/707031) - NOTIMPLEMENTED(); + NOTREACHED() << " for service " << service_name; } // static void ChildProcessLauncherHelper::ResetRegisteredFilesForTesting() { - // TODO(fuchsia): Implement this. (crbug.com/707031) - NOTIMPLEMENTED(); } void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() { @@ -85,7 +82,6 @@ DCHECK(mojo_channel_); DCHECK(mojo_channel_->remote_endpoint().is_valid()); - // TODO(750938): Implement sandboxed/isolated subprocess launching. Process child_process; child_process.process = base::LaunchProcess(*command_line(), options); return child_process;
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc index ae486a2..1024c39 100644 --- a/content/browser/frame_host/cross_process_frame_connector.cc +++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -150,8 +150,8 @@ delegate_was_shown_after_crash_ = false; view_->SetFrameConnectorDelegate(this); - if (is_hidden_) - OnVisibilityChanged(false); + if (visibility_ != blink::mojom::FrameVisibility::kRenderedInViewport) + OnVisibilityChanged(visibility_); FrameMsg_ViewChanged_Params params; if (!features::IsMultiProcessMash()) params.frame_sink_id = view_->GetFrameSinkId(); @@ -370,8 +370,10 @@ } } -void CrossProcessFrameConnector::OnVisibilityChanged(bool visible) { - is_hidden_ = !visible; +void CrossProcessFrameConnector::OnVisibilityChanged( + blink::mojom::FrameVisibility visibility) { + bool visible = visibility != blink::mojom::FrameVisibility::kNotRendered; + visibility_ = visibility; if (IsVisible()) { // Record metrics if a crashed subframe became visible as a result of this // visibility change. @@ -380,6 +382,10 @@ if (!view_) return; + frame_proxy_in_parent_renderer_->frame_tree_node() + ->current_frame_host() + ->VisibilityChanged(visibility); + // If there is an inner WebContents, it should be notified of the change in // the visibility. The Show/Hide methods will not be called if an inner // WebContents exists since the corresponding WebContents will itself call @@ -453,7 +459,7 @@ } bool CrossProcessFrameConnector::IsHidden() const { - return is_hidden_; + return visibility_ == blink::mojom::FrameVisibility::kNotRendered; } #if defined(USE_AURA) @@ -588,7 +594,7 @@ } bool CrossProcessFrameConnector::IsVisible() { - if (is_hidden_) + if (visibility_ == blink::mojom::FrameVisibility::kNotRendered) return false; if (viewport_intersection_rect().IsEmpty()) return false;
diff --git a/content/browser/frame_host/cross_process_frame_connector.h b/content/browser/frame_host/cross_process_frame_connector.h index d7f7cea..cf9648bf 100644 --- a/content/browser/frame_host/cross_process_frame_connector.h +++ b/content/browser/frame_host/cross_process_frame_connector.h
@@ -14,6 +14,7 @@ #include "content/browser/renderer_host/frame_connector_delegate.h" #include "content/common/content_export.h" #include "content/common/frame_visual_properties.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom.h" namespace IPC { class Message; @@ -158,6 +159,8 @@ // became visible. void DelegateWasShown(); + blink::mojom::FrameVisibility visibility() const { return visibility_; } + private: friend class MockCrossProcessFrameConnector; @@ -181,7 +184,7 @@ void OnUpdateViewportIntersection(const gfx::Rect& viewport_intersection, const gfx::Rect& compositor_visible_rect, bool occluded_or_obscured); - void OnVisibilityChanged(bool visible); + void OnVisibilityChanged(blink::mojom::FrameVisibility visibility); void OnSetIsInert(bool); void OnSetInheritedEffectiveTouchAction(cc::TouchAction); void OnUpdateRenderThrottlingStatus(bool is_throttled, @@ -199,8 +202,9 @@ bool subtree_throttled_ = false; // Visibility state of the corresponding frame owner element in parent process - // which is set through CSS. - bool is_hidden_ = false; + // which is set through CSS or scrolling. + blink::mojom::FrameVisibility visibility_ = + blink::mojom::FrameVisibility::kRenderedInViewport; // Used to make sure we only log UMA once per renderer crash. bool is_crash_already_logged_ = false;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index b699b0c2..870875d 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -3019,6 +3019,11 @@ } #endif +void RenderFrameHostImpl::VisibilityChanged( + blink::mojom::FrameVisibility visibility) { + visibility_ = visibility; +} + void RenderFrameHostImpl::OnDidBlockFramebust(const GURL& url) { delegate_->OnDidBlockFramebust(url); }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 57296a8..3dcbda6 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -870,6 +870,11 @@ // activated. void OnPortalActivated(); + // mojom::FrameHost: + void VisibilityChanged(blink::mojom::FrameVisibility) override; + + blink::mojom::FrameVisibility visibility() const { return visibility_; } + protected: friend class RenderFrameHostFactory; @@ -1957,6 +1962,9 @@ // BackForwardCache: bool is_in_back_forward_cache_ = false; + blink::mojom::FrameVisibility visibility_ = + blink::mojom::FrameVisibility::kRenderedInViewport; + // NOTE: This must be the last member. base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_;
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc index c108626d..510aab1 100644 --- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -2016,4 +2016,43 @@ EXPECT_EQ(0, process->get_media_stream_count_for_testing()); } +// Test that a frame is visible/hidden depending on its WebContents visibility +// state. +IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, + VisibilityScrolledOutOfView) { + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + + GURL main_frame(embedded_test_server()->GetURL("/iframe_out_of_view.html")); + GURL child_url(embedded_test_server()->GetURL("/hello.html")); + + // This will set up the page frame tree as A(A1()). + ASSERT_TRUE(NavigateToURL(shell(), main_frame)); + FrameTreeNode* root = web_contents->GetFrameTree()->root(); + FrameTreeNode* nested_iframe_node = root->child_at(0); + NavigateFrameToURL(nested_iframe_node, child_url); + + ASSERT_EQ(blink::mojom::FrameVisibility::kRenderedOutOfViewport, + nested_iframe_node->current_frame_host()->visibility()); +} + +// Test that a frame is visible/hidden depending on its WebContents visibility +// state. +IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, VisibilityChildInView) { + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + + GURL main_frame(embedded_test_server()->GetURL("/iframe_clipped.html")); + GURL child_url(embedded_test_server()->GetURL("/hello.html")); + + // This will set up the page frame tree as A(A1()). + ASSERT_TRUE(NavigateToURL(shell(), main_frame)); + FrameTreeNode* root = web_contents->GetFrameTree()->root(); + FrameTreeNode* nested_iframe_node = root->child_at(0); + NavigateFrameToURL(nested_iframe_node, child_url); + + ASSERT_EQ(blink::mojom::FrameVisibility::kRenderedInViewport, + nested_iframe_node->current_frame_host()->visibility()); +} + } // namespace content
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc index e70b7e4..6d7451f 100644 --- a/content/browser/frame_host/render_frame_proxy_host.cc +++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -270,15 +270,20 @@ return; } - // This message should only be received for subframes. Note that we can't - // restrict it to just the current SiteInstances of the ancestors of this - // frame, because another frame in the tree may be able to detach this frame - // by navigating its parent. - if (frame_tree_node_->IsMainFrame()) { - bad_message::ReceivedBadMessage(GetProcess(), bad_message::RFPH_DETACH); + // For a main frame with no outer delegate, no further work is needed. In this + // case, detach can only be triggered by closing the entire RenderViewHost. + // Instead, this cleanup relies on the destructors of RenderFrameHost and + // RenderFrameProxyHost decrementing the refcounts of their associated + // RenderViewHost. When the refcount hits 0, the corresponding renderer object + // is cleaned up. Since WebContents destruction will also destroy + // RenderFrameHost/RenderFrameProxyHost objects in FrameTree, this eventually + // results in all the associated RenderViewHosts being closed. + if (frame_tree_node_->IsMainFrame()) return; - } + // Otherwise, a remote child frame has been removed from the frame tree. + // Make sure that this action is mirrored to all the other renderers, so + // the frame tree remains consistent. frame_tree_node_->current_frame_host()->DetachFromProxy(); }
diff --git a/content/browser/media/session/media_metadata_sanitizer.cc b/content/browser/media/session/media_metadata_sanitizer.cc index e7e109e..c98ad630 100644 --- a/content/browser/media/session/media_metadata_sanitizer.cc +++ b/content/browser/media/session/media_metadata_sanitizer.cc
@@ -54,63 +54,32 @@ return true; } -// Sanitize MediaImage. The method should not be called if |image.src| is bad. -media_session::MediaMetadata::MediaImage SanitizeMediaImage( - const media_session::MediaMetadata::MediaImage& image) { - media_session::MediaMetadata::MediaImage sanitized_image; - - sanitized_image.src = image.src; - sanitized_image.type = image.type.substr(0, kMaxMediaImageTypeLength); - for (const auto& size : image.sizes) { - sanitized_image.sizes.push_back(size); - if (sanitized_image.sizes.size() == kMaxNumberOfMediaImageSizes) - break; - } - - return sanitized_image; -} - } // anonymous namespace -bool MediaMetadataSanitizer::CheckSanity( - const media_session::MediaMetadata& metadata) { - if (metadata.title.size() > kMaxIPCStringLength) +bool MediaMetadataSanitizer::SanitizeAndConvert( + const blink::mojom::SpecMediaMetadataPtr& metadata, + media_session::MediaMetadata* metadata_out) { + if (metadata->title.size() > kMaxIPCStringLength) return false; - if (metadata.artist.size() > kMaxIPCStringLength) + if (metadata->artist.size() > kMaxIPCStringLength) return false; - if (metadata.album.size() > kMaxIPCStringLength) + if (metadata->album.size() > kMaxIPCStringLength) return false; - if (metadata.artwork.size() > kMaxNumberOfMediaImages) + if (metadata->artwork.size() > kMaxNumberOfMediaImages) return false; - for (const auto& image : metadata.artwork) { + metadata_out->title = metadata->title; + metadata_out->artist = metadata->artist; + metadata_out->album = metadata->album; + + for (const auto& image : metadata->artwork) { if (!CheckMediaImageSanity(image)) return false; + + metadata_out->artwork.push_back(image); } return true; } -media_session::MediaMetadata MediaMetadataSanitizer::Sanitize( - const media_session::MediaMetadata& metadata) { - media_session::MediaMetadata sanitized_metadata; - - sanitized_metadata.title = metadata.title.substr(0, kMaxIPCStringLength); - sanitized_metadata.artist = metadata.artist.substr(0, kMaxIPCStringLength); - sanitized_metadata.album = metadata.album.substr(0, kMaxIPCStringLength); - - for (const auto& image : metadata.artwork) { - if (!CheckMediaImageSrcSanity(image.src)) - continue; - - sanitized_metadata.artwork.push_back( - CheckMediaImageSanity(image) ? image : SanitizeMediaImage(image)); - - if (sanitized_metadata.artwork.size() == kMaxNumberOfMediaImages) - break; - } - - return sanitized_metadata; -} - } // namespace content
diff --git a/content/browser/media/session/media_metadata_sanitizer.h b/content/browser/media/session/media_metadata_sanitizer.h index 10cd45a..c3719ee9 100644 --- a/content/browser/media/session/media_metadata_sanitizer.h +++ b/content/browser/media/session/media_metadata_sanitizer.h
@@ -5,6 +5,8 @@ #ifndef CONTENT_BROWSER_MEDIA_SESSION_MEDIA_METADATA_SANITIZER_H_ #define CONTENT_BROWSER_MEDIA_SESSION_MEDIA_METADATA_SANITIZER_H_ +#include "third_party/blink/public/platform/modules/mediasession/media_session.mojom.h" + namespace media_session { struct MediaMetadata; } // namespace media_session @@ -13,12 +15,11 @@ class MediaMetadataSanitizer { public: - // Check the sanity of |metadata|. - static bool CheckSanity(const media_session::MediaMetadata& metadata); - - // Sanitizes |metadata| and return the result. - static media_session::MediaMetadata Sanitize( - const media_session::MediaMetadata& metadata); + // Converts |metadata| to a media_session::MediaMetadata object and returns + // whether it is valid. + static bool SanitizeAndConvert( + const blink::mojom::SpecMediaMetadataPtr& metadata, + media_session::MediaMetadata* metadata_out); }; } // namespace content
diff --git a/content/browser/media/session/media_session_impl_browsertest.cc b/content/browser/media/session/media_session_impl_browsertest.cc index c51de6a..8ee483b2 100644 --- a/content/browser/media/session/media_session_impl_browsertest.cc +++ b/content/browser/media/session/media_session_impl_browsertest.cc
@@ -2197,11 +2197,18 @@ // Set up the service and information. EnsureMediaSessionService(); - media_session::MediaMetadata metadata; - metadata.title = base::ASCIIToUTF16("title"); - metadata.artist = base::ASCIIToUTF16("artist"); - metadata.album = base::ASCIIToUTF16("album"); - mock_media_session_service_->SetMetadata(metadata); + media_session::MediaMetadata expected_metadata; + expected_metadata.title = base::ASCIIToUTF16("title"); + expected_metadata.artist = base::ASCIIToUTF16("artist"); + expected_metadata.album = base::ASCIIToUTF16("album"); + expected_metadata.source_title = GetExpectedSourceTitle(); + + blink::mojom::SpecMediaMetadataPtr spec_metadata( + blink::mojom::SpecMediaMetadata::New()); + spec_metadata->title = base::ASCIIToUTF16("title"); + spec_metadata->artist = base::ASCIIToUTF16("artist"); + spec_metadata->album = base::ASCIIToUTF16("album"); + mock_media_session_service_->SetMetadata(std::move(spec_metadata)); // Make sure the service is routed, auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>( @@ -2212,8 +2219,7 @@ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent); ResolveAudioFocusSuccess(); - metadata.source_title = GetExpectedSourceTitle(); - EXPECT_EQ(metadata, observer.WaitForNonEmptyMetadata()); + EXPECT_EQ(expected_metadata, observer.WaitForNonEmptyMetadata()); } }
diff --git a/content/browser/media/session/media_session_impl_service_routing_unittest.cc b/content/browser/media/session/media_session_impl_service_routing_unittest.cc index c25285d..683e4759 100644 --- a/content/browser/media/session/media_session_impl_service_routing_unittest.cc +++ b/content/browser/media/session/media_session_impl_service_routing_unittest.cc
@@ -277,7 +277,7 @@ CreateServiceForFrame(main_frame_); - services_[main_frame_]->SetMetadata(media_session::MediaMetadata()); + services_[main_frame_]->SetMetadata(nullptr); services_[main_frame_]->EnableAction(MediaSessionAction::kPlay); observer.WaitForActions(); @@ -312,7 +312,13 @@ media_session::test::MockMediaSessionMojoObserver observer( *GetMediaSession()); - services_[main_frame_]->SetMetadata(expected_metadata); + blink::mojom::SpecMediaMetadataPtr spec_metadata( + blink::mojom::SpecMediaMetadata::New()); + spec_metadata->title = base::ASCIIToUTF16("title"); + spec_metadata->artist = base::ASCIIToUTF16("artist"); + spec_metadata->album = base::ASCIIToUTF16("album"); + + services_[main_frame_]->SetMetadata(std::move(spec_metadata)); services_[main_frame_]->EnableAction(MediaSessionAction::kSeekForward); observer.WaitForActions(); @@ -334,7 +340,16 @@ CreateServiceForFrame(main_frame_); - services_[main_frame_]->SetMetadata(expected_metadata); + { + blink::mojom::SpecMediaMetadataPtr spec_metadata( + blink::mojom::SpecMediaMetadata::New()); + spec_metadata->title = base::ASCIIToUTF16("title"); + spec_metadata->artist = base::ASCIIToUTF16("artist"); + spec_metadata->album = base::ASCIIToUTF16("album"); + + services_[main_frame_]->SetMetadata(std::move(spec_metadata)); + } + services_[main_frame_]->EnableAction(MediaSessionAction::kSeekForward); { @@ -372,7 +387,15 @@ CreateServiceForFrame(main_frame_); - services_[main_frame_]->SetMetadata(expected_metadata); + { + blink::mojom::SpecMediaMetadataPtr spec_metadata( + blink::mojom::SpecMediaMetadata::New()); + spec_metadata->title = base::ASCIIToUTF16("title"); + spec_metadata->artist = base::ASCIIToUTF16("artist"); + spec_metadata->album = base::ASCIIToUTF16("album"); + + services_[main_frame_]->SetMetadata(std::move(spec_metadata)); + } StartPlayerForFrame(main_frame_); @@ -577,7 +600,15 @@ { media_session::test::MockMediaSessionMojoObserver observer( *GetMediaSession()); - services_[main_frame_]->SetMetadata(expected_metadata); + + blink::mojom::SpecMediaMetadataPtr spec_metadata( + blink::mojom::SpecMediaMetadata::New()); + spec_metadata->title = base::ASCIIToUTF16("title"); + spec_metadata->artist = base::ASCIIToUTF16("artist"); + spec_metadata->album = base::ASCIIToUTF16("album"); + + services_[main_frame_]->SetMetadata(std::move(spec_metadata)); + EXPECT_EQ(expected_metadata, observer.WaitForNonEmptyMetadata()); } } @@ -593,7 +624,7 @@ { media_session::test::MockMediaSessionMojoObserver observer( *GetMediaSession()); - services_[main_frame_]->SetMetadata(base::nullopt); + services_[main_frame_]->SetMetadata(nullptr); // When the session becomes controllable we should receive default // metadata. The |is_controllable| boolean will also become true.
diff --git a/content/browser/media/session/media_session_service_impl.cc b/content/browser/media/session/media_session_service_impl.cc index fbb3b101..2173235 100644 --- a/content/browser/media/session/media_session_service_impl.cc +++ b/content/browser/media/session/media_session_service_impl.cc
@@ -47,7 +47,7 @@ // At this point the BrowsingContext of the frame has changed, so the members // need to be reset, and notify MediaSessionImpl. SetPlaybackState(blink::mojom::MediaSessionPlaybackState::NONE); - SetMetadata(base::nullopt); + SetMetadata(nullptr); ClearActions(); } @@ -69,19 +69,25 @@ } void MediaSessionServiceImpl::SetMetadata( - const base::Optional<media_session::MediaMetadata>& metadata) { + blink::mojom::SpecMediaMetadataPtr metadata) { + metadata_.reset(); + // When receiving a MediaMetadata, the browser process can't trust that it is // coming from a known and secure source. It must be processed accordingly. - if (metadata.has_value() && - !MediaMetadataSanitizer::CheckSanity(metadata.value())) { - RenderFrameHost* rfh = GetRenderFrameHost(); - if (rfh) { - rfh->GetProcess()->ShutdownForBadMessage( - RenderProcessHost::CrashReportMode::GENERATE_CRASH_DUMP); + if (!metadata.is_null()) { + media_session::MediaMetadata new_metadata; + + if (!MediaMetadataSanitizer::SanitizeAndConvert(metadata, &new_metadata)) { + RenderFrameHost* rfh = GetRenderFrameHost(); + if (rfh) { + rfh->GetProcess()->ShutdownForBadMessage( + RenderProcessHost::CrashReportMode::GENERATE_CRASH_DUMP); + } + return; } - return; + + metadata_ = new_metadata; } - metadata_ = metadata; MediaSessionImpl* session = GetMediaSession(); if (session)
diff --git a/content/browser/media/session/media_session_service_impl.h b/content/browser/media/session/media_session_service_impl.h index 305b8a95..15baf5d 100644 --- a/content/browser/media/session/media_session_service_impl.h +++ b/content/browser/media/session/media_session_service_impl.h
@@ -48,8 +48,7 @@ void SetClient(blink::mojom::MediaSessionClientPtr client) override; void SetPlaybackState(blink::mojom::MediaSessionPlaybackState state) override; - void SetMetadata( - const base::Optional<media_session::MediaMetadata>& metadata) override; + void SetMetadata(blink::mojom::SpecMediaMetadataPtr metadata) override; void EnableAction(media_session::mojom::MediaSessionAction action) override; void DisableAction(media_session::mojom::MediaSessionAction action) override;
diff --git a/content/browser/portal/portal_browsertest.cc b/content/browser/portal/portal_browsertest.cc index db38596..69f6b3c 100644 --- a/content/browser/portal/portal_browsertest.cc +++ b/content/browser/portal/portal_browsertest.cc
@@ -318,4 +318,44 @@ EXPECT_TRUE(proxy_host->is_render_frame_proxy_live()); } +// Tests that the portal's outer delegate frame tree node and any iframes +// inside the portal are deleted when the portal element is removed from the +// document. +IN_PROC_BROWSER_TEST_F(PortalBrowserTest, DetachPortal) { + EXPECT_TRUE(NavigateToURL( + shell(), embedded_test_server()->GetURL("portal.test", "/title1.html"))); + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + RenderFrameHostImpl* main_frame = web_contents->GetMainFrame(); + + Portal* portal = nullptr; + PortalCreatedObserver portal_created_observer(main_frame); + GURL a_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(a)")); + EXPECT_TRUE(ExecJs(main_frame, + JsReplace("var portal = document.createElement('portal');" + "portal.src = $1;" + "document.body.appendChild(portal);", + a_url))); + + // Wait for portal to be created. + portal = portal_created_observer.WaitUntilPortalCreated(); + WebContentsImpl* portal_contents = portal->GetPortalContents(); + FrameTreeNode* portal_main_frame_node = + portal_contents->GetFrameTree()->root(); + + // The portal should not have navigated yet, wait for the first navigation. + TestNavigationObserver navigation_observer(portal_contents); + navigation_observer.Wait(); + + // Remove portal from document and wait for frames to be deleted. + FrameDeletedObserver fdo1(portal_main_frame_node->render_manager() + ->GetOuterDelegateNode() + ->current_frame_host()); + FrameDeletedObserver fdo2( + portal_main_frame_node->child_at(0)->current_frame_host()); + EXPECT_TRUE(ExecJs(main_frame, "document.body.removeChild(portal);")); + fdo1.Wait(); + fdo2.Wait(); +} } // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 43baa4c..60e37cf 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -854,15 +854,35 @@ GetScreenInfo(&visual_properties->screen_info); - if (delegate_) { + if (!delegate_) { + visual_properties->display_mode = blink::kWebDisplayModeBrowser; + } else { visual_properties->is_fullscreen_granted = delegate_->IsFullscreenForCurrentTab(); visual_properties->display_mode = delegate_->GetDisplayMode(this); visual_properties->zoom_level = delegate_->GetPendingPageZoomLevel(); - } else { - visual_properties->is_fullscreen_granted = false; - visual_properties->display_mode = blink::kWebDisplayModeBrowser; - visual_properties->zoom_level = 0; + + RenderViewHostDelegateView* rvh_delegate_view = + delegate_->GetDelegateView(); + DCHECK(rvh_delegate_view); + + visual_properties->browser_controls_shrink_blink_size = + rvh_delegate_view->DoBrowserControlsShrinkRendererSize(); + + float top_controls_height = rvh_delegate_view->GetTopControlsHeight(); + float bottom_controls_height = rvh_delegate_view->GetBottomControlsHeight(); + float browser_controls_dsf_multiplier = 1.f; + // The top and bottom control sizes are physical pixels but the IPC wants + // DIPs *when not using page zoom for DSF* because blink layout is working + // in DIPs then. + if (!IsUseZoomForDSFEnabled()) { + browser_controls_dsf_multiplier = + visual_properties->screen_info.device_scale_factor; + } + visual_properties->top_controls_height = + top_controls_height / browser_controls_dsf_multiplier; + visual_properties->bottom_controls_height = + bottom_controls_height / browser_controls_dsf_multiplier; } visual_properties->auto_resize_enabled = auto_resize_enabled_; @@ -872,32 +892,6 @@ visual_properties->page_scale_factor = page_scale_factor_; if (view_) { - // TODO(danakj): Move this browser controls code out of the if-view block? - if (delegate_) { - RenderViewHostDelegateView* rvh_delegate_view = - delegate_->GetDelegateView(); - DCHECK(rvh_delegate_view); - - visual_properties->browser_controls_shrink_blink_size = - rvh_delegate_view->DoBrowserControlsShrinkRendererSize(); - - float top_controls_height = rvh_delegate_view->GetTopControlsHeight(); - float bottom_controls_height = - rvh_delegate_view->GetBottomControlsHeight(); - float browser_controls_dsf_multiplier = 1.f; - // The top and bottom control sizes are physical pixels but the IPC wants - // DIPs *when not using page zoom for DSF* because blink layout is working - // in DIPs then. - if (!IsUseZoomForDSFEnabled()) { - browser_controls_dsf_multiplier = - visual_properties->screen_info.device_scale_factor; - } - visual_properties->top_controls_height = - top_controls_height / browser_controls_dsf_multiplier; - visual_properties->bottom_controls_height = - bottom_controls_height / browser_controls_dsf_multiplier; - } - visual_properties->new_size = view_->GetRequestedRendererSize(); visual_properties->capture_sequence_number = view_->GetCaptureSequenceNumber();
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index c9dc674..001baf7 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -2276,6 +2276,29 @@ #endif } +IN_PROC_BROWSER_TEST_F(SitePerProcessProgrammaticScrollTest, + ScrolledOutOfView) { + GURL main_frame( + embedded_test_server()->GetURL("a.com", kIframeOutOfViewHTML)); + GURL child_url_b( + embedded_test_server()->GetURL("b.com", kIframeOutOfViewHTML)); + + // This will set up the page frame tree as A(B()). + ASSERT_TRUE(NavigateToURL(shell(), main_frame)); + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + WaitForOnLoad(root); + NavigateFrameToURL(root->child_at(0), child_url_b); + WaitForOnLoad(root->child_at(0)); + + FrameTreeNode* nested_iframe_node = root->child_at(0); + RenderFrameProxyHost* proxy_to_parent = + nested_iframe_node->render_manager()->GetProxyToParent(); + CrossProcessFrameConnector* connector = + proxy_to_parent->cross_process_frame_connector(); + ASSERT_EQ(blink::mojom::FrameVisibility::kRenderedOutOfViewport, + connector->visibility()); +} + // This test verifies that smooth scrolling works correctly inside nested OOPIFs // which are same origin with the parent. Note that since the frame tree has // a A(B(A1())) structure, if and A1 and A2 shared the same @@ -2394,68 +2417,6 @@ EXPECT_FALSE(RenderViewHost::FromID(subframe_process_id, subframe_rvh_id)); } -// Ensure that root frames cannot be detached. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, RestrictFrameDetach) { - GURL main_url(embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))")); - EXPECT_TRUE(NavigateToURL(shell(), main_url)); - - // It is safe to obtain the root frame tree node here, as it doesn't change. - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); - - TestNavigationObserver observer(shell()->web_contents()); - - // Load cross-site pages into both iframes. - GURL foo_url = embedded_test_server()->GetURL("foo.com", "/title2.html"); - NavigateFrameToURL(root->child_at(0), foo_url); - EXPECT_TRUE(observer.last_navigation_succeeded()); - EXPECT_EQ(foo_url, observer.last_navigation_url()); - GURL bar_url = embedded_test_server()->GetURL("bar.com", "/title2.html"); - NavigateFrameToURL(root->child_at(1), bar_url); - EXPECT_TRUE(observer.last_navigation_succeeded()); - EXPECT_EQ(bar_url, observer.last_navigation_url()); - - // Ensure that we have created new processes for the subframes. - ASSERT_EQ(2U, root->child_count()); - FrameTreeNode* foo_child = root->child_at(0); - SiteInstance* foo_site_instance = - foo_child->current_frame_host()->GetSiteInstance(); - EXPECT_NE(shell()->web_contents()->GetSiteInstance(), foo_site_instance); - FrameTreeNode* bar_child = root->child_at(1); - SiteInstance* bar_site_instance = - bar_child->current_frame_host()->GetSiteInstance(); - EXPECT_NE(shell()->web_contents()->GetSiteInstance(), bar_site_instance); - - EXPECT_EQ( - " Site A ------------ proxies for B C\n" - " |--Site B ------- proxies for A C\n" - " +--Site C ------- proxies for A B\n" - "Where A = http://a.com/\n" - " B = http://foo.com/\n" - " C = http://bar.com/", - DepictFrameTree(root)); - - // Simulate an attempt to detach the root frame from foo_site_instance. This - // should kill foo_site_instance's process. - RenderFrameProxyHost* foo_mainframe_rfph = - root->render_manager()->GetRenderFrameProxyHost(foo_site_instance); - content::RenderProcessHostKillWaiter kill_waiter( - foo_mainframe_rfph->GetProcess()); - FrameHostMsg_Detach evil_msg2(foo_mainframe_rfph->GetRoutingID()); - IPC::IpcSecurityTestUtil::PwnMessageReceived( - foo_mainframe_rfph->GetProcess()->GetChannel(), evil_msg2); - EXPECT_EQ(bad_message::RFPH_DETACH, kill_waiter.Wait()); - - EXPECT_EQ( - " Site A ------------ proxies for B C\n" - " |--Site B ------- proxies for A C\n" - " +--Site C ------- proxies for A B\n" - "Where A = http://a.com/\n" - " B = http://foo.com/ (no process)\n" - " C = http://bar.com/", - DepictFrameTree(root)); -} - IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NavigateRemoteFrame) { GURL main_url(embedded_test_server()->GetURL( "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index 7abc0ae2..57f2cfc 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -20,6 +20,7 @@ import "services/viz/public/interfaces/compositing/surface_id.mojom"; import "third_party/blink/public/mojom/blob/blob_url_store.mojom"; import "third_party/blink/public/mojom/feature_policy/feature_policy.mojom"; +import "third_party/blink/public/mojom/frame/lifecycle.mojom"; import "third_party/blink/public/mojom/frame/navigation_initiator.mojom"; import "third_party/blink/public/mojom/loader/url_loader_factory_bundle.mojom"; import "third_party/blink/public/mojom/portal/portal.mojom"; @@ -383,6 +384,10 @@ // longer fullscreen. FullscreenStateChanged(bool is_fullscreen); + // Notifies the browser that the current frame has changed its visibility + // status. + VisibilityChanged(blink.mojom.FrameVisibility visibility); + // Updates information to determine whether a user gesture should carryover to // future navigations. This is needed so navigations within a certain // timeframe of a request initiated by a gesture will be treated as if they
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 5786c40..c8a145df 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -62,6 +62,7 @@ #include "third_party/blink/public/common/messaging/transferable_message.h" #include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom.h" #include "third_party/blink/public/platform/web_focus_type.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/public/platform/web_intrinsic_sizing_info.h" @@ -155,6 +156,8 @@ content::NavigationDownloadPolicy::kMaxValue) IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FeaturePolicyDisposition, blink::mojom::FeaturePolicyDisposition::kMaxValue) +IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FrameVisibility, + blink::mojom::FrameVisibility::kMaxValue) IPC_STRUCT_TRAITS_BEGIN(blink::WebFloatSize) IPC_STRUCT_TRAITS_MEMBER(width) @@ -1462,7 +1465,8 @@ bool /* occluded or obscured */) // Informs the child that the frame has changed visibility. -IPC_MESSAGE_ROUTED1(FrameHostMsg_VisibilityChanged, bool /* visible */) +IPC_MESSAGE_ROUTED1(FrameHostMsg_VisibilityChanged, + blink::mojom::FrameVisibility /* visibility */) // Sent by a RenderFrameProxy to the browser signaling that the renderer // has determined the DOM subtree it represents is inert and should no
diff --git a/content/public/test/unittest_test_suite.cc b/content/public/test/unittest_test_suite.cc index 5d1c4b9..788e922 100644 --- a/content/public/test/unittest_test_suite.cc +++ b/content/public/test/unittest_test_suite.cc
@@ -36,6 +36,18 @@ std::string disabled = command_line->GetSwitchValueASCII(switches::kDisableFeatures); + // Unit tests don't currently work with the Network Service enabled. + // base::TestSuite will reset the FeatureList, so modify the underlying + // CommandLine object to disable the network service when it's parsed again. + disabled += ",NetworkService"; + base::CommandLine new_command_line(command_line->GetProgram()); + base::CommandLine::SwitchMap switches = command_line->GetSwitches(); + switches.erase(switches::kDisableFeatures); + new_command_line.AppendSwitchASCII(switches::kDisableFeatures, disabled); + for (const auto& iter : switches) + new_command_line.AppendSwitchNative(iter.first, iter.second); + *base::CommandLine::ForCurrentProcess() = new_command_line; + // The TaskScheduler created by the test launcher is never destroyed. // Similarly, the FeatureList created here is never destroyed so it // can safely be accessed by the TaskScheduler. @@ -47,6 +59,7 @@ #if defined(OS_FUCHSIA) // Use headless ozone platform on Fuchsia by default. // TODO(crbug.com/865172): Remove this flag. + command_line = base::CommandLine::ForCurrentProcess(); if (!command_line->HasSwitch(switches::kOzonePlatform)) command_line->AppendSwitchASCII(switches::kOzonePlatform, "headless"); #endif
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index db91a60..c5a69ff 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -2561,6 +2561,11 @@ frame_->OnPortalActivated(); } +void RenderFrameImpl::VisibilityChanged( + blink::mojom::FrameVisibility visibility) { + GetFrameHost()->VisibilityChanged(visibility); +} + #if defined(OS_ANDROID) void RenderFrameImpl::ExtractSmartClipData( const gfx::Rect& rect,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 381d964..d8271dc 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -824,6 +824,7 @@ void BubbleLogicalScrollInParentFrame( blink::WebScrollDirection direction, blink::WebScrollGranularity granularity) override; + void VisibilityChanged(blink::mojom::FrameVisibility visibility) override; // WebFrameSerializerClient implementation: void DidSerializeDataForFrame(
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index d29afb3..b2eef59 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -729,7 +729,7 @@ mus_embedded_frame_.reset(); #endif - if (type == DetachType::kRemove && web_frame_->Parent()) { + if (type == DetachType::kRemove) { // Let the browser process know this subframe is removed, so that it is // destroyed in its current process. Send(new FrameHostMsg_Detach(routing_id_)); @@ -858,8 +858,9 @@ last_compositor_visible_rect_, last_occluded_or_obscured_)); } -void RenderFrameProxy::VisibilityChanged(bool visible) { - Send(new FrameHostMsg_VisibilityChanged(routing_id_, visible)); +void RenderFrameProxy::VisibilityChanged( + blink::mojom::FrameVisibility visibility) { + Send(new FrameHostMsg_VisibilityChanged(routing_id_, visibility)); } void RenderFrameProxy::SetIsInert(bool inert) {
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 0f94066..05438f7 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -209,7 +209,7 @@ void UpdateRemoteViewportIntersection( const blink::WebRect& viewport_intersection, bool occluded_or_obscured) override; - void VisibilityChanged(bool visible) override; + void VisibilityChanged(blink::mojom::FrameVisibility visibility) override; void SetIsInert(bool) override; void SetInheritedEffectiveTouchAction(cc::TouchAction) override; void UpdateRenderThrottlingStatus(bool is_throttled,
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 318f5078..398e0972 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -908,8 +908,6 @@ settings->SetSmoothScrollForFindEnabled(prefs.smooth_scroll_for_find_enabled); settings->SetHideDownloadUI(prefs.hide_download_ui); - WebRuntimeFeatures::EnableNewRemotePlaybackPipeline( - base::FeatureList::IsEnabled(media::kNewRemotePlaybackPipeline)); settings->SetPresentationReceiver(prefs.presentation_receiver);
diff --git a/content/renderer/renderer_main_platform_delegate_fuchsia.cc b/content/renderer/renderer_main_platform_delegate_fuchsia.cc index 7af6212..376b47f 100644 --- a/content/renderer/renderer_main_platform_delegate_fuchsia.cc +++ b/content/renderer/renderer_main_platform_delegate_fuchsia.cc
@@ -16,9 +16,6 @@ void RendererMainPlatformDelegate::PlatformUninitialize() {} bool RendererMainPlatformDelegate::EnableSandbox() { - // TODO(750938): Report NOTIMPLEMENTED() here until we re-enable sandboxing - // of sub-processes. - NOTIMPLEMENTED(); return true; }
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc index 0d148c8a..4cc3e61f 100644 --- a/content/test/test_render_frame.cc +++ b/content/test/test_render_frame.cc
@@ -145,6 +145,8 @@ void FullscreenStateChanged(bool is_fullscreen) override {} + void VisibilityChanged(blink::mojom::FrameVisibility visibility) override {} + #if defined(OS_ANDROID) void UpdateUserGestureCarryoverInfo() override {} #endif
diff --git a/fuchsia/common/webrunner_content_client.cc b/fuchsia/common/webrunner_content_client.cc index 019d7e0..f27320e6 100644 --- a/fuchsia/common/webrunner_content_client.cc +++ b/fuchsia/common/webrunner_content_client.cc
@@ -36,7 +36,7 @@ } blink::OriginTrialPolicy* WebRunnerContentClient::GetOriginTrialPolicy() { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return nullptr; }
diff --git a/fuchsia/http/sandbox_policy b/fuchsia/http/sandbox_policy index 15be6c0..63bb84253 100644 --- a/fuchsia/http/sandbox_policy +++ b/fuchsia/http/sandbox_policy
@@ -2,6 +2,7 @@ "features": [ "root-ssl-certificates" ], "services": [ "fuchsia.net.LegacySocketProvider", + "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack" ] }
diff --git a/fuchsia/runners/cast/sandbox_policy b/fuchsia/runners/cast/sandbox_policy index aa36caa..bb596db1 100644 --- a/fuchsia/runners/cast/sandbox_policy +++ b/fuchsia/runners/cast/sandbox_policy
@@ -5,6 +5,7 @@ "fuchsia.fonts.Provider", "fuchsia.media.Audio", "fuchsia.net.LegacySocketProvider", + "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.process.Launcher", "fuchsia.ui.input.ImeService",
diff --git a/fuchsia/runners/web/sandbox_policy b/fuchsia/runners/web/sandbox_policy index 9f8cb63..7db7d14 100644 --- a/fuchsia/runners/web/sandbox_policy +++ b/fuchsia/runners/web/sandbox_policy
@@ -6,6 +6,7 @@ "fuchsia.media.Audio", "fuchsia.mediacodec.CodecFactory", "fuchsia.net.LegacySocketProvider", + "fuchsia.net.SocketProvider", "fuchsia.netstack.Netstack", "fuchsia.process.Launcher", "fuchsia.ui.input.ImeService",
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index cd1605f..24c1570 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn
@@ -272,6 +272,7 @@ include_dirs = [ "//third_party/mesa_headers" ] public_deps = [ + "//cc/paint", "//gpu/command_buffer/common", "//gpu/command_buffer/common:gles2_sources", "//gpu/command_buffer/common:raster_sources", @@ -283,7 +284,6 @@ ":service", "//base", "//base/third_party/dynamic_annotations", - "//cc/paint", "//components/viz/common:resource_format_utils", "//gpu/command_buffer/client", "//gpu/command_buffer/common:gles2_utils",
diff --git a/gpu/ipc/service/DEPS b/gpu/ipc/service/DEPS index 0af5af5..0f692245 100644 --- a/gpu/ipc/service/DEPS +++ b/gpu/ipc/service/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+cc/paint", "+components/viz/common/features.h", "+components/viz/common/resources/resource_format.h", "+third_party/skia",
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc index 500fcc4..899ad32 100644 --- a/gpu/ipc/service/command_buffer_stub.cc +++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/shared_memory.h" +#include "base/no_destructor.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" @@ -782,13 +783,23 @@ } std::unique_ptr<MemoryTracker> CommandBufferStub::CreateMemoryTracker( - const GPUCreateCommandBufferConfig init_params) const { + const GPUCreateCommandBufferConfig& init_params) const { + MemoryTrackerFactory current_factory = GetMemoryTrackerFactory(); + if (current_factory) + return current_factory.Run(init_params); + return std::make_unique<GpuCommandBufferMemoryTracker>( channel_->client_id(), channel_->client_tracing_id(), command_buffer_id_.GetUnsafeValue(), init_params.attribs.context_type, channel_->task_runner()); } +// static +void CommandBufferStub::SetMemoryTrackerFactoryForTesting( + MemoryTrackerFactory factory) { + SetOrGetMemoryTrackerFactory(factory); +} + MemoryTracker* CommandBufferStub::GetMemoryTracker() const { return context_group_->memory_tracker(); } @@ -820,4 +831,20 @@ command_buffer_->SetParseError(error::kLostContext); } +// static +CommandBufferStub::MemoryTrackerFactory +CommandBufferStub::GetMemoryTrackerFactory() { + return SetOrGetMemoryTrackerFactory(base::NullCallback()); +} + +// static +CommandBufferStub::MemoryTrackerFactory +CommandBufferStub::SetOrGetMemoryTrackerFactory(MemoryTrackerFactory factory) { + static base::NoDestructor<MemoryTrackerFactory> current_factory{ + base::NullCallback()}; + if (factory) + *current_factory = factory; + return *current_factory; +} + } // namespace gpu
diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h index a1fb4bed..69fa89e 100644 --- a/gpu/ipc/service/command_buffer_stub.h +++ b/gpu/ipc/service/command_buffer_stub.h
@@ -12,6 +12,7 @@ #include <string> #include <vector> +#include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" @@ -44,6 +45,7 @@ namespace gpu { class DecoderContext; struct Mailbox; +class MemoryTracker; struct SyncToken; struct WaitForCommandState; class GpuChannel; @@ -102,6 +104,14 @@ void OnRescheduleAfterFinished() override; void ScheduleGrContextCleanup() override; + using MemoryTrackerFactory = + base::RepeatingCallback<std::unique_ptr<MemoryTracker>( + const GPUCreateCommandBufferConfig&)>; + + // Overrides the way CreateMemoryTracker() uses to create a MemoryTracker. + // This is intended for mocking the MemoryTracker in tests. + static void SetMemoryTrackerFactoryForTesting(MemoryTrackerFactory factory); + MemoryTracker* GetMemoryTracker() const; // Whether this command buffer can currently handle IPC messages. @@ -138,7 +148,7 @@ GpuChannel* channel); std::unique_ptr<MemoryTracker> CreateMemoryTracker( - const GPUCreateCommandBufferConfig init_params) const; + const GPUCreateCommandBufferConfig& init_params) const; // Must be called during Initialize(). Takes ownership to co-ordinate // teardown in Destroy(). @@ -233,6 +243,16 @@ static void SetContextGpuFeatureInfo(gl::GLContext* context, const GpuFeatureInfo& gpu_feature_info); + static MemoryTrackerFactory GetMemoryTrackerFactory(); + + // Overrides the way CreateMemoryTracker() uses to create a MemoryTracker. If + // |factory| is base::NullCallback(), it returns the current + // MemoryTrackerFactory (initially base::NullCallback() which + // CreateMemoryTracker() should interpret as a signal to use the default). + // This is intended for mocking the MemoryTracker in tests. + static MemoryTrackerFactory SetOrGetMemoryTrackerFactory( + MemoryTrackerFactory factory); + std::unique_ptr<DecoderContext> decoder_context_; uint32_t last_flush_id_;
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc index b542d16..9546122 100644 --- a/gpu/ipc/service/gpu_channel.cc +++ b/gpu/ipc/service/gpu_channel.cc
@@ -267,6 +267,7 @@ static_cast<int32_t>(GpuChannelReservedRoutes::kImageDecodeAccelerator)) { if (!image_decode_accelerator_stub_->OnMessageReceived(message)) return MessageErrorHandler(message, "Invalid image decode request"); + return true; } bool handle_out_of_order =
diff --git a/gpu/ipc/service/gpu_channel_manager_unittest.cc b/gpu/ipc/service/gpu_channel_manager_unittest.cc index 25dbb562..5d170b3 100644 --- a/gpu/ipc/service/gpu_channel_manager_unittest.cc +++ b/gpu/ipc/service/gpu_channel_manager_unittest.cc
@@ -15,7 +15,8 @@ class GpuChannelManagerTest : public GpuChannelTestCommon { public: - GpuChannelManagerTest() : GpuChannelTestCommon() {} + GpuChannelManagerTest() + : GpuChannelTestCommon(true /* use_stub_bindings */) {} ~GpuChannelManagerTest() override = default; #if defined(OS_ANDROID)
diff --git a/gpu/ipc/service/gpu_channel_test_common.cc b/gpu/ipc/service/gpu_channel_test_common.cc index 81a5e03..4a3ba8f4 100644 --- a/gpu/ipc/service/gpu_channel_test_common.cc +++ b/gpu/ipc/service/gpu_channel_test_common.cc
@@ -46,18 +46,22 @@ DISALLOW_COPY_AND_ASSIGN(TestGpuChannelManagerDelegate); }; -GpuChannelTestCommon::GpuChannelTestCommon() - : GpuChannelTestCommon(std::vector<int32_t>()) {} +GpuChannelTestCommon::GpuChannelTestCommon(bool use_stub_bindings) + : GpuChannelTestCommon(std::vector<int32_t>(), use_stub_bindings) {} GpuChannelTestCommon::GpuChannelTestCommon( - std::vector<int32_t> enabled_workarounds) + std::vector<int32_t> enabled_workarounds, + bool use_stub_bindings) : task_runner_(new base::TestSimpleTaskRunner), io_task_runner_(new base::TestSimpleTaskRunner), sync_point_manager_(new SyncPointManager()), scheduler_(new Scheduler(task_runner_, sync_point_manager_.get())), channel_manager_delegate_(new TestGpuChannelManagerDelegate()) { // We need GL bindings to actually initialize command buffers. - gl::GLSurfaceTestSupport::InitializeOneOffWithStubBindings(); + if (use_stub_bindings) + gl::GLSurfaceTestSupport::InitializeOneOffWithStubBindings(); + else + gl::GLSurfaceTestSupport::InitializeOneOff(); GpuFeatureInfo feature_info; feature_info.enabled_gpu_driver_bug_workarounds =
diff --git a/gpu/ipc/service/gpu_channel_test_common.h b/gpu/ipc/service/gpu_channel_test_common.h index cb2ccce..a8575a39 100644 --- a/gpu/ipc/service/gpu_channel_test_common.h +++ b/gpu/ipc/service/gpu_channel_test_common.h
@@ -6,6 +6,7 @@ #define GPU_IPC_SERVICE_GPU_CHANNEL_TEST_COMMON_H_ #include <memory> +#include <vector> #include "base/memory/ref_counted.h" #include "base/memory/unsafe_shared_memory_region.h" @@ -29,9 +30,10 @@ class GpuChannelTestCommon : public testing::Test { public: - GpuChannelTestCommon(); + explicit GpuChannelTestCommon(bool use_stub_bindings); // Constructor which allows a custom set of GPU driver bug workarounds. - explicit GpuChannelTestCommon(std::vector<int32_t> enabled_workarounds); + GpuChannelTestCommon(std::vector<int32_t> enabled_workarounds, + bool use_stub_bindings); ~GpuChannelTestCommon() override; protected:
diff --git a/gpu/ipc/service/gpu_channel_unittest.cc b/gpu/ipc/service/gpu_channel_unittest.cc index b290851e..08d3aa4 100644 --- a/gpu/ipc/service/gpu_channel_unittest.cc +++ b/gpu/ipc/service/gpu_channel_unittest.cc
@@ -12,7 +12,11 @@ namespace gpu { -class GpuChannelTest : public GpuChannelTestCommon {}; +class GpuChannelTest : public GpuChannelTestCommon { + public: + GpuChannelTest() : GpuChannelTestCommon(true /* use_stub_bindings */) {} + ~GpuChannelTest() override = default; +}; #if defined(OS_WIN) const SurfaceHandle kFakeSurfaceHandle = reinterpret_cast<SurfaceHandle>(1); @@ -234,7 +238,8 @@ class GpuChannelExitForContextLostTest : public GpuChannelTestCommon { public: GpuChannelExitForContextLostTest() - : GpuChannelTestCommon({EXIT_ON_CONTEXT_LOST}) {} + : GpuChannelTestCommon({EXIT_ON_CONTEXT_LOST} /* enabled_workarounds */, + true /* use_stub_bindings */) {} }; TEST_F(GpuChannelExitForContextLostTest, CreateFailsDuringLostContextShutdown) {
diff --git a/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc b/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc index ac9f6a2..9a80565 100644 --- a/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc +++ b/gpu/ipc/service/image_decode_accelerator_stub_unittest.cc
@@ -6,32 +6,68 @@ #include <stdint.h> #include <utility> -#include <vector> +#include "base/atomicops.h" +#include "base/bind.h" #include "base/containers/queue.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/numerics/checked_math.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_simple_task_runner.h" +#include "cc/paint/image_transfer_cache_entry.h" +#include "cc/paint/transfer_cache_entry.h" +#include "gpu/command_buffer/common/buffer.h" +#include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/common/constants.h" +#include "gpu/command_buffer/common/context_creation_attribs.h" +#include "gpu/command_buffer/common/context_result.h" +#include "gpu/command_buffer/common/scheduling_priority.h" #include "gpu/command_buffer/common/sync_token.h" +#include "gpu/command_buffer/service/context_group.h" +#include "gpu/command_buffer/service/decoder_context.h" +#include "gpu/command_buffer/service/mocks.h" +#include "gpu/command_buffer/service/service_transfer_cache.h" +#include "gpu/command_buffer/service/shared_context_state.h" #include "gpu/command_buffer/service/sync_point_manager.h" +#include "gpu/command_buffer/service/transfer_buffer_manager.h" +#include "gpu/config/gpu_driver_bug_workarounds.h" #include "gpu/config/gpu_finch_features.h" #include "gpu/ipc/common/command_buffer_id.h" #include "gpu/ipc/common/gpu_messages.h" +#include "gpu/ipc/common/surface_handle.h" +#include "gpu/ipc/service/command_buffer_stub.h" +#include "gpu/ipc/service/gpu_channel.h" #include "gpu/ipc/service/gpu_channel_manager.h" #include "gpu/ipc/service/gpu_channel_test_common.h" #include "gpu/ipc/service/image_decode_accelerator_worker.h" +#include "ipc/ipc_message.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImageInfo.h" +#include "third_party/skia/include/core/SkSize.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/size.h" +#include "url/gurl.h" using testing::InSequence; using testing::StrictMock; namespace gpu { -class GpuChannel; +class MemoryTracker; + +namespace { + +std::unique_ptr<MemoryTracker> CreateMockMemoryTracker( + const GPUCreateCommandBufferConfig& init_params) { + return std::make_unique<gles2::MockMemoryTracker>(); +} + +scoped_refptr<Buffer> MakeBufferForTesting() { + return MakeMemoryBuffer(sizeof(base::subtle::Atomic32)); +} + +} // namespace // This mock allows individual tests to decide asynchronously when to finish a // decode by using the FinishOneDecode() method. @@ -83,19 +119,45 @@ const int kChannelId = 1; +const int32_t kCommandBufferRouteId = + static_cast<int32_t>(GpuChannelReservedRoutes::kMaxValue) + 1; + // Test fixture: the general strategy for testing is to have a GPU channel test // infrastructure (provided by GpuChannelTestCommon), ask the channel to handle -// decode requests, and expect sync token releases and invokations to the -// ImageDecodeAcceleratorWorker functionality. +// decode requests, and expect sync token releases, invocations to the +// ImageDecodeAcceleratorWorker functionality, and transfer cache entry +// creation. class ImageDecodeAcceleratorStubTest : public GpuChannelTestCommon { public: - ImageDecodeAcceleratorStubTest() : GpuChannelTestCommon() {} + ImageDecodeAcceleratorStubTest() + : GpuChannelTestCommon(false /* use_stub_bindings */) {} ~ImageDecodeAcceleratorStubTest() override = default; SyncPointManager* sync_point_manager() const { return channel_manager()->sync_point_manager(); } + ServiceTransferCache* GetServiceTransferCache() { + ContextResult context_result; + scoped_refptr<SharedContextState> shared_context_state = + channel_manager()->GetSharedContextState(&context_result); + if (context_result != ContextResult::kSuccess || !shared_context_state) { + return nullptr; + } + return shared_context_state->transfer_cache(); + } + + int GetRasterDecoderId() { + GpuChannel* channel = channel_manager()->LookupChannel(kChannelId); + if (!channel) + return -1; + CommandBufferStub* command_buffer = + channel->LookupCommandBuffer(kCommandBufferRouteId); + if (!command_buffer || !command_buffer->decoder_context()) + return -1; + return command_buffer->decoder_context()->GetRasterDecoderId(); + } + void SetUp() override { GpuChannelTestCommon::SetUp(); // TODO(andrescj): get rid of the |feature_list_| when the feature is @@ -104,7 +166,49 @@ features::kVaapiJpegImageDecodeAcceleration); channel_manager()->SetImageDecodeAcceleratorWorkerForTesting( &image_decode_accelerator_worker_); - ASSERT_TRUE(CreateChannel(kChannelId, false /* is_gpu_host */)); + + // Initialize the GrContext so that texture uploading works. + ContextResult context_result; + scoped_refptr<SharedContextState> shared_context_state = + channel_manager()->GetSharedContextState(&context_result); + ASSERT_EQ(ContextResult::kSuccess, context_result); + ASSERT_TRUE(shared_context_state); + shared_context_state->InitializeGrContext(GpuDriverBugWorkarounds(), + nullptr); + + GpuChannel* channel = CreateChannel(kChannelId, false /* is_gpu_host */); + ASSERT_TRUE(channel); + + // Create a raster command buffer so that the ImageDecodeAcceleratorStub can + // have access to a TransferBufferManager. Note that we mock the + // MemoryTracker because GpuCommandBufferMemoryTracker uses a timer that + // would make RunTasksUntilIdle() run forever. + CommandBufferStub::SetMemoryTrackerFactoryForTesting( + base::BindRepeating(&CreateMockMemoryTracker)); + GPUCreateCommandBufferConfig init_params; + init_params.surface_handle = kNullSurfaceHandle; + init_params.share_group_id = MSG_ROUTING_NONE; + init_params.stream_id = 0; + init_params.stream_priority = SchedulingPriority::kNormal; + init_params.attribs = ContextCreationAttribs(); + init_params.attribs.enable_gles2_interface = false; + init_params.attribs.enable_raster_interface = true; + init_params.attribs.bind_generates_resource = false; + init_params.active_url = GURL(); + ContextResult result = ContextResult::kTransientFailure; + Capabilities capabilities; + HandleMessage(channel, + new GpuChannelMsg_CreateCommandBuffer( + init_params, kCommandBufferRouteId, + GetSharedMemoryRegion(), &result, &capabilities)); + ASSERT_EQ(ContextResult::kSuccess, result); + CommandBufferStub* command_buffer = + channel->LookupCommandBuffer(kCommandBufferRouteId); + ASSERT_TRUE(command_buffer); + + // Make sure there are no pending tasks before starting the test. + ASSERT_EQ(0u, task_runner()->NumPendingTasks()); + ASSERT_EQ(0u, io_task_runner()->NumPendingTasks()); } void TearDown() override { @@ -114,7 +218,8 @@ } SyncToken SendDecodeRequest(const gfx::Size& output_size, - uint64_t release_count) { + uint64_t release_count, + uint32_t transfer_cache_entry_id) { GpuChannel* channel = channel_manager()->LookupChannel(kChannelId); if (!channel) { // It's possible that the channel was destroyed as part of an earlier @@ -124,18 +229,41 @@ return SyncToken(); } + // Create the decode sync token for the decode request so that we can test + // that it's actually released. SyncToken decode_sync_token( CommandBufferNamespace::GPU_IO, CommandBufferIdFromChannelAndRoute( kChannelId, static_cast<int32_t>( GpuChannelReservedRoutes::kImageDecodeAccelerator)), release_count); + + // We need a buffer to make sure that the ImageDecodeAcceleratorStub can + // create a ServiceDiscardableHandle. + scoped_refptr<Buffer> handle_buffer = MakeBufferForTesting(); + CommandBufferStub* command_buffer = + channel->LookupCommandBuffer(kCommandBufferRouteId); + if (!command_buffer) + return SyncToken(); + scoped_refptr<gles2::ContextGroup> context_group = + command_buffer->context_group(); + if (!context_group) + return SyncToken(); + TransferBufferManager* transfer_buffer_manager = + context_group->transfer_buffer_manager(); + if (!transfer_buffer_manager) + return SyncToken(); + int32_t buffer_shm_id = GetNextBufferId(); + transfer_buffer_manager->RegisterTransferBuffer(buffer_shm_id, + std::move(handle_buffer)); + + // Send the IPC decode request. GpuChannelMsg_ScheduleImageDecode_Params decode_params; decode_params.encoded_data = std::vector<uint8_t>(); decode_params.output_size = output_size; - decode_params.raster_decoder_route_id = 1; - decode_params.transfer_cache_entry_id = 1u; - decode_params.discardable_handle_shm_id = 0; + decode_params.raster_decoder_route_id = kCommandBufferRouteId; + decode_params.transfer_cache_entry_id = transfer_cache_entry_id; + decode_params.discardable_handle_shm_id = buffer_shm_id; decode_params.discardable_handle_shm_offset = 0u; decode_params.target_color_space = gfx::ColorSpace(); decode_params.needs_mips = false; @@ -157,6 +285,35 @@ } } + void CheckTransferCacheEntries(std::vector<SkISize> expected_sizes) { + ServiceTransferCache* transfer_cache = GetServiceTransferCache(); + ASSERT_TRUE(transfer_cache); + + // First, check the number of entries and early out if 0 entries are + // expected. + const size_t num_actual_cache_entries = + transfer_cache->entries_count_for_testing(); + ASSERT_EQ(expected_sizes.size(), num_actual_cache_entries); + if (expected_sizes.empty()) + return; + + // Then, check the dimensions of the entries to make sure they are as + // expected. + int raster_decoder_id = GetRasterDecoderId(); + ASSERT_GE(raster_decoder_id, 0); + for (size_t i = 0; i < num_actual_cache_entries; i++) { + auto* decode_entry = static_cast<cc::ServiceImageTransferCacheEntry*>( + transfer_cache->GetEntry(ServiceTransferCache::EntryKey( + raster_decoder_id, cc::TransferCacheEntryType::kImage, i + 1))); + ASSERT_TRUE(decode_entry); + ASSERT_TRUE(decode_entry->image()); + EXPECT_EQ(expected_sizes[i].width(), + decode_entry->image()->dimensions().width()); + EXPECT_EQ(expected_sizes[i].height(), + decode_entry->image()->dimensions().height()); + } + } + protected: StrictMock<MockImageDecodeAcceleratorWorker> image_decode_accelerator_worker_; @@ -170,11 +327,8 @@ // completed. This should cause one sync token to be released and the scheduler // sequence to be disabled. Then, the second decode is completed. This should // cause the other sync token to be released. -// -// Disabled until ImageDecodeAcceleratorStubTest supports transfer cache -// infrastructure. See https://crbug.com/868400. TEST_F(ImageDecodeAcceleratorStubTest, - DISABLED_MultipleDecodesCompletedAfterSequenceIsDisabled) { + MultipleDecodesCompletedAfterSequenceIsDisabled) { { InSequence call_sequence; EXPECT_CALL(image_decode_accelerator_worker_, DoDecode(gfx::Size(100, 100))) @@ -183,9 +337,11 @@ .Times(1); } const SyncToken decode1_sync_token = SendDecodeRequest( - gfx::Size(100, 100) /* output_size */, 1u /* release_count */); + gfx::Size(100, 100) /* output_size */, 1u /* release_count */, + 1u /* transfer_cache_entry_id */); const SyncToken decode2_sync_token = SendDecodeRequest( - gfx::Size(200, 200) /* output_size */, 2u /* release_count */); + gfx::Size(200, 200) /* output_size */, 2u /* release_count */, + 2u /* transfer_cache_entry_id */); // A decode sync token should not be released before a decode is finished. RunTasksUntilIdle(); @@ -208,17 +364,17 @@ // The channel should still exist at the end. EXPECT_TRUE(channel_manager()->LookupChannel(kChannelId)); + + // Check that the decoded images are in the transfer cache. + CheckTransferCacheEntries({SkISize::Make(100, 100), SkISize::Make(200, 200)}); } // Tests the following flow: three decode requests are sent. The first decode // completes which should cause the scheduler sequence to be enabled. Right // after that (while the sequence is still enabled), the other two decodes // complete. At the end, all the sync tokens should be released. -// -// Disabled until ImageDecodeAcceleratorStubTest supports transfer cache -// infrastructure. See https://crbug.com/868400. TEST_F(ImageDecodeAcceleratorStubTest, - DISABLED_MultipleDecodesCompletedWhileSequenceIsEnabled) { + MultipleDecodesCompletedWhileSequenceIsEnabled) { { InSequence call_sequence; EXPECT_CALL(image_decode_accelerator_worker_, DoDecode(gfx::Size(100, 100))) @@ -229,11 +385,14 @@ .Times(1); } const SyncToken decode1_sync_token = SendDecodeRequest( - gfx::Size(100, 100) /* output_size */, 1u /* release_count */); + gfx::Size(100, 100) /* output_size */, 1u /* release_count */, + 1u /* transfer_cache_entry_id */); const SyncToken decode2_sync_token = SendDecodeRequest( - gfx::Size(200, 200) /* output_size */, 2u /* release_count */); + gfx::Size(200, 200) /* output_size */, 2u /* release_count */, + 2u /* transfer_cache_entry_id */); const SyncToken decode3_sync_token = SendDecodeRequest( - gfx::Size(300, 300) /* output_size */, 3u /* release_count */); + gfx::Size(300, 300) /* output_size */, 3u /* release_count */, + 3u /* transfer_cache_entry_id */); // A decode sync token should not be released before a decode is finished. RunTasksUntilIdle(); @@ -252,16 +411,17 @@ // The channel should still exist at the end. EXPECT_TRUE(channel_manager()->LookupChannel(kChannelId)); + + // Check that the decoded images are in the transfer cache. + CheckTransferCacheEntries({SkISize::Make(100, 100), SkISize::Make(200, 200), + SkISize::Make(300, 300)}); } // Tests the following flow: three decode requests are sent. The first decode // fails which should trigger the destruction of the channel. The second // succeeds and the third one fails. Regardless, the channel should still be // destroyed and all sync tokens should be released. -// -// Disabled until ImageDecodeAcceleratorStubTest supports transfer cache -// infrastructure. See https://crbug.com/868400. -TEST_F(ImageDecodeAcceleratorStubTest, DISABLED_FailedDecodes) { +TEST_F(ImageDecodeAcceleratorStubTest, FailedDecodes) { { InSequence call_sequence; EXPECT_CALL(image_decode_accelerator_worker_, DoDecode(gfx::Size(100, 100))) @@ -272,11 +432,14 @@ .Times(1); } const SyncToken decode1_sync_token = SendDecodeRequest( - gfx::Size(100, 100) /* output_size */, 1u /* release_count */); + gfx::Size(100, 100) /* output_size */, 1u /* release_count */, + 1u /* transfer_cache_entry_id */); const SyncToken decode2_sync_token = SendDecodeRequest( - gfx::Size(200, 200) /* output_size */, 2u /* release_count */); + gfx::Size(200, 200) /* output_size */, 2u /* release_count */, + 2u /* transfer_cache_entry_id */); const SyncToken decode3_sync_token = SendDecodeRequest( - gfx::Size(300, 300) /* output_size */, 3u /* release_count */); + gfx::Size(300, 300) /* output_size */, 3u /* release_count */, + 3u /* transfer_cache_entry_id */); // A decode sync token should not be released before a decode is finished. RunTasksUntilIdle(); @@ -294,17 +457,20 @@ EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(decode1_sync_token)); EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(decode2_sync_token)); EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(decode3_sync_token)); + + // We expect no entries in the transfer cache. + CheckTransferCacheEntries({}); } -// Disabled until ImageDecodeAcceleratorStubTest supports transfer cache -// infrastructure. See https://crbug.com/868400. -TEST_F(ImageDecodeAcceleratorStubTest, DISABLED_OutOfOrderSyncTokens) { +TEST_F(ImageDecodeAcceleratorStubTest, OutOfOrderSyncTokens) { EXPECT_CALL(image_decode_accelerator_worker_, DoDecode(gfx::Size(100, 100))) .Times(1); const SyncToken decode1_sync_token = SendDecodeRequest( - gfx::Size(100, 100) /* output_size */, 2u /* release_count */); + gfx::Size(100, 100) /* output_size */, 2u /* release_count */, + 1u /* transfer_cache_entry_id */); const SyncToken decode2_sync_token = SendDecodeRequest( - gfx::Size(200, 200) /* output_size */, 1u /* release_count */); + gfx::Size(200, 200) /* output_size */, 1u /* release_count */, + 2u /* transfer_cache_entry_id */); // We expect the destruction of the ImageDecodeAcceleratorStub, which also // implies that all decode sync tokens should be released. @@ -312,45 +478,54 @@ EXPECT_FALSE(channel_manager()->LookupChannel(kChannelId)); EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(decode1_sync_token)); EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(decode2_sync_token)); + + // We expect no entries in the transfer cache. + CheckTransferCacheEntries({}); } -// Disabled until ImageDecodeAcceleratorStubTest supports transfer cache -// infrastructure. See https://crbug.com/868400. -TEST_F(ImageDecodeAcceleratorStubTest, DISABLED_ZeroReleaseCountSyncToken) { +TEST_F(ImageDecodeAcceleratorStubTest, ZeroReleaseCountSyncToken) { const SyncToken decode_sync_token = SendDecodeRequest( - gfx::Size(100, 100) /* output_size */, 0u /* release_count */); + gfx::Size(100, 100) /* output_size */, 0u /* release_count */, + 1u /* transfer_cache_entry_id */); // We expect the destruction of the ImageDecodeAcceleratorStub, which also // implies that all decode sync tokens should be released. RunTasksUntilIdle(); EXPECT_FALSE(channel_manager()->LookupChannel(kChannelId)); EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(decode_sync_token)); + + // We expect no entries in the transfer cache. + CheckTransferCacheEntries({}); } -// Disabled until ImageDecodeAcceleratorStubTest supports transfer cache -// infrastructure. See https://crbug.com/868400. -TEST_F(ImageDecodeAcceleratorStubTest, DISABLED_ZeroWidthOutputSize) { +TEST_F(ImageDecodeAcceleratorStubTest, ZeroWidthOutputSize) { const SyncToken decode_sync_token = SendDecodeRequest( - gfx::Size(0, 100) /* output_size */, 1u /* release_count */); + gfx::Size(0, 100) /* output_size */, 1u /* release_count */, + 1u /* transfer_cache_entry_id */); // We expect the destruction of the ImageDecodeAcceleratorStub, which also // implies that all decode sync tokens should be released. RunTasksUntilIdle(); EXPECT_FALSE(channel_manager()->LookupChannel(kChannelId)); EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(decode_sync_token)); + + // We expect no entries in the transfer cache. + CheckTransferCacheEntries({}); } -// Disabled until ImageDecodeAcceleratorStubTest supports transfer cache -// infrastructure. See https://crbug.com/868400. -TEST_F(ImageDecodeAcceleratorStubTest, DISABLED_ZeroHeightOutputSize) { +TEST_F(ImageDecodeAcceleratorStubTest, ZeroHeightOutputSize) { const SyncToken decode_sync_token = SendDecodeRequest( - gfx::Size(100, 0) /* output_size */, 1u /* release_count */); + gfx::Size(100, 0) /* output_size */, 1u /* release_count */, + 1u /* transfer_cache_entry_id */); // We expect the destruction of the ImageDecodeAcceleratorStub, which also // implies that all decode sync tokens should be released. RunTasksUntilIdle(); EXPECT_FALSE(channel_manager()->LookupChannel(kChannelId)); EXPECT_TRUE(sync_point_manager()->IsSyncTokenReleased(decode_sync_token)); + + // We expect no entries in the transfer cache. + CheckTransferCacheEntries({}); } } // namespace gpu
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index 18aed07..951c8a0 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -2327,57 +2327,83 @@ manifest_name: "REVISION" builders { name: "buildbucket/luci.chromium.ci/Win Builder Goma Canary" + category: "win|rel" } builders { name: "buildbucket/luci.chromium.ci/Win Builder (dbg) Goma Canary" + category: "win|dbg" } builders { name: "buildbucket/luci.chromium.ci/Win Goma Canary LocalOutputCache" + category: "win|rel" + short_name: "loc" } builders { name: "buildbucket/luci.chromium.ci/Win cl.exe Goma Canary LocalOutputCache" + category: "cl.exe|rel" + short_name: "loc" } builders { name: "buildbucket/luci.chromium.ci/Win7 Builder Goma Canary" + category: "win7|rel" } builders { name: "buildbucket/luci.chromium.ci/Win7 Builder (dbg) Goma Canary" + category: "win7|dbg" } builders { name: "buildbucket/luci.chromium.ci/WinMSVC64 Goma Canary" + category: "cl.exe|rel" } builders { name: "buildbucket/luci.chromium.ci/Mac Builder Goma Canary" + category: "mac|rel" } builders { name: "buildbucket/luci.chromium.ci/Mac Builder (dbg) Goma Canary" + category: "mac|dbg" } builders { name: "buildbucket/luci.chromium.ci/Mac Goma Canary (clobber)" + category: "mac|rel" + short_name: "clb" } builders { name: "buildbucket/luci.chromium.ci/Mac Builder (dbg) Goma Canary (clobber)" + category: "mac|dbg" + short_name: "clb" } builders { name: "buildbucket/luci.chromium.ci/Mac Goma Canary LocalOutputCache" + category: "mac|rel" + short_name: "loc" } builders { name: "buildbucket/luci.chromium.ci/chromeos-amd64-generic-rel-goma-canary" + category: "cros|rel" } builders { name: "buildbucket/luci.chromium.ci/Linux Builder Goma Canary" + category: "linux|rel" } builders { name: "buildbucket/luci.chromium.ci/Linux x64 Goma Canary (clobber)" + category: "linux|rel" + short_name: "clb" } builders { name: "buildbucket/luci.chromium.ci/Linux x64 Goma Canary LocalOutputCache" + category: "linux|rel" + short_name: "loc" } builders { name: "buildbucket/luci.chromium.ci/Android Builder (dbg) Goma Canary" + category: "android|dbg" } builders { name: "buildbucket/luci.chromium.ci/ios-device-goma-canary-clobber" + category: "ios|rel" + short_name: "clb" } } @@ -2390,57 +2416,83 @@ manifest_name: "REVISION" builders { name: "buildbucket/luci.chromium.ci/Win Builder Goma Latest Client" + category: "win|rel" } builders { name: "buildbucket/luci.chromium.ci/Win Builder (dbg) Goma Latest Client" + category: "win|dbg" } builders { name: "buildbucket/luci.chromium.ci/Win Goma Latest Client LocalOutputCache" + category: "win|rel" + short_name: "loc" } builders { name: "buildbucket/luci.chromium.ci/Win cl.exe Goma Latest Client LocalOutputCache" + category: "cl.exe|rel" + short_name: "loc" } builders { name: "buildbucket/luci.chromium.ci/Win7 Builder Goma Latest Client" + category: "win7|rel" } builders { name: "buildbucket/luci.chromium.ci/Win7 Builder (dbg) Goma Latest Client" + category: "win7|dbg" } builders { name: "buildbucket/luci.chromium.ci/WinMSVC64 Goma Latest Client" + category: "cl.exe|rel" } builders { name: "buildbucket/luci.chromium.ci/Mac Builder Goma Latest Client" + category: "mac|rel" } builders { name: "buildbucket/luci.chromium.ci/Mac Builder (dbg) Goma Latest Client" + category: "mac|dbg" } builders { name: "buildbucket/luci.chromium.ci/Mac Goma Latest Client (clobber)" + category: "mac|rel" + short_name: "clb" } builders { name: "buildbucket/luci.chromium.ci/Mac Builder (dbg) Goma Latest Client (clobber)" + category: "mac|dbg" + short_name: "clb" } builders { name: "buildbucket/luci.chromium.ci/Mac Goma Latest Client LocalOutputCache" + category: "mac|rel" + short_name: "loc" } builders { name: "buildbucket/luci.chromium.ci/chromeos-amd64-generic-rel-goma-latest-client" + category: "cros|rel" } builders { name: "buildbucket/luci.chromium.ci/Linux Builder Goma Latest Client" + category: "linux|rel" } builders { name: "buildbucket/luci.chromium.ci/Linux x64 Goma Latest Client (clobber)" + category: "linux|rel" + short_name: "clb" } builders { name: "buildbucket/luci.chromium.ci/Linux x64 Goma Latest Client LocalOutputCache" + category: "linux|rel" + short_name: "loc" } builders { name: "buildbucket/luci.chromium.ci/Android Builder (dbg) Goma Latest Client" + category: "android|dbg" } builders { name: "buildbucket/luci.chromium.ci/ios-device-goma-latest-client-clobber" + category: "ios" + short_name: "clb" } }
diff --git a/ios/build/bots/scripts/xcodebuild_runner.py b/ios/build/bots/scripts/xcodebuild_runner.py index fc96327..c4ca40c7 100644 --- a/ios/build/bots/scripts/xcodebuild_runner.py +++ b/ios/build/bots/scripts/xcodebuild_runner.py
@@ -75,13 +75,11 @@ return status_summary -def collect_test_results(cmd_list, plist_path, return_code, output): +def collect_test_results(plist_path, output): """Gets test result data from Info.plist and from test output. Args: - cmd_list: (list(str)) A running command. plist_path: (str) A path to plist-file. - return_code: (int) A return code of cmd_list command. output: (str) An output of command. Returns: Test result as a map: @@ -97,16 +95,14 @@ """ test_results = { 'passed': {}, - 'failed': {}, - 'errors': [] + 'failed': {} } root = plistlib.readPlist(plist_path) for action in root['Actions']: action_result = action['ActionResult'] - if ((action_result['TestsCount'] == 0 and - action_result['TestsFailedCount'] == 0 and - action_result['ErrorCount'] != 0) + if ((root['TestsCount'] == 0 and + root['TestsFailedCount'] == 0) or 'TestSummaryPath' not in action_result): test_results['failed']['TESTS_DID_NOT_START'] = [] else: @@ -115,15 +111,6 @@ summary = test_status_summary(summary_plist) test_results['failed'] = summary['failed'] test_results['passed'] = summary['passed'] - - for error_summary in action_result['ErrorSummaries']: - test_results['errors'].append(error_summary['Message']) - # If xcodebuild finished with non-zero status and no failure/error - # in the Info.plist log. - if return_code and ( - not test_results['failed'] and not test_results['errors']): - test_results['errors'].append( - 'Return code of "%s" is not 0!' % cmd_list) test_results['output'] = output return test_results @@ -328,11 +315,11 @@ """Calculates test summary - how many passed, failed and error tests. Returns: - Dictionary with number of errors, passed and failed tests. + Dictionary with number of passed and failed tests. Failed tests will be calculated from the last test attempt. - Passed tests and errors calculated for each test attempt. + Passed tests calculated for each test attempt. """ - test_statuses = ['errors', 'passed', 'failed'] + test_statuses = ['passed', 'failed'] for status in test_statuses: self.logs[status] = 0 @@ -341,9 +328,6 @@ if test_status not in test_attempt_results: continue results = test_attempt_results[test_status] - if test_status == 'errors': - self.logs['errors'] += len(results) - continue for _, destinations_egtests in results.iteritems(): if test_status == 'passed' or ( # Number of failed tests is taken only from last run. @@ -351,11 +335,12 @@ self.test_results['attempts']) - 1): self.logs[test_status] += len(destinations_egtests) - def launch_attempt(self, cmd): + def launch_attempt(self, cmd, out_dir): """Launch a process and do logging simultaneously. Args: cmd: (list[str]) A command to run. + out_dir: (str) Output directory given to the command. Used in tests only. Returns: A tuple (cmd, returncode, output) where: @@ -392,33 +377,32 @@ # total number of attempts is self.retries+1 for attempt in range(self.retries + 1): outdir_attempt = os.path.join(self.out_dir, 'attempt_%d' % attempt) - if attempt == 0: + # Create a command for the 1st run or if tests did not start, + # re-run the same command but with different output folder. + # (http://crbug.com/916620) If tests did not start, repeat the command. + if (not self.test_results['attempts'] or 'TESTS_DID_NOT_START' + in self.test_results['attempts'][-1]['failed']): cmd_list = self.command(self.egtests_app, outdir_attempt, self.destination, self.shards) - initial_command = list(cmd_list) - # (http://crbug.com/916620) If tests has not started, repeat the command - # otherwise re-init based on list of failed tests. - elif 'TESTS_DID_NOT_START' not in self.test_results[ - 'attempts'][-1]['failed']: + if attempt == 0: + initial_command = list(cmd_list) + # Re-init the command based on list of failed tests. + else: cmd_list = self._make_cmd_list_for_failed_tests( self.test_results['attempts'][-1]['failed'], outdir_attempt, test_args=self.egtests_app.test_args, env_vars=self.egtests_app.env_vars) - else: - # If tests did not start, re-run the same command - # but with different output folder. - cmd_list = cmd_list[:-2] + ['-resultBundlePath', outdir_attempt] + # TODO(crbug.com/914878): add heartbeat logging to xcodebuild_runner. print 'Start test attempt #%d for command [%s]' % ( attempt, ' '.join(cmd_list)) - return_code, output = self.launch_attempt(cmd_list) + _, output = self.launch_attempt(cmd_list, outdir_attempt) self.test_results['attempts'].append( - collect_test_results(cmd_list, os.path.join(outdir_attempt, - 'Info.plist'), - return_code, output)) + collect_test_results(os.path.join(outdir_attempt, 'Info.plist'), + output)) if self.retries == attempt or not self.test_results[ 'attempts'][-1]['failed']: break @@ -616,10 +600,8 @@ {'cmd': ' '.join(result['cmd']), 'logs': result['logs']}) self.test_results['end_run'] = int(time.time()) - # Test is failed if any error occurs during test run - # or there are failures for last run. - return not self.test_results['commands'][-1]['logs']['failed'] and all( - [not r['logs']['errors'] for r in self.test_results['commands']]) + # Test is failed if there are failures for the last run. + return not self.test_results['commands'][-1]['logs']['failed'] def erase_all_simulators(self): """Erases all simulator devices.
diff --git a/ios/build/bots/scripts/xcodebuild_runner_test.py b/ios/build/bots/scripts/xcodebuild_runner_test.py index 614c218..4fe768d2 100644 --- a/ios/build/bots/scripts/xcodebuild_runner_test.py +++ b/ios/build/bots/scripts/xcodebuild_runner_test.py
@@ -7,6 +7,9 @@ import mock import os +import plistlib +import shutil +import tempfile import test_runner import test_runner_test import xcodebuild_runner @@ -14,8 +17,7 @@ _ROOT_FOLDER_PATH = 'root/folder' _XCODE_BUILD_VERSION = '10B61' -_DESTINATION = ('platform=iOS Simulator,OS=12.0,name=iPhone 7 Plus;' - 'platform=iOS Simulator,OS=12.0,name=iPhone X') +_DESTINATION = 'platform=iOS Simulator,OS=12.0,name=iPhone X' _OUT_DIR = 'out/dir' _XTEST_RUN = '/tmp/temp_file.xctestrun' _EGTESTS_APP_PATH = '%s/any_egtests.app' % _ROOT_FOLDER_PATH @@ -24,41 +26,108 @@ class XCodebuildRunnerTest(test_runner_test.TestCase): """Test case to test xcodebuild_runner.""" + def setUp(self): + super(XCodebuildRunnerTest, self).setUp() + self.mock(os.path, 'exists', lambda _: True) + self.mock(xcodebuild_runner.LaunchCommand, '_copy_screenshots', + lambda _1, _2, _3: None) + self.mock(xcodebuild_runner.LaunchCommand, 'summary_log', lambda _: None) + self.tmpdir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.tmpdir, ignore_errors=True) + super(XCodebuildRunnerTest, self).tearDown() + + def fake_launch_attempt(self, obj, statuses): + attempt = [0] + info_plist_statuses = { + 'not_started': { + 'Actions': [{'ActionResult': {}}], + 'TestsCount': 0, 'TestsFailedCount': 0 + }, + 'fail': { + 'Actions': [ + {'ActionResult': { + 'TestSummaryPath': '1_Test/TestSummaries.plist'} + } + ], + 'TestsCount': 99, + 'TestsFailedCount': 1}, + 'pass': { + 'Actions': [ + {'ActionResult': { + 'TestSummaryPath': '1_Test/TestSummaries.plist'} + } + ], + 'TestsCount': 100, + 'TestsFailedCount': 0} + } + + test_summary = { + 'TestableSummaries': [ + {'TargetName': 'egtests', + 'Tests': [ + {'Subtests': [ + {'Subtests': [ + {'Subtests': [ + {'TestIdentifier': 'passed_test', + 'TestStatus': 'Success' + } + ] + } + ] + } + ] + } + ] + } + ] + } + + def the_fake(cmd, attempt_outdir): + index = attempt[0] + attempt[0] += 1 + self.assertEqual(os.path.join(self.tmpdir, 'attempt_%d' % index), + attempt_outdir) + self.assertEqual(1, cmd.count(attempt_outdir)) + os.mkdir(attempt_outdir) + with open(os.path.join(attempt_outdir, 'Info.plist'), 'w') as f: + plistlib.writePlist(info_plist_statuses[statuses[index]], f) + summary_folder = os.path.join(attempt_outdir, '1_Test') + os.mkdir(summary_folder) + with open(os.path.join(summary_folder, 'TestSummaries.plist'), 'w') as f: + plistlib.writePlist(test_summary, f) + return (-6, 'Output for attempt_%d' % index) + + obj.launch_attempt = the_fake + def testEgtests_not_found_egtests_app(self): + self.mock(os.path, 'exists', lambda _: False) with self.assertRaises(test_runner.AppNotFoundError): xcodebuild_runner.EgtestsApp(_EGTESTS_APP_PATH) - @mock.patch('os.path.exists', autospec=True) - def testEgtests_not_found_plugins(self, mock_path_exists): - mock_path_exists.return_value = True + def testEgtests_not_found_plugins(self): egtests = xcodebuild_runner.EgtestsApp(_EGTESTS_APP_PATH) - mock_path_exists.return_value = False + self.mock(os.path, 'exists', lambda _: False) with self.assertRaises(test_runner.PlugInsNotFoundError): egtests._xctest_path() @mock.patch('os.listdir', autospec=True) - @mock.patch('os.path.exists', autospec=True) - def testEgtests_found_xctest(self, mock_path_exists, mock_listdir): - mock_path_exists.return_value = True + def testEgtests_found_xctest(self, mock_listdir): mock_listdir.return_value = ['any_egtests.xctest'] self.assertEqual('/PlugIns/any_egtests.xctest', xcodebuild_runner.EgtestsApp( _EGTESTS_APP_PATH)._xctest_path()) @mock.patch('os.listdir', autospec=True) - @mock.patch('os.path.exists', autospec=True) - def testEgtests_not_found_xctest(self, mock_path_exists, mock_listdir): - mock_path_exists.return_value = True + def testEgtests_not_found_xctest(self, mock_listdir): mock_listdir.return_value = ['some_egtests.xctest'] egtest = xcodebuild_runner.EgtestsApp(_EGTESTS_APP_PATH) with self.assertRaises(test_runner.XCTestPlugInNotFoundError): egtest._xctest_path() @mock.patch('os.listdir', autospec=True) - @mock.patch('os.path.exists', autospec=True) - def testEgtests_xctestRunNode_without_filter(self, mock_path_exists, - mock_listdir): - mock_path_exists.return_value = True + def testEgtests_xctestRunNode_without_filter(self, mock_listdir): mock_listdir.return_value = ['any_egtests.xctest'] egtest_node = xcodebuild_runner.EgtestsApp( _EGTESTS_APP_PATH).xctestrun_node()['any_egtests_module'] @@ -66,10 +135,8 @@ self.assertNotIn('SkipTestIdentifiers', egtest_node) @mock.patch('os.listdir', autospec=True) - @mock.patch('os.path.exists', autospec=True) - def testEgtests_xctestRunNode_with_filter_only_identifiers( - self, mock_path_exists, mock_listdir): - mock_path_exists.return_value = True + def testEgtests_xctestRunNode_with_filter_only_identifiers(self, + mock_listdir): mock_listdir.return_value = ['any_egtests.xctest'] filtered_tests = ['TestCase1/testMethod1', 'TestCase1/testMethod2', 'TestCase2/testMethod1', 'TestCase1/testMethod2'] @@ -80,10 +147,8 @@ self.assertNotIn('SkipTestIdentifiers', egtest_node) @mock.patch('os.listdir', autospec=True) - @mock.patch('os.path.exists', autospec=True) - def testEgtests_xctestRunNode_with_filter_skip_identifiers( - self, mock_path_exists, mock_listdir): - mock_path_exists.return_value = True + def testEgtests_xctestRunNode_with_filter_skip_identifiers(self, + mock_listdir): mock_listdir.return_value = ['any_egtests.xctest'] skipped_tests = ['TestCase1/testMethod1', 'TestCase1/testMethod2', 'TestCase2/testMethod1', 'TestCase1/testMethod2'] @@ -94,16 +159,13 @@ self.assertNotIn('OnlyTestIdentifiers', egtest_node) @mock.patch('xcodebuild_runner.LaunchCommand.fill_xctest_run', autospec=True) - @mock.patch('os.path.exists', autospec=True) - def testLaunchCommand_command(self, mock_path_exists, mock_fill_xctestrun): - mock_path_exists.return_value = True - destination = 'platform=iOS Simulator,OS=12.0,name=iPhone X' + def testLaunchCommand_command(self, mock_fill_xctestrun): mock_fill_xctestrun.return_value = _XTEST_RUN mock_egtest = mock.MagicMock(spec=xcodebuild_runner.EgtestsApp) type(mock_egtest).egtests_path = mock.PropertyMock( return_value=_EGTESTS_APP_PATH) cmd = xcodebuild_runner.LaunchCommand( - mock_egtest, destination, shards=3, retries=1, out_dir=_OUT_DIR) + mock_egtest, _DESTINATION, shards=3, retries=1, out_dir=_OUT_DIR) self.assertEqual(['xcodebuild', 'test-without-building', '-xctestrun', '/tmp/temp_file.xctestrun', '-destination', @@ -113,19 +175,17 @@ '-parallel-testing-worker-count', '3'], cmd.command(egtests_app=mock_egtest, out_dir=_OUT_DIR, - destination=destination, + destination=_DESTINATION, shards=3)) @mock.patch('plistlib.writePlist', autospec=True) - @mock.patch('os.path.exists', autospec=True) @mock.patch('os.path.join', autospec=True) - def testFill_xctest_run(self, mock_path_join, mock_path_exists, _): + def testFill_xctest_run(self, mock_path_join, _): + self._mocks[xcodebuild_runner.LaunchCommand].pop('fill_xctest_run', None) mock_path_join.return_value = _XTEST_RUN - mock_path_exists.return_value = True - destination = 'platform=iOS Simulator,OS=12.0,name=iPhone X' mock_egtest = mock.MagicMock(spec=xcodebuild_runner.EgtestsApp) launch_command = xcodebuild_runner.LaunchCommand( - mock_egtest, destination, shards=1, retries=1, out_dir=_OUT_DIR) + mock_egtest, _DESTINATION, shards=1, retries=1, out_dir=_OUT_DIR) self.assertEqual(_XTEST_RUN, launch_command.fill_xctest_run(mock_egtest)) self.assertEqual([mock.call.xctestrun_node()], mock_egtest.method_calls) @@ -135,15 +195,12 @@ out_dir=_OUT_DIR).fill_xctest_run([]) @mock.patch('xcodebuild_runner.LaunchCommand.fill_xctest_run', autospec=True) - @mock.patch('os.path.exists', autospec=True) - def testLaunchCommand_make_cmd_list_for_failed_tests(self, mock_path_exists, + def testLaunchCommand_make_cmd_list_for_failed_tests(self, fill_xctest_run_mock): - mock_path_exists.return_value = True fill_xctest_run_mock.side_effect = [ '/var/folders/tmpfile1' ] egtest_app = 'module_1_egtests.app' - destination = 'platform=iOS Simulator,OS=12.0,name=iPhone X' egtest_app_path = '%s/%s' % (_ROOT_FOLDER_PATH, egtest_app) failed_tests = { egtest_app: [ @@ -159,7 +216,7 @@ return_value=egtest_app_path) cmd = xcodebuild_runner.LaunchCommand( egtests_app=mock_egtest, - destination=destination, + destination=_DESTINATION, out_dir='out/dir/attempt_2/iPhone X 12.0', shards=1, retries=1 @@ -169,3 +226,16 @@ self.assertEqual(1, len(fill_xctest_run_mock.mock_calls)) self.assertItemsEqual(expected_egtests.__dict__, fill_xctest_run_mock.mock_calls[0][1][1].__dict__) + + @mock.patch('os.listdir', autospec=True) + def testLaunchCommand_restartFailed1stAttempt(self, mock_listdir): + mock_listdir.return_value = ['any_egtests.xctest'] + egtests = xcodebuild_runner.EgtestsApp(_EGTESTS_APP_PATH) + launch_command = xcodebuild_runner.LaunchCommand(egtests, + _DESTINATION, + shards=1, + retries=3, + out_dir=self.tmpdir) + self.fake_launch_attempt(launch_command, ['not_started', 'pass']) + launch_command.launch() + self.assertEqual(2, len(launch_command.test_results))
diff --git a/ios/chrome/browser/translate/BUILD.gn b/ios/chrome/browser/translate/BUILD.gn index 26760ce2..5521bf0 100644 --- a/ios/chrome/browser/translate/BUILD.gn +++ b/ios/chrome/browser/translate/BUILD.gn
@@ -79,23 +79,18 @@ ":translate", "//base", "//base/test:test_support", - "//components/language/core/browser", - "//components/sync_preferences:test_support", - "//components/translate/core/browser", - "//components/translate/core/browser:unit_tests", + "//components/translate/core/browser:test_support", "//components/translate/ios/browser", "//ios/chrome/browser", - "//ios/chrome/browser/browser_state:test_support", - "//ios/chrome/browser/translate", "//ios/chrome/browser/web:test_support", "//ios/chrome/common", "//ios/public/provider/chrome/browser:test_support", - "//ios/web", - "//ios/web/public/test", + "//ios/web/public", + "//ios/web/public/test:util", "//skia", - "//testing/gmock:gmock", + "//testing/gmock", "//testing/gtest", - "//url", + "//url:url", ] }
diff --git a/ios/chrome/browser/translate/chrome_ios_translate_client.h b/ios/chrome/browser/translate/chrome_ios_translate_client.h index 68d2c86..4b46653 100644 --- a/ios/chrome/browser/translate/chrome_ios_translate_client.h +++ b/ios/chrome/browser/translate/chrome_ios_translate_client.h
@@ -78,15 +78,27 @@ bool IsTranslatableURL(const GURL& url) override; void ShowReportLanguageDetectionErrorUI(const GURL& report_url) override; + id<LanguageSelectionHandler> language_selection_handler() { + return language_selection_handler_; + } + void set_language_selection_handler(id<LanguageSelectionHandler> handler) { language_selection_handler_ = handler; } + id<TranslateOptionSelectionHandler> translate_option_selection_handler() { + return translate_option_selection_handler_; + } + void set_translate_option_selection_handler( id<TranslateOptionSelectionHandler> handler) { translate_option_selection_handler_ = handler; } + id<TranslateNotificationHandler> translate_notification_handler() { + return translate_notification_handler_; + } + void set_translate_notification_handler( id<TranslateNotificationHandler> handler) { translate_notification_handler_ = handler;
diff --git a/ios/chrome/browser/translate/translate_infobar_delegate_observer_bridge_unittest.mm b/ios/chrome/browser/translate/translate_infobar_delegate_observer_bridge_unittest.mm index d6943d0..fae6ee7 100644 --- a/ios/chrome/browser/translate/translate_infobar_delegate_observer_bridge_unittest.mm +++ b/ios/chrome/browser/translate/translate_infobar_delegate_observer_bridge_unittest.mm
@@ -6,16 +6,7 @@ #include <memory> -#include "components/language/core/browser/language_model.h" -#include "components/sync_preferences/testing_pref_service_syncable.h" -#include "components/translate/core/browser/mock_translate_client.h" -#include "components/translate/core/browser/mock_translate_driver.h" -#include "components/translate/core/browser/mock_translate_ranker.h" -#include "components/translate/core/browser/translate_infobar_delegate.h" -#include "components/translate/core/browser/translate_manager.h" -#include "components/translate/core/browser/translate_pref_names.h" -#include "components/translate/core/browser/translate_prefs.h" -#include "testing/gmock/include/gmock/gmock.h" +#include "components/translate/core/browser/mock_translate_infobar_delegate.h" #include "testing/gtest_mac.h" #include "testing/platform_test.h" @@ -23,75 +14,8 @@ #error "This file requires ARC support." #endif -using testing::_; -using translate::testing::MockTranslateClient; -using translate::testing::MockTranslateDriver; -using translate::testing::MockTranslateRanker; - -class MockLanguageModel : public language::LanguageModel { - std::vector<LanguageDetails> GetLanguages() override { - return {LanguageDetails("en", 1.0)}; - } -}; - -class MockTranslateInfoBarDelegate - : public translate::TranslateInfoBarDelegate { - public: - MockTranslateInfoBarDelegate( - const base::WeakPtr<translate::TranslateManager>& translate_manager, - bool is_off_the_record, - translate::TranslateStep step, - const std::string& original_language, - const std::string& target_language, - translate::TranslateErrors::Type error_type, - bool triggered_from_menu) - : translate::TranslateInfoBarDelegate(translate_manager, - is_off_the_record, - step, - original_language, - target_language, - error_type, - triggered_from_menu) {} - ~MockTranslateInfoBarDelegate() override {} - - MOCK_METHOD1(SetObserver, void(Observer* observer)); -}; - -class MockTranslateInfoBarDelegateFactory { - public: - MockTranslateInfoBarDelegateFactory() { - pref_service_ = - std::make_unique<sync_preferences::TestingPrefServiceSyncable>(); - translate::TranslatePrefs::RegisterProfilePrefs(pref_service_->registry()); - pref_service_->registry()->RegisterBooleanPref( - prefs::kOfferTranslateEnabled, true); - client_ = - std::make_unique<MockTranslateClient>(&driver_, pref_service_.get()); - ranker_ = std::make_unique<MockTranslateRanker>(); - language_model_ = std::make_unique<MockLanguageModel>(); - manager_ = std::make_unique<translate::TranslateManager>( - client_.get(), ranker_.get(), language_model_.get()); - delegate_ = std::make_unique<MockTranslateInfoBarDelegate>( - manager_->GetWeakPtr(), false, - translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE, "fr", "en", - translate::TranslateErrors::Type::NONE, false); - } - - ~MockTranslateInfoBarDelegateFactory() = default; - - MockTranslateInfoBarDelegate* GetMockTranslateInfoBarDelegate() { - return delegate_.get(); - } - - private: - MockTranslateDriver driver_; - std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> pref_service_; - std::unique_ptr<MockTranslateClient> client_; - std::unique_ptr<MockTranslateRanker> ranker_; - std::unique_ptr<MockLanguageModel> language_model_; - std::unique_ptr<translate::TranslateManager> manager_; - std::unique_ptr<MockTranslateInfoBarDelegate> delegate_; -}; +using translate::testing::MockTranslateInfoBarDelegate; +using translate::testing::MockTranslateInfoBarDelegateFactory; @interface TestTranslateInfoBarDelegateObserver : NSObject <TranslateInfobarDelegateObserving> @@ -129,7 +53,8 @@ class TranslateInfobarDelegateObserverBridgeTest : public PlatformTest { protected: TranslateInfobarDelegateObserverBridgeTest() - : observer_([[TestTranslateInfoBarDelegateObserver alloc] init]) { + : delegate_factory_("fr", "en"), + observer_([[TestTranslateInfoBarDelegateObserver alloc] init]) { // Make sure the observer bridge sets up itself as an observer. EXPECT_CALL(*GetDelegate(), SetObserver(_)).Times(1);
diff --git a/ios/chrome/browser/ui/translate/BUILD.gn b/ios/chrome/browser/ui/translate/BUILD.gn index d0ab04d0..ad3499c 100644 --- a/ios/chrome/browser/ui/translate/BUILD.gn +++ b/ios/chrome/browser/ui/translate/BUILD.gn
@@ -71,3 +71,28 @@ "//ui/base", ] } + +source_set("unit_tests") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + sources = [ + "translate_infobar_mediator_unittest.mm", + ] + deps = [ + ":translate", + "//components/translate/core/browser:test_support", + "//ios/chrome/browser/browser_state:test_support", + "//ios/chrome/browser/translate", + "//ios/chrome/browser/ui/popup_menu/public:popup_menu_ui", + "//ios/chrome/browser/ui/translate:translate_ui", + "//ios/chrome/browser/ui/translate/cells", + "//ios/chrome/browser/web_state_list", + "//ios/chrome/browser/web_state_list:test_support", + "//ios/web/public/test", + "//ios/web/public/test/fakes", + "//skia", + "//testing/gmock", + "//testing/gtest", + "//third_party/ocmock:ocmock", + ] +}
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm index c67aff5..955bf22 100644 --- a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm +++ b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm
@@ -75,12 +75,12 @@ // the ripple effect on the button won't be seen. [UIView animateWithDuration:kActivityIndicatorVisbilityAnimationDuration animations:^{ - self.activityIndicator.hidden = NO; - self.button.hidden = YES; + self.activityIndicator.alpha = 1.0; + self.button.alpha = 0.0; }]; } else { - self.button.hidden = NO; - self.activityIndicator.hidden = YES; + self.button.alpha = 1.0; + self.activityIndicator.alpha = 0.0; [self.activityIndicator stopAnimating]; [self.button setTitleColor:[self titleColor] forState:UIControlStateNormal]; @@ -96,7 +96,7 @@ self.activityIndicator.cycleColors = @[ [[MDCPalette cr_bluePalette] tint500] ]; [self.activityIndicator setRadius:kActivityIndicatorRadius]; - self.activityIndicator.hidden = YES; // Initially hidden. + self.activityIndicator.alpha = 0.0; // Initially hidden. [self addSubview:self.activityIndicator]; [NSLayoutConstraint activateConstraints:@[
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_mediator_unittest.mm b/ios/chrome/browser/ui/translate/translate_infobar_mediator_unittest.mm new file mode 100644 index 0000000..8a9c84b --- /dev/null +++ b/ios/chrome/browser/ui/translate/translate_infobar_mediator_unittest.mm
@@ -0,0 +1,260 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/translate/translate_infobar_mediator.h" + +#include <memory> + +#import "base/mac/foundation_util.h" +#include "base/strings/utf_string_conversions.h" +#include "components/translate/core/browser/mock_translate_infobar_delegate.h" +#import "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#include "ios/chrome/browser/translate/chrome_ios_translate_client.h" +#import "ios/chrome/browser/translate/language_selection_handler.h" +#import "ios/chrome/browser/translate/translate_option_selection_handler.h" +#import "ios/chrome/browser/ui/popup_menu/public/popup_menu_consumer.h" +#import "ios/chrome/browser/ui/translate/cells/select_language_popup_menu_item.h" +#import "ios/chrome/browser/ui/translate/cells/translate_popup_menu_item.h" +#import "ios/chrome/browser/ui/translate/translate_notification_handler.h" +#import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/chrome/browser/web_state_list/web_state_opener.h" +#import "ios/web/public/test/fakes/crw_test_js_injection_receiver.h" +#import "ios/web/public/test/fakes/test_navigation_manager.h" +#import "ios/web/public/test/fakes/test_web_state.h" +#include "ios/web/public/test/test_web_thread_bundle.h" +#include "testing/gtest_mac.h" +#include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#import "third_party/ocmock/gtest_support.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using translate::testing::MockTranslateInfoBarDelegate; +using translate::testing::MockTranslateInfoBarDelegateFactory; + +// A protocol used to mock a +// id<LanguageSelectionHandler,TranslateOptionSelectionHandler>. +@protocol TestSelectionHandlerProtocol <LanguageSelectionHandler, + TranslateOptionSelectionHandler> +@end + +// Test class that conforms to PopupMenuConsumer and exposes the menu items. +@interface TestPopupMenuConsumer : NSObject <PopupMenuConsumer> + +@property(nonatomic, strong) + NSMutableArray<TableViewItem<PopupMenuItem>*>* items; + +@end + +@implementation TestPopupMenuConsumer + +@synthesize itemToHighlight; + +- (void)setPopupMenuItems: + (NSArray<NSArray<TableViewItem<PopupMenuItem>*>*>*)items { + _items = [[NSMutableArray alloc] init]; + + for (NSArray* innerArray in items) { + [_items addObjectsFromArray:innerArray]; + } +} + +- (void)itemsHaveChanged:(NSArray<TableViewItem<PopupMenuItem>*>*)items { + EXPECT_TRUE(false) << "This method should not be called."; +} + +@end + +class TranslateInfobarMediatorTest : public PlatformTest { + protected: + TranslateInfobarMediatorTest() + : browser_state_(TestChromeBrowserState::Builder().Build()), + web_state_list_( + std::make_unique<WebStateList>(&web_state_list_delegate_)), + delegate_factory_("fr", "en"), + selection_handler_([OCMockObject + niceMockForProtocol:@protocol(TestSelectionHandlerProtocol)]), + notification_handler_([OCMockObject + niceMockForProtocol:@protocol(TranslateNotificationHandler)]), + mediator_([[TranslateInfobarMediator alloc] + initWithSelectionHandler:selection_handler_ + notificationHandler:notification_handler_]) { + CreateTranslateClient(); + } + + WebStateList* web_state_list() { return web_state_list_.get(); } + + id selection_handler() { return selection_handler_; } + + id notification_handler() { return notification_handler_; } + + TranslateInfobarMediator* mediator() { return mediator_; } + + void CreateTranslateClient() { + auto web_state = std::make_unique<web::TestWebState>(); + + // Set up browser state. + web_state->SetBrowserState(browser_state_.get()); + + // Set up navigation manager. + std::unique_ptr<web::TestNavigationManager> navigation_manager = + std::make_unique<web::TestNavigationManager>(); + navigation_manager->SetBrowserState(browser_state_.get()); + web_state->SetNavigationManager(std::move(navigation_manager)); + + // Set up JS injection receiver. + CRWTestJSInjectionReceiver* injectionReceiver = + [[CRWTestJSInjectionReceiver alloc] init]; + web_state->SetJSInjectionReceiver(injectionReceiver); + + // Create ChromeIOSTranslateClient. + ChromeIOSTranslateClient::CreateForWebState(web_state.get()); + + int effective_index = web_state_list_->InsertWebState( + 0, std::move(web_state), WebStateList::INSERT_NO_FLAGS, + WebStateOpener()); + web_state_list_->ActivateWebStateAt(effective_index); + } + + ChromeIOSTranslateClient* GetTranslateClient() { + return ChromeIOSTranslateClient::FromWebState( + web_state_list_->GetActiveWebState()); + } + + MockTranslateInfoBarDelegate* GetDelegate() { + return delegate_factory_.GetMockTranslateInfoBarDelegate(); + } + + private: + web::TestWebThreadBundle web_thread_bundle_; + std::unique_ptr<TestChromeBrowserState> browser_state_; + FakeWebStateListDelegate web_state_list_delegate_; + std::unique_ptr<WebStateList> web_state_list_; + MockTranslateInfoBarDelegateFactory delegate_factory_; + id selection_handler_; + id notification_handler_; + TranslateInfobarMediator* mediator_; + + DISALLOW_COPY_AND_ASSIGN(TranslateInfobarMediatorTest); +}; + +// Tests that the mediator installs UI handlers on existing +// ChromeIOSTranslateClient instances as well as new ones that become available. +TEST_F(TranslateInfobarMediatorTest, InstallHandlers) { + ChromeIOSTranslateClient* translate_client = GetTranslateClient(); + + // Make sure the handlers are not set. + EXPECT_EQ(nil, translate_client->language_selection_handler()); + EXPECT_EQ(nil, translate_client->translate_option_selection_handler()); + EXPECT_EQ(nil, translate_client->translate_notification_handler()); + + TranslateInfobarMediator* translate_infobar_mediator = mediator(); + translate_infobar_mediator.webStateList = web_state_list(); + + EXPECT_EQ(selection_handler(), + translate_client->language_selection_handler()); + EXPECT_EQ(selection_handler(), + translate_client->translate_option_selection_handler()); + EXPECT_EQ(notification_handler(), + translate_client->translate_notification_handler()); + + CreateTranslateClient(); + ChromeIOSTranslateClient* new_translate_client = GetTranslateClient(); + EXPECT_NE(new_translate_client, translate_client); + + EXPECT_EQ(selection_handler(), + new_translate_client->language_selection_handler()); + EXPECT_EQ(selection_handler(), + new_translate_client->translate_option_selection_handler()); + EXPECT_EQ(notification_handler(), + new_translate_client->translate_notification_handler()); +} + +// Tests that the mediator sets the expected menu items for the translate +// options popup menu on its consumer. +TEST_F(TranslateInfobarMediatorTest, TranslateOptionMenuItems) { + // Set up what TranslateInfoBarDelegate should return. + EXPECT_CALL(*GetDelegate(), original_language_name()) + .WillRepeatedly(testing::Return(base::UTF8ToUTF16("French"))); + EXPECT_CALL(*GetDelegate(), ShouldAlwaysTranslate()) + .WillOnce(testing::Return(true)); + + TranslateInfobarMediator* translate_infobar_mediator = mediator(); + translate_infobar_mediator.type = + TranslatePopupMenuTypeTranslateOptionSelection; + translate_infobar_mediator.infobarDelegate = GetDelegate(); + TestPopupMenuConsumer* consumer = [[TestPopupMenuConsumer alloc] init]; + translate_infobar_mediator.consumer = consumer; + + ASSERT_EQ(5U, consumer.items.count); + + TranslatePopupMenuItem* firstItem = + base::mac::ObjCCastStrict<TranslatePopupMenuItem>(consumer.items[0]); + EXPECT_EQ(PopupMenuActionChangeTargetLanguage, firstItem.actionIdentifier); + EXPECT_FALSE(firstItem.selected); + + TranslatePopupMenuItem* secondItem = + base::mac::ObjCCastStrict<TranslatePopupMenuItem>(consumer.items[1]); + EXPECT_EQ(PopupMenuActionAlwaysTranslateSourceLanguage, + secondItem.actionIdentifier); + EXPECT_TRUE(secondItem.selected); + + TranslatePopupMenuItem* thirdItem = + base::mac::ObjCCastStrict<TranslatePopupMenuItem>(consumer.items[2]); + EXPECT_EQ(PopupMenuActionNeverTranslateSourceLanguage, + thirdItem.actionIdentifier); + EXPECT_FALSE(thirdItem.selected); + + TranslatePopupMenuItem* fourthItem = + base::mac::ObjCCastStrict<TranslatePopupMenuItem>(consumer.items[3]); + EXPECT_EQ(PopupMenuActionNeverTranslateSite, fourthItem.actionIdentifier); + EXPECT_FALSE(fourthItem.selected); + + TranslatePopupMenuItem* fifthItem = + base::mac::ObjCCastStrict<TranslatePopupMenuItem>(consumer.items[4]); + EXPECT_EQ(PopupMenuActionChangeSourceLanguage, fifthItem.actionIdentifier); + EXPECT_FALSE(fifthItem.selected); +} + +// Tests that the mediator sets the expected menu items for the language +// selection popup menu on its consumer. +TEST_F(TranslateInfobarMediatorTest, LanguageSelectionMenuItems) { + // Set up what TranslateInfoBarDelegate should return. + EXPECT_CALL(*GetDelegate(), num_languages()) + .WillRepeatedly(testing::Return(3ul)); + EXPECT_CALL(*GetDelegate(), language_code_at(0)) + .WillOnce(testing::Return("en")); + EXPECT_CALL(*GetDelegate(), language_name_at(0)) + .WillOnce(testing::Return(base::UTF8ToUTF16("English"))); + EXPECT_CALL(*GetDelegate(), language_code_at(2)) + .WillOnce(testing::Return("fr")); + EXPECT_CALL(*GetDelegate(), language_name_at(2)) + .WillOnce(testing::Return(base::UTF8ToUTF16("French"))); + + TranslateInfobarMediator* translate_infobar_mediator = mediator(); + translate_infobar_mediator.type = TranslatePopupMenuTypeLanguageSelection; + translate_infobar_mediator.infobarDelegate = GetDelegate(); + translate_infobar_mediator.unavailableLanguageIndex = 1; + TestPopupMenuConsumer* consumer = [[TestPopupMenuConsumer alloc] init]; + translate_infobar_mediator.consumer = consumer; + + ASSERT_EQ(2U, consumer.items.count); + + SelectLanguagePopupMenuItem* firstItem = + base::mac::ObjCCastStrict<SelectLanguagePopupMenuItem>(consumer.items[0]); + EXPECT_EQ(PopupMenuActionSelectLanguage, firstItem.actionIdentifier); + EXPECT_FALSE(firstItem.selected); + EXPECT_TRUE([firstItem.languageCode isEqualToString:@"en"]); + EXPECT_TRUE([firstItem.title isEqualToString:@"English"]); + + SelectLanguagePopupMenuItem* secondItem = + base::mac::ObjCCastStrict<SelectLanguagePopupMenuItem>(consumer.items[1]); + EXPECT_EQ(PopupMenuActionSelectLanguage, secondItem.actionIdentifier); + EXPECT_FALSE(secondItem.selected); + EXPECT_TRUE([secondItem.languageCode isEqualToString:@"fr"]); + EXPECT_TRUE([secondItem.title isEqualToString:@"French"]); +}
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 7a3808b5..bb4f959 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -242,6 +242,7 @@ "//ios/chrome/browser/ui/toolbar:unit_tests", "//ios/chrome/browser/ui/toolbar/fullscreen:unit_tests", "//ios/chrome/browser/ui/toolbar_container:unit_tests", + "//ios/chrome/browser/ui/translate:unit_tests", "//ios/chrome/browser/ui/util:unit_tests", "//ios/chrome/browser/ui/voice:unit_tests", "//ios/chrome/browser/update_client:unit_tests",
diff --git a/ios/web_view/shell/shell_view_controller.m b/ios/web_view/shell/shell_view_controller.m index 9227aba..1ed8f80 100644 --- a/ios/web_view/shell/shell_view_controller.m +++ b/ios/web_view/shell/shell_view_controller.m
@@ -141,6 +141,7 @@ action:@selector(showMenu) forControlEvents:UIControlEventTouchUpInside]; + _field.placeholder = @"Search or type URL"; _field.backgroundColor = [UIColor whiteColor]; _field.tintColor = _headerBackgroundView.backgroundColor; [_field setContentHuggingPriority:UILayoutPriorityDefaultLow - 1
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 7cfab24..972ca80d 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -281,10 +281,6 @@ const base::Feature kNewEncodeCpuLoadEstimator{ "NewEncodeCpuLoadEstimator", base::FEATURE_DISABLED_BY_DEFAULT}; -// Use the new Remote Playback / media flinging pipeline. -const base::Feature kNewRemotePlaybackPipeline{ - "NewRemotePlaybackPipeline", base::FEATURE_ENABLED_BY_DEFAULT}; - // Use the new RTC hardware decode path via RTCVideoDecoderAdapter. const base::Feature kRTCVideoDecoderAdapter{"RTCVideoDecoderAdapter", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index bd8b8cd..0400e04 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -118,7 +118,6 @@ MEDIA_EXPORT extern const base::Feature kMojoVideoDecoder; MEDIA_EXPORT extern const base::Feature kMseBufferByPts; MEDIA_EXPORT extern const base::Feature kNewEncodeCpuLoadEstimator; -MEDIA_EXPORT extern const base::Feature kNewRemotePlaybackPipeline; MEDIA_EXPORT extern const base::Feature kOverflowIconsForMediaControls; MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo; MEDIA_EXPORT extern const base::Feature kPictureInPicture;
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index b7ec12c..fab6bfba 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -128,10 +128,6 @@ return base::FeatureList::IsEnabled(kBackgroundVideoPauseOptimization); } -bool IsNewRemotePlaybackPipelineEnabled() { - return base::FeatureList::IsEnabled(kNewRemotePlaybackPipeline); -} - bool IsNetworkStateError(blink::WebMediaPlayer::NetworkState state) { bool result = state == blink::WebMediaPlayer::kNetworkStateFormatError || state == blink::WebMediaPlayer::kNetworkStateNetworkError || @@ -2399,7 +2395,7 @@ DVLOG(1) << __func__; DCHECK(main_task_runner_->BelongsToCurrentThread()); - if (observer_ && IsNewRemotePlaybackPipelineEnabled() && mb_data_source_) + if (observer_ && mb_data_source_) observer_->OnDataSourceInitialized(mb_data_source_->GetUrlAfterRedirects()); if (!success) {
diff --git a/media/capabilities/learning_helper.cc b/media/capabilities/learning_helper.cc index 2102d70..a70c0ced 100644 --- a/media/capabilities/learning_helper.cc +++ b/media/capabilities/learning_helper.cc
@@ -13,6 +13,7 @@ using learning::LabelledExample; using learning::LearningSessionImpl; using learning::LearningTask; +using learning::SequenceBoundFeatureProvider; using learning::TargetValue; const char* const kDroppedFrameRatioTreeTaskName = "DroppedFrameRatioTreeTask"; @@ -49,7 +50,7 @@ dropped_frame_task.uma_hacky_confusion_matrix = "Media.Learning.MediaCapabilities.DroppedFrameRatioTask.BaseTree"; learning_session_.Post(FROM_HERE, &LearningSessionImpl::RegisterTask, - dropped_frame_task); + dropped_frame_task, SequenceBoundFeatureProvider()); // Modify the task to use a table-based learner. dropped_frame_task.name = kDroppedFrameRatioTableTaskName; @@ -57,7 +58,7 @@ dropped_frame_task.uma_hacky_confusion_matrix = "Media.Learning.MediaCapabilities.DroppedFrameRatioTask.BaseTable"; learning_session_.Post(FROM_HERE, &LearningSessionImpl::RegisterTask, - dropped_frame_task); + dropped_frame_task, SequenceBoundFeatureProvider()); } LearningHelper::~LearningHelper() = default;
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/media/gpu/windows/dxva_video_decode_accelerator_win.cc index b42ad52..9c7c5eba5 100644 --- a/media/gpu/windows/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -230,7 +230,7 @@ return true; Microsoft::WRL::ComPtr<IDXGIAdapter> adapter; - hr = dxgi_device->GetAdapter(adapter.GetAddressOf()); + hr = dxgi_device->GetAdapter(&adapter); if (FAILED(hr)) return true; @@ -393,7 +393,7 @@ Microsoft::WRL::ComPtr<IMFSample>()); Microsoft::WRL::ComPtr<IMFMediaBuffer> buffer; - HRESULT hr = sample->GetBufferByIndex(0, buffer.GetAddressOf()); + HRESULT hr = sample->GetBufferByIndex(0, &buffer); RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from sample", Microsoft::WRL::ComPtr<IMFSample>()); @@ -874,7 +874,7 @@ HRESULT hr = E_FAIL; - hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d9_.GetAddressOf()); + hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9_); RETURN_ON_HR_FAILURE(hr, "Direct3DCreate9Ex failed", false); hr = d3d9_->CheckDeviceFormatConversion( @@ -883,13 +883,9 @@ RETURN_ON_HR_FAILURE(hr, "D3D9 driver does not support H/W format conversion", false); - Microsoft::WRL::ComPtr<IDirect3DDevice9> angle_device = - gl::QueryD3D9DeviceObjectFromANGLE(); - if (angle_device.Get()) + if (auto angle_device = gl::QueryD3D9DeviceObjectFromANGLE()) { using_angle_device_ = true; - - if (using_angle_device_) { - hr = angle_device.CopyTo(d3d9_device_ex_.GetAddressOf()); + hr = angle_device.As(&d3d9_device_ex_); RETURN_ON_HR_FAILURE( hr, "QueryInterface for IDirect3DDevice9Ex from angle device failed", false); @@ -906,23 +902,23 @@ present_params.FullScreen_RefreshRateInHz = 0; present_params.PresentationInterval = 0; - hr = d3d9_->CreateDeviceEx( - D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, - D3DCREATE_FPU_PRESERVE | D3DCREATE_MIXED_VERTEXPROCESSING | - D3DCREATE_MULTITHREADED, - &present_params, NULL, d3d9_device_ex_.GetAddressOf()); + hr = d3d9_->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, + D3DCREATE_FPU_PRESERVE | + D3DCREATE_MIXED_VERTEXPROCESSING | + D3DCREATE_MULTITHREADED, + &present_params, NULL, &d3d9_device_ex_); RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device", false); } hr = DXVA2CreateDirect3DDeviceManager9(&dev_manager_reset_token_, - device_manager_.GetAddressOf()); + &device_manager_); RETURN_ON_HR_FAILURE(hr, "DXVA2CreateDirect3DDeviceManager9 failed", false); hr = device_manager_->ResetDevice(d3d9_device_ex_.Get(), dev_manager_reset_token_); RETURN_ON_HR_FAILURE(hr, "Failed to reset device", false); - hr = d3d9_device_ex_->CreateQuery(D3DQUERYTYPE_EVENT, query_.GetAddressOf()); + hr = d3d9_device_ex_->CreateQuery(D3DQUERYTYPE_EVENT, &query_); RETURN_ON_HR_FAILURE(hr, "Failed to create D3D device query", false); // Ensure query_ API works (to avoid an infinite loop later in // CopyOutputSampleDataToPictureBuffer). @@ -996,7 +992,7 @@ // Create video processor hr = video_processor_service_->CreateVideoProcessor( - guids[g], &inputDesc, D3DFMT_X8R8G8B8, 0, processor_.GetAddressOf()); + guids[g], &inputDesc, D3DFMT_X8R8G8B8, 0, &processor_); if (hr) continue; @@ -1020,8 +1016,8 @@ if (D3D11Device()) return true; - HRESULT hr = create_dxgi_device_manager_( - &dx11_dev_manager_reset_token_, d3d11_device_manager_.GetAddressOf()); + HRESULT hr = create_dxgi_device_manager_(&dx11_dev_manager_reset_token_, + &d3d11_device_manager_); RETURN_ON_HR_FAILURE(hr, "MFCreateDXGIDeviceManager failed", false); angle_device_ = gl::QueryD3D11DeviceObjectFromANGLE(); @@ -1033,9 +1029,9 @@ using_angle_device_ = true; DCHECK(!use_fp16_); - angle_device_->GetImmediateContext(d3d11_device_context_.GetAddressOf()); + angle_device_->GetImmediateContext(&d3d11_device_context_); - hr = angle_device_.CopyTo(video_device_.GetAddressOf()); + hr = angle_device_.As(&video_device_); RETURN_ON_HR_FAILURE(hr, "Failed to get video device", false); } else { // This array defines the set of DirectX hardware feature levels we support. @@ -1054,9 +1050,8 @@ hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, feature_levels, base::size(feature_levels), - D3D11_SDK_VERSION, d3d11_device_.GetAddressOf(), - &feature_level_out, - d3d11_device_context_.GetAddressOf()); + D3D11_SDK_VERSION, &d3d11_device_, + &feature_level_out, &d3d11_device_context_); if (hr == DXGI_ERROR_SDK_COMPONENT_MISSING) { LOG(ERROR) << "Debug DXGI device creation failed, falling back to release."; @@ -1068,17 +1063,16 @@ if (!d3d11_device_context_) { hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, feature_levels, base::size(feature_levels), - D3D11_SDK_VERSION, d3d11_device_.GetAddressOf(), - &feature_level_out, - d3d11_device_context_.GetAddressOf()); + D3D11_SDK_VERSION, &d3d11_device_, + &feature_level_out, &d3d11_device_context_); RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device", false); } - hr = d3d11_device_.CopyTo(video_device_.GetAddressOf()); + hr = d3d11_device_.As(&video_device_); RETURN_ON_HR_FAILURE(hr, "Failed to get video device", false); } - hr = d3d11_device_context_.CopyTo(video_context_.GetAddressOf()); + hr = d3d11_device_context_.As(&video_context_); RETURN_ON_HR_FAILURE(hr, "Failed to get video context", false); D3D11_FEATURE_DATA_D3D11_OPTIONS options; @@ -1121,7 +1115,7 @@ D3D11_QUERY_DESC query_desc; query_desc.Query = D3D11_QUERY_EVENT; query_desc.MiscFlags = 0; - hr = D3D11Device()->CreateQuery(&query_desc, d3d11_query_.GetAddressOf()); + hr = D3D11Device()->CreateQuery(&query_desc, &d3d11_query_); RETURN_ON_HR_FAILURE(hr, "Failed to create DX11 device query", false); return true; @@ -1462,7 +1456,7 @@ // creating surfaces larger than 1920 x 1088. if (device && !IsLegacyGPU(device.Get())) { Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device; - if (SUCCEEDED(device.CopyTo(IID_PPV_ARGS(&video_device)))) { + if (SUCCEEDED(device.As(&video_device))) { max_h264_resolutions = GetMaxResolutionsForGUIDs( max_h264_resolutions.first, video_device.Get(), {DXVA2_ModeH264_E, DXVA2_Intel_ModeH264_E}, @@ -1703,7 +1697,7 @@ bool DXVAVideoDecodeAccelerator::CheckDecoderDxvaSupport() { Microsoft::WRL::ComPtr<IMFAttributes> attributes; - HRESULT hr = decoder_->GetAttributes(attributes.GetAddressOf()); + HRESULT hr = decoder_->GetAttributes(&attributes); RETURN_ON_HR_FAILURE(hr, "Failed to get decoder attributes", false); UINT32 dxva = 0; @@ -1773,7 +1767,7 @@ bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { Microsoft::WRL::ComPtr<IMFMediaType> media_type; - HRESULT hr = MFCreateMediaType(media_type.GetAddressOf()); + HRESULT hr = MFCreateMediaType(&media_type); RETURN_ON_HR_FAILURE(hr, "MFCreateMediaType failed", false); hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); @@ -1812,8 +1806,7 @@ // ensure that we get the proper surfaces created under the hood. if (GetPictureBufferMechanism() == PictureBufferMechanism::BIND) { Microsoft::WRL::ComPtr<IMFAttributes> out_attributes; - HRESULT hr = - decoder_->GetOutputStreamAttributes(0, out_attributes.GetAddressOf()); + HRESULT hr = decoder_->GetOutputStreamAttributes(0, &out_attributes); RETURN_ON_HR_FAILURE(hr, "Failed to get stream attributes", false); out_attributes->SetUINT32(MF_SA_D3D11_BINDFLAGS, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DECODER); @@ -2064,8 +2057,8 @@ } Microsoft::WRL::ComPtr<IMFMediaBuffer> output_buffer; - HRESULT hr = pending_sample->output_sample->GetBufferByIndex( - 0, output_buffer.GetAddressOf()); + HRESULT hr = + pending_sample->output_sample->GetBufferByIndex(0, &output_buffer); RETURN_AND_NOTIFY_ON_HR_FAILURE( hr, "Failed to get buffer from output sample", PLATFORM_FAILURE, ); @@ -2074,16 +2067,15 @@ if (use_dx11_) { Microsoft::WRL::ComPtr<IMFDXGIBuffer> dxgi_buffer; - hr = output_buffer.CopyTo(dxgi_buffer.GetAddressOf()); + hr = output_buffer.As(&dxgi_buffer); RETURN_AND_NOTIFY_ON_HR_FAILURE( hr, "Failed to get DXGIBuffer from output sample", PLATFORM_FAILURE, ); - hr = dxgi_buffer->GetResource( - __uuidof(ID3D11Texture2D), - reinterpret_cast<void**>(d3d11_texture.GetAddressOf())); + hr = + dxgi_buffer->GetResource(__uuidof(ID3D11Texture2D), &d3d11_texture); } else { hr = MFGetService(output_buffer.Get(), MR_BUFFER_SERVICE, - IID_PPV_ARGS(surface.GetAddressOf())); + IID_PPV_ARGS(&surface)); } RETURN_AND_NOTIFY_ON_HR_FAILURE( hr, "Failed to get surface from output sample", PLATFORM_FAILURE, ); @@ -2812,12 +2804,12 @@ } Microsoft::WRL::ComPtr<IMFMediaBuffer> output_buffer; - hr = input_sample->GetBufferByIndex(0, output_buffer.GetAddressOf()); + hr = input_sample->GetBufferByIndex(0, &output_buffer); RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", PLATFORM_FAILURE, ); Microsoft::WRL::ComPtr<IMFDXGIBuffer> dxgi_buffer; - hr = output_buffer.CopyTo(dxgi_buffer.GetAddressOf()); + hr = output_buffer.As(&dxgi_buffer); RETURN_AND_NOTIFY_ON_HR_FAILURE( hr, "Failed to get DXGIBuffer from output sample", PLATFORM_FAILURE, ); UINT index = 0; @@ -2826,8 +2818,7 @@ PLATFORM_FAILURE, ); Microsoft::WRL::ComPtr<ID3D11Texture2D> dx11_decoding_texture; - hr = dxgi_buffer->GetResource( - IID_PPV_ARGS(dx11_decoding_texture.GetAddressOf())); + hr = dxgi_buffer->GetResource(IID_PPV_ARGS(&dx11_decoding_texture)); RETURN_AND_NOTIFY_ON_HR_FAILURE( hr, "Failed to get resource from output sample", PLATFORM_FAILURE, ); @@ -2836,8 +2827,7 @@ output_view_desc.Texture2D.MipSlice = 0; Microsoft::WRL::ComPtr<ID3D11VideoProcessorOutputView> output_view; hr = video_device_->CreateVideoProcessorOutputView( - dest_texture, enumerator_.Get(), &output_view_desc, - output_view.GetAddressOf()); + dest_texture, enumerator_.Get(), &output_view_desc, &output_view); RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to get output view", PLATFORM_FAILURE, ); @@ -2848,7 +2838,7 @@ Microsoft::WRL::ComPtr<ID3D11VideoProcessorInputView> input_view; hr = video_device_->CreateVideoProcessorInputView( dx11_decoding_texture.Get(), enumerator_.Get(), &input_view_desc, - input_view.GetAddressOf()); + &input_view); RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to get input view", PLATFORM_FAILURE, ); @@ -2941,6 +2931,9 @@ int width, int height, const gfx::ColorSpace& color_space) { + // This code path is never used by PictureBufferMechanism::BIND paths. + DCHECK_NE(GetPictureBufferMechanism(), PictureBufferMechanism::BIND); + if (width < processor_width_ || height != processor_height_) { d3d11_processor_.Reset(); enumerator_.Reset(); @@ -2959,13 +2952,13 @@ desc.OutputHeight = height; desc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL; - HRESULT hr = video_device_->CreateVideoProcessorEnumerator( - &desc, enumerator_.GetAddressOf()); + HRESULT hr = + video_device_->CreateVideoProcessorEnumerator(&desc, &enumerator_); RETURN_ON_HR_FAILURE(hr, "Failed to enumerate video processors", false); // TODO(Hubbe): Find correct index hr = video_device_->CreateVideoProcessor(enumerator_.Get(), 0, - d3d11_processor_.GetAddressOf()); + &d3d11_processor_); RETURN_ON_HR_FAILURE(hr, "Failed to create video processor.", false); processor_width_ = width; processor_height_ = height; @@ -2974,76 +2967,81 @@ d3d11_processor_.Get(), 0, false); } - if (GetPictureBufferMechanism() == PictureBufferMechanism::COPY_TO_NV12 || + // If we're copying textures or just not using color space information, set + // the same color space on input and output. + if ((!use_color_info_ && !use_fp16_) || + GetPictureBufferMechanism() == PictureBufferMechanism::COPY_TO_NV12 || GetPictureBufferMechanism() == PictureBufferMechanism::DELAYED_COPY_TO_NV12) { - // If we're copying NV12 textures, make sure we set the same - // color space on input and output. const auto d3d11_color_space = gfx::ColorSpaceWin::GetD3D11ColorSpace(color_space); video_context_->VideoProcessorSetOutputColorSpace(d3d11_processor_.Get(), &d3d11_color_space); - video_context_->VideoProcessorSetStreamColorSpace(d3d11_processor_.Get(), 0, &d3d11_color_space); dx11_converter_output_color_space_ = color_space; + return true; + } + + // This path is only used for copying to RGB textures. + DCHECK_EQ(GetPictureBufferMechanism(), PictureBufferMechanism::COPY_TO_RGB); + + // On platforms prior to Windows 10 we won't have a ID3D11VideoContext1. + Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context1; + if (FAILED(video_context_.As(&video_context1))) { + auto d3d11_color_space = + gfx::ColorSpaceWin::GetD3D11ColorSpace(color_space); + video_context_->VideoProcessorSetStreamColorSpace(d3d11_processor_.Get(), 0, + &d3d11_color_space); + + // Since older platforms won't have HDR, just use SRGB. + dx11_converter_output_color_space_ = gfx::ColorSpace::CreateSRGB(); + d3d11_color_space = gfx::ColorSpaceWin::GetD3D11ColorSpace( + dx11_converter_output_color_space_); + video_context_->VideoProcessorSetOutputColorSpace(d3d11_processor_.Get(), + &d3d11_color_space); + return true; + } + + // Since the video processor doesn't support HLG, lets just do the YUV->RGB + // conversion and let the output color space be HLG. This won't work well + // unless color management is on, but if color management is off we don't + // support HLG anyways. + if (color_space == gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020, + gfx::ColorSpace::TransferID::ARIB_STD_B67, + gfx::ColorSpace::MatrixID::BT709, + gfx::ColorSpace::RangeID::LIMITED)) { + video_context1->VideoProcessorSetStreamColorSpace1( + d3d11_processor_.Get(), 0, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020); + video_context1->VideoProcessorSetOutputColorSpace1( + d3d11_processor_.Get(), DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020); + dx11_converter_output_color_space_ = color_space.GetAsFullRangeRGB(); + return true; + } + + if (use_fp16_ && config_.target_color_space.IsHDR() && color_space.IsHDR()) { + // Note, we only use the SCRGBLinear output color space when the input is + // PQ, because nvidia drivers will not convert G22 to G10 for some reason. + dx11_converter_output_color_space_ = gfx::ColorSpace::CreateSCRGBLinear(); } else { dx11_converter_output_color_space_ = gfx::ColorSpace::CreateSRGB(); - if (use_color_info_ || use_fp16_) { - Microsoft::WRL::ComPtr<ID3D11VideoContext1> video_context1; - HRESULT hr = video_context_.CopyTo(video_context1.GetAddressOf()); - if (SUCCEEDED(hr)) { - if (use_fp16_ && config_.target_color_space.IsHDR() && - color_space.IsHDR()) { - // Note, we only use the SCRGBLinear output color space when - // the input is PQ, because nvidia drivers will not convert - // G22 to G10 for some reason. - dx11_converter_output_color_space_ = - gfx::ColorSpace::CreateSCRGBLinear(); - } - // Since the video processor doesn't support HLG, let's just do the - // YUV->RGB conversion and let the output color space be HLG. - // This won't work well unless color management is on, but if color - // management is off we don't support HLG anyways. - if (color_space == - gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020, - gfx::ColorSpace::TransferID::ARIB_STD_B67, - gfx::ColorSpace::MatrixID::BT709, - gfx::ColorSpace::RangeID::LIMITED)) { - video_context1->VideoProcessorSetStreamColorSpace1( - d3d11_processor_.Get(), 0, - DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020); - video_context1->VideoProcessorSetOutputColorSpace1( - d3d11_processor_.Get(), - DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020); - dx11_converter_output_color_space_ = color_space.GetAsFullRangeRGB(); - } else { - DVLOG(2) << "input color space: " << color_space - << " DXGIColorSpace: " - << gfx::ColorSpaceWin::GetDXGIColorSpace(color_space); - DVLOG(2) << "output color space:" - << dx11_converter_output_color_space_ << " DXGIColorSpace: " - << gfx::ColorSpaceWin::GetDXGIColorSpace( - dx11_converter_output_color_space_); - video_context1->VideoProcessorSetStreamColorSpace1( - d3d11_processor_.Get(), 0, - gfx::ColorSpaceWin::GetDXGIColorSpace(color_space)); - video_context1->VideoProcessorSetOutputColorSpace1( - d3d11_processor_.Get(), gfx::ColorSpaceWin::GetDXGIColorSpace( - dx11_converter_output_color_space_)); - } - } else { - D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = - gfx::ColorSpaceWin::GetD3D11ColorSpace(color_space); - video_context_->VideoProcessorSetStreamColorSpace( - d3d11_processor_.Get(), 0, &d3d11_color_space); - d3d11_color_space = gfx::ColorSpaceWin::GetD3D11ColorSpace( - dx11_converter_output_color_space_); - video_context_->VideoProcessorSetOutputColorSpace( - d3d11_processor_.Get(), &d3d11_color_space); - } - } } + + DVLOG(2) << "input color space: " << color_space << " DXGIColorSpace: " + << gfx::ColorSpaceWin::GetDXGIColorSpace(color_space); + DVLOG(2) << "output color space:" << dx11_converter_output_color_space_ + << " DXGIColorSpace: " + << gfx::ColorSpaceWin::GetDXGIColorSpace( + dx11_converter_output_color_space_); + + video_context1->VideoProcessorSetStreamColorSpace1( + d3d11_processor_.Get(), 0, + gfx::ColorSpaceWin::GetDXGIColorSpace(color_space)); + video_context1->VideoProcessorSetOutputColorSpace1( + d3d11_processor_.Get(), gfx::ColorSpaceWin::GetDXGIColorSpace( + dx11_converter_output_color_space_)); + return true; } @@ -3051,18 +3049,16 @@ int* width, int* height) { Microsoft::WRL::ComPtr<IMFMediaBuffer> output_buffer; - HRESULT hr = sample->GetBufferByIndex(0, output_buffer.GetAddressOf()); + HRESULT hr = sample->GetBufferByIndex(0, &output_buffer); RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from output sample", false); if (use_dx11_) { Microsoft::WRL::ComPtr<IMFDXGIBuffer> dxgi_buffer; Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture; - hr = output_buffer.CopyTo(dxgi_buffer.GetAddressOf()); + hr = output_buffer.As(&dxgi_buffer); RETURN_ON_HR_FAILURE(hr, "Failed to get DXGIBuffer from output sample", false); - hr = dxgi_buffer->GetResource( - __uuidof(ID3D11Texture2D), - reinterpret_cast<void**>(d3d11_texture.GetAddressOf())); + hr = dxgi_buffer->GetResource(__uuidof(ID3D11Texture2D), &d3d11_texture); RETURN_ON_HR_FAILURE(hr, "Failed to get D3D11Texture from output buffer", false); D3D11_TEXTURE2D_DESC d3d11_texture_desc; @@ -3073,7 +3069,7 @@ } else { Microsoft::WRL::ComPtr<IDirect3DSurface9> surface; hr = MFGetService(output_buffer.Get(), MR_BUFFER_SERVICE, - IID_PPV_ARGS(surface.GetAddressOf())); + IID_PPV_ARGS(&surface)); RETURN_ON_HR_FAILURE(hr, "Failed to get D3D surface from output sample", false); D3DSURFACE_DESC surface_desc; @@ -3092,9 +3088,8 @@ HRESULT hr = E_FAIL; Microsoft::WRL::ComPtr<IMFMediaType> media_type; - for (uint32_t i = 0; SUCCEEDED( - transform->GetOutputAvailableType(0, i, media_type.GetAddressOf())); - ++i) { + for (uint32_t i = 0; + SUCCEEDED(transform->GetOutputAvailableType(0, i, &media_type)); ++i) { GUID out_subtype = {0}; hr = media_type->GetGUID(MF_MT_SUBTYPE, &out_subtype); RETURN_ON_HR_FAILURE(hr, "Failed to get output major type", false); @@ -3122,7 +3117,7 @@ } Microsoft::WRL::ComPtr<IMFMediaBuffer> buffer; - HRESULT hr = sample->GetBufferByIndex(0, buffer.GetAddressOf()); + HRESULT hr = sample->GetBufferByIndex(0, &buffer); RETURN_ON_HR_FAILURE(hr, "Failed to get buffer from input sample", hr); mf::MediaBufferScopedPointer scoped_media_buffer(buffer.Get());
diff --git a/media/learning/common/labelled_example.cc b/media/learning/common/labelled_example.cc index 6c8cb7d..76d0850 100644 --- a/media/learning/common/labelled_example.cc +++ b/media/learning/common/labelled_example.cc
@@ -69,6 +69,8 @@ TrainingData::~TrainingData() = default; +TrainingData& TrainingData::operator=(const TrainingData& rhs) = default; + TrainingData& TrainingData::operator=(TrainingData&& rhs) = default; TrainingData TrainingData::DeDuplicate() const {
diff --git a/media/learning/common/labelled_example.h b/media/learning/common/labelled_example.h index ee89586f..4f43c54 100644 --- a/media/learning/common/labelled_example.h +++ b/media/learning/common/labelled_example.h
@@ -65,6 +65,7 @@ TrainingData(const TrainingData& rhs); TrainingData(TrainingData&& rhs); + TrainingData& operator=(const TrainingData& rhs); TrainingData& operator=(TrainingData&& rhs); ~TrainingData();
diff --git a/media/learning/impl/BUILD.gn b/media/learning/impl/BUILD.gn index aae0ddd..4275583e 100644 --- a/media/learning/impl/BUILD.gn +++ b/media/learning/impl/BUILD.gn
@@ -16,6 +16,8 @@ "distribution_reporter.h", "extra_trees_trainer.cc", "extra_trees_trainer.h", + "feature_provider.cc", + "feature_provider.h", "learning_session_impl.cc", "learning_session_impl.h", "learning_task_controller.h",
diff --git a/media/learning/impl/feature_provider.cc b/media/learning/impl/feature_provider.cc new file mode 100644 index 0000000..2408b4d --- /dev/null +++ b/media/learning/impl/feature_provider.cc
@@ -0,0 +1,15 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/learning/impl/feature_provider.h" + +namespace media { +namespace learning { + +FeatureProvider::FeatureProvider() = default; + +FeatureProvider::~FeatureProvider() = default; + +} // namespace learning +} // namespace media
diff --git a/media/learning/impl/feature_provider.h b/media/learning/impl/feature_provider.h new file mode 100644 index 0000000..a8f0a57 --- /dev/null +++ b/media/learning/impl/feature_provider.h
@@ -0,0 +1,54 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_LEARNING_IMPL_FEATURE_PROVIDER_H_ +#define MEDIA_LEARNING_IMPL_FEATURE_PROVIDER_H_ + +#include <map> +#include <string> + +#include "base/callback.h" +#include "base/component_export.h" +#include "base/macros.h" +#include "base/threading/sequence_bound.h" +#include "media/learning/common/labelled_example.h" +#include "media/learning/common/learning_task.h" + +namespace media { +namespace learning { + +// Add features to a training example. If the LearningTask's feature +// description includes feature names that a FeatureProvider knows about, then +// it will replace their value in the examples with whatever value that feature +// should have. For example, "NetworkType" might be replaced by a value that +// indicates the type of network connection. +class COMPONENT_EXPORT(LEARNING_IMPL) FeatureProvider { + public: + using LabelledExampleCB = base::OnceCallback<void(LabelledExample)>; + + FeatureProvider(); + virtual ~FeatureProvider(); + + // Update |example| to include whatever features are specified by |task_|, + // and call |cb| once they're filled in. + virtual void AddFeatures(const LabelledExample& example, + LabelledExampleCB cb) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(FeatureProvider); +}; + +// Since FeatureProviders are often going to thread-hop, provide this typedef. +using SequenceBoundFeatureProvider = base::SequenceBound<FeatureProvider>; + +// Factory callback, since things that create implementations will likely be +// elsewhere (e.g., content/) from the things which use them (e.g., here). May +// return an empty provider if the task doesn't require one. +using FeatureProviderFactoryCB = + base::RepeatingCallback<SequenceBoundFeatureProvider(const LearningTask&)>; + +} // namespace learning +} // namespace media + +#endif // MEDIA_LEARNING_IMPL_FEATURE_PROVIDER_H_
diff --git a/media/learning/impl/learning_session_impl.cc b/media/learning/impl/learning_session_impl.cc index aee1e93..a7d6e63 100644 --- a/media/learning/impl/learning_session_impl.cc +++ b/media/learning/impl/learning_session_impl.cc
@@ -4,6 +4,8 @@ #include "media/learning/impl/learning_session_impl.h" +#include <utility> + #include "base/bind.h" #include "base/logging.h" #include "media/learning/impl/distribution_reporter.h" @@ -14,10 +16,12 @@ LearningSessionImpl::LearningSessionImpl() : controller_factory_( - base::BindRepeating([](const LearningTask& task) + base::BindRepeating([](const LearningTask& task, + SequenceBoundFeatureProvider feature_provider) -> std::unique_ptr<LearningTaskController> { return std::make_unique<LearningTaskControllerImpl>( - task, DistributionReporter::Create(task)); + task, DistributionReporter::Create(task), + std::move(feature_provider)); })) {} LearningSessionImpl::~LearningSessionImpl() = default; @@ -34,9 +38,12 @@ iter->second->AddExample(example); } -void LearningSessionImpl::RegisterTask(const LearningTask& task) { +void LearningSessionImpl::RegisterTask( + const LearningTask& task, + SequenceBoundFeatureProvider feature_provider) { DCHECK(task_map_.count(task.name) == 0); - task_map_.emplace(task.name, controller_factory_.Run(task)); + task_map_.emplace(task.name, + controller_factory_.Run(task, std::move(feature_provider))); } } // namespace learning
diff --git a/media/learning/impl/learning_session_impl.h b/media/learning/impl/learning_session_impl.h index 80c50fa..1938f0a 100644 --- a/media/learning/impl/learning_session_impl.h +++ b/media/learning/impl/learning_session_impl.h
@@ -8,7 +8,9 @@ #include <map> #include "base/component_export.h" +#include "base/threading/sequence_bound.h" #include "media/learning/common/learning_session.h" +#include "media/learning/impl/feature_provider.h" #include "media/learning/impl/learning_task_controller.h" namespace media { @@ -19,12 +21,13 @@ class COMPONENT_EXPORT(LEARNING_IMPL) LearningSessionImpl : public LearningSession { public: - explicit LearningSessionImpl(); + LearningSessionImpl(); ~LearningSessionImpl() override; using CreateTaskControllerCB = base::RepeatingCallback<std::unique_ptr<LearningTaskController>( - const LearningTask&)>; + const LearningTask&, + SequenceBoundFeatureProvider)>; void SetTaskControllerFactoryCBForTesting(CreateTaskControllerCB cb); @@ -34,7 +37,9 @@ // Registers |task|, so that calls to AddExample with |task.name| will work. // This will create a new controller for the task. - void RegisterTask(const LearningTask& task); + void RegisterTask(const LearningTask& task, + SequenceBoundFeatureProvider feature_provider = + SequenceBoundFeatureProvider()); private: // [task_name] = task controller.
diff --git a/media/learning/impl/learning_session_impl_unittest.cc b/media/learning/impl/learning_session_impl_unittest.cc index 96dae4f..36f343e 100644 --- a/media/learning/impl/learning_session_impl_unittest.cc +++ b/media/learning/impl/learning_session_impl_unittest.cc
@@ -3,9 +3,12 @@ // found in the LICENSE file. #include <memory> +#include <utility> #include <vector> #include "base/bind.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "media/learning/impl/learning_session_impl.h" #include "media/learning/impl/learning_task_controller.h" #include "testing/gtest/include/gtest/gtest.h" @@ -17,23 +20,49 @@ public: class FakeLearningTaskController : public LearningTaskController { public: - FakeLearningTaskController(const LearningTask& task) {} + FakeLearningTaskController(const LearningTask& task, + SequenceBoundFeatureProvider feature_provider) + : feature_provider_(std::move(feature_provider)) { + // As a complete hack, call the only public method on fp so that + // we can verify that it was given to us by the session. + if (!feature_provider_.is_null()) { + feature_provider_.Post(FROM_HERE, &FeatureProvider::AddFeatures, + LabelledExample(), + FeatureProvider::LabelledExampleCB()); + } + } void AddExample(const LabelledExample& example) override { example_ = example; } + SequenceBoundFeatureProvider feature_provider_; LabelledExample example_; }; + class FakeFeatureProvider : public FeatureProvider { + public: + FakeFeatureProvider(bool* flag_ptr) : flag_ptr_(flag_ptr) {} + + // Do nothing, except note that we were called. + void AddFeatures(const LabelledExample& example, + FeatureProvider::LabelledExampleCB cb) override { + *flag_ptr_ = true; + }; + + bool* flag_ptr_ = nullptr; + }; + using ControllerVector = std::vector<FakeLearningTaskController*>; LearningSessionImplTest() { session_ = std::make_unique<LearningSessionImpl>(); session_->SetTaskControllerFactoryCBForTesting(base::BindRepeating( - [](ControllerVector* controllers, const LearningTask& task) + [](ControllerVector* controllers, const LearningTask& task, + SequenceBoundFeatureProvider feature_provider) -> std::unique_ptr<LearningTaskController> { - auto controller = std::make_unique<FakeLearningTaskController>(task); + auto controller = std::make_unique<FakeLearningTaskController>( + task, std::move(feature_provider)); controllers->push_back(controller.get()); return controller; }, @@ -43,6 +72,8 @@ task_1_.name = "task_1"; } + base::test::ScopedTaskEnvironment scoped_task_environment_; + std::unique_ptr<LearningSessionImpl> session_; LearningTask task_0_; @@ -74,5 +105,17 @@ EXPECT_EQ(task_controllers_[1]->example_, example_1); } +TEST_F(LearningSessionImplTest, FeatureProviderIsForwarded) { + // Verify that a FeatureProvider actually gets forwarded to the LTC. + bool flag = false; + session_->RegisterTask(task_0_, + base::SequenceBound<FakeFeatureProvider>( + base::SequencedTaskRunnerHandle::Get(), &flag)); + scoped_task_environment_.RunUntilIdle(); + // Registering the task should create a FakeLearningTaskController, which will + // call AddFeatures on the fake FeatureProvider. + EXPECT_TRUE(flag); +} + } // namespace learning } // namespace media
diff --git a/media/learning/impl/learning_task_controller_impl.cc b/media/learning/impl/learning_task_controller_impl.cc index 31e182f..d5cf92b 100644 --- a/media/learning/impl/learning_task_controller_impl.cc +++ b/media/learning/impl/learning_task_controller_impl.cc
@@ -15,9 +15,11 @@ LearningTaskControllerImpl::LearningTaskControllerImpl( const LearningTask& task, - std::unique_ptr<DistributionReporter> reporter) + std::unique_ptr<DistributionReporter> reporter, + SequenceBoundFeatureProvider feature_provider) : task_(task), training_data_(std::make_unique<TrainingData>()), + feature_provider_(std::move(feature_provider)), reporter_(std::move(reporter)) { switch (task_.model) { case LearningTask::Model::kExtraTrees: @@ -32,6 +34,18 @@ LearningTaskControllerImpl::~LearningTaskControllerImpl() = default; void LearningTaskControllerImpl::AddExample(const LabelledExample& example) { + if (!feature_provider_.is_null()) { + // TODO(liberato): BindToCurrentSequence + feature_provider_.Post( + FROM_HERE, &FeatureProvider::AddFeatures, example, + base::BindOnce(&LearningTaskControllerImpl::OnExampleReady, + AsWeakPtr())); + } else { + OnExampleReady(example); + } +} + +void LearningTaskControllerImpl::OnExampleReady(LabelledExample example) { if (training_data_->size() >= task_.max_data_set_size) { // Replace a random example. We don't necessarily want to replace the // oldest, since we don't necessarily want to enforce an ad-hoc recency
diff --git a/media/learning/impl/learning_task_controller_impl.h b/media/learning/impl/learning_task_controller_impl.h index b2d4a6a..6f40924 100644 --- a/media/learning/impl/learning_task_controller_impl.h +++ b/media/learning/impl/learning_task_controller_impl.h
@@ -11,6 +11,7 @@ #include "base/component_export.h" #include "base/memory/weak_ptr.h" #include "media/learning/impl/distribution_reporter.h" +#include "media/learning/impl/feature_provider.h" #include "media/learning/impl/learning_task_controller.h" #include "media/learning/impl/random_number_generator.h" #include "media/learning/impl/training_algorithm.h" @@ -27,13 +28,19 @@ public: LearningTaskControllerImpl( const LearningTask& task, - std::unique_ptr<DistributionReporter> reporter = nullptr); + std::unique_ptr<DistributionReporter> reporter = nullptr, + SequenceBoundFeatureProvider feature_provider = + SequenceBoundFeatureProvider()); ~LearningTaskControllerImpl() override; // LearningTaskController void AddExample(const LabelledExample& example) override; private: + // Called when a new example has been finished by |feature_provider_|, if + // needed, to actually add the example. + void OnExampleReady(LabelledExample example); + // Called by |training_cb_| when the model is trained. void OnModelTrained(std::unique_ptr<Model> model); @@ -57,6 +64,9 @@ // Training algorithm that we'll use. std::unique_ptr<TrainingAlgorithm> trainer_; + // Optional feature provider. + SequenceBoundFeatureProvider feature_provider_; + // Optional reporter for training accuracy. std::unique_ptr<DistributionReporter> reporter_;
diff --git a/media/learning/impl/learning_task_controller_impl_unittest.cc b/media/learning/impl/learning_task_controller_impl_unittest.cc index 32cfa21..3d854676 100644 --- a/media/learning/impl/learning_task_controller_impl_unittest.cc +++ b/media/learning/impl/learning_task_controller_impl_unittest.cc
@@ -4,7 +4,11 @@ #include "media/learning/impl/learning_task_controller_impl.h" +#include <utility> + #include "base/bind.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "media/learning/impl/distribution_reporter.h" #include "testing/gtest/include/gtest/gtest.h" @@ -61,44 +65,75 @@ const TrainingData& training_data, TrainedModelCB model_cb) override { (*num_models_)++; + training_data_ = training_data; std::move(model_cb).Run(std::make_unique<FakeModel>(target_value_)); } + const TrainingData& training_data() const { return training_data_; } + private: int* num_models_ = nullptr; TargetValue target_value_; + + // Most recently provided training data. + TrainingData training_data_; + }; + + // Increments feature 0. + class FakeFeatureProvider : public FeatureProvider { + public: + void AddFeatures(const LabelledExample& example, + LabelledExampleCB cb) override { + LabelledExample new_example = example; + new_example.features[0] = FeatureValue(example.features[0].value() + 1); + std::move(cb).Run(new_example); + } }; LearningTaskControllerImplTest() : predicted_target_(123), not_predicted_target_(456) { + // Set the name so that we can check it later. + task_.name = "TestTask"; // Don't require too many training examples per report. task_.max_data_set_size = 20; task_.min_new_data_fraction = 0.1; + } + void CreateController(SequenceBoundFeatureProvider feature_provider = + SequenceBoundFeatureProvider()) { std::unique_ptr<FakeDistributionReporter> reporter = std::make_unique<FakeDistributionReporter>(task_); reporter_raw_ = reporter.get(); controller_ = std::make_unique<LearningTaskControllerImpl>( - task_, std::move(reporter)); - controller_->SetTrainerForTesting( - std::make_unique<FakeTrainer>(&num_models_, predicted_target_)); + task_, std::move(reporter), std::move(feature_provider)); + + auto fake_trainer = + std::make_unique<FakeTrainer>(&num_models_, predicted_target_); + trainer_raw_ = fake_trainer.get(); + controller_->SetTrainerForTesting(std::move(fake_trainer)); } + base::test::ScopedTaskEnvironment scoped_task_environment_; + // Number of models that we trained. int num_models_ = 0; + FakeModel* last_model_ = nullptr; // Two distinct targets. const TargetValue predicted_target_; const TargetValue not_predicted_target_; FakeDistributionReporter* reporter_raw_ = nullptr; + FakeTrainer* trainer_raw_ = nullptr; LearningTask task_; std::unique_ptr<LearningTaskControllerImpl> controller_; }; TEST_F(LearningTaskControllerImplTest, AddingExamplesTrainsModelAndReports) { + CreateController(); + LabelledExample example; // Up to the first 1/training_fraction examples should train on each example. @@ -139,5 +174,19 @@ EXPECT_EQ(reporter_raw_->num_correct_, count * 3 - 1); // Unchanged. } +TEST_F(LearningTaskControllerImplTest, FeatureProviderIsUsed) { + // If a FeatureProvider factory is provided, make sure that it's used to + // adjust new examples. + SequenceBoundFeatureProvider feature_provider = + base::SequenceBound<FakeFeatureProvider>( + base::SequencedTaskRunnerHandle::Get()); + CreateController(std::move(feature_provider)); + LabelledExample example; + example.features.push_back(FeatureValue(123)); + controller_->AddExample(example); + scoped_task_environment_.RunUntilIdle(); + EXPECT_EQ(trainer_raw_->training_data()[0].features[0], FeatureValue(124)); +} + } // namespace learning } // namespace media
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc index 6544e86..eeb06fc 100644 --- a/media/test/pipeline_integration_test_base.cc +++ b/media/test/pipeline_integration_test_base.cc
@@ -597,10 +597,12 @@ FakeEncryptedMedia* encrypted_media) { ParseTestTypeFlags(test_type); - if (fuzzing_) + if (fuzzing_) { EXPECT_CALL(*source, InitSegmentReceivedMock(_)).Times(AnyNumber()); - else if (!(test_type & kExpectDemuxerFailure)) + EXPECT_CALL(*source, OnParseWarningMock(_)).Times(AnyNumber()); + } else if (!(test_type & kExpectDemuxerFailure)) { EXPECT_CALL(*source, InitSegmentReceivedMock(_)).Times(AtLeast(1)); + } EXPECT_CALL(*this, OnMetadata(_)) .Times(AtMost(1))
diff --git a/mojo/public/cpp/system/file_data_pipe_producer.cc b/mojo/public/cpp/system/file_data_pipe_producer.cc index 0fc1f30..f207e0d 100644 --- a/mojo/public/cpp/system/file_data_pipe_producer.cc +++ b/mojo/public/cpp/system/file_data_pipe_producer.cc
@@ -266,8 +266,11 @@ void FileDataPipeProducer::InitializeNewRequest(CompletionCallback callback) { DCHECK(!file_sequence_state_); + // TODO(crbug.com/924416): Re-evaluate how TaskPriority is set here and in + // other file URL-loading-related code. Some callers require USER_VISIBLE + // (i.e., BEST_EFFORT is not enough). auto file_task_runner = base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); + {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); file_sequence_state_ = new FileSequenceState( std::move(producer_), file_task_runner, base::BindOnce(&FileDataPipeProducer::OnWriteComplete,
diff --git a/net/BUILD.gn b/net/BUILD.gn index 311e601..ace5ca4 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -6425,6 +6425,8 @@ ] deps = [ ":net_fuzzer_test_support", + ":quic_test_tools", + ":test_support", "//base", "//net", ]
diff --git a/net/http/http_auth_cache_unittest.cc b/net/http/http_auth_cache_unittest.cc index eadfbe45..41016b0 100644 --- a/net/http/http_auth_cache_unittest.cc +++ b/net/http/http_auth_cache_unittest.cc
@@ -12,7 +12,6 @@ #include "base/test/simple_test_tick_clock.h" #include "net/base/net_errors.h" #include "net/http/http_auth_cache.h" -#include "net/http/http_auth_handler.h" #include "testing/gtest/include/gtest/gtest.h" using base::ASCIIToUTF16; @@ -21,43 +20,6 @@ namespace { -class MockAuthHandler : public HttpAuthHandler { - public: - MockAuthHandler(HttpAuth::Scheme scheme, - const std::string& realm, - HttpAuth::Target target) { - // Can't use initializer list since these are members of the base class. - auth_scheme_ = scheme; - realm_ = realm; - score_ = 1; - target_ = target; - properties_ = 0; - } - - HttpAuth::AuthorizationResult HandleAnotherChallenge( - HttpAuthChallengeTokenizer* challenge) override { - return HttpAuth::AUTHORIZATION_RESULT_REJECT; - } - - protected: - bool Init(HttpAuthChallengeTokenizer* challenge, - const SSLInfo& ssl_info) override { - return false; // Unused. - } - - int GenerateAuthTokenImpl(const AuthCredentials*, - const HttpRequestInfo*, - CompletionOnceCallback callback, - std::string* auth_token) override { - *auth_token = "mock-credentials"; - return OK; - } - - - private: - ~MockAuthHandler() override = default; -}; - const char kRealm1[] = "Realm1"; const char kRealm2[] = "Realm2"; const char kRealm3[] = "Realm3"; @@ -90,75 +52,54 @@ // Add cache entries for 4 realms: "Realm1", "Realm2", "Realm3" and // "Realm4" - std::unique_ptr<HttpAuthHandler> realm1_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm1, HttpAuth::AUTH_SERVER)); - cache.Add(origin, realm1_handler->realm(), realm1_handler->auth_scheme(), - "Basic realm=Realm1", + cache.Add(origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm1", CreateASCIICredentials("realm1-user", "realm1-password"), "/foo/bar/index.html"); - std::unique_ptr<HttpAuthHandler> realm2_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm2, HttpAuth::AUTH_SERVER)); - cache.Add(origin, realm2_handler->realm(), realm2_handler->auth_scheme(), - "Basic realm=Realm2", + cache.Add(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm2", CreateASCIICredentials("realm2-user", "realm2-password"), "/foo2/index.html"); - std::unique_ptr<HttpAuthHandler> realm3_basic_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm3, HttpAuth::AUTH_PROXY)); cache.Add( - origin, - realm3_basic_handler->realm(), - realm3_basic_handler->auth_scheme(), - "Basic realm=Realm3", + origin, kRealm3, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm3", CreateASCIICredentials("realm3-basic-user", "realm3-basic-password"), std::string()); - std::unique_ptr<HttpAuthHandler> realm3_digest_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_DIGEST, kRealm3, HttpAuth::AUTH_PROXY)); - cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "Digest realm=Realm3", - CreateASCIICredentials("realm3-digest-user", - "realm3-digest-password"), - "/baz/index.html"); + cache.Add( + origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, "Digest realm=Realm3", + CreateASCIICredentials("realm3-digest-user", "realm3-digest-password"), + "/baz/index.html"); - std::unique_ptr<HttpAuthHandler> realm4_basic_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm4, HttpAuth::AUTH_SERVER)); - cache.Add(origin, realm4_basic_handler->realm(), - realm4_basic_handler->auth_scheme(), "Basic realm=Realm4", - CreateASCIICredentials("realm4-basic-user", - "realm4-basic-password"), - "/"); + cache.Add( + origin, kRealm4, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm4", + CreateASCIICredentials("realm4-basic-user", "realm4-basic-password"), + "/"); - std::unique_ptr<HttpAuthHandler> origin2_realm5_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm5, HttpAuth::AUTH_SERVER)); - cache.Add(origin2, origin2_realm5_handler->realm(), - origin2_realm5_handler->auth_scheme(), "Basic realm=Realm5", + cache.Add(origin2, kRealm5, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm5", CreateASCIICredentials("realm5-user", "realm5-password"), "/"); cache.Add( - origin2, realm3_basic_handler->realm(), - realm3_basic_handler->auth_scheme(), "Basic realm=Realm3", + origin2, kRealm3, HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=Realm3", CreateASCIICredentials("realm3-basic-user", "realm3-basic-password"), std::string()); // There is no Realm5 in origin entry = cache.Lookup(origin, kRealm5, HttpAuth::AUTH_SCHEME_BASIC); - EXPECT_TRUE(NULL == entry); + EXPECT_FALSE(entry); // While Realm3 does exist, the origin scheme is wrong. entry = cache.Lookup(GURL("https://www.google.com"), kRealm3, HttpAuth::AUTH_SCHEME_BASIC); - EXPECT_TRUE(NULL == entry); + EXPECT_FALSE(entry); // Realm, origin scheme ok, authentication scheme wrong entry = cache.Lookup (GURL("http://www.google.com"), kRealm1, HttpAuth::AUTH_SCHEME_DIGEST); - EXPECT_TRUE(NULL == entry); + EXPECT_FALSE(entry); // Valid lookup by origin, realm, scheme. entry = cache.Lookup( GURL("http://www.google.com:80"), kRealm3, HttpAuth::AUTH_SCHEME_BASIC); - ASSERT_FALSE(NULL == entry); + ASSERT_TRUE(entry); EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme()); EXPECT_EQ(kRealm3, entry->realm()); EXPECT_EQ("Basic realm=Realm3", entry->auth_challenge()); @@ -169,14 +110,14 @@ // Same realm, scheme with different origins HttpAuthCache::Entry* entry2 = cache.Lookup( GURL("http://www.foobar.com:80"), kRealm3, HttpAuth::AUTH_SCHEME_BASIC); - ASSERT_FALSE(NULL == entry2); + ASSERT_TRUE(entry2); EXPECT_NE(entry, entry2); // Valid lookup by origin, realm, scheme when there's a duplicate // origin, realm in the cache entry = cache.Lookup( GURL("http://www.google.com:80"), kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); - ASSERT_FALSE(NULL == entry); + ASSERT_TRUE(entry); EXPECT_EQ(HttpAuth::AUTH_SCHEME_DIGEST, entry->scheme()); EXPECT_EQ(kRealm3, entry->realm()); EXPECT_EQ("Digest realm=Realm3", entry->auth_challenge()); @@ -187,7 +128,7 @@ // Valid lookup by realm. entry = cache.Lookup(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC); - ASSERT_FALSE(NULL == entry); + ASSERT_TRUE(entry); EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme()); EXPECT_EQ(kRealm2, entry->realm()); EXPECT_EQ("Basic realm=Realm2", entry->auth_challenge()); @@ -199,8 +140,8 @@ cache.Lookup(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC); HttpAuthCache::Entry* p_realm4_entry = cache.Lookup(origin, kRealm4, HttpAuth::AUTH_SCHEME_BASIC); - EXPECT_FALSE(NULL == p_realm2_entry); - EXPECT_FALSE(NULL == p_realm4_entry); + EXPECT_TRUE(p_realm2_entry); + EXPECT_TRUE(p_realm4_entry); HttpAuthCache::Entry realm2_entry = *p_realm2_entry; HttpAuthCache::Entry realm4_entry = *p_realm4_entry; // Realm4 applies to '/' and Realm2 applies to '/foo2/'. @@ -228,7 +169,7 @@ // Confirm we find the same realm, different auth scheme by path lookup HttpAuthCache::Entry* p_realm3_digest_entry = cache.Lookup(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); - EXPECT_FALSE(NULL == p_realm3_digest_entry); + EXPECT_TRUE(p_realm3_digest_entry); HttpAuthCache::Entry realm3_digest_entry = *p_realm3_digest_entry; entry = cache.LookupByPath(origin, "/baz/index.html"); EXPECT_TRUE(realm3_digest_entry.IsEqualForTesting(*entry)); @@ -240,7 +181,7 @@ // Confirm we find the same realm, different auth scheme by path lookup HttpAuthCache::Entry* p_realm3DigestEntry = cache.Lookup(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST); - EXPECT_FALSE(NULL == p_realm3DigestEntry); + EXPECT_TRUE(p_realm3DigestEntry); HttpAuthCache::Entry realm3DigestEntry = *p_realm3DigestEntry; entry = cache.LookupByPath(origin, "/baz/index.html"); EXPECT_TRUE(realm3DigestEntry.IsEqualForTesting(*entry)); @@ -251,7 +192,7 @@ // Lookup using empty path (may be used for proxy). entry = cache.LookupByPath(origin, std::string()); - EXPECT_FALSE(NULL == entry); + EXPECT_TRUE(entry); EXPECT_EQ(HttpAuth::AUTH_SCHEME_BASIC, entry->scheme()); EXPECT_EQ(kRealm3, entry->realm()); } @@ -293,20 +234,19 @@ TEST(HttpAuthCacheTest, AddToExistingEntry) { HttpAuthCache cache; GURL origin("http://www.foobar.com:70"); - const std::string auth_challenge = "Basic realm=MyRealm"; + const std::string kAuthChallenge = "Basic realm=MyRealm"; + const std::string kRealm = "MyRealm"; - std::unique_ptr<HttpAuthHandler> handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, "MyRealm", HttpAuth::AUTH_SERVER)); - HttpAuthCache::Entry* orig_entry = cache.Add( - origin, handler->realm(), handler->auth_scheme(), auth_challenge, - CreateASCIICredentials("user1", "password1"), "/x/y/z/"); - cache.Add(origin, handler->realm(), handler->auth_scheme(), auth_challenge, + HttpAuthCache::Entry* orig_entry = + cache.Add(origin, kRealm, HttpAuth::AUTH_SCHEME_BASIC, kAuthChallenge, + CreateASCIICredentials("user1", "password1"), "/x/y/z/"); + cache.Add(origin, kRealm, HttpAuth::AUTH_SCHEME_BASIC, kAuthChallenge, CreateASCIICredentials("user2", "password2"), "/z/y/x/"); - cache.Add(origin, handler->realm(), handler->auth_scheme(), auth_challenge, + cache.Add(origin, kRealm, HttpAuth::AUTH_SCHEME_BASIC, kAuthChallenge, CreateASCIICredentials("user3", "password3"), "/z/y"); - HttpAuthCache::Entry* entry = cache.Lookup( - origin, "MyRealm", HttpAuth::AUTH_SCHEME_BASIC); + HttpAuthCache::Entry* entry = + cache.Lookup(origin, kRealm, HttpAuth::AUTH_SCHEME_BASIC); EXPECT_TRUE(entry == orig_entry); EXPECT_EQ(ASCIIToUTF16("user3"), entry->credentials().username()); @@ -320,30 +260,15 @@ TEST(HttpAuthCacheTest, Remove) { GURL origin("http://foobar2.com"); - std::unique_ptr<HttpAuthHandler> realm1_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm1, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm2_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm2, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm3_basic_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm3, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm3_digest_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_DIGEST, kRealm3, HttpAuth::AUTH_SERVER)); - HttpAuthCache cache; - cache.Add(origin, realm1_handler->realm(), realm1_handler->auth_scheme(), - "basic realm=Realm1", AuthCredentials(kAlice, k123), "/"); - cache.Add(origin, realm2_handler->realm(), realm2_handler->auth_scheme(), - "basic realm=Realm2", CreateASCIICredentials("bob", "princess"), - "/"); - cache.Add(origin, realm3_basic_handler->realm(), - realm3_basic_handler->auth_scheme(), "basic realm=Realm3", + cache.Add(origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, "basic realm=Realm1", + AuthCredentials(kAlice, k123), "/"); + cache.Add(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC, "basic realm=Realm2", + CreateASCIICredentials("bob", "princess"), "/"); + cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_BASIC, "basic realm=Realm3", AuthCredentials(kAdmin, kPassword), "/"); - cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kRoot, kWileCoyote), "/"); + cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), "/"); // Fails, because there is no realm "Realm5". EXPECT_FALSE(cache.Remove( @@ -387,9 +312,8 @@ AuthCredentials(kRoot, kWileCoyote))); // Succeed as above, but when entries were added in opposite order - cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kRoot, kWileCoyote), "/"); + cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), "/"); EXPECT_TRUE(cache.Remove( origin, kRealm3, HttpAuth::AUTH_SCHEME_BASIC, AuthCredentials(kAdmin, kPassword))); @@ -531,12 +455,8 @@ TEST(HttpAuthCacheTest, UpdateStaleChallenge) { HttpAuthCache cache; GURL origin("http://foobar2.com"); - std::unique_ptr<HttpAuthHandler> digest_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_DIGEST, kRealm1, HttpAuth::AUTH_PROXY)); HttpAuthCache::Entry* entry_pre = cache.Add( - origin, - digest_handler->realm(), - digest_handler->auth_scheme(), + origin, kRealm1, HttpAuth::AUTH_SCHEME_DIGEST, "Digest realm=Realm1," "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\"", CreateASCIICredentials("realm-digest-user", "realm-digest-password"), @@ -548,9 +468,7 @@ EXPECT_EQ(4, entry_pre->IncrementNonceCount()); bool update_success = cache.UpdateStaleChallenge( - origin, - digest_handler->realm(), - digest_handler->auth_scheme(), + origin, kRealm1, HttpAuth::AUTH_SCHEME_DIGEST, "Digest realm=Realm1," "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\"," "stale=\"true\""); @@ -558,18 +476,14 @@ // After the stale update, the entry should still exist in the cache and // the nonce count should be reset to 0. - HttpAuthCache::Entry* entry_post = cache.Lookup( - origin, - digest_handler->realm(), - digest_handler->auth_scheme()); + HttpAuthCache::Entry* entry_post = + cache.Lookup(origin, kRealm1, HttpAuth::AUTH_SCHEME_DIGEST); ASSERT_TRUE(entry_post != NULL); EXPECT_EQ(2, entry_post->IncrementNonceCount()); // UpdateStaleChallenge will fail if an entry doesn't exist in the cache. bool update_failure = cache.UpdateStaleChallenge( - origin, - kRealm2, - digest_handler->auth_scheme(), + origin, kRealm2, HttpAuth::AUTH_SCHEME_DIGEST, "Digest realm=Realm2," "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\"," "stale=\"true\""); @@ -581,46 +495,30 @@ std::string path("/some/path"); std::string another_path("/another/path"); - std::unique_ptr<HttpAuthHandler> realm1_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm1, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm2_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm2, HttpAuth::AUTH_PROXY)); - - std::unique_ptr<HttpAuthHandler> realm3_digest_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_DIGEST, kRealm3, HttpAuth::AUTH_SERVER)); - - std::unique_ptr<HttpAuthHandler> realm4_handler(new MockAuthHandler( - HttpAuth::AUTH_SCHEME_BASIC, kRealm4, HttpAuth::AUTH_SERVER)); - HttpAuthCache first_cache; HttpAuthCache::Entry* entry; - first_cache.Add(origin, realm1_handler->realm(), - realm1_handler->auth_scheme(), "basic realm=Realm1", - AuthCredentials(kAlice, k123), path); - first_cache.Add(origin, realm2_handler->realm(), - realm2_handler->auth_scheme(), "basic realm=Realm2", - AuthCredentials(kAlice2, k1234), path); - first_cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kRoot, kWileCoyote), path); - entry = first_cache.Add( - origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kRoot, kWileCoyote), another_path); + first_cache.Add(origin, kRealm1, HttpAuth::AUTH_SCHEME_BASIC, + "basic realm=Realm1", AuthCredentials(kAlice, k123), path); + first_cache.Add(origin, kRealm2, HttpAuth::AUTH_SCHEME_BASIC, + "basic realm=Realm2", AuthCredentials(kAlice2, k1234), path); + first_cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", AuthCredentials(kRoot, kWileCoyote), + path); + entry = first_cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", + AuthCredentials(kRoot, kWileCoyote), another_path); EXPECT_EQ(2, entry->IncrementNonceCount()); HttpAuthCache second_cache; // Will be overwritten by kRoot:kWileCoyote. - second_cache.Add(origin, realm3_digest_handler->realm(), - realm3_digest_handler->auth_scheme(), "digest realm=Realm3", - AuthCredentials(kAlice2, k1234), path); + second_cache.Add(origin, kRealm3, HttpAuth::AUTH_SCHEME_DIGEST, + "digest realm=Realm3", AuthCredentials(kAlice2, k1234), + path); // Should be left intact. - second_cache.Add(origin, realm4_handler->realm(), - realm4_handler->auth_scheme(), "basic realm=Realm4", - AuthCredentials(kAdmin, kRoot), path); + second_cache.Add(origin, kRealm4, HttpAuth::AUTH_SCHEME_BASIC, + "basic realm=Realm4", AuthCredentials(kAdmin, kRoot), path); second_cache.UpdateAllFrom(first_cache);
diff --git a/net/third_party/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc b/net/third_party/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc index d88170d..2f2af2f 100644 --- a/net/third_party/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc +++ b/net/third_party/quic/core/qpack/fuzzer/qpack_encoder_stream_sender_fuzzer.cc
@@ -8,6 +8,7 @@ #include <cstdint> #include <limits> +#include "net/third_party/quic/core/qpack/qpack_encoder_test_utils.h" #include "net/third_party/quic/platform/api/quic_fuzzed_data_provider.h" #include "net/third_party/quic/platform/api/quic_string.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" @@ -15,22 +16,12 @@ namespace quic { namespace test { -// A QpackEncoderStreamSender::Delegate implementation that ignores encoded -// data. -class NoOpDelegate : public QpackEncoderStreamSender::Delegate { - public: - NoOpDelegate() = default; - ~NoOpDelegate() override = default; - - void WriteEncoderStreamData(QuicStringPiece data) override {} -}; - // This fuzzer exercises QpackEncoderStreamSender. // TODO(bnc): Encoded data could be fed into QpackEncoderStreamReceiver and // decoded instructions directly compared to input. Figure out how to get gMock // enabled for cc_fuzz_target target types. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - NoOpDelegate delegate; + NoopEncoderStreamSenderDelegate delegate; QpackEncoderStreamSender sender(&delegate); QuicFuzzedDataProvider provider(data, size);
diff --git a/net/third_party/quic/core/qpack/qpack_encoder_stream_sender_test.cc b/net/third_party/quic/core/qpack/qpack_encoder_stream_sender_test.cc index 76215eea..4e4255e 100644 --- a/net/third_party/quic/core/qpack/qpack_encoder_stream_sender_test.cc +++ b/net/third_party/quic/core/qpack/qpack_encoder_stream_sender_test.cc
@@ -4,6 +4,7 @@ #include "net/third_party/quic/core/qpack/qpack_encoder_stream_sender.h" +#include "net/third_party/quic/core/qpack/qpack_encoder_test_utils.h" #include "net/third_party/quic/platform/api/quic_test.h" #include "net/third_party/quic/platform/api/quic_text_utils.h" #include "testing/gmock/include/gmock/gmock.h" @@ -16,19 +17,12 @@ namespace test { namespace { -class MockSenderDelegate : public QpackEncoderStreamSender::Delegate { - public: - ~MockSenderDelegate() override = default; - - MOCK_METHOD1(WriteEncoderStreamData, void(QuicStringPiece data)); -}; - class QpackEncoderStreamSenderTest : public QuicTest { protected: QpackEncoderStreamSenderTest() : stream_(&delegate_) {} ~QpackEncoderStreamSenderTest() override = default; - StrictMock<MockSenderDelegate> delegate_; + StrictMock<MockEncoderStreamSenderDelegate> delegate_; QpackEncoderStreamSender stream_; };
diff --git a/net/third_party/quic/core/qpack/qpack_encoder_test_utils.h b/net/third_party/quic/core/qpack/qpack_encoder_test_utils.h index 8c8d8ca6..cafd6fee 100644 --- a/net/third_party/quic/core/qpack/qpack_encoder_test_utils.h +++ b/net/third_party/quic/core/qpack/qpack_encoder_test_utils.h
@@ -42,6 +42,15 @@ void WriteEncoderStreamData(QuicStringPiece data) override; }; +// Mock QpackEncoderStreamSender::Delegate implementation. +class MockEncoderStreamSenderDelegate + : public QpackEncoderStreamSender::Delegate { + public: + ~MockEncoderStreamSenderDelegate() override = default; + + MOCK_METHOD1(WriteEncoderStreamData, void(QuicStringPiece data)); +}; + QuicString QpackEncode( QpackEncoder::DecoderStreamErrorDelegate* decoder_stream_error_delegate, QpackEncoderStreamSender::Delegate* encoder_stream_sender_delegate,
diff --git a/net/third_party/quic/core/qpack/qpack_header_table_test.cc b/net/third_party/quic/core/qpack/qpack_header_table_test.cc index b058844..fa9096ff 100644 --- a/net/third_party/quic/core/qpack/qpack_header_table_test.cc +++ b/net/third_party/quic/core/qpack/qpack_header_table_test.cc
@@ -5,7 +5,6 @@ #include "net/third_party/quic/core/qpack/qpack_header_table.h" #include "net/third_party/quic/core/qpack/qpack_static_table.h" -#include "net/third_party/quic/core/qpack/qpack_test_utils.h" #include "net/third_party/quic/platform/api/quic_arraysize.h" #include "net/third_party/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h"
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc index 7e26e4cd..35a5b1e 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -8,12 +8,17 @@ #include <map> #include <utility> +#include "base/base64.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/json/json_writer.h" #include "base/memory/ref_counted_memory.h" +#include "base/metrics/histogram_samples.h" +#include "base/metrics/statistics_recorder.h" #include "base/no_destructor.h" +#include "base/pickle.h" #include "base/process/process_handle.h" +#include "base/trace_event/common/trace_event_common.h" #include "base/trace_event/trace_buffer.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" @@ -515,12 +520,14 @@ RegisterWithTraceLog(); } - TraceLog::GetInstance()->SetEnabled( - TraceConfig(data_source_config.trace_config), TraceLog::RECORDING_MODE); + auto trace_config = TraceConfig(data_source_config.trace_config); + TraceLog::GetInstance()->SetEnabled(trace_config, TraceLog::RECORDING_MODE); + ResetHistograms(trace_config); } void TraceEventDataSource::StopTracing( base::OnceClosure stop_complete_callback) { + LogHistograms(); stop_complete_callback_ = std::move(stop_complete_callback); auto on_tracing_stopped_callback = @@ -571,6 +578,36 @@ } } +void TraceEventDataSource::LogHistogram(base::HistogramBase* histogram) { + if (!histogram) { + return; + } + auto samples = histogram->SnapshotSamples(); + base::Pickle pickle; + samples->Serialize(&pickle); + std::string buckets; + base::Base64Encode( + std::string(static_cast<const char*>(pickle.data()), pickle.size()), + &buckets); + TRACE_EVENT_INSTANT2("benchmark", "UMAHistogramDelta", + TRACE_EVENT_SCOPE_PROCESS, "name", + histogram->histogram_name(), "buckets", buckets); +} + +void TraceEventDataSource::ResetHistograms(const TraceConfig& trace_config) { + histograms_.clear(); + for (const std::string& histogram_name : trace_config.histogram_names()) { + histograms_.push_back(histogram_name); + LogHistogram(base::StatisticsRecorder::FindHistogram(histogram_name)); + } +} + +void TraceEventDataSource::LogHistograms() { + for (const std::string& histogram_name : histograms_) { + LogHistogram(base::StatisticsRecorder::FindHistogram(histogram_name)); + } +} + void TraceEventDataSource::Flush( base::RepeatingClosure flush_complete_callback) { DCHECK(TraceLog::GetInstance()->IsEnabled());
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.h b/services/tracing/public/cpp/perfetto/trace_event_data_source.h index b803d12..2ff06aae 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.h +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.h
@@ -11,7 +11,9 @@ #include "base/component_export.h" #include "base/macros.h" +#include "base/metrics/histogram_base.h" #include "base/threading/thread_local.h" +#include "base/trace_event/trace_config.h" #include "services/tracing/public/cpp/perfetto/producer_client.h" namespace perfetto { @@ -108,6 +110,14 @@ void ReturnTraceWriter( std::unique_ptr<perfetto::StartupTraceWriter> trace_writer); + // Extracts UMA histogram names that should be logged in traces and logs their + // starting values. + void ResetHistograms(const base::trace_event::TraceConfig& trace_config); + // Logs selected UMA histogram. + void LogHistograms(); + // Logs a given histogram in traces. + void LogHistogram(base::HistogramBase* histogram); + base::OnceClosure stop_complete_callback_; base::Lock lock_; // Protects subsequent members. @@ -118,6 +128,7 @@ // SetupStartupTracing() is called. std::unique_ptr<perfetto::StartupTraceWriterRegistry> startup_writer_registry_; + std::vector<std::string> histograms_; DISALLOW_COPY_AND_ASSIGN(TraceEventDataSource); };
diff --git a/styleguide/c++/c++11.html b/styleguide/c++/c++11.html index 82d92ee..3227676 100644 --- a/styleguide/c++/c++11.html +++ b/styleguide/c++/c++11.html
@@ -319,14 +319,6 @@ </tr> <tr> -<td>thread_local storage class</td> -<td><code>thread_local int foo = 1;</code></td> -<td>Puts variables into thread local storage.</td> -<td><a href="http://en.cppreference.com/w/cpp/language/storage_duration">Storage duration</a></td> -<td>Allowed only for POD data. (<a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/2msN8k3Xzgs">discussion</a>, <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/h7O5BdtWCZw">fork</a>). Use <a href="https://cs.chromium.org/chromium/src/base/threading/sequence_local_storage_slot.h">SequenceLocalStorageSlot</a> for sequence support, and <a href="https://cs.chromium.org/chromium/src/base/threading/thread_local.h">ThreadLocal</a>/<a href="https://cs.chromium.org/chromium/src/base/threading/thread_local_storage.h">ThreadLocalStorage</a> for other cases.</td> -</tr> - -<tr> <td>Type Aliases ("using" instead of "typedef")</td> <td><code>using <i>new_alias</i> = <i>typename</i></code></td> <td>Allows parameterized typedefs</td> @@ -784,6 +776,14 @@ <td>Banned in the <a href="https://google.github.io/styleguide/cppguide.html#Operator_Overloading">Google Style Guide</a>.</td> </tr> +<tr> +<td>thread_local storage class</td> +<td><code>thread_local int foo = 1;</code></td> +<td>Puts variables into thread local storage.</td> +<td><a href="http://en.cppreference.com/w/cpp/language/storage_duration">Storage duration</a></td> +<td>Some surprising effects on Mac (<a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/2msN8k3Xzgs">discussion</a>, <a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/h7O5BdtWCZw">fork</a>). Use <a href="https://cs.chromium.org/chromium/src/base/threading/sequence_local_storage_slot.h">SequenceLocalStorageSlot</a> for sequence support, and <a href="https://cs.chromium.org/chromium/src/base/threading/thread_local.h">ThreadLocal</a>/<a href="https://cs.chromium.org/chromium/src/base/threading/thread_local_storage.h">ThreadLocalStorage</a> otherwise.</td> +</tr> + </tbody> </table>
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index fe4da53..20d8fdc 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -5627,24 +5627,6 @@ { "args": [ "--use-gpu-in-tests", - "--test-launcher-retry-limit=0" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:5912-18.0.5", - "os": "Ubuntu", - "pool": "Chrome-GPU" - } - ], - "shards": 4 - }, - "test": "dawn_end2end_tests" - }, - { - "args": [ - "--use-gpu-in-tests", "--use-cmd-decoder=validating" ], "swarming": {
diff --git a/testing/buildbot/filters/webui_polymer2_browser_tests.filter b/testing/buildbot/filters/webui_polymer2_browser_tests.filter index bead418..6cf3c55 100644 --- a/testing/buildbot/filters/webui_polymer2_browser_tests.filter +++ b/testing/buildbot/filters/webui_polymer2_browser_tests.filter
@@ -254,6 +254,15 @@ OnboardingWelcomeEmailChooserTest.* OnboardingWelcomeWelcomeAppTest.* OpenAudioFiles/* +PDFAnnotationsTest.* +PDFExtensionClipboardTest.* +PDFExtensionHitTestTest.* +PDFExtensionInternalLinkClickTest.* +PDFExtensionLinkClickTest.* +PDFExtensionLoadTest.* +PDFExtensionTest.* +PDFIsolatedExtensionTest.* +PDFPluginDisabledTest.* PrintPreviewAdvancedDialogTest.* PrintPreviewAdvancedItemTest.* PrintPreviewBaseSettingsSectionTest.*
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 764dccf..3ef5a8b 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -435,6 +435,7 @@ 'dawn_end2end_tests': { 'remove_from': [ # chromium.gpu.fyi + 'Linux FYI Experimental Release (Intel HD 630)', # https://crbug.com/927459 'Linux FYI Release (AMD R7 240)', # https://crbug.com/915430 ], },
diff --git a/testing/scripts/common.py b/testing/scripts/common.py index 566d2e3b..1e60d71 100644 --- a/testing/scripts/common.py +++ b/testing/scripts/common.py
@@ -300,12 +300,12 @@ self.options.isolated_script_test_filter) # Augment test repeat if needed - if self.options.isolated_script_test_repeat: + if self.options.isolated_script_test_repeat is not None: isolated_script_cmd += self.generate_test_repeat_args( self.options.isolated_script_test_repeat) # Augment test launcher retry limit args if needed - if self.options.isolated_script_test_launcher_retry_limit: + if self.options.isolated_script_test_launcher_retry_limit is not None: isolated_script_cmd += self.generate_test_launcher_retry_limit_args( self.options.isolated_script_test_launcher_retry_limit)
diff --git a/testing/scripts/run_isolated_script_test.py b/testing/scripts/run_isolated_script_test.py index ea5e54f..733de14b 100755 --- a/testing/scripts/run_isolated_script_test.py +++ b/testing/scripts/run_isolated_script_test.py
@@ -76,7 +76,7 @@ return ['--isolated-script-test-output=%s' % output] def generate_test_launcher_retry_limit_args(self, retry_limit): - return ['--isolated-script-test-retry-limit=%d' % retry_limit] + return ['--isolated-script-test-launcher-retry-limit=%d' % retry_limit] def generate_test_repeat_args(self, repeat_count): return ['--isolated-script-test-repeat=%d' % repeat_count]
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 516ebbdc..d0d93fd 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -42,6 +42,7 @@ "frame/document_interface_broker.mojom", "frame/find_in_page.mojom", "frame/frame_host_test_interface.mojom", + "frame/lifecycle.mojom", "frame/navigation_initiator.mojom", "leak_detector/leak_detector.mojom", "loader/code_cache.mojom",
diff --git a/third_party/blink/public/mojom/frame/lifecycle.mojom b/third_party/blink/public/mojom/frame/lifecycle.mojom new file mode 100644 index 0000000..4a97cc5 --- /dev/null +++ b/third_party/blink/public/mojom/frame/lifecycle.mojom
@@ -0,0 +1,15 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module blink.mojom; + +// The frame visibility status. +enum FrameVisibility { + // Rendered but not in the current viewport. + kRenderedOutOfViewport, + // Rendered in current viewport. + kRenderedInViewport, + // Not visible, no layout object created. ie. display: none + kNotRendered, +};
diff --git a/third_party/blink/public/platform/modules/mediasession/media_session.mojom b/third_party/blink/public/platform/modules/mediasession/media_session.mojom index a1c7453..cf4324444 100644 --- a/third_party/blink/public/platform/modules/mediasession/media_session.mojom +++ b/third_party/blink/public/platform/modules/mediasession/media_session.mojom
@@ -21,6 +21,15 @@ DidReceiveAction(media_session.mojom.MediaSessionAction action); }; +// MediaMetadata +// Spec: https://wicg.github.io/mediasession/ +struct SpecMediaMetadata { + mojo_base.mojom.String16 title; + mojo_base.mojom.String16 artist; + mojo_base.mojom.String16 album; + array<media_session.mojom.MediaImage> artwork; +}; + interface MediaSessionService { // MediaSessionClient interface is used to notify Blink MediaSession of // media control actions. @@ -31,7 +40,7 @@ // Notifies the browser that the metadata is set, |metadata| will be displayed // on the UI. - SetMetadata(media_session.mojom.MediaMetadata? metadata); + SetMetadata(SpecMediaMetadata? metadata); // Notifies the browser that the event handler for |action| has been set, // browser needs to show a media button in the UI or register listeners to the
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index 177112d..3e5e1d7 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -39,6 +39,7 @@ #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" #include "third_party/blink/public/common/frame/user_activation_update_type.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-shared.h" #include "third_party/blink/public/platform/blame_context.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h" #include "third_party/blink/public/platform/web_application_cache_host.h" @@ -629,6 +630,8 @@ // A performance timing event (e.g. first paint) occurred virtual void DidChangePerformanceTiming() {} + virtual void VisibilityChanged(blink::mojom::FrameVisibility visibility) {} + // UseCounter ---------------------------------------------------------- // Blink exhibited a certain loading behavior that the browser process will // use for segregated histograms.
diff --git a/third_party/blink/public/web/web_remote_frame_client.h b/third_party/blink/public/web/web_remote_frame_client.h index f9a76268..21558161 100644 --- a/third_party/blink/public/web/web_remote_frame_client.h +++ b/third_party/blink/public/web/web_remote_frame_client.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_REMOTE_FRAME_CLIENT_H_ #include "cc/paint/paint_canvas.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-shared.h" #include "third_party/blink/public/platform/web_focus_type.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_touch_action.h" @@ -50,7 +51,7 @@ const WebRect& viewport_intersection, bool occluded_or_obscured) {} - virtual void VisibilityChanged(bool visible) {} + virtual void VisibilityChanged(blink::mojom::FrameVisibility visibility) {} // Set or clear the inert property on the remote frame. virtual void SetIsInert(bool) {}
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl index 67f99ba..df10119 100644 --- a/third_party/blink/renderer/core/dom/document.idl +++ b/third_party/blink/renderer/core/dom/document.idl
@@ -188,8 +188,8 @@ [MeasureAs=DocumentCaretRangeFromPoint] Range caretRangeFromPoint([DefaultValue=Undefined] optional long x, [DefaultValue=Undefined] optional long y); - // https://wicg.github.io/feature-policy/#the-policy-object - [OriginTrialEnabled=FeaturePolicyJavaScriptInterface] readonly attribute FeaturePolicy featurePolicy; + // https://w3c.github.io/webappsec-feature-policy/#the-policy-object + [RuntimeEnabled=FeaturePolicyJavaScriptInterface] readonly attribute FeaturePolicy featurePolicy; // Deprecated prefixed page visibility API. // TODO(davidben): This is a property so attaching a deprecation warning results in false positives when outputting
diff --git a/third_party/blink/renderer/core/editing/reveal_selection_scope.cc b/third_party/blink/renderer/core/editing/reveal_selection_scope.cc index afe5f8b..ee210ff 100644 --- a/third_party/blink/renderer/core/editing/reveal_selection_scope.cc +++ b/third_party/blink/renderer/core/editing/reveal_selection_scope.cc
@@ -43,10 +43,12 @@ RevealSelectionScope::~RevealSelectionScope() { DCHECK(GetEditor().PreventRevealSelection()); GetEditor().DecreasePreventRevealSelection(); - if (!GetEditor().PreventRevealSelection()) { - frame_->Selection().RevealSelection(ScrollAlignment::kAlignToEdgeIfNeeded, - kRevealExtent); - } + if (GetEditor().PreventRevealSelection()) + return; + if (!frame_->Selection().IsAvailable()) + return; + frame_->Selection().RevealSelection(ScrollAlignment::kAlignToEdgeIfNeeded, + kRevealExtent); } Editor& RevealSelectionScope::GetEditor() {
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index 4db791f0..950c306 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -762,6 +762,12 @@ } } +void LocalFrameClientImpl::VisibilityChanged( + blink::mojom::FrameVisibility visibility) { + if (WebLocalFrameClient* client = web_frame_->Client()) + client->VisibilityChanged(visibility); +} + DocumentLoader* LocalFrameClientImpl::CreateDocumentLoader( LocalFrame* frame, WebNavigationType navigation_type,
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h index e075470e..339bbe9 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -156,6 +156,7 @@ bool ShouldTrackUseCounter(const KURL&) override; void SelectorMatchChanged(const Vector<String>& added_selectors, const Vector<String>& removed_selectors) override; + void VisibilityChanged(blink::mojom::FrameVisibility visibility) override; // Creates a WebDocumentLoaderImpl that is a DocumentLoader but also has: // - storage to store an extra data that can be used by the content layer
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 3fbb691..abc88263 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -10654,30 +10654,34 @@ class TestWebRemoteFrameClientForVisibility : public frame_test_helpers::TestWebRemoteFrameClient { public: - TestWebRemoteFrameClientForVisibility() : visible_(true) {} + TestWebRemoteFrameClientForVisibility() = default; ~TestWebRemoteFrameClientForVisibility() override = default; // frame_test_helpers::TestWebRemoteFrameClient: - void VisibilityChanged(bool visible) override { visible_ = visible; } + void VisibilityChanged(blink::mojom::FrameVisibility visibility) override { + visibility_ = visibility; + } - bool IsVisible() const { return visible_; } + blink::mojom::FrameVisibility visibility() const { return visibility_; } private: - bool visible_; + blink::mojom::FrameVisibility visibility_ = + blink::mojom::FrameVisibility::kRenderedInViewport; }; -class WebFrameVisibilityChangeTest : public WebFrameTest { +class WebRemoteFrameVisibilityChangeTest : public WebFrameTest { public: - WebFrameVisibilityChangeTest() { + WebRemoteFrameVisibilityChangeTest() { RegisterMockedHttpURLLoad("visible_iframe.html"); RegisterMockedHttpURLLoad("single_iframe.html"); frame_ = web_view_helper_.InitializeAndLoad(base_url_ + "single_iframe.html") ->MainFrameImpl(); + web_view_helper_.Resize(WebSize(640, 480)); web_remote_frame_ = frame_test_helpers::CreateRemote(&remote_frame_client_); } - ~WebFrameVisibilityChangeTest() override = default; + ~WebRemoteFrameVisibilityChangeTest() override = default; void ExecuteScriptOnMainFrame(const WebScriptSource& script) { MainFrame()->ExecuteScript(script); @@ -10703,23 +10707,132 @@ Persistent<WebRemoteFrameImpl> web_remote_frame_; }; -TEST_F(WebFrameVisibilityChangeTest, RemoteFrameVisibilityChange) { +TEST_F(WebRemoteFrameVisibilityChangeTest, FrameVisibilityChange) { SwapLocalFrameToRemoteFrame(); ExecuteScriptOnMainFrame(WebScriptSource( "document.querySelector('iframe').style.display = 'none';")); - EXPECT_FALSE(RemoteFrameClient()->IsVisible()); + EXPECT_EQ(blink::mojom::FrameVisibility::kNotRendered, + RemoteFrameClient()->visibility()); ExecuteScriptOnMainFrame(WebScriptSource( "document.querySelector('iframe').style.display = 'block';")); - EXPECT_TRUE(RemoteFrameClient()->IsVisible()); + EXPECT_EQ(blink::mojom::FrameVisibility::kRenderedInViewport, + RemoteFrameClient()->visibility()); + + ExecuteScriptOnMainFrame(WebScriptSource( + "var padding = document.createElement('div');" + "padding.style = 'width: 400px; height: 800px;';" + "document.body.insertBefore(padding, document.body.firstChild);")); + EXPECT_EQ(blink::mojom::FrameVisibility::kRenderedOutOfViewport, + RemoteFrameClient()->visibility()); + + ExecuteScriptOnMainFrame( + WebScriptSource("document.scrollingElement.scrollTop = 800;")); + EXPECT_EQ(blink::mojom::FrameVisibility::kRenderedInViewport, + RemoteFrameClient()->visibility()); } -TEST_F(WebFrameVisibilityChangeTest, RemoteFrameParentVisibilityChange) { +TEST_F(WebRemoteFrameVisibilityChangeTest, ParentVisibilityChange) { SwapLocalFrameToRemoteFrame(); ExecuteScriptOnMainFrame( WebScriptSource("document.querySelector('iframe').parentElement.style." "display = 'none';")); - EXPECT_FALSE(RemoteFrameClient()->IsVisible()); + EXPECT_EQ(blink::mojom::FrameVisibility::kNotRendered, + RemoteFrameClient()->visibility()); +} + +class TestWebLocalFrameClientForVisibility + : public frame_test_helpers::TestWebFrameClient { + public: + TestWebLocalFrameClientForVisibility() = default; + ~TestWebLocalFrameClientForVisibility() override = default; + + // frame_test_helpers::TestWebFrameClient: + void VisibilityChanged(blink::mojom::FrameVisibility visibility) override { + visibility_ = visibility; + } + + blink::mojom::FrameVisibility visibility() const { return visibility_; } + + private: + blink::mojom::FrameVisibility visibility_ = + blink::mojom::FrameVisibility::kRenderedInViewport; +}; + +class WebLocalFrameVisibilityChangeTest + : public WebFrameTest, + public frame_test_helpers::TestWebFrameClient { + public: + WebLocalFrameVisibilityChangeTest() { + RegisterMockedHttpURLLoad("visible_iframe.html"); + RegisterMockedHttpURLLoad("single_iframe.html"); + frame_ = web_view_helper_ + .InitializeAndLoad(base_url_ + "single_iframe.html", this) + ->MainFrameImpl(); + web_view_helper_.Resize(WebSize(640, 480)); + } + + ~WebLocalFrameVisibilityChangeTest() override = default; + + void ExecuteScriptOnMainFrame(const WebScriptSource& script) { + MainFrame()->ExecuteScript(script); + MainFrame()->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); + RunPendingTasks(); + } + + WebLocalFrame* MainFrame() { return frame_; } + + // frame_test_helpers::TestWebFrameClient: + WebLocalFrame* CreateChildFrame(WebLocalFrame* parent, + WebTreeScopeType scope, + const WebString& name, + const WebString& fallback_name, + WebSandboxFlags, + const ParsedFeaturePolicy&, + const WebFrameOwnerProperties&, + FrameOwnerElementType) override { + return CreateLocalChild(*parent, scope, &child_client_); + } + + TestWebLocalFrameClientForVisibility& ChildClient() { return child_client_; } + + private: + TestWebLocalFrameClientForVisibility child_client_; + frame_test_helpers::WebViewHelper web_view_helper_; + WebLocalFrame* frame_; +}; + +TEST_F(WebLocalFrameVisibilityChangeTest, FrameVisibilityChange) { + ExecuteScriptOnMainFrame(WebScriptSource( + "document.querySelector('iframe').style.display = 'none';")); + EXPECT_EQ(blink::mojom::FrameVisibility::kNotRendered, + ChildClient().visibility()); + + ExecuteScriptOnMainFrame(WebScriptSource( + "document.querySelector('iframe').style.display = 'block';")); + EXPECT_EQ(blink::mojom::FrameVisibility::kRenderedInViewport, + ChildClient().visibility()); + + ExecuteScriptOnMainFrame(WebScriptSource( + "var padding = document.createElement('div');" + "padding.style = 'width: 400px; height: 800px;';" + "document.body.insertBefore(padding, document.body.firstChild);")); + EXPECT_EQ(blink::mojom::FrameVisibility::kRenderedOutOfViewport, + ChildClient().visibility()); + + ExecuteScriptOnMainFrame( + WebScriptSource("document.scrollingElement.scrollTop = 800;")); + EXPECT_EQ(blink::mojom::FrameVisibility::kRenderedInViewport, + ChildClient().visibility()); +} + +TEST_F(WebLocalFrameVisibilityChangeTest, ParentVisibilityChange) { + ExecuteScriptOnMainFrame( + WebScriptSource("document.querySelector('iframe').parentElement.style." + "display = 'none';")); + EXPECT_EQ(blink::mojom::FrameVisibility::kNotRendered, + ChildClient().visibility()); } static void EnableGlobalReuseForUnownedMainFrames(WebSettings* settings) {
diff --git a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc index 5cc3f254..5402a61 100644 --- a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc +++ b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
@@ -82,7 +82,8 @@ String(text), ImeTextSpanVectorBuilder::Build(ime_text_spans), selection_start, selection_end); - return text.IsEmpty() || GetInputMethodController().HasComposition(); + return text.IsEmpty() || + (GetFrame() && GetInputMethodController().HasComposition()); } bool WebInputMethodControllerImpl::FinishComposingText( @@ -202,6 +203,7 @@ InputMethodController& WebInputMethodControllerImpl::GetInputMethodController() const { + DCHECK(GetFrame()); return GetFrame()->GetInputMethodController(); }
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy.idl b/third_party/blink/renderer/core/feature_policy/feature_policy.idl index beadb01..e2f45f8 100644 --- a/third_party/blink/renderer/core/feature_policy/feature_policy.idl +++ b/third_party/blink/renderer/core/feature_policy/feature_policy.idl
@@ -5,7 +5,7 @@ // https://wicg.github.io/feature-policy/#the-policy-object [ NoInterfaceObject, - OriginTrialEnabled=FeaturePolicyJavaScriptInterface, + RuntimeEnabled=FeaturePolicyJavaScriptInterface, ImplementedAs=DOMFeaturePolicy ] interface FeaturePolicy { [MeasureAs=FeaturePolicyJSAPI] boolean allowsFeature(DOMString feature, optional DOMString url);
diff --git a/third_party/blink/renderer/core/frame/frame_client.h b/third_party/blink/renderer/core/frame/frame_client.h index 0bd60f8..5fb93df 100644 --- a/third_party/blink/renderer/core/frame/frame_client.h +++ b/third_party/blink/renderer/core/frame/frame_client.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_CLIENT_H_ #include "base/unguessable_token.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/public/platform/blame_context.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -33,6 +34,8 @@ virtual void FrameFocused() const = 0; + virtual void VisibilityChanged(blink::mojom::FrameVisibility visibility) = 0; + virtual base::UnguessableToken GetDevToolsFrameToken() const = 0; virtual ~FrameClient() = default;
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index d1b9cc5..fecf84b9 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -367,6 +367,7 @@ [](LocalFrameView* frame_view, bool is_visible) { if (!frame_view) return; + frame_view->UpdateVisibility(is_visible); frame_view->UpdateRenderThrottlingStatus( !is_visible, frame_view->subtree_throttled_); }, @@ -4263,4 +4264,21 @@ lifecycle_observers_.erase(observer); } +void LocalFrameView::UpdateVisibility(bool is_visible) { + blink::mojom::FrameVisibility visibility; + if (!is_attached_) { + visibility = blink::mojom::FrameVisibility::kNotRendered; + } else if (!is_visible) { + visibility = blink::mojom::FrameVisibility::kRenderedOutOfViewport; + } else { + visibility = blink::mojom::FrameVisibility::kRenderedInViewport; + } + if (visibility_ == visibility) + return; + visibility_ = visibility; + if (auto* client = GetFrame().Client()) { + client->VisibilityChanged(visibility); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index 9fd61ff7..eb3a569a 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -30,6 +30,7 @@ #include <utility> #include "third_party/blink/public/common/manifest/web_display_mode.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/public/platform/shape_properties.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/frame_view.h" @@ -862,6 +863,8 @@ void LayoutFromRootObject(LayoutObject& root); + void UpdateVisibility(bool is_visible); + LayoutSize size_; typedef HashSet<scoped_refptr<LayoutEmbeddedObject>> EmbeddedObjectSet; @@ -874,6 +877,8 @@ bool is_attached_; bool self_visible_; bool parent_visible_; + blink::mojom::FrameVisibility visibility_ = + blink::mojom::FrameVisibility::kRenderedInViewport; WebDisplayMode display_mode_;
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client.h b/third_party/blink/renderer/core/frame/remote_frame_client.h index b9c8598..dd07bbd 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_client.h +++ b/third_party/blink/renderer/core/frame/remote_frame_client.h
@@ -58,8 +58,6 @@ virtual void AdvanceFocus(WebFocusType, LocalFrame* source) = 0; - virtual void VisibilityChanged(bool visible) = 0; - virtual void SetIsInert(bool) = 0; virtual void SetInheritedEffectiveTouchAction(TouchAction) = 0;
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc index ffb4e27..156dc6b 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc +++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
@@ -166,8 +166,9 @@ WebLocalFrameImpl::FromFrame(source)); } -void RemoteFrameClientImpl::VisibilityChanged(bool visible) { - web_frame_->Client()->VisibilityChanged(visible); +void RemoteFrameClientImpl::VisibilityChanged( + blink::mojom::FrameVisibility visibility) { + web_frame_->Client()->VisibilityChanged(visibility); } void RemoteFrameClientImpl::SetIsInert(bool inert) {
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h index 06878012..92d3aa9 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h +++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
@@ -50,7 +50,7 @@ const IntRect& screen_space_rect) override; void UpdateRemoteViewportIntersection(const IntRect&, bool) override; void AdvanceFocus(WebFocusType, LocalFrame*) override; - void VisibilityChanged(bool visible) override; + void VisibilityChanged(blink::mojom::FrameVisibility) override; void SetIsInert(bool) override; void SetInheritedEffectiveTouchAction(TouchAction) override; void UpdateRenderThrottlingStatus(bool is_throttled,
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.cc b/third_party/blink/renderer/core/frame/remote_frame_view.cc index 5697f4b..a850a44 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_view.cc +++ b/third_party/blink/renderer/core/frame/remote_frame_view.cc
@@ -61,6 +61,7 @@ is_attached_ = true; if (ParentFrameView()->IsVisible()) SetParentVisible(true); + UpdateVisibility(true); SetupRenderThrottling(); subtree_throttled_ = ParentFrameView()->CanThrottleRendering(); @@ -297,12 +298,12 @@ void RemoteFrameView::Hide() { self_visible_ = false; - remote_frame_->Client()->VisibilityChanged(false); + UpdateVisibility(scroll_visible_); } void RemoteFrameView::Show() { self_visible_ = true; - remote_frame_->Client()->VisibilityChanged(true); + UpdateVisibility(scroll_visible_); } void RemoteFrameView::SetParentVisible(bool visible) { @@ -312,8 +313,24 @@ parent_visible_ = visible; if (!self_visible_) return; + UpdateVisibility(scroll_visible_); +} - remote_frame_->Client()->VisibilityChanged(self_visible_ && parent_visible_); +void RemoteFrameView::UpdateVisibility(bool scroll_visible) { + blink::mojom::FrameVisibility visibility; + scroll_visible_ = scroll_visible; + if (self_visible_ && parent_visible_) { + visibility = scroll_visible + ? blink::mojom::FrameVisibility::kRenderedInViewport + : blink::mojom::FrameVisibility::kRenderedOutOfViewport; + } else { + visibility = blink::mojom::FrameVisibility::kNotRendered; + } + + if (visibility == visibility_) + return; + visibility_ = visibility; + remote_frame_->Client()->VisibilityChanged(visibility); } void RemoteFrameView::SetupRenderThrottling() { @@ -327,6 +344,7 @@ visibility_observer_ = MakeGarbageCollected<ElementVisibilityObserver>( target_element, WTF::BindRepeating( [](RemoteFrameView* remote_view, bool is_visible) { + remote_view->UpdateVisibility(is_visible); remote_view->UpdateRenderThrottlingStatus( !is_visible, remote_view->subtree_throttled_); },
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.h b/third_party/blink/renderer/core/frame/remote_frame_view.h index 9389744..d80aecf 100644 --- a/third_party/blink/renderer/core/frame/remote_frame_view.h +++ b/third_party/blink/renderer/core/frame/remote_frame_view.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REMOTE_FRAME_VIEW_H_ #include "cc/paint/paint_canvas.h" +#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document_lifecycle.h" #include "third_party/blink/renderer/core/frame/frame_view.h" #include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h" @@ -85,6 +86,7 @@ void UpdateRenderThrottlingStatus(bool hidden, bool subtree_throttled); bool CanThrottleRendering() const; void SetupRenderThrottling(); + void UpdateVisibility(bool scroll_visible); // The properties and handling of the cycle between RemoteFrame // and its RemoteFrameView corresponds to that between LocalFrame @@ -97,6 +99,9 @@ IntRect frame_rect_; bool self_visible_; bool parent_visible_; + bool scroll_visible_ = true; + blink::mojom::FrameVisibility visibility_ = + blink::mojom::FrameVisibility::kRenderedInViewport; Member<ElementVisibilityObserver> visibility_observer_; bool subtree_throttled_ = false;
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.idl b/third_party/blink/renderer/core/html/html_iframe_element.idl index 7f5f9ea..9bea0c3 100644 --- a/third_party/blink/renderer/core/html/html_iframe_element.idl +++ b/third_party/blink/renderer/core/html/html_iframe_element.idl
@@ -43,8 +43,8 @@ // Feature Policy [CEReactions, Reflect] attribute DOMString allow; - // https://wicg.github.io/feature-policy/#the-policy-object - [OriginTrialEnabled=FeaturePolicyJavaScriptInterface] readonly attribute FeaturePolicy featurePolicy; + // https://w3c.github.io/webappsec-feature-policy/#the-policy-object + [RuntimeEnabled=FeaturePolicyJavaScriptInterface] readonly attribute FeaturePolicy featurePolicy; [RuntimeEnabled=LazyFrameLoading, CEReactions, Reflect, ReflectOnly=("on", "off", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString lazyLoad;
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index b45129b6..c6b5f3c6 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -3320,12 +3320,16 @@ void HTMLMediaElement::RemoteRouteAvailabilityChanged( WebRemotePlaybackAvailability availability) { - if (RemotePlaybackClient() && - !RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()) { - // The new remote playback pipeline is using the Presentation API for - // remote playback device availability monitoring. + // The new remote playback pipeline is using the Presentation API for + // remote playback device availability monitoring. + // This code is left as is because many tests depend on this path for the + // moment, but it will be cleaned up. + // TODO(https://crbug.com/927099): Clean up old discovery paths. + // TODO(https://crubg.com/927451): Remove test depencencies on + // RemoteRouteAvailabilityChanged + + if (RemotePlaybackClient()) RemotePlaybackClient()->AvailabilityChanged(availability); - } } bool HTMLMediaElement::HasRemoteRoutes() const { @@ -3358,10 +3362,8 @@ void HTMLMediaElement::RemotePlaybackCompatibilityChanged(const WebURL& url, bool is_compatible) { - if (RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled() && - RemotePlaybackClient()) { + if (RemotePlaybackClient()) RemotePlaybackClient()->SourceChanged(url, is_compatible); - } } bool HTMLMediaElement::HasSelectedVideoTrack() {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.cc index 846f7b76..bf73a03c 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.cc
@@ -5,10 +5,20 @@ #include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h" +#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" namespace blink { +std::ostream& operator<<(std::ostream& out, + const NGCaretNavigator::Position& position) { + return out << position.index << "/" + << (position.IsBeforeCharacter() ? "BeforeCharacter" + : "AfterCharacter"); +} + NGCaretNavigator::~NGCaretNavigator() = default; NGCaretNavigator::NGCaretNavigator(const LayoutBlockFlow& context) @@ -89,6 +99,68 @@ return move_direction == MoveDirection::kTowardsLeft; } +NGCaretNavigator::Line NGCaretNavigator::ContainingLineOf( + unsigned index) const { + DCHECK_LT(index, GetText().length()); + // TODO(xiaochengh): Make it work for multi-col + DCHECK(context_.CurrentFragment()); + unsigned last_line_end = 0; + for (const auto child : context_.CurrentFragment()->Children()) { + if (!child->IsLineBox()) + continue; + const NGPhysicalLineBoxFragment* line = + ToNGPhysicalLineBoxFragment(child.get()); + DCHECK(line->BreakToken()); + DCHECK(line->BreakToken()->IsInlineType()); + const NGInlineBreakToken* token = ToNGInlineBreakToken(line->BreakToken()); + const unsigned line_end = + token->IsFinished() ? GetText().length() : token->TextOffset(); + if (line_end > index) + return {last_line_end, line_end, line->BaseDirection()}; + last_line_end = line_end; + } + NOTREACHED(); + return {}; +} + +bool NGCaretNavigator::IsValidCaretPosition(const Position& position) const { + unsigned index = position.index; + if (position.IsAfterCharacter() && IsLineBreak(index)) + return false; + if (IsCollapsedSpaceByLineWrap(index)) + return false; + if (IsIgnoredInCaretMovement(index)) + return false; + // TODO(xiaochengh): Handle other cases + return true; +} + +bool NGCaretNavigator::IsCollapsibleWhitespace(unsigned index) const { + DCHECK_LT(index, GetText().length()); + if (GetText()[index] != kSpaceCharacter) + return false; + const NGInlineItem& item = GetData().FindItemForTextOffset(index); + return item.Style()->CollapseWhiteSpace(); +} + +bool NGCaretNavigator::IsLineBreak(unsigned index) const { + DCHECK_LT(index, GetText().length()); + return GetText()[index] == kNewlineCharacter; +} + +bool NGCaretNavigator::IsCollapsedSpaceByLineWrap(unsigned index) const { + DCHECK_LT(index, GetText().length()); + if (!IsCollapsibleWhitespace(index)) + return false; + return index + 1 == ContainingLineOf(index).end_offset; +} + +bool NGCaretNavigator::IsIgnoredInCaretMovement(unsigned index) const { + // TODO(xiaochengh): Include floats, out-of-flows and CSS-generated contents. + return IsCollapsedSpaceByLineWrap(index) && + index != VisualLastCharacterOf(ContainingLineOf(index)); +} + NGCaretNavigator::Position NGCaretNavigator::LeftEdgeOf(unsigned index) const { return EdgeOfInternal(index, MoveDirection::kTowardsLeft); } @@ -117,67 +189,90 @@ return MoveCharacterInternal(index, MoveDirection::kTowardsRight); } -// static -base::Optional<unsigned> NGCaretNavigator::MoveVisualIndex( - unsigned visual_index, - unsigned length, - MoveDirection move_direction) { - if (move_direction == MoveDirection::kTowardsLeft) { - if (!visual_index) - return base::nullopt; - return visual_index - 1; - } - - if (visual_index + 1 == length) - return base::nullopt; - return visual_index + 1; -} - -Vector<int32_t, 32> NGCaretNavigator::IndicesInVisualOrder() const { +Vector<int32_t, 32> NGCaretNavigator::CharacterIndicesInVisualOrder( + const Line& line) const { DCHECK(IsBidiEnabled()); Vector<UBiDiLevel, 32> levels; - levels.resize(GetText().length()); - for (unsigned i = 0; i < GetText().length(); ++i) - levels[i] = BidiLevelAt(i); + levels.ReserveCapacity(line.end_offset - line.start_offset); + for (unsigned i = line.start_offset; i < line.end_offset; ++i) + levels.push_back(BidiLevelAt(i)); - Vector<int32_t, 32> result; - result.resize(levels.size()); - NGBidiParagraph::IndicesInVisualOrder(levels, &result); - return result; + Vector<int32_t, 32> indices(levels.size()); + NGBidiParagraph::IndicesInVisualOrder(levels, &indices); + + for (auto& index : indices) + index += line.start_offset; + return indices; } -unsigned NGCaretNavigator::VisualIndexOf(unsigned index) const { - if (!IsBidiEnabled()) - return index; +unsigned NGCaretNavigator::VisualMostForwardCharacterOf( + const Line& line, + MoveDirection direction) const { + if (!IsBidiEnabled()) { + if (direction == MoveDirection::kTowardsLeft) + return line.start_offset; + return line.end_offset - 1; + } - const auto indices_in_visual_order = IndicesInVisualOrder(); - const auto* visual_iterator = std::find(indices_in_visual_order.begin(), - indices_in_visual_order.end(), index); - DCHECK_NE(visual_iterator, indices_in_visual_order.end()); - return std::distance(indices_in_visual_order.begin(), visual_iterator); + const auto indices_in_visual_order = CharacterIndicesInVisualOrder(line); + if (direction == MoveDirection::kTowardsLeft) + return indices_in_visual_order.front(); + return indices_in_visual_order.back(); +} + +unsigned NGCaretNavigator::VisualFirstCharacterOf(const Line& line) const { + return VisualMostForwardCharacterOf(line, IsLtr(line.base_direction) + ? MoveDirection::kTowardsLeft + : MoveDirection::kTowardsRight); +} + +unsigned NGCaretNavigator::VisualLastCharacterOf(const Line& line) const { + return VisualMostForwardCharacterOf(line, IsLtr(line.base_direction) + ? MoveDirection::kTowardsRight + : MoveDirection::kTowardsLeft); } NGCaretNavigator::VisualCharacterMovementResult NGCaretNavigator::MoveCharacterInternal(unsigned index, MoveDirection move_direction) const { - DCHECK_LT(index, GetText().length()); - const unsigned visual_index = VisualIndexOf(index); - const TextDirection base_direction = GetData().BaseDirection(); + const Line line = ContainingLineOf(index); - const base::Optional<unsigned> maybe_result_visual_index = - MoveVisualIndex(visual_index, GetText().length(), move_direction); - if (!maybe_result_visual_index.has_value()) { - if (TowardsSameDirection(move_direction, base_direction)) - return {VisualMovementResultType::kAfterContext, base::nullopt}; - return {VisualMovementResultType::kBeforeContext, base::nullopt}; + if (index == VisualMostForwardCharacterOf(line, move_direction)) { + if (TowardsSameDirection(move_direction, line.base_direction)) { + if (line.end_offset == GetText().length()) + return {VisualMovementResultType::kAfterContext, base::nullopt}; + const Line next_line = ContainingLineOf(line.end_offset); + return {VisualMovementResultType::kWithinContext, + VisualFirstCharacterOf(next_line)}; + } + + if (!line.start_offset) + return {VisualMovementResultType::kBeforeContext, base::nullopt}; + const Line last_line = ContainingLineOf(line.start_offset - 1); + return {VisualMovementResultType::kWithinContext, + VisualLastCharacterOf(last_line)}; } - const unsigned result_visual_index = maybe_result_visual_index.value(); - const unsigned result_index = - IsBidiEnabled() ? IndicesInVisualOrder()[result_visual_index] - : result_visual_index; - return {VisualMovementResultType::kWithinContext, result_index}; + if (!IsBidiEnabled()) { + if (move_direction == MoveDirection::kTowardsLeft) + return {VisualMovementResultType::kWithinContext, index - 1}; + return {VisualMovementResultType::kWithinContext, index + 1}; + } + + Vector<int32_t, 32> indices_in_visual_order = + CharacterIndicesInVisualOrder(line); + const int32_t* visual_location = std::find( + indices_in_visual_order.begin(), indices_in_visual_order.end(), index); + DCHECK_NE(visual_location, indices_in_visual_order.end()); + if (move_direction == MoveDirection::kTowardsLeft) { + DCHECK_NE(visual_location, indices_in_visual_order.begin()); + return {VisualMovementResultType::kWithinContext, + *std::prev(visual_location)}; + } + DCHECK_NE(std::next(visual_location), indices_in_visual_order.end()); + return {VisualMovementResultType::kWithinContext, + *std::next(visual_location)}; } NGCaretNavigator::VisualCaretMovementResult NGCaretNavigator::LeftPositionOf( @@ -190,7 +285,8 @@ return MoveCaretInternal(caret_position, MoveDirection::kTowardsRight); } -NGCaretNavigator::VisualCaretMovementResult NGCaretNavigator::MoveCaretInternal( +NGCaretNavigator::UnvalidatedVisualCaretMovementResult +NGCaretNavigator::MoveCaretWithoutValidation( const Position& caret_position, MoveDirection move_direction) const { const unsigned index = caret_position.index; @@ -198,19 +294,45 @@ if (caret_position == EdgeOfInternal(index, opposite_direction)) { // TODO(xiaochengh): Consider grapheme cluster return {VisualMovementResultType::kWithinContext, - EdgeOfInternal(index, move_direction)}; + EdgeOfInternal(index, move_direction), + !IsIgnoredInCaretMovement(index)}; } VisualCharacterMovementResult forward_character = MoveCharacterInternal(index, move_direction); - if (forward_character.IsWithinContext()) { - DCHECK(forward_character.index.has_value()); - const Position forward_caret = - EdgeOfInternal(forward_character.index.value(), opposite_direction); - return MoveCaretInternal(forward_caret, move_direction); - } + if (!forward_character.IsWithinContext()) + return {forward_character.type}; - return {forward_character.type, base::nullopt}; + DCHECK(forward_character.index.has_value()); + const Position forward_caret = + EdgeOfInternal(forward_character.index.value(), opposite_direction); + return {VisualMovementResultType::kWithinContext, forward_caret}; +} + +NGCaretNavigator::VisualCaretMovementResult NGCaretNavigator::MoveCaretInternal( + const Position& caret_position, + MoveDirection move_direction) const { + bool has_passed_character = false; + base::Optional<Position> last_position; + for (Position runner = caret_position; + !has_passed_character || !IsValidCaretPosition(runner);) { + const UnvalidatedVisualCaretMovementResult next = + MoveCaretWithoutValidation(runner, move_direction); + if (next.type != VisualMovementResultType::kWithinContext) + return {next.type, base::nullopt}; + + // TODO(xiaochengh): Handle editing-ignored contents, e.g., CSS-generated. + if (next.has_passed_character) + has_passed_character = true; + + runner = next.position.value(); + last_position = runner; + + // TODO(xiaochengh): Handle the case where we reach a different line with a + // different base direction, which occurs with 'unicode-bidi: plain-text'. + } + DCHECK(last_position.has_value()); + return {VisualMovementResultType::kWithinContext, last_position.value()}; } } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h index 45e58a04..046de98 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h
@@ -18,7 +18,6 @@ namespace blink { class LayoutBlockFlow; -class NGInlineItem; struct NGInlineNodeData; // Hosts the |text_content| of an inline formatting context and provides @@ -79,7 +78,6 @@ // - Grapheme clusters // - Enterable atomic inlines // - Editing-ignored contents - // - Multiple lines enum class VisualMovementResultType { kWithinContext, @@ -126,12 +124,39 @@ VisualCaretMovementResult RightPositionOf(const Position&) const; private: + // A caret position is invalid if it is: + // - kAfter to a line break character. + // - Anchored to a collapsible space that's removed by line wrap. + // - Anchored to a character that's ignored in caret movement. + // TODO(xiaochengh): Handle the the following: + // - Enterable atomic inlines + bool IsValidCaretPosition(const Position&) const; + bool IsLineBreak(unsigned index) const; + bool IsCollapsibleWhitespace(unsigned index) const; + bool IsCollapsedSpaceByLineWrap(unsigned index) const; + bool IsIgnoredInCaretMovement(unsigned index) const; + enum class MoveDirection { kTowardsLeft, kTowardsRight }; static MoveDirection OppositeDirectionOf(MoveDirection); static bool TowardsSameDirection(MoveDirection, TextDirection); - static base::Optional<unsigned> MoveVisualIndex(unsigned index, - unsigned length, - MoveDirection); + + // ------ Line-related functions ------ + + // A line contains a consecutive substring of |GetText()|. The lines should + // not overlap, and should together cover the entire |GetText()|. + struct Line { + unsigned start_offset; + unsigned end_offset; + TextDirection base_direction; + }; + Line ContainingLineOf(unsigned index) const; + Vector<int32_t, 32> CharacterIndicesInVisualOrder(const Line&) const; + unsigned VisualMostForwardCharacterOf(const Line&, + MoveDirection direction) const; + unsigned VisualLastCharacterOf(const Line&) const; + unsigned VisualFirstCharacterOf(const Line&) const; + + // ------ Implementation of public visual movement functions ------ Position EdgeOfInternal(unsigned index, MoveDirection) const; VisualCharacterMovementResult MoveCharacterInternal(unsigned index, @@ -139,15 +164,32 @@ VisualCaretMovementResult MoveCaretInternal(const Position&, MoveDirection) const; + // Performs a "minimal" caret movement to the left/right without validating + // the result. The result might be invalid due to, e.g., anchored to an + // unallowed character, being visually the same as the input, etc. It's a + // subroutine of |MoveCaretInternal|, who keeps calling it until both of the + // folliwng are satisfied: + // - We've reached a valid caret position. + // - During the process, the caret has moved passing a character on which + // |IsIgnoredInCaretMovement| is false (indicated by |has_passed_character|). + struct UnvalidatedVisualCaretMovementResult { + VisualMovementResultType type; + base::Optional<Position> position; + bool has_passed_character = false; + }; + UnvalidatedVisualCaretMovementResult MoveCaretWithoutValidation( + const Position&, + MoveDirection) const; + const NGInlineNodeData& GetData() const; - const NGInlineItem& GetItem(unsigned index) const; - Vector<int32_t, 32> IndicesInVisualOrder() const; - unsigned VisualIndexOf(unsigned index) const; const LayoutBlockFlow& context_; DocumentLifecycle::DisallowTransitionScope disallow_transition_; }; +CORE_EXPORT std::ostream& operator<<(std::ostream&, + const NGCaretNavigator::Position&); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_CARET_NAVIGATOR_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator_test.cc index 582a210..c386e4f 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator_test.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h" #include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h" +#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" namespace blink { @@ -252,4 +253,144 @@ EXPECT_EQ(CaretBefore(5), *RightPositionOf(CaretAfter(8)).position); } +// Tests below check caret movement crossing line boundaries + +TEST_F(NGCaretNavigatorTest, HardLineBreak) { + SetupHtml("container", "<div id=container>abc<br>def</div>"); + + EXPECT_TRUE(LeftPositionOf(CaretBefore(0)).IsBeforeContext()); + + EXPECT_TRUE(RightPositionOf(CaretAfter(2)).IsWithinContext()); + EXPECT_EQ(CaretBefore(4), *RightPositionOf(CaretAfter(2)).position); + + EXPECT_TRUE(RightPositionOf(CaretBefore(3)).IsWithinContext()); + EXPECT_EQ(CaretBefore(4), *RightPositionOf(CaretBefore(3)).position); + + EXPECT_TRUE(LeftPositionOf(CaretBefore(4)).IsWithinContext()); + EXPECT_EQ(CaretBefore(3), *LeftPositionOf(CaretBefore(4)).position); + + EXPECT_TRUE(RightPositionOf(CaretAfter(6)).IsAfterContext()); +} + +TEST_F(NGCaretNavigatorTest, SoftLineWrapAtSpace) { + SetupHtml("container", "<div id=container style=\"width:0\">abc def</div>"); + + EXPECT_TRUE(LeftPositionOf(CaretBefore(0)).IsBeforeContext()); + + EXPECT_TRUE(RightPositionOf(CaretAfter(2)).IsWithinContext()); + EXPECT_EQ(CaretBefore(4), *RightPositionOf(CaretAfter(2)).position); + + EXPECT_TRUE(RightPositionOf(CaretBefore(3)).IsWithinContext()); + EXPECT_EQ(CaretBefore(4), *RightPositionOf(CaretBefore(3)).position); + + EXPECT_TRUE(LeftPositionOf(CaretBefore(4)).IsWithinContext()); + EXPECT_EQ(CaretAfter(2), *LeftPositionOf(CaretBefore(4)).position); + + EXPECT_TRUE(RightPositionOf(CaretAfter(6)).IsAfterContext()); +} + +TEST_F(NGCaretNavigatorTest, BidiAndSoftLineWrapAtSpaceLtr) { + LoadAhem(); + SetupHtml("container", + "<div id=container style='font: 10px/10px Ahem; width: 100px'>" + "before אבגד " + "הוזחטי" + "ךכלםמן" + "נסעףפץ" + "</div>"); + + // Moving left from "|before DCBA" should be before context + EXPECT_TRUE(LeftPositionOf(CaretBefore(0)).IsBeforeContext()); + + // Moving right from "before |DCBA" should yield "before D|CBA" + EXPECT_TRUE(RightPositionOf(CaretAfter(10)).IsWithinContext()); + EXPECT_EQ(CaretBefore(10), *RightPositionOf(CaretAfter(10)).position); + EXPECT_TRUE(RightPositionOf(CaretAfter(6)).IsWithinContext()); + EXPECT_EQ(CaretBefore(10), *RightPositionOf(CaretAfter(6)).position); + + // Moving left from "before |DCBA" should yield "before| DCBA" + EXPECT_TRUE(LeftPositionOf(CaretAfter(10)).IsWithinContext()); + EXPECT_EQ(CaretBefore(6), *LeftPositionOf(CaretAfter(10)).position); + EXPECT_TRUE(LeftPositionOf(CaretAfter(6)).IsWithinContext()); + EXPECT_EQ(CaretBefore(6), *LeftPositionOf(CaretAfter(6)).position); + + // Moving right from "before DCBA|" should yield "V|UTSRQPONMLKJIHGFE" + EXPECT_TRUE(RightPositionOf(CaretBefore(7)).IsWithinContext()); + EXPECT_EQ(CaretBefore(29), *RightPositionOf(CaretBefore(7)).position); + + // Moving left from "|VUTSRQPONMLKJIHGFE" should yield "before DCB|A" + EXPECT_TRUE(LeftPositionOf(CaretAfter(29)).IsWithinContext()); + EXPECT_EQ(CaretAfter(7), *LeftPositionOf(CaretAfter(29)).position); + + // Moving right from "VUTSRQPONMLKJIHGFE|" should be after context + EXPECT_TRUE(RightPositionOf(CaretBefore(12)).IsAfterContext()); +} + +TEST_F(NGCaretNavigatorTest, BidiAndSoftLineWrapAtSpaceRtl) { + LoadAhem(); + SetupHtml( + "container", + "<div dir=rtl id=container style='font: 10px/10px Ahem; width: 120px'>" + "אבגד after encyclopedia" + "</div>"); + + // Moving right from "after DCBA|" should be before context + EXPECT_TRUE(RightPositionOf(CaretBefore(0)).IsBeforeContext()); + + // Moving left from "after| DCBA" should yield "afte|r DCBA" + EXPECT_TRUE(LeftPositionOf(CaretAfter(4)).IsWithinContext()); + EXPECT_EQ(CaretBefore(9), *LeftPositionOf(CaretAfter(4)).position); + EXPECT_TRUE(LeftPositionOf(CaretAfter(9)).IsWithinContext()); + EXPECT_EQ(CaretBefore(9), *LeftPositionOf(CaretAfter(9)).position); + + // Moving right from "after| DCBA" should yield "after |DCBA" + EXPECT_TRUE(RightPositionOf(CaretAfter(4)).IsWithinContext()); + EXPECT_EQ(CaretBefore(4), *RightPositionOf(CaretAfter(4)).position); + EXPECT_TRUE(RightPositionOf(CaretAfter(9)).IsWithinContext()); + EXPECT_EQ(CaretBefore(4), *RightPositionOf(CaretAfter(9)).position); + + // Moving left from "|after DCBA" should yield "encyclopedi|a" + EXPECT_TRUE(LeftPositionOf(CaretBefore(5)).IsWithinContext()); + EXPECT_EQ(CaretBefore(22), *LeftPositionOf(CaretBefore(5)).position); + + // Moving right from "encyclopedia|" should yield "a|fter DCBA" + EXPECT_TRUE(RightPositionOf(CaretAfter(22)).IsWithinContext()); + EXPECT_EQ(CaretAfter(5), *RightPositionOf(CaretAfter(22)).position); + + // Moving left from "|encyclopedia" should be after context + EXPECT_TRUE(LeftPositionOf(CaretBefore(11)).IsAfterContext()); +} + +TEST_F(NGCaretNavigatorTest, SoftLineWrapAtHyphen) { + SetupHtml("container", "<div id=container style=\"width:0\">abc-def</div>"); + + EXPECT_TRUE(LeftPositionOf(CaretBefore(0)).IsBeforeContext()); + + // 3 -> 4 + EXPECT_TRUE(RightPositionOf(CaretAfter(2)).IsWithinContext()); + EXPECT_EQ(CaretAfter(3), *RightPositionOf(CaretAfter(2)).position); + EXPECT_TRUE(RightPositionOf(CaretBefore(3)).IsWithinContext()); + EXPECT_EQ(CaretAfter(3), *RightPositionOf(CaretBefore(3)).position); + + // 4 -> 5 + EXPECT_TRUE(RightPositionOf(CaretAfter(3)).IsWithinContext()); + EXPECT_EQ(CaretAfter(4), *RightPositionOf(CaretAfter(3)).position); + EXPECT_TRUE(RightPositionOf(CaretBefore(4)).IsWithinContext()); + EXPECT_EQ(CaretAfter(4), *RightPositionOf(CaretBefore(4)).position); + + // 5 -> 4 + EXPECT_TRUE(LeftPositionOf(CaretBefore(5)).IsWithinContext()); + EXPECT_EQ(CaretBefore(4), *LeftPositionOf(CaretBefore(5)).position); + EXPECT_TRUE(LeftPositionOf(CaretAfter(4)).IsWithinContext()); + EXPECT_EQ(CaretBefore(4), *LeftPositionOf(CaretAfter(4)).position); + + // 4 -> 3 + EXPECT_TRUE(LeftPositionOf(CaretBefore(4)).IsWithinContext()); + EXPECT_EQ(CaretBefore(3), *LeftPositionOf(CaretBefore(4)).position); + EXPECT_TRUE(LeftPositionOf(CaretAfter(3)).IsWithinContext()); + EXPECT_EQ(CaretBefore(3), *LeftPositionOf(CaretAfter(3)).position); + + EXPECT_TRUE(RightPositionOf(CaretAfter(6)).IsAfterContext()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h index 55bde22..eaf1f49 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.h +++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -355,6 +355,8 @@ } bool AllowScriptExtensions() override { return false; } + void VisibilityChanged(blink::mojom::FrameVisibility) override {} + WebCookieJar* CookieJar() const override { return nullptr; } service_manager::InterfaceProvider* GetInterfaceProvider() override { @@ -446,7 +448,7 @@ void UpdateRemoteViewportIntersection(const IntRect& viewport_intersection, bool occluded_or_obscured) override {} void AdvanceFocus(WebFocusType, LocalFrame* source) override {} - void VisibilityChanged(bool visible) override {} + void VisibilityChanged(blink::mojom::FrameVisibility) override {} void SetIsInert(bool) override {} void SetInheritedEffectiveTouchAction(TouchAction) override {} void UpdateRenderThrottlingStatus(bool is_throttled,
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc index f84f3cfc..e503a8b 100644 --- a/third_party/blink/renderer/core/paint/box_painter_base.cc +++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -309,6 +309,112 @@ namespace { +// Given the |size| that the whole image should draw at, and the input phase +// requested by the content, and the space between repeated tiles, return a +// rectangle with |size| and a location that respects the phase but is no more +// than one size + space in magnitude. In practice, this means that if there is +// no repeating the returned rect would contain the destination_offset +// location. The destination_offset passed here must exactly match the location +// of the subset in a following call to ComputeSubsetForBackground. +FloatRect ComputePhaseForBackground(const FloatPoint& destination_offset, + const FloatSize& size, + const FloatPoint& phase, + const FloatSize& spacing) { + const FloatSize step_per_tile(size + spacing); + return FloatRect( + FloatPoint( + destination_offset.X() + fmodf(-phase.X(), step_per_tile.Width()), + destination_offset.Y() + fmodf(-phase.Y(), step_per_tile.Height())), + size); +} + +// Compute the image subset, in intrinsic image coordinates, that gets mapped +// onto the |subset|, when the whole image would be drawn with phase and size +// given by |phase_and_size|. Assumes |phase_and_size| contains |subset|. The +// location of the requested subset should be the painting snapped location, or +// whatever was used as a destination_offset in ComputePhaseForBackground. +// +// It is used to undo the offset added in ComputePhaseForBackground. The size +// of requested subset should be the unsnapped size so that the computed +// scale and location in the source image can be correctly determined. +FloatRect ComputeSubsetForBackground(const FloatRect& phase_and_size, + const FloatRect& subset, + const FloatSize& intrinsic_size) { + // TODO(schenney): Re-enable this after determining why it fails for + // CAP, and maybe other cases. + // DCHECK(phase_and_size.Contains(subset)); + + const FloatSize scale(phase_and_size.Width() / intrinsic_size.Width(), + phase_and_size.Height() / intrinsic_size.Height()); + return FloatRect((subset.X() - phase_and_size.X()) / scale.Width(), + (subset.Y() - phase_and_size.Y()) / scale.Height(), + subset.Width() / scale.Width(), + subset.Height() / scale.Height()); +} + +// The unsnapped_subset_size should be the target painting area implied by the +// content, without any snapping applied. It is necessary to correctly +// compute the subset of the source image to paint into the destination. +// The snapped_paint_rect should be the target destination for painting into. +// The phase is never snapped. +// The tile_size is the total image size. The mapping from this size +// to the unsnapped_dest_rect size defines the scaling of the image for +// sprite computation. +void DrawTiledBackground(GraphicsContext& context, + Image* image, + const FloatSize& unsnapped_subset_size, + const FloatRect& snapped_paint_rect, + const FloatPoint& phase, + const FloatSize& tile_size, + SkBlendMode op, + const FloatSize& repeat_spacing) { + DCHECK(!tile_size.IsEmpty()); + + // Use the intrinsic size of the image if it has one, otherwise force the + // generated image to be the tile size. + FloatSize intrinsic_tile_size(image->Size()); + FloatSize scale(1, 1); + if (image->HasRelativeSize()) { + intrinsic_tile_size = tile_size; + } else { + scale = FloatSize(tile_size.Width() / intrinsic_tile_size.Width(), + tile_size.Height() / intrinsic_tile_size.Height()); + } + + const FloatRect one_tile_rect = ComputePhaseForBackground( + snapped_paint_rect.Location(), tile_size, phase, repeat_spacing); + + // Check and see if a single draw of the image can cover the entire area we + // are supposed to tile. The dest_rect_for_subset must use the same + // location that was used in ComputePhaseForBackground and the unsnapped + // destination rect in order to correctly evaluate the subset size and + // location in the presence of border snapping and zoom. + FloatRect dest_rect_for_subset(snapped_paint_rect.Location(), + unsnapped_subset_size); + if (one_tile_rect.Contains(dest_rect_for_subset)) { + FloatRect visible_src_rect = ComputeSubsetForBackground( + one_tile_rect, dest_rect_for_subset, intrinsic_tile_size); + // Round to avoid filtering pulling in neighboring pixels, for the + // common case of sprite maps. + // TODO(schenney): Snapping at this level is a problem for cases where we + // might be animating background-position to pan over an image. Ideally we + // would either snap only if close to integral, or move snapping + // calculations up the stack. + visible_src_rect = FloatRect(RoundedIntRect(visible_src_rect)); + context.DrawImage(image, Image::kSyncDecode, snapped_paint_rect, + &visible_src_rect, op, kDoNotRespectImageOrientation); + return; + } + + // Note that this tile rect the image's pre-scaled size. + FloatRect tile_rect(FloatPoint(), intrinsic_tile_size); + // This call takes the unscaled image, applies the given scale, and paints + // it into the snapped_dest_rect using phase from one_tile_rect and the + // given repeat spacing. Note the phase is already scaled. + context.DrawImageTiled(image, snapped_paint_rect, tile_rect, scale, + one_tile_rect.Location(), repeat_spacing, op); +} + inline bool PaintFastBottomLayer(Node* node, const PaintInfo& paint_info, const BoxPainterBase::FillLayerInfo& info, @@ -359,7 +465,7 @@ // Phase calculation uses the actual painted location, given by the // border-snapped destination rect. - image_tile = Image::ComputePhaseForBackground( + image_tile = ComputePhaseForBackground( FloatPoint(geometry.SnappedDestRect().Location()), FloatSize(geometry.TileSize()), geometry.Phase(), FloatSize(geometry.SpaceSize())); @@ -417,7 +523,7 @@ // so snap to integers. This is particuarly important for sprite maps. // Calculation up to this point, in LayoutUnits, can lead to small variations // from integer size, so it is safe to round without introducing major issues. - const FloatRect unrounded_subset = Image::ComputeSubsetForBackground( + const FloatRect unrounded_subset = ComputeSubsetForBackground( image_tile, dest_rect_for_subset, intrinsic_tile_size); FloatRect src_rect = FloatRect(RoundedIntRect(unrounded_subset)); @@ -541,17 +647,17 @@ // NOTE: This method can be called with no image in situations when a bad // resource locator is given such as "//:0", so still check for image. if (info.should_paint_image && !geometry.SnappedDestRect().IsEmpty() && - image) { + !geometry.TileSize().IsEmpty() && image) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", inspector_paint_image_event::Data( node, *info.image, FloatRect(image->Rect()), FloatRect(scrolled_paint_rect))); - context.DrawTiledImage(image, - FloatSize(geometry.UnsnappedDestRect().Size()), - FloatRect(geometry.SnappedDestRect()), - geometry.Phase(), FloatSize(geometry.TileSize()), - composite_op, FloatSize(geometry.SpaceSize())); + DrawTiledBackground(context, image, + FloatSize(geometry.UnsnappedDestRect().Size()), + FloatRect(geometry.SnappedDestRect()), geometry.Phase(), + FloatSize(geometry.TileSize()), composite_op, + FloatSize(geometry.SpaceSize())); } }
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc index 2eecda79..2293a21 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc +++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -384,6 +384,8 @@ flags.setBlendMode(composite_op); flags.setColorFilter(sk_ref_sp(context.GetColorFilter())); context.DrawRect(dst_rect, flags); + + StartAnimation(); } sk_sp<PaintRecord> SVGImage::PaintRecordForContainer(
diff --git a/third_party/blink/renderer/core/timing/performance_observer.cc b/third_party/blink/renderer/core/timing/performance_observer.cc index 6141b19..546f3be 100644 --- a/third_party/blink/renderer/core/timing/performance_observer.cc +++ b/third_party/blink/renderer/core/timing/performance_observer.cc
@@ -85,6 +85,7 @@ callback_(callback), performance_(performance), filter_options_(PerformanceEntry::kInvalid), + type_(PerformanceObserverType::kUnknown), is_registered_(false) { DCHECK(performance_); } @@ -97,23 +98,64 @@ return; } - PerformanceEntryTypeMask entry_types = PerformanceEntry::kInvalid; - if (observer_init->hasEntryTypes() && observer_init->entryTypes().size()) { + if (observer_init->hasEntryTypes()) { + if (observer_init->hasType()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kSyntaxError, + "An observe() call MUST NOT include both entryTypes and type."); + return; + } + if (type_ == PerformanceObserverType::kTypeObserver) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidModificationError, + "This observer has performed observe({type:...}, therefore it cannot " + "perform observe({entryTypes:...})"); + return; + } + type_ = PerformanceObserverType::kEntryTypesObserver; + PerformanceEntryTypeMask entry_types = PerformanceEntry::kInvalid; const Vector<String>& sequence = observer_init->entryTypes(); for (const auto& entry_type_string : sequence) { entry_types |= PerformanceEntry::ToEntryTypeEnum(AtomicString(entry_type_string)); } + if (entry_types == PerformanceEntry::kInvalid) { + String message = + "The Performance Observer MUST have at least one valid entryType in " + "its " + "entryTypes attribute."; + GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( + kJSMessageSource, kWarningMessageLevel, message)); + return; + } + filter_options_ = entry_types; + } else { + if (!observer_init->hasType()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kSyntaxError, + "An observe() call MUST include either entryTypes or type."); + return; + } + if (type_ == PerformanceObserverType::kEntryTypesObserver) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidModificationError, + "This observer has performed observe({entryTypes:...}, therefore it " + "cannot perform observe({type:...})"); + return; + } + type_ = PerformanceObserverType::kTypeObserver; + PerformanceEntryType entry_type = + PerformanceEntry::ToEntryTypeEnum(AtomicString(observer_init->type())); + if (entry_type == PerformanceEntry::kInvalid) { + String message = + "The Performance Observer MUST have a valid entryType in its " + "type attribute."; + GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( + kJSMessageSource, kWarningMessageLevel, message)); + return; + } + filter_options_ |= entry_type; } - if (entry_types == PerformanceEntry::kInvalid) { - String message = - "A Performance Observer MUST have at least one valid entryType in its " - "entryTypes attribute."; - GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( - kJSMessageSource, kWarningMessageLevel, message)); - return; - } - filter_options_ = entry_types; if (is_registered_) performance_->UpdatePerformanceObserverFilterOptions(); else
diff --git a/third_party/blink/renderer/core/timing/performance_observer.h b/third_party/blink/renderer/core/timing/performance_observer.h index c104376..48dd3bed 100644 --- a/third_party/blink/renderer/core/timing/performance_observer.h +++ b/third_party/blink/renderer/core/timing/performance_observer.h
@@ -55,6 +55,18 @@ void Trace(blink::Visitor*) override; private: + // This describes the types of parameters that an observer can have in its + // observe() function. An observer of type kEntryTypesObserver has already + // made a call observe({entryTypes...}) so can only do subsequent observe() + // calls with the 'entryTypes' parameter. An observer of type kTypeObserver + // has already made a call observe({type...}) so it can only perform + // subsequent observe() calls with the 'type' parameter. An observer of type + // kUnknown has not called observe(). + enum class PerformanceObserverType { + kEntryTypesObserver, + kTypeObserver, + kUnknown, + }; void Deliver(); bool ShouldBeSuspended() const; @@ -63,6 +75,7 @@ WeakMember<Performance> performance_; PerformanceEntryVector performance_entries_; PerformanceEntryTypeMask filter_options_; + PerformanceObserverType type_; bool is_registered_; };
diff --git a/third_party/blink/renderer/core/timing/performance_observer_init.idl b/third_party/blink/renderer/core/timing/performance_observer_init.idl index acb2790..08e0440 100644 --- a/third_party/blink/renderer/core/timing/performance_observer_init.idl +++ b/third_party/blink/renderer/core/timing/performance_observer_init.idl
@@ -5,5 +5,6 @@ // https://w3c.github.io/performance-timeline/#performanceobserverinit-dictionary dictionary PerformanceObserverInit { - required sequence<DOMString> entryTypes; + sequence<DOMString> entryTypes; + DOMString type; };
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc index b55b955..6ebfa142 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -473,7 +473,7 @@ } static int g_global_descriptor = 0; -static ThreadIdentifier g_libxml_loader_thread = 0; +static base::PlatformThreadId g_libxml_loader_thread = 0; static int MatchFunc(const char*) { // Only match loads initiated due to uses of libxml2 from within
diff --git a/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css b/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css index 31e1a8f..7291d01 100644 --- a/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css +++ b/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css
@@ -13,7 +13,7 @@ .elements-disclosure li { /** Keep margin-left & padding-left in sync with ElementsTreeElements.updateDecorators **/ padding: 0 0 0 14px; - margin-top: 1px; + border-top: 1px solid transparent; margin-left: -2px; word-wrap: break-word; position: relative;
diff --git a/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc b/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc index 501686f..983ab58 100644 --- a/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc +++ b/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc
@@ -87,22 +87,19 @@ } // anonymous namespace -media_session::mojom::blink::MediaMetadataPtr +blink::mojom::blink::SpecMediaMetadataPtr MediaMetadataSanitizer::SanitizeAndConvertToMojo(const MediaMetadata* metadata, ExecutionContext* context) { - media_session::mojom::blink::MediaMetadataPtr mojo_metadata; if (!metadata) - return mojo_metadata; + return blink::mojom::blink::SpecMediaMetadataPtr(); - mojo_metadata = media_session::mojom::blink::MediaMetadata::New(); + blink::mojom::blink::SpecMediaMetadataPtr mojo_metadata( + blink::mojom::blink::SpecMediaMetadata::New()); mojo_metadata->title = metadata->title().Left(kMaxStringLength); mojo_metadata->artist = metadata->artist().Left(kMaxStringLength); mojo_metadata->album = metadata->album().Left(kMaxStringLength); - // |source_title_| is populated by content::MediaSessionImpl. - mojo_metadata->source_title = g_empty_string16_bit; - for (const MediaImage* image : metadata->artwork()) { media_session::mojom::blink::MediaImagePtr mojo_image = SanitizeMediaImageAndConvertToMojo(image, context);
diff --git a/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h b/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h index 1c78dab..e37f00a5 100644 --- a/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h +++ b/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h
@@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASESSION_MEDIA_METADATA_SANITIZER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASESSION_MEDIA_METADATA_SANITIZER_H_ -#include "services/media_session/public/mojom/media_session.mojom-blink.h" +#include "third_party/blink/public/platform/modules/mediasession/media_session.mojom-blink.h" namespace blink { @@ -16,7 +16,7 @@ public: // Produce the sanitized metadata, which will later be sent to the // MediaSession mojo service. - static media_session::mojom::blink::MediaMetadataPtr SanitizeAndConvertToMojo( + static blink::mojom::blink::SpecMediaMetadataPtr SanitizeAndConvertToMojo( const MediaMetadata*, ExecutionContext*); };
diff --git a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc index bc1154f..eb3674a 100644 --- a/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc +++ b/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -245,40 +245,30 @@ } void RemotePlayback::PromptInternal() { - DCHECK(RuntimeEnabledFeatures::RemotePlaybackBackendEnabled()); - - if (RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()) { - PresentationController* controller = - PresentationController::FromContext(GetExecutionContext()); - if (controller && !availability_urls_.IsEmpty()) { - controller->GetPresentationService()->StartPresentation( - availability_urls_, - WTF::Bind(&RemotePlayback::HandlePresentationResponse, - WrapPersistent(this))); - } else { - // TODO(yuryu): Wrapping PromptCancelled with base::OnceClosure as - // InspectorInstrumentation requires a globally unique pointer to track - // tasks. We can remove the wrapper if InspectorInstrumentation returns a - // task id. - base::OnceClosure task = - WTF::Bind(&RemotePlayback::PromptCancelled, WrapPersistent(this)); - std::unique_ptr<int> task_id = std::make_unique<int>(0); - probe::AsyncTaskScheduled(GetExecutionContext(), "promptCancelled", - task_id.get()); - GetExecutionContext() - ->GetTaskRunner(TaskType::kMediaElementEvent) - ->PostTask(FROM_HERE, WTF::Bind(RunRemotePlaybackTask, - WrapPersistent(GetExecutionContext()), - WTF::Passed(std::move(task)), - WTF::Passed(std::move(task_id)))); - } - return; + PresentationController* controller = + PresentationController::FromContext(GetExecutionContext()); + if (controller && !availability_urls_.IsEmpty()) { + controller->GetPresentationService()->StartPresentation( + availability_urls_, + WTF::Bind(&RemotePlayback::HandlePresentationResponse, + WrapPersistent(this))); + } else { + // TODO(yuryu): Wrapping PromptCancelled with base::OnceClosure as + // InspectorInstrumentation requires a globally unique pointer to track + // tasks. We can remove the wrapper if InspectorInstrumentation returns a + // task id. + base::OnceClosure task = + WTF::Bind(&RemotePlayback::PromptCancelled, WrapPersistent(this)); + std::unique_ptr<int> task_id = std::make_unique<int>(0); + probe::AsyncTaskScheduled(GetExecutionContext(), "promptCancelled", + task_id.get()); + GetExecutionContext() + ->GetTaskRunner(TaskType::kMediaElementEvent) + ->PostTask(FROM_HERE, WTF::Bind(RunRemotePlaybackTask, + WrapPersistent(GetExecutionContext()), + WTF::Passed(std::move(task)), + WTF::Passed(std::move(task_id)))); } - - if (state_ == WebRemotePlaybackState::kDisconnected) - media_element_->RequestRemotePlayback(); - else - media_element_->RequestRemotePlaybackControl(); } int RemotePlayback::WatchAvailabilityInternal( @@ -363,30 +353,26 @@ switch (state_) { case WebRemotePlaybackState::kConnecting: DispatchEvent(*Event::Create(event_type_names::kConnecting)); - if (RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()) { - if (media_element_->IsHTMLVideoElement()) { - // TODO(xjz): Pass the remote device name. - ToHTMLVideoElement(media_element_)->MediaRemotingStarted(WebString()); - } - media_element_->FlingingStarted(); + if (media_element_->IsHTMLVideoElement()) { + // TODO(xjz): Pass the remote device name. + ToHTMLVideoElement(media_element_)->MediaRemotingStarted(WebString()); } + media_element_->FlingingStarted(); break; case WebRemotePlaybackState::kConnected: DispatchEvent(*Event::Create(event_type_names::kConnect)); break; case WebRemotePlaybackState::kDisconnected: DispatchEvent(*Event::Create(event_type_names::kDisconnect)); - if (RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()) { - if (media_element_->IsHTMLVideoElement()) { - ToHTMLVideoElement(media_element_) - ->MediaRemotingStopped( - WebLocalizedString::kMediaRemotingStopNoText); - } - CleanupConnections(); - presentation_id_ = ""; - presentation_url_ = KURL(); - media_element_->FlingingStopped(); + if (media_element_->IsHTMLVideoElement()) { + ToHTMLVideoElement(media_element_) + ->MediaRemotingStopped( + WebLocalizedString::kMediaRemotingStopNoText); } + CleanupConnections(); + presentation_id_ = ""; + presentation_url_ = KURL(); + media_element_->FlingingStopped(); break; } @@ -423,8 +409,6 @@ void RemotePlayback::SourceChanged(const WebURL& source, bool is_source_supported) { - DCHECK(RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()); - if (IsBackgroundAvailabilityMonitoringDisabled()) return; @@ -482,15 +466,10 @@ if (state_ == WebRemotePlaybackState::kDisconnected) return; - if (RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()) { - auto* controller = - PresentationController::FromContext(GetExecutionContext()); - if (controller) { - controller->GetPresentationService()->CloseConnection(presentation_url_, - presentation_id_); - } - } else { - media_element_->RequestRemotePlaybackStop(); + auto* controller = PresentationController::FromContext(GetExecutionContext()); + if (controller) { + controller->GetPresentationService()->CloseConnection(presentation_url_, + presentation_id_); } } @@ -501,7 +480,6 @@ void RemotePlayback::AvailabilityChanged( mojom::blink::ScreenAvailability availability) { - DCHECK(RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()); DCHECK(is_listening_); // TODO(avayvod): Use mojom::ScreenAvailability directly once @@ -531,7 +509,6 @@ } const Vector<KURL>& RemotePlayback::Urls() const { - DCHECK(RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()); // TODO(avayvod): update the URL format and add frame url, mime type and // response headers when available. return availability_urls_; @@ -539,7 +516,6 @@ void RemotePlayback::OnConnectionSuccess( mojom::blink::PresentationConnectionResultPtr result) { - DCHECK(RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()); presentation_id_ = std::move(result->presentation_info->id); presentation_url_ = std::move(result->presentation_info->url); @@ -558,7 +534,6 @@ void RemotePlayback::OnConnectionError( const mojom::blink::PresentationError& error) { - DCHECK(RuntimeEnabledFeatures::NewRemotePlaybackPipelineEnabled()); presentation_id_ = ""; presentation_url_ = KURL(); if (error.error_type == @@ -603,9 +578,6 @@ } void RemotePlayback::StopListeningForAvailability() { - if (!RuntimeEnabledFeatures::RemotePlaybackBackendEnabled()) - return; - if (!is_listening_) return; @@ -623,9 +595,6 @@ if (IsBackgroundAvailabilityMonitoringDisabled()) return; - if (!RuntimeEnabledFeatures::RemotePlaybackBackendEnabled()) - return; - if (is_listening_) return;
diff --git a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h index 133061d5..fdd3f19 100644 --- a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h +++ b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
@@ -243,7 +243,7 @@ // Graph locking. RecursiveMutex context_graph_mutex_; - std::atomic<ThreadIdentifier> audio_thread_; + std::atomic<base::PlatformThreadId> audio_thread_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h index 6d109ed..b132901 100644 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h +++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h
@@ -140,7 +140,7 @@ Mutex authorizer_lock_; CrossThreadPersistent<DatabaseAuthorizer> authorizer_; - ThreadIdentifier opening_thread_; + base::PlatformThreadId opening_thread_; Mutex database_closing_mutex_;
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc index 4e7e0c1..4aeea414 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
@@ -75,6 +75,28 @@ "WebGL 2.0 Compute (" + String(ContextGL()->GetString(GL_VERSION)) + ")"); } + case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE: + case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: + case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_COMBINED_ATOMIC_COUNTERS: + case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: + case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: + case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE: + case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: + case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: + case GL_MAX_COMPUTE_UNIFORM_BLOCKS: + case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: + case GL_MAX_COMPUTE_IMAGE_UNIFORMS: + case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: + case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: + case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: + case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_VERTEX_ATOMIC_COUNTERS: + case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: + return GetIntParameter(script_state, pname); + case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: + return GetInt64Parameter(script_state, pname); default: return WebGL2RenderingContextBase::getParameter(script_state, pname);
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl index 4ec4777..4d3e73a 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl +++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl
@@ -38,8 +38,16 @@ const GLenum MAX_SHADER_STORAGE_BUFFER_BINDINGS = 0x90DD; const GLenum MAX_SHADER_STORAGE_BLOCK_SIZE = 0x90DE; const GLenum SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = 0x90DF; + const GLenum MAX_COMPUTE_SHARED_MEMORY_SIZE = 0x8262; + const GLenum MAX_COMPUTE_UNIFORM_COMPONENTS = 0x8263; const GLenum MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS = 0x8264; const GLenum MAX_COMPUTE_ATOMIC_COUNTERS = 0x8265; + const GLenum MAX_COMPUTE_WORK_GROUP_INVOCATIONS = 0x90EB; + const GLenum MAX_COMPUTE_UNIFORM_BLOCKS = 0x91BB; + const GLenum MAX_COMPUTE_TEXTURE_IMAGE_UNITS = 0x91BC; + const GLenum MAX_COMPUTE_IMAGE_UNIFORMS = 0x91BD; + const GLenum MAX_COMPUTE_WORK_GROUP_COUNT = 0x91BE; + const GLenum MAX_COMPUTE_WORK_GROUP_SIZE = 0x91BF; const GLenum ATOMIC_COUNTER_BUFFER_INDEX = 0x9301; const GLenum ATOMIC_COUNTER_BUFFER = 0x92C0; const GLenum ATOMIC_COUNTER_BUFFER_BINDING = 0x92C1;
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index 66d8748a..f95cbea7 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -4703,6 +4703,8 @@ ContextGL()->GetInteger64i_v(target, index, &value); return WebGLAny(script_state, value); } + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: case GL_ATOMIC_COUNTER_BUFFER_SIZE: case GL_ATOMIC_COUNTER_BUFFER_START: case GL_SHADER_STORAGE_BUFFER_SIZE: @@ -4716,6 +4718,7 @@ ContextGL()->GetInteger64i_v(target, index, &value); return WebGLAny(script_state, value); } + default: SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter", "invalid parameter name");
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index 545c96f5..a7c6a23 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -3420,7 +3420,15 @@ ContextGL()->GetProgramiv(ObjectOrZero(program), pname, &value); return WebGLAny(script_state, value); case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: - if (IsWebGL2OrHigher()) { + if (!IsWebGL2OrHigher()) { + SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", + "invalid parameter name"); + return ScriptValue::CreateNull(script_state); + } + ContextGL()->GetProgramiv(ObjectOrZero(program), pname, &value); + return WebGLAny(script_state, static_cast<unsigned>(value)); + case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: + if (context_type_ == Platform::kWebGL2ComputeContextType) { ContextGL()->GetProgramiv(ObjectOrZero(program), pname, &value); return WebGLAny(script_state, static_cast<unsigned>(value)); }
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string.h b/third_party/blink/renderer/platform/bindings/parkable_string.h index 30cdf7b..7372323 100644 --- a/third_party/blink/renderer/platform/bindings/parkable_string.h +++ b/third_party/blink/renderer/platform/bindings/parkable_string.h
@@ -126,7 +126,7 @@ const unsigned length_; #if DCHECK_IS_ON() - const ThreadIdentifier owning_thread_; + const base::PlatformThreadId owning_thread_; #endif void AssertOnValidThread() const {
diff --git a/third_party/blink/renderer/platform/bindings/string_resource.h b/third_party/blink/renderer/platform/bindings/string_resource.h index 7874392..6cd6989f 100644 --- a/third_party/blink/renderer/platform/bindings/string_resource.h +++ b/third_party/blink/renderer/platform/bindings/string_resource.h
@@ -108,7 +108,7 @@ private: #if DCHECK_IS_ON() - WTF::ThreadIdentifier thread_id_; + base::PlatformThreadId thread_id_; #endif DISALLOW_COPY_AND_ASSIGN(StringResourceBase);
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index ff0142b..4e8379a 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -511,10 +511,6 @@ RuntimeEnabledFeatures::SetBackgroundVideoTrackOptimizationEnabled(enable); } -void WebRuntimeFeatures::EnableNewRemotePlaybackPipeline(bool enable) { - RuntimeEnabledFeatures::SetNewRemotePlaybackPipelineEnabled(enable); -} - void WebRuntimeFeatures::EnableRemotePlaybackAPI(bool enable) { RuntimeEnabledFeatures::SetRemotePlaybackEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc index cc494d2..197174a0 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -995,17 +995,17 @@ std::min(resampling, ImageInterpolationQuality())); } -void GraphicsContext::DrawTiledImage(Image* image, - const FloatSize& unsnapped_subset_size, - const FloatRect& snapped_paint_rect, - const FloatPoint& unsnapped_phase, - const FloatSize& tile_size, - SkBlendMode op, - const FloatSize& repeat_spacing) { +void GraphicsContext::DrawImageTiled(Image* image, + const FloatRect& dest_rect, + const FloatRect& src_rect, + const FloatSize& scale_src_to_dest, + const FloatPoint& phase, + const FloatSize& repeat_spacing, + SkBlendMode op) { if (ContextDisabled() || !image) return; - image->DrawTiledBackground(*this, unsnapped_subset_size, snapped_paint_rect, - unsnapped_phase, tile_size, op, repeat_spacing); + image->DrawPattern(*this, src_rect, scale_src_to_dest, phase, op, dest_rect, + repeat_spacing); paint_controller_.SetImagePainted(); }
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.h b/third_party/blink/renderer/platform/graphics/graphics_context.h index f46176a4..a8dcb080 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.h +++ b/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -223,14 +223,13 @@ const FloatRect& src_rect, SkBlendMode = SkBlendMode::kSrcOver, RespectImageOrientationEnum = kDoNotRespectImageOrientation); - // Used for background image - void DrawTiledImage(Image*, - const FloatSize& unsnapped_subset_size, - const FloatRect& snapped_paint_rect, - const FloatPoint& unsnapped_phase, - const FloatSize& tile_size, - SkBlendMode = SkBlendMode::kSrcOver, - const FloatSize& repeat_spacing = FloatSize()); + void DrawImageTiled(Image* image, + const FloatRect& dest_rect, + const FloatRect& src_rect, + const FloatSize& scale_src_to_dest, + const FloatPoint& phase, + const FloatSize& repeat_spacing, + SkBlendMode = SkBlendMode::kSrcOver); // Used for border image void DrawTiledImage(Image*, const FloatRect& dest_rect,
diff --git a/third_party/blink/renderer/platform/graphics/image.cc b/third_party/blink/renderer/platform/graphics/image.cc index efa5fa09..dba1d08 100644 --- a/third_party/blink/renderer/platform/graphics/image.cc +++ b/third_party/blink/renderer/platform/graphics/image.cc
@@ -141,66 +141,6 @@ } // TODO(schenney): Lift this code, with the calculations for subsetting the -// image and the like, up the stack into a BackgroundPainter. -void Image::DrawTiledBackground(GraphicsContext& ctxt, - const FloatSize& unsnapped_subset_size, - const FloatRect& snapped_paint_rect, - const FloatPoint& phase, - const FloatSize& tile_size, - SkBlendMode op, - const FloatSize& repeat_spacing) { - if (tile_size.IsEmpty()) - return; - - // Use the intrinsic size of the image if it has one, otherwise force the - // generated image to be the tile size. - FloatSize intrinsic_tile_size(Size()); - FloatSize scale(1, 1); - if (HasRelativeSize()) { - intrinsic_tile_size.SetWidth(tile_size.Width()); - intrinsic_tile_size.SetHeight(tile_size.Height()); - } else { - scale = FloatSize(tile_size.Width() / intrinsic_tile_size.Width(), - tile_size.Height() / intrinsic_tile_size.Height()); - } - - const FloatRect one_tile_rect = ComputePhaseForBackground( - snapped_paint_rect.Location(), tile_size, phase, repeat_spacing); - - // Check and see if a single draw of the image can cover the entire area we - // are supposed to tile. The dest_rect_for_subset must use the same - // location that was used in ComputePhaseForBackground and the unsnapped - // destination rect in order to correctly evaluate the subset size and - // location in the presence of border snapping and zoom. - FloatRect dest_rect_for_subset(snapped_paint_rect.Location(), - unsnapped_subset_size); - if (one_tile_rect.Contains(dest_rect_for_subset)) { - FloatRect visible_src_rect = ComputeSubsetForBackground( - one_tile_rect, dest_rect_for_subset, intrinsic_tile_size); - // Round to avoid filtering pulling in neighboring pixels, for the - // common case of sprite maps. - // TODO(schenney): Snapping at this level is a problem for cases where we - // might be animating background-position to pan over an image. Ideally we - // would either snap only if close to integral, or move snapping - // calculations up the stack. - visible_src_rect = FloatRect(RoundedIntRect(visible_src_rect)); - ctxt.DrawImage(this, kSyncDecode, snapped_paint_rect, &visible_src_rect, op, - kDoNotRespectImageOrientation); - return; - } - - // Note that this tile rect the image's pre-scaled size. - FloatRect tile_rect(FloatPoint(), intrinsic_tile_size); - // This call takes the unscaled image, applies the given scale, and paints - // it into the snapped_dest_rect using phase from one_tile_rect and the - // given repeat spacing. Note the phase is already scaled. - DrawPattern(ctxt, tile_rect, scale, one_tile_rect.Location(), op, - snapped_paint_rect, repeat_spacing); - - StartAnimation(); -} - -// TODO(schenney): Lift this code, with the calculations for subsetting the // image and the like, up the stack into a border painting class. void Image::DrawTiledBorder(GraphicsContext& ctxt, const FloatRect& dst_rect, @@ -295,8 +235,6 @@ DrawPattern(ctxt, src_rect, tile_scale_factor, pattern_phase, op, dst_rect, spacing); } - - StartAnimation(); } namespace { @@ -412,6 +350,8 @@ context.DrawRect(dest_rect, flags); + StartAnimation(); + if (CurrentFrameIsLazyDecoded()) { TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Draw LazyPixelRef", TRACE_EVENT_SCOPE_THREAD, @@ -454,33 +394,6 @@ return true; } -FloatRect Image::ComputePhaseForBackground(const FloatPoint& destination_offset, - const FloatSize& size, - const FloatPoint& phase, - const FloatSize& spacing) { - const FloatSize step_per_tile(size + spacing); - return FloatRect( - FloatPoint( - destination_offset.X() + fmodf(-phase.X(), step_per_tile.Width()), - destination_offset.Y() + fmodf(-phase.Y(), step_per_tile.Height())), - size); -} - -FloatRect Image::ComputeSubsetForBackground(const FloatRect& phase_and_size, - const FloatRect& subset, - const FloatSize& intrinsic_size) { - // TODO(schenney): Re-enable this after determining why it fails for - // CAP, and maybe other cases. - // DCHECK(phase_and_size.Contains(subset)); - - const FloatSize scale(phase_and_size.Width() / intrinsic_size.Width(), - phase_and_size.Height() / intrinsic_size.Height()); - return FloatRect((subset.X() - phase_and_size.X()) / scale.Width(), - (subset.Y() - phase_and_size.Y()) / scale.Height(), - subset.Width() / scale.Width(), - subset.Height() / scale.Height()); -} - SkBitmap Image::AsSkBitmapForCurrentFrame( RespectImageOrientationEnum should_respect_image_orientation) { PaintImage paint_image = PaintImageForCurrentFrame();
diff --git a/third_party/blink/renderer/platform/graphics/image.h b/third_party/blink/renderer/platform/graphics/image.h index 490c63f..a6e42e8 100644 --- a/third_party/blink/renderer/platform/graphics/image.h +++ b/third_party/blink/renderer/platform/graphics/image.h
@@ -223,33 +223,6 @@ return nullptr; } - // Given the |size| that the whole image should draw at, and the - // input phase requested by the content, and the space between repeated tiles, - // return a rectangle with |size| and a location that respects - // the phase but is no more than one size + space in magnitude. In practice, - // this means that if there is no repeating the returned rect would contain - // the destination_offset location. The destination_offset passed here must - // exactly match the location of the subset in a following call to - // ComputeSubsetForBackground. - static FloatRect ComputePhaseForBackground( - const FloatPoint& destination_offset, - const FloatSize& size, - const FloatPoint& phase, - const FloatSize& spacing); - - // Compute the image subset, in intrinsic image coordinates, that gets mapped - // onto the |subset|, when the whole image would be drawn with phase - // and size given by |phase_and_size|. Assumes - // |phase_and_size| contains |subset|. The location - // of the requested subset should be the painting snapped location, or - // whatever was used as a destination_offset in ComputePhaseForBackground. - // It is used to undo the offset added in ComputePhaseForBackground. The size - // of requested subset should be the unsnapped size so that the computed - // scale and location in the source image can be correctly determined. - static FloatRect ComputeSubsetForBackground(const FloatRect& phase_and_size, - const FloatRect& subset, - const FloatSize& intrinsic_size); - virtual sk_sp<PaintRecord> PaintRecordForContainer( const KURL& url, const IntSize& container_size, @@ -278,22 +251,6 @@ protected: Image(ImageObserver* = nullptr, bool is_multipart = false); - // The unsnapped_subset_size should be the target painting area implied by the - // content, without any snapping applied. It is necessary to correctly - // compute the subset of the source image to paint into the destination. - // The snapped_paint_rect should be the target destination for painting into. - // The phase is never snapped. - // The tile_size is the total image size. The mapping from this size - // to the unsnapped_dest_rect size defines the scaling of the image for - // sprite computation. - void DrawTiledBackground(GraphicsContext&, - const FloatSize& unsnapped_subset_size, - const FloatRect& snapped_paint_rect, - const FloatPoint& phase, - const FloatSize& tile_size, - SkBlendMode, - const FloatSize& repeat_spacing); - void DrawTiledBorder(GraphicsContext&, const FloatRect& dst_rect, const FloatRect& src_rect,
diff --git a/third_party/blink/renderer/platform/heap/thread_state.h b/third_party/blink/renderer/platform/heap/thread_state.h index 00282d6..a7bca2b 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.h +++ b/third_party/blink/renderer/platform/heap/thread_state.h
@@ -260,7 +260,7 @@ bool CheckThread() const { return thread_ == CurrentThread(); } ThreadHeap& Heap() const { return *heap_; } - ThreadIdentifier ThreadId() const { return thread_; } + base::PlatformThreadId ThreadId() const { return thread_; } // When ThreadState is detaching from non-main thread its // heap is expected to be empty (because it is going away). @@ -667,7 +667,7 @@ static uint8_t main_thread_state_storage_[]; std::unique_ptr<ThreadHeap> heap_; - ThreadIdentifier thread_; + base::PlatformThreadId thread_; std::unique_ptr<PersistentRegion> persistent_region_; std::unique_ptr<PersistentRegion> weak_persistent_region_; intptr_t* start_of_stack_;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index a6cdb4f6..6eaa00ff 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -485,9 +485,7 @@ }, { name: "FeaturePolicyJavaScriptInterface", - implied_by: ["ExperimentalProductivityFeatures"], - origin_trial_feature_name: "FeaturePolicyJSAPI", - status: "experimental" + status: "stable" }, { name: "FeaturePolicyReporting", @@ -1466,7 +1464,7 @@ }, { name: "WebXR", - origin_trial_feature_name: "WebXRDeviceM69", + origin_trial_feature_name: "WebXRDeviceM73", status: "experimental", }, // Subset of the Gamepad extensions used for early WebXR implementations
diff --git a/third_party/blink/renderer/platform/supplementable.h b/third_party/blink/renderer/platform/supplementable.h index c88d7238..d0222bf 100644 --- a/third_party/blink/renderer/platform/supplementable.h +++ b/third_party/blink/renderer/platform/supplementable.h
@@ -222,8 +222,8 @@ #if DCHECK_IS_ON() private: - ThreadIdentifier attached_thread_id_; - ThreadIdentifier creation_thread_id_; + base::PlatformThreadId attached_thread_id_; + base::PlatformThreadId creation_thread_id_; #endif };
diff --git a/third_party/blink/renderer/platform/timer.h b/third_party/blink/renderer/platform/timer.h index 92bfbbb1..ae0457d 100644 --- a/third_party/blink/renderer/platform/timer.h +++ b/third_party/blink/renderer/platform/timer.h
@@ -102,7 +102,7 @@ scoped_refptr<base::SingleThreadTaskRunner> web_task_runner_; #if DCHECK_IS_ON() - ThreadIdentifier thread_; + base::PlatformThreadId thread_; #endif base::WeakPtrFactory<TimerBase> weak_ptr_factory_;
diff --git a/third_party/blink/renderer/platform/wtf/std_lib_extras.h b/third_party/blink/renderer/platform/wtf/std_lib_extras.h index 4c5bf0e..bf2d8f0b 100644 --- a/third_party/blink/renderer/platform/wtf/std_lib_extras.h +++ b/third_party/blink/renderer/platform/wtf/std_lib_extras.h
@@ -153,7 +153,7 @@ InstanceStorage<WrapperType> instance_; #if DCHECK_IS_ON() bool safely_initialized_; - ThreadIdentifier thread_; + base::PlatformThreadId thread_; #endif DISALLOW_COPY_AND_ASSIGN(StaticSingleton);
diff --git a/third_party/blink/renderer/platform/wtf/thread_restriction_verifier.h b/third_party/blink/renderer/platform/wtf/thread_restriction_verifier.h index 6a1dd19..ef2d9a8f 100644 --- a/third_party/blink/renderer/platform/wtf/thread_restriction_verifier.h +++ b/third_party/blink/renderer/platform/wtf/thread_restriction_verifier.h
@@ -99,7 +99,7 @@ bool shared_; - ThreadIdentifier owning_thread_; + base::PlatformThreadId owning_thread_; }; } // namespace WTF
diff --git a/third_party/blink/renderer/platform/wtf/thread_specific.h b/third_party/blink/renderer/platform/wtf/thread_specific.h index 31a7d75..44179d69 100644 --- a/third_party/blink/renderer/platform/wtf/thread_specific.h +++ b/third_party/blink/renderer/platform/wtf/thread_specific.h
@@ -87,10 +87,7 @@ // longer has a graceful shutdown sequence. Be careful to call this function // (which can be re-entrant) while the pointer is still set, to avoid lazily // allocating WTFThreadData after it is destroyed. - // This check cannot be performed using WTF::IsMainThread, as it uses TLS to - // store thread information, and we can't rely on the destruction order of - // TLS variables. - if (CurrentThread() == g_main_thread_identifier) + if (IsMainThread()) return; // The memory was allocated via Partitions::FastZeroedMalloc, and then the
diff --git a/third_party/blink/renderer/platform/wtf/threading.cc b/third_party/blink/renderer/platform/wtf/threading.cc index 51dd1b47..07eb8a7 100644 --- a/third_party/blink/renderer/platform/wtf/threading.cc +++ b/third_party/blink/renderer/platform/wtf/threading.cc
@@ -8,8 +8,8 @@ namespace WTF { -ThreadIdentifier CurrentThread() { - thread_local ThreadIdentifier g_id = base::PlatformThread::CurrentId(); +base::PlatformThreadId CurrentThread() { + thread_local base::PlatformThreadId g_id = base::PlatformThread::CurrentId(); return g_id; }
diff --git a/third_party/blink/renderer/platform/wtf/threading.h b/third_party/blink/renderer/platform/wtf/threading.h index 4f7aedac..ad6c743 100644 --- a/third_party/blink/renderer/platform/wtf/threading.h +++ b/third_party/blink/renderer/platform/wtf/threading.h
@@ -40,13 +40,11 @@ namespace WTF { -using ThreadIdentifier = base::PlatformThreadId; - // Initializes global state required by |currentThread|. // Needs to be called once during program execution, before |currentThread|. WTF_EXPORT void InitializeCurrentThread(); -WTF_EXPORT ThreadIdentifier CurrentThread(); +WTF_EXPORT base::PlatformThreadId CurrentThread(); #if DCHECK_IS_ON() WTF_EXPORT bool IsBeforeThreadCreated(); @@ -55,7 +53,6 @@ } // namespace WTF -using WTF::ThreadIdentifier; using WTF::CurrentThread; #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_THREADING_H_
diff --git a/third_party/blink/renderer/platform/wtf/wtf.cc b/third_party/blink/renderer/platform/wtf/wtf.cc index 1d85de8b..e6cfcb8 100644 --- a/third_party/blink/renderer/platform/wtf/wtf.cc +++ b/third_party/blink/renderer/platform/wtf/wtf.cc
@@ -47,16 +47,7 @@ bool g_initialized; void (*g_call_on_main_thread_function)(MainThreadFunction, void*); -ThreadIdentifier g_main_thread_identifier; - -#if defined(COMPONENT_BUILD) && defined(OS_WIN) -static thread_local bool g_is_main_thread = false; -bool IsMainThread() { - return g_is_main_thread; -} -#else -thread_local bool g_is_main_thread = false; -#endif +base::PlatformThreadId g_main_thread_identifier; namespace internal { @@ -66,13 +57,16 @@ } // namespace internal +bool IsMainThread() { + return CurrentThread() == g_main_thread_identifier; +} + void Initialize(void (*call_on_main_thread_function)(MainThreadFunction, void*)) { // WTF, and Blink in general, cannot handle being re-initialized. // Make that explicit here. CHECK(!g_initialized); g_initialized = true; - g_is_main_thread = true; g_main_thread_identifier = CurrentThread(); WTFThreadData::Initialize();
diff --git a/third_party/blink/renderer/platform/wtf/wtf.h b/third_party/blink/renderer/platform/wtf/wtf.h index f9a53868..a8f024d6 100644 --- a/third_party/blink/renderer/platform/wtf/wtf.h +++ b/third_party/blink/renderer/platform/wtf/wtf.h
@@ -31,7 +31,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_WTF_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_WTF_H_ -#include "build/build_config.h" #include "third_party/blink/renderer/platform/wtf/compiler.h" #include "third_party/blink/renderer/platform/wtf/threading.h" #include "third_party/blink/renderer/platform/wtf/wtf_export.h" @@ -39,22 +38,12 @@ namespace WTF { typedef void MainThreadFunction(void*); -WTF_EXPORT extern ThreadIdentifier g_main_thread_identifier; +WTF_EXPORT extern base::PlatformThreadId g_main_thread_identifier; // This function must be called exactly once from the main thread before using // anything else in WTF. WTF_EXPORT void Initialize(void (*)(MainThreadFunction, void*)); - -// thread_local variables can't be exported on Windows, so we use an extra -// function call on component builds. -#if defined(COMPONENT_BUILD) && defined(OS_WIN) WTF_EXPORT bool IsMainThread(); -#else -WTF_EXPORT extern thread_local bool g_is_main_thread; -inline bool IsMainThread() { - return g_is_main_thread; -} -#endif namespace internal { void CallOnMainThread(MainThreadFunction*, void* context);
diff --git a/third_party/blink/renderer/platform/wtf/wtf_thread_data.h b/third_party/blink/renderer/platform/wtf/wtf_thread_data.h index 21213473..58e7197 100644 --- a/third_party/blink/renderer/platform/wtf/wtf_thread_data.h +++ b/third_party/blink/renderer/platform/wtf/wtf_thread_data.h
@@ -54,7 +54,7 @@ ICUConverterWrapper& CachedConverterICU() { return *cached_converter_icu_; } - ThreadIdentifier ThreadId() const { return thread_id_; } + base::PlatformThreadId ThreadId() const { return thread_id_; } // Must be called on the main thread before any callers to wtfThreadData(). static void Initialize(); @@ -67,7 +67,7 @@ std::unique_ptr<AtomicStringTable> atomic_string_table_; std::unique_ptr<ICUConverterWrapper> cached_converter_icu_; - ThreadIdentifier thread_id_; + base::PlatformThreadId thread_id_; #if defined(OS_WIN) && defined(COMPILER_MSVC) size_t thread_stack_size_ = 0u;
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index 5690db5..a1003bc 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -40,6 +40,7 @@ 'base::MakeRefCounted', 'base::Optional', 'base::OptionalOrNullptr', + 'base::PlatformThreadId', 'base::RefCountedData', 'base::RunLoop', 'base::CreateSequencedTaskRunnerWithTraits',
diff --git a/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_runner_unittest.py b/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_runner_unittest.py index e7c4bf0..50751bd 100644 --- a/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_runner_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/controllers/web_test_runner_unittest.py
@@ -27,6 +27,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import sys import unittest from blinkpy.common.host_mock import MockHost @@ -79,6 +80,9 @@ self._should_have_http_lock = http_lock +# TODO(crbug.com/926841): Debug running this test on Swarming on Windows. +# Ensure that all child processes are always cleaned up. +@unittest.skipIf(sys.platform == 'win32', 'may not clean up child processes') class WebTestRunnerTests(unittest.TestCase): # pylint: disable=protected-access
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index fbaee64..fb37c03 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -125,6 +125,10 @@ # This was disabled by sheriff on Dec 31. Also failing on Win7, will need more investigation. crbug.com/891427 [ Mac Win7 ] virtual/mouseevent_fractional/fast/events/touch/gesture/touch-gesture-scroll-listbox.html [ Pass Failure Timeout Crash ] +# Unexpected failures (due to leaks?) +crbug.com/927454 [ Linux ] external/wpt/pointerevents/pointerevent_pointerleave_descendant_over.html [ Pass Failure ] +crbug.com/927454 [ Linux ] external/wpt/pointerevents/pointerevent_lostpointercapture_is_first.html [ Pass Failure ] + # ====== Site Isolation failures from here ====== # See also third_party/blink/web_tests/virtual/not-site-per-process/README.md # @@ -142,7 +146,6 @@ crbug.com/771003 http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] crbug.com/771003 virtual/outofblink-cors-ns/http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] crbug.com/771003 virtual/outofblink-cors/http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] -crbug.com/771003 virtual/feature-policy-for-sandbox/http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] # Tests temporarily disabled with Site Isolation - known differences in product # behavior (either accepted for the long-term, or for the short-term): @@ -154,7 +157,6 @@ crbug.com/669083 http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Failure ] crbug.com/669083 virtual/outofblink-cors-ns/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Failure ] crbug.com/669083 virtual/outofblink-cors/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Failure ] -crbug.com/669083 virtual/feature-policy-for-sandbox/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Failure ] crbug.com/886588 external/wpt/dom/events/EventListener-addEventListener.sub.window.html [ Failure ] # Tests temporarily disabled with Site Isolation - uninvestigated bugs: @@ -170,7 +172,6 @@ crbug.com/793127 http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] crbug.com/793127 virtual/outofblink-cors-ns/http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] crbug.com/793127 virtual/outofblink-cors/http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] -crbug.com/793127 virtual/feature-policy-for-sandbox/http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] crbug.com/801992 http/tests/misc/iframe-script-modify-attr.html [ Pass Crash ] crbug.com/807675 http/tests/images/image-decode-in-frame.html [ Crash Failure ] crbug.com/819800 external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html [ Failure ] @@ -1789,26 +1790,10 @@ crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_forward_line_br.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_forward_line_range.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_forward_line_small_line.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_03_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_04_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_17_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_17_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_18_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_18_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_19_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_19_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_20_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_20_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_21_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_21_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_22_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_22_rtl.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_23_ltr.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_23_rtl.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_24_ltr.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_24_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_41_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_42_ltr.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_right_character_in_mixed_bidi.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_01_ltr_multi_line.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_01_rtl_multi_line.html [ Failure Crash ] @@ -1828,26 +1813,10 @@ crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_08_rtl_multi_line.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_09_ltr_multi_line.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_word_09_rtl_multi_line.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_03_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_04_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_17_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_17_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_18_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_18_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_19_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_19_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_20_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_20_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_21_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_21_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_22_ltr.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_22_rtl.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_23_ltr.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_23_rtl.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_24_ltr.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_24_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_41_rtl.html [ Failure ] -crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_character_42_ltr.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_01_ltr_multi_line.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_01_rtl_multi_line.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_right_word_02_ltr_multi_line.html [ Failure Crash ] @@ -2057,7 +2026,6 @@ crbug.com/518883 crbug.com/390452 http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] crbug.com/518883 crbug.com/390452 virtual/outofblink-cors/http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] crbug.com/518883 crbug.com/390452 virtual/outofblink-cors-ns/http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] -crbug.com/518883 crbug.com/390452 virtual/feature-policy-for-sandbox/http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] crbug.com/518987 http/tests/xmlhttprequest/navigation-abort-detaches-frame.html [ Pass Timeout ] crbug.com/518987 virtual/outofblink-cors/http/tests/xmlhttprequest/navigation-abort-detaches-frame.html [ Pass Timeout ] crbug.com/518987 virtual/outofblink-cors-ns/http/tests/xmlhttprequest/navigation-abort-detaches-frame.html [ Pass Timeout ] @@ -2459,10 +2427,6 @@ crbug.com/528062 [ Win ] virtual/outofblink-cors-ns/http/tests/security/contentSecurityPolicy/cached-frame-csp.html [ Failure ] crbug.com/528062 [ Win ] virtual/outofblink-cors-ns/http/tests/security/xssAuditor/cached-frame.html [ Failure ] crbug.com/528062 [ Win ] virtual/outofblink-cors-ns/http/tests/security/xssAuditor/chunked-big-script.html [ Failure ] -crbug.com/528062 [ Win ] virtual/feature-policy-for-sandbox/http/tests/security/XFrameOptions/x-frame-options-cached.html [ Failure ] -crbug.com/528062 [ Win ] virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/cached-frame-csp.html [ Failure ] -crbug.com/528062 [ Win ] virtual/feature-policy-for-sandbox/http/tests/security/xssAuditor/cached-frame.html [ Failure ] -crbug.com/528062 [ Win ] virtual/feature-policy-for-sandbox/http/tests/security/xssAuditor/chunked-big-script.html [ Failure ] # When drawing subpixel smoothed glyphs, CoreGraphics will fake bold the glyphs. # In this configuration, the pixel smoothed glyphs will be created from subpixel smoothed glyphs. @@ -2744,7 +2708,6 @@ crbug.com/501659 http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] crbug.com/501659 virtual/outofblink-cors/http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] crbug.com/501659 virtual/outofblink-cors-ns/http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] -crbug.com/501659 virtual/feature-policy-for-sandbox/http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] crbug.com/501659 fast/css/stylesheet-candidate-nodes-crash.xhtml [ Failure ] crbug.com/545140 [ Mac ] fast/encoding/denormalised-voiced-japanese-chars.html [ Failure ] @@ -2869,7 +2832,6 @@ crbug.com/763830 http/tests/security/cors-rfc1918/ [ Skip ] crbug.com/763830 virtual/outofblink-cors/http/tests/security/cors-rfc1918/ [ Skip ] crbug.com/763830 virtual/outofblink-cors-ns/http/tests/security/cors-rfc1918/ [ Skip ] -crbug.com/763830 virtual/feature-policy-for-sandbox/http/tests/security/cors-rfc1918/ [ Skip ] crbug.com/831729 external/wpt/event-timing/event-timing-crossiframe.html [ Timeout ] crbug.com/831729 external/wpt/event-timing/event-timing-observer-manual.html [ Skip ] @@ -3881,6 +3843,8 @@ crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2j.html [ Failure ] crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2k.html [ Failure ] crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/the-page/body-margin-2l.html [ Failure ] +crbug.com/626703 external/wpt/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html [ Timeout ] +crbug.com/626703 external/wpt/webaudio/the-audio-api/the-analysernode-interface/test-analyser-output.html [ Timeout ] crbug.com/626703 external/wpt/css/css-fonts/font-synthesis-01.html [ Failure ] crbug.com/626703 external/wpt/css/css-fonts/font-synthesis-02.html [ Failure ] crbug.com/626703 external/wpt/css/css-fonts/font-synthesis-03.html [ Failure ] @@ -4393,7 +4357,6 @@ crbug.com/610835 http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] crbug.com/610835 virtual/outofblink-cors/http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] crbug.com/610835 virtual/outofblink-cors-ns/http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] -crbug.com/610835 virtual/feature-policy-for-sandbox/http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] # Added 2016-12-12 crbug.com/673539 [ Linux ] css3/filters/effect-contrast-hw.html [ Pass Failure ] @@ -4571,8 +4534,6 @@ crbug.com/724027 virtual/outofblink-cors/http/tests/security/contentSecurityPolicy/source-list-parsing-04.html [ Skip ] crbug.com/724027 virtual/outofblink-cors-ns/http/tests/security/contentSecurityPolicy/directive-parsing-03.html [ Skip ] crbug.com/724027 virtual/outofblink-cors-ns/http/tests/security/contentSecurityPolicy/source-list-parsing-04.html [ Skip ] -crbug.com/724027 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/directive-parsing-03.html [ Skip ] -crbug.com/724027 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/source-list-parsing-04.html [ Skip ] # Sheriff failures 2017-05-16 crbug.com/722212 fast/events/pointerevents/mouse-pointer-event-properties.html [ Failure Timeout Pass ] @@ -4672,7 +4633,6 @@ crbug.com/708994 http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] crbug.com/708994 virtual/outofblink-cors/http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] crbug.com/708994 virtual/outofblink-cors-ns/http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] -crbug.com/708994 virtual/feature-policy-for-sandbox/http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] crbug.com/745887 [ Mac ] fast/frames/sandboxed-iframe-plugins.html [ Failure Pass ] crbug.com/745887 [ Win ] fast/frames/sandboxed-iframe-plugins.html [ Failure Pass ] @@ -5874,9 +5834,6 @@ # Sheriff 2019-01-11 crbug.com/921038 virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed/legacy-performance-memory-counters-enabled.html [ Skip ] -# Fails until document.featurePolicy is available in stable -crbug.com/917070 virtual/stable/webexposed/feature-policy-features.html [ Failure ] - # Mac doesn't support lowLatency Canvas Contexts. crbug.com/922218 [ Mac ] fast/canvas-api/canvas-lowlatency-getContext.html [ Failure ] @@ -6013,19 +5970,6 @@ # WebXR feature policy feature name in Chrome doesn't match spec. crbug.com/924670 external/wpt/webvr/webvr-supported-by-feature-policy.html [ Failure ] -# Feature Policy for Sandbox currently causes these tests to fail. -crbug.com/926245 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/sandbox-empty-subframe.html [ Failure ] -crbug.com/926245 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/sandbox-empty.html [ Failure ] -crbug.com/926245 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/sandbox-in-http-header-control.html [ Failure ] -crbug.com/926245 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/sandbox-invalid-header.html [ Failure ] -crbug.com/926247 virtual/feature-policy-for-sandbox/http/tests/navigation/new-window-sandboxed-iframe.html [ Failure ] -crbug.com/926247 virtual/feature-policy-for-sandbox/http/tests/security/popup-allowed-by-sandbox-is-sandboxed.html [ Failure ] -crbug.com/926248 virtual/feature-policy-for-sandbox/mhtml/page_with_css_and_js_ie.mht [ Failure ] -crbug.com/926248 virtual/feature-policy-for-sandbox/mhtml/page_with_css_and_js_unmht.mht [ Failure ] -crbug.com/926248 virtual/feature-policy-for-sandbox/mhtml/page_with_javascript.mht [ Failure ] -crbug.com/926248 virtual/feature-policy-for-sandbox/mhtml/transfer_encoding_8bit.mht [ Failure ] -crbug.com/926249 virtual/feature-policy-for-sandbox/http/tests/security/sandbox-iframe-blocks-modals.php [ Failure ] - # Sheriff 2019-01-25 crbug.com/925325 [ Mac ] storage/indexeddb/index-population.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index d3e1231..0c1c5bd 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1013,20 +1013,5 @@ "prefix": "bidi-caret-affinity", "base": "editing/selection/modify_move", "args": ["--enable-blink-features=BidiCaretAffinity,EditingNG"] - }, - { - "prefix": "feature-policy-for-sandbox", - "base": "http/tests/navigation", - "args": ["--enable-blink-features=FeaturePolicyForSandbox"] - }, - { - "prefix": "feature-policy-for-sandbox", - "base": "http/tests/security", - "args": ["--enable-blink-features=FeaturePolicyForSandbox"] - }, - { - "prefix": "feature-policy-for-sandbox", - "base": "mhtml", - "args": ["--enable-blink-features=FeaturePolicyForSandbox"] } ]
diff --git a/third_party/blink/web_tests/editing/input/remove_frame_on_set_composition.html b/third_party/blink/web_tests/editing/input/remove_frame_on_set_composition.html new file mode 100644 index 0000000..a9358def --- /dev/null +++ b/third_party/blink/web_tests/editing/input/remove_frame_on_set_composition.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../assert_selection.js"></script> +<script> +selection_test( + '<iframe id=child></iframe>', + selection => { + const child = selection.document.getElementById('child'); + const childDocument = child.contentDocument; + const textarea = childDocument.createElement('textarea'); + childDocument.body.appendChild(textarea); + textarea.addEventListener("input", () => child.remove()); + textarea.focus(); + + assert_own_property( + window, 'textInputController', + 'This test requires textInputController to simulate IME operations'); + textInputController.setComposition("foo"); + }, + '', + 'SetComposition should not crash when event handler removes frame'); +</script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_03_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_03_rtl.html index 1dc0c737..2350f12 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_03_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_03_rtl.html
@@ -3,22 +3,30 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl">|<br>abc</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl"><br>|abc</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl"><br>abc|</div>' + : '<div contenteditable dir="rtl"><br>|abc</div>', '3-0 rtl left character'); selection_test( '<div contenteditable dir="rtl"><br>|abc</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl"><br>ab|c</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl"><br>|abc</div>' + : '<div contenteditable dir="rtl"><br>ab|c</div>', '3-1 rtl left character'); selection_test( '<div contenteditable dir="rtl"><br>a|bc</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl"><br>abc|</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl"><br>|abc</div>' + : '<div contenteditable dir="rtl"><br>abc|</div>', '3-2 rtl left character'); selection_test( @@ -30,6 +38,8 @@ selection_test( '<div contenteditable dir="rtl"><br>abc|</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl"><br>abc|</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl"><br>ab|c</div>' + : '<div contenteditable dir="rtl"><br>abc|</div>', '3-4 rtl left character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_04_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_04_ltr.html index 557b896..44a42da 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_04_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_04_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr">|<br>\u05D0\u05D1\u05D2</div>', selection => selection.modify('move', 'left', 'character'), @@ -12,7 +14,9 @@ selection_test( '<div contenteditable dir="ltr"><br>|\u05D0\u05D1\u05D2</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr">|<br>\u05D0\u05D1\u05D2</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr"><br>\u05D0|\u05D1\u05D2</div>' + : '<div contenteditable dir="ltr">|<br>\u05D0\u05D1\u05D2</div>', '4-1 ltr left character'); selection_test( @@ -24,12 +28,16 @@ selection_test( '<div contenteditable dir="ltr"><br>\u05D0\u05D1|\u05D2</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr"><br>|\u05D0\u05D1\u05D2</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr"><br>\u05D0\u05D1\u05D2|</div>' + : '<div contenteditable dir="ltr"><br>|\u05D0\u05D1\u05D2</div>', '4-3 ltr left character'); selection_test( '<div contenteditable dir="ltr"><br>\u05D0\u05D1\u05D2|</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr"><br>\u05D0|\u05D1\u05D2</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr">|<br>\u05D0\u05D1\u05D2</div>' + : '<div contenteditable dir="ltr"><br>\u05D0|\u05D1\u05D2</div>', '4-4 ltr left character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_17_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_17_ltr.html index cf63c58..8e68af5 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_17_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_17_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), @@ -48,25 +50,33 @@ selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-7 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-8 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-9 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before |\u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-10 ltr left character'); selection_test( @@ -84,19 +94,25 @@ selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-13 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-14 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0|\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-15 ltr left character'); selection_test( @@ -156,12 +172,16 @@ selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-25 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0|\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0|\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-26 ltr left character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_17_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_17_rtl.html index 5bd1afe..f6a5ded 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_17_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_17_rtl.html
@@ -3,16 +3,22 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">befor|e \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">befor|e \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-0 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">b|efore \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-1 rtl left character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_18_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_18_ltr.html index 815ebd7..097da3b8 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_18_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_18_ltr.html
@@ -3,10 +3,14 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">\u05DC|\u05E4\u05E0\u05D9 after encyclopedia</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', '18-0 ltr left character'); selection_test( @@ -24,7 +28,9 @@ selection_test( '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0|\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', '18-3 ltr left character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_18_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_18_rtl.html index 6ef28dc..016ad93 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_18_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_18_rtl.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), @@ -36,31 +38,41 @@ selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', '18-5 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', '18-6 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', '18-7 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 |after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', '18-8 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', '18-9 rtl left character'); selection_test( @@ -84,19 +96,25 @@ selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', '18-13 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>', '18-14 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after e|ncyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', '18-15 rtl left character'); selection_test( @@ -162,6 +180,8 @@ selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', '18-26 rtl left character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_19_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_19_ltr.html index 2194fbb..676c5b3 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_19_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_19_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), @@ -48,25 +50,33 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-7 ltr left character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-8 ltr left character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-9 ltr left character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before |\u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-10 ltr left character'); selection_test( @@ -84,19 +94,25 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-13 ltr left character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-14 ltr left character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0|\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-15 ltr left character'); selection_test( @@ -156,12 +172,16 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-25 ltr left character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0|\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0|\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-26 ltr left character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_19_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_19_rtl.html index 1b08caf..1f31ae2d 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_19_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_19_rtl.html
@@ -3,16 +3,22 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">befor|e \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">befor|e \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-0 rtl left character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">b|efore \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-1 rtl left character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_20_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_20_ltr.html index 2b181cc8..6e8bc1b 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_20_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_20_ltr.html
@@ -3,10 +3,14 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">\u05DC|\u05E4\u05E0\u05D9 after encyclopedia</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', '20-0 ltr left character'); selection_test( @@ -24,7 +28,9 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0|\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', '20-3 ltr left character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_20_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_20_rtl.html index 9ece180..bd47600 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_20_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_20_rtl.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), @@ -36,31 +38,41 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', '20-5 rtl left character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', '20-6 rtl left character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', '20-7 rtl left character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 |after encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', '20-8 rtl left character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', '20-9 rtl left character'); selection_test( @@ -84,19 +96,25 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', '20-13 rtl left character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>', '20-14 rtl left character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after e|ncyclopedia</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', '20-15 rtl left character'); selection_test( @@ -162,6 +180,8 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', '20-26 rtl left character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_21_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_21_ltr.html index 6ffa4ea..63beaec7 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_21_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_21_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), @@ -54,7 +56,9 @@ selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9|\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-8 ltr left character'); selection_test( @@ -90,19 +94,25 @@ selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6|\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-14 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9|\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9|\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-15 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE|\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-16 ltr left character'); selection_test( @@ -120,7 +130,9 @@ selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA|\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-19 ltr left character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_21_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_21_rtl.html index 0a3605c..435f069 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_21_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_21_rtl.html
@@ -4,17 +4,22 @@ <script src="../../assert_selection.js"></script> <script> const isMac = navigator.platform.indexOf('Mac') === 0; +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; selection_test( '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">This i|s \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This i|s \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-0 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="width: 100px;">T|his is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-1 rtl left character'); selection_test( @@ -134,17 +139,23 @@ selection_test( '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>' - : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>', + usesBidiAffinity + ? (isMac + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.|</div>') + : (isMac + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>'), '21-21 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 t|he boxes.</div>', selection => selection.modify('move', 'left', 'character'), - isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>' - : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>' + : (isMac + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>'), '21-22 rtl left character'); selection_test( @@ -157,7 +168,9 @@ '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>', selection => selection.modify('move', 'left', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>', '21-24 rtl left character'); @@ -165,7 +178,9 @@ '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>', selection => selection.modify('move', 'left', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.|</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>', '21-25 rtl left character'); @@ -173,7 +188,9 @@ '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the b|oxes.</div>', selection => selection.modify('move', 'left', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>', '21-26 rtl left character');
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_22_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_22_ltr.html index d8529378..f006a6b 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_22_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_22_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), @@ -54,7 +56,9 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9|\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-8 ltr left character'); selection_test( @@ -90,19 +94,25 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6|\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-14 ltr left character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9|\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9|\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-15 ltr left character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE|\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-16 ltr left character'); selection_test( @@ -120,7 +130,9 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA|\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-19 ltr left character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_22_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_22_rtl.html index b22d368..f83df320 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_22_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_22_rtl.html
@@ -4,17 +4,22 @@ <script src="../../assert_selection.js"></script> <script> const isMac = navigator.platform.indexOf('Mac') === 0; +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">This i|s \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This i|s \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-0 rtl left character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 100px;">T|his is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-1 rtl left character'); selection_test( @@ -134,17 +139,23 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>', selection => selection.modify('move', 'left', 'character'), - isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>' - : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>', + usesBidiAffinity + ? (isMac + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.|</div>') + : (isMac + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>'), '22-21 rtl left character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 t|he boxes.</div>', selection => selection.modify('move', 'left', 'character'), - isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>' - : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>' + : (isMac + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>'), '22-22 rtl left character'); selection_test( @@ -157,7 +168,9 @@ '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>', selection => selection.modify('move', 'left', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>', '22-24 rtl left character'); @@ -165,7 +178,9 @@ '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>', selection => selection.modify('move', 'left', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.|</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>', '22-25 rtl left character'); @@ -173,7 +188,9 @@ '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the b|oxes.</div>', selection => selection.modify('move', 'left', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>', '22-26 rtl left character');
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_41_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_41_ltr.html index b47614cc..dae274a 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_41_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_41_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">|abc<!-- -->\n<!-- -->def</div>', selection => selection.modify('move', 'left', 'character'),
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_41_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_41_rtl.html index 48e1ff9..4f92a6a7 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_41_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_41_rtl.html
@@ -3,16 +3,22 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">|abc<!-- -->\n<!-- -->def</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">ab|c \n def</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n def|</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">ab|c \n def</div>', '41-0 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">a|bc<!-- -->\n<!-- -->def</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc| \n def</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">|abc \n def</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc| \n def</div>', '41-1 rtl left character'); selection_test( @@ -24,31 +30,41 @@ selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc|<!-- -->\n<!-- -->def</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc \n |def</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n def|</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc \n |def</div>', '41-3 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc<!-- -->|\n<!-- -->def</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc \n |def</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n def|</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc \n |def</div>', '41-4 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc<!-- -->\n|<!-- -->def</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc \n de|f</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n| def</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc \n de|f</div>', '41-5 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc<!-- -->\n<!-- -->|def</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc \n de|f</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n |def</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc \n de|f</div>', '41-6 rtl left character'); selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc<!-- -->\n<!-- -->d|ef</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc \n def|</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n |def</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc \n def|</div>', '41-7 rtl left character'); selection_test( @@ -60,6 +76,8 @@ selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc<!-- -->\n<!-- -->def|</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc \n def|</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n de|f</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc \n def|</div>', '41-9 rtl left character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_42_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_42_ltr.html index d925b1f..143d2c4 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_42_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_42_ltr.html
@@ -3,10 +3,14 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">|\u05D0\u05D1\u05D2<!-- -->\n<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">|\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0|\u05D1\u05D2 \n \u05D3\u05D4\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">|\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5</div>', '42-0 ltr left character'); selection_test( @@ -18,7 +22,9 @@ selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1|\u05D2<!-- -->\n<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">|\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2| \n \u05D3\u05D4\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">|\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5</div>', '42-2 ltr left character'); selection_test( @@ -36,13 +42,17 @@ selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2<!-- -->\n|<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2| \n \u05D3\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3|\u05D4\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2| \n \u05D3\u05D4\u05D5</div>', '42-5 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2<!-- -->\n<!-- -->|\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2| \n \u05D3\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3|\u05D4\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2| \n \u05D3\u05D4\u05D5</div>', '42-6 ltr left character'); selection_test( @@ -54,12 +64,16 @@ selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2<!-- -->\n<!-- -->\u05D3\u05D4|\u05D5</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n |\u05D3\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5|</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n |\u05D3\u05D4\u05D5</div>', '42-8 ltr left character'); selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2<!-- -->\n<!-- -->\u05D3\u05D4\u05D5|</div>', selection => selection.modify('move', 'left', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3|\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2| \n \u05D3\u05D4\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3|\u05D4\u05D5</div>', '42-9 ltr left character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_42_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_42_rtl.html index f55d5ba..28376ae 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_42_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_left_character_42_rtl.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">|\u05D0\u05D1\u05D2<!-- -->\n<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'left', 'character'),
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_03_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_03_rtl.html index ff83714..6c9b03cb 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_03_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_03_rtl.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl">|<br>abc</div>', selection => selection.modify('move', 'right', 'character'), @@ -12,7 +14,9 @@ selection_test( '<div contenteditable dir="rtl"><br>|abc</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl">|<br>abc</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl"><br>a|bc</div>' + : '<div contenteditable dir="rtl">|<br>abc</div>', '3-1 rtl right character'); selection_test( @@ -24,12 +28,16 @@ selection_test( '<div contenteditable dir="rtl"><br>ab|c</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl"><br>|abc</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl"><br>abc|</div>' + : '<div contenteditable dir="rtl"><br>|abc</div>', '3-3 rtl right character'); selection_test( '<div contenteditable dir="rtl"><br>abc|</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl"><br>a|bc</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl">|<br>abc</div>' + : '<div contenteditable dir="rtl"><br>a|bc</div>', '3-4 rtl right character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_04_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_04_ltr.html index 7ff29cb..d5a704c1 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_04_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_04_ltr.html
@@ -3,22 +3,30 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr">|<br>\u05D0\u05D1\u05D2</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr"><br>|\u05D0\u05D1\u05D2</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr"><br>\u05D0\u05D1\u05D2|</div>' + : '<div contenteditable dir="ltr"><br>|\u05D0\u05D1\u05D2</div>', '4-0 ltr right character'); selection_test( '<div contenteditable dir="ltr"><br>|\u05D0\u05D1\u05D2</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr"><br>\u05D0\u05D1|\u05D2</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr"><br>|\u05D0\u05D1\u05D2</div>' + : '<div contenteditable dir="ltr"><br>\u05D0\u05D1|\u05D2</div>', '4-1 ltr right character'); selection_test( '<div contenteditable dir="ltr"><br>\u05D0|\u05D1\u05D2</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr"><br>\u05D0\u05D1\u05D2|</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr"><br>|\u05D0\u05D1\u05D2</div>' + : '<div contenteditable dir="ltr"><br>\u05D0\u05D1\u05D2|</div>', '4-2 ltr right character'); selection_test( @@ -30,6 +38,8 @@ selection_test( '<div contenteditable dir="ltr"><br>\u05D0\u05D1\u05D2|</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr"><br>\u05D0\u05D1\u05D2|</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr"><br>\u05D0\u05D1|\u05D2</div>' + : '<div contenteditable dir="ltr"><br>\u05D0\u05D1\u05D2|</div>', '4-4 ltr right character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_17_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_17_ltr.html index 2ade4e5..7b1217d 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_17_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_17_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), @@ -48,31 +50,41 @@ selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-7 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-8 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-9 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before |\u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-10 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-11 ltr right character'); selection_test( @@ -90,19 +102,25 @@ selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-14 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>', '17-15 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0|\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', '17-16 ltr right character'); selection_test( @@ -162,6 +180,8 @@ selection_test( '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', '17-26 ltr right character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_17_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_17_rtl.html index d32b488..b783dcd 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_17_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_17_rtl.html
@@ -3,10 +3,14 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">b|efore \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-0 rtl right character'); selection_test( @@ -36,7 +40,9 @@ selection_test( '<div contenteditable dir="rtl" style="width: 120px;">befor|e \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '17-5 rtl right character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_18_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_18_ltr.html index 1a8d244..ecd04a59 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_18_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_18_ltr.html
@@ -3,16 +3,22 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0|\u05D9 after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0|\u05D9 after encyclopedia</div>', '18-0 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 120px;">\u05DC|\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '18-1 ltr right character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_18_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_18_rtl.html index c3b74718..5cb9e0a 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_18_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_18_rtl.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), @@ -36,25 +38,33 @@ selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '18-5 rtl right character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '18-6 rtl right character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '18-7 rtl right character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 |after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '18-8 rtl right character'); selection_test( @@ -78,19 +88,25 @@ selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', '18-12 rtl right character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>', '18-13 rtl right character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after e|ncyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', '18-14 rtl right character'); selection_test( @@ -156,12 +172,16 @@ selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', '18-25 rtl right character'); selection_test( '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after e|ncyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after e|ncyclopedia</div>', '18-26 rtl right character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_19_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_19_ltr.html index 3954c06..b442a94 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_19_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_19_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), @@ -48,31 +50,41 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-7 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-8 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-9 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before |\u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-10 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0|\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before | \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-11 ltr right character'); selection_test( @@ -90,19 +102,25 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9| \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8|\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-14 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>', '19-15 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0|\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 |\u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', '19-16 ltr right character'); selection_test( @@ -162,6 +180,8 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9|\u05D4</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4|</div>', '19-26 ltr right character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_19_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_19_rtl.html index cc423bbf..ded2aab 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_19_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_19_rtl.html
@@ -3,10 +3,14 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">b|efore \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-0 rtl right character'); selection_test( @@ -36,7 +40,9 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">befor|e \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">before| \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">|before \u05D0\u05D7\u05E8\u05D9 \u05D0\u05E0\u05E6\u05D9\u05E7\u05DC\u05D5\u05E4\u05D3\u05D9\u05D4</div>', '19-5 rtl right character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_20_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_20_ltr.html index cae48c1..bdc5128 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_20_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_20_ltr.html
@@ -3,16 +3,22 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0|\u05D9 after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0|\u05D9 after encyclopedia</div>', '20-0 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 120px;">\u05DC|\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>' + : '<div contenteditable dir="ltr" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '20-1 ltr right character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_20_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_20_rtl.html index d303e55..e91c37e 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_20_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_20_rtl.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">|\u05DC\u05E4\u05E0\u05D9 after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), @@ -36,25 +38,33 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '20-5 rtl right character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '20-6 rtl right character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '20-7 rtl right character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 |after encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>', '20-8 rtl right character'); selection_test( @@ -78,19 +88,25 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 afte|r encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 | after encyclopedia</div>', '20-12 rtl right character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9| after encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>', '20-13 rtl right character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after e|ncyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after| encyclopedia</div>', '20-14 rtl right character'); selection_test( @@ -156,12 +172,16 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedi|a</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after |encyclopedia</div>', '20-25 rtl right character'); selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after encyclopedia|</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after e|ncyclopedia</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 a|fter encyclopedia</div>' + : '<div contenteditable dir="rtl" style="width: 120px;">\u05DC\u05E4\u05E0\u05D9 after e|ncyclopedia</div>', '20-26 rtl right character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_21_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_21_ltr.html index cba98b84..f487061 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_21_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_21_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), @@ -54,13 +56,17 @@ selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6|\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA|\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6|\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-8 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9|\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-9 ltr right character'); selection_test( @@ -96,19 +102,25 @@ selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6|\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-15 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA|\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA|\u05E8 the boxes.</div>', '21-16 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE|\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>', '21-17 ltr right character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_21_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_21_rtl.html index 487a33c..70795fa8 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_21_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_21_rtl.html
@@ -4,11 +4,14 @@ <script src="../../assert_selection.js"></script> <script> const isMac = navigator.platform.indexOf('Mac') === 0; +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; selection_test( '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">T|his is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-0 rtl right character'); selection_test( @@ -44,7 +47,9 @@ selection_test( '<div contenteditable dir="rtl" style="width: 100px;">This i|s \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '21-6 rtl right character'); selection_test( @@ -134,7 +139,9 @@ selection_test( '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 t|he boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>', '21-21 rtl right character'); selection_test( @@ -147,7 +154,9 @@ '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>', selection => selection.modify('move', 'right', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>', '21-23 rtl right character'); @@ -155,7 +164,9 @@ '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>', selection => selection.modify('move', 'right', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 t|he boxes.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 t|he boxes.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>', '21-24 rtl right character'); @@ -163,7 +174,9 @@ '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>', selection => selection.modify('move', 'right', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the b|oxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the b|oxes.</div>', '21-25 rtl right character'); @@ -188,9 +201,11 @@ selection_test( '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>', selection => selection.modify('move', 'right', 'character'), - isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>' - : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>' + : (isMac + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>'), '21-29 rtl right character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_22_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_22_ltr.html index c297174d..2ed70af 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_22_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_22_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), @@ -54,13 +56,17 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6|\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA|\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6|\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-8 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is \u05D9|\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is |\u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-9 ltr right character'); selection_test( @@ -96,19 +102,25 @@ selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8| \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6|\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-15 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA|\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA|\u05E8 the boxes.</div>', '22-16 ltr right character'); selection_test( '<div contenteditable dir="ltr" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE|\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 |\u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="ltr" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>', '22-17 ltr right character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_22_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_22_rtl.html index 53a53ef..7780052 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_22_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_22_rtl.html
@@ -4,11 +4,14 @@ <script src="../../assert_selection.js"></script> <script> const isMac = navigator.platform.indexOf('Mac') === 0; +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">T|his is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-0 rtl right character'); selection_test( @@ -44,7 +47,9 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This i|s \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is| \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">|This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes.</div>', '22-6 rtl right character'); selection_test( @@ -134,7 +139,9 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 t|he boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>', '22-21 rtl right character'); selection_test( @@ -147,7 +154,9 @@ '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 th|e boxes.</div>', selection => selection.modify('move', 'right', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>', '22-23 rtl right character'); @@ -155,7 +164,9 @@ '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>', selection => selection.modify('move', 'right', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 t|he boxes.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8| the boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 t|he boxes.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>', '22-24 rtl right character'); @@ -163,7 +174,9 @@ '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>', selection => selection.modify('move', 'right', 'character'), isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>' + ? (usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the b|oxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the| boxes.</div>') : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the b|oxes.</div>', '22-25 rtl right character'); @@ -188,9 +201,11 @@ selection_test( '<div contenteditable dir="rtl" contenteditable style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxe|s.</div>', selection => selection.modify('move', 'right', 'character'), - isMac - ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>' - : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the boxes|.</div>' + : (isMac + ? '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 the |boxes.</div>' + : '<div contenteditable dir="rtl" style="width: 100px;">This is \u05D9\u05D5\u05EA\u05E8 \u05E6\u05E8 \u05DE\u05D9\u05EA\u05E8 |the boxes.</div>'), '22-29 rtl right character'); selection_test(
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_41_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_41_ltr.html index f418457..11be489 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_41_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_41_ltr.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">|abc<!-- -->\n<!-- -->def</div>', selection => selection.modify('move', 'right', 'character'),
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_41_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_41_rtl.html index c9023032..d13a0c8 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_41_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_41_rtl.html
@@ -3,10 +3,14 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">|abc<!-- -->\n<!-- -->def</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">|abc \n def</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">a|bc \n def</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">|abc \n def</div>', '41-0 rtl right character'); selection_test( @@ -18,7 +22,9 @@ selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">ab|c<!-- -->\n<!-- -->def</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">|abc \n def</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc| \n def</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">|abc \n def</div>', '41-2 rtl right character'); selection_test( @@ -36,13 +42,17 @@ selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc<!-- -->\n|<!-- -->def</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc| \n def</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n d|ef</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc| \n def</div>', '41-5 rtl right character'); selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc<!-- -->\n<!-- -->|def</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc| \n def</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n d|ef</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc| \n def</div>', '41-6 rtl right character'); selection_test( @@ -54,12 +64,16 @@ selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc<!-- -->\n<!-- -->de|f</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc \n |def</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc \n def|</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc \n |def</div>', '41-8 rtl right character'); selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">abc<!-- -->\n<!-- -->def|</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="rtl" style="white-space: pre;">abc \n d|ef</div>', + usesBidiAffinity + ? '<div contenteditable dir="rtl" style="white-space: pre;">abc| \n def</div>' + : '<div contenteditable dir="rtl" style="white-space: pre;">abc \n d|ef</div>', '41-9 rtl right character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_42_ltr.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_42_ltr.html index 482bfc6..b9aa4dbd 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_42_ltr.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_42_ltr.html
@@ -3,16 +3,22 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">|\u05D0\u05D1\u05D2<!-- -->\n<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1|\u05D2 \n \u05D3\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5|</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1|\u05D2 \n \u05D3\u05D4\u05D5</div>', '42-0 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0|\u05D1\u05D2<!-- -->\n<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2| \n \u05D3\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">|\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2| \n \u05D3\u05D4\u05D5</div>', '42-1 ltr right character'); selection_test( @@ -24,31 +30,41 @@ selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2|<!-- -->\n<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n |\u05D3\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5|</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n |\u05D3\u05D4\u05D5</div>', '42-3 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2<!-- -->|\n<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n |\u05D3\u05D4\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5|</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n |\u05D3\u05D4\u05D5</div>', '42-4 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2<!-- -->\n|<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4|\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n| \u05D3\u05D4\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4|\u05D5</div>', '42-5 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2<!-- -->\n<!-- -->|\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4|\u05D5</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n |\u05D3\u05D4\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4|\u05D5</div>', '42-6 ltr right character'); selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2<!-- -->\n<!-- -->\u05D3|\u05D4\u05D5</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5|</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n |\u05D3\u05D4\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5|</div>', '42-7 ltr right character'); selection_test( @@ -60,6 +76,8 @@ selection_test( '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2<!-- -->\n<!-- -->\u05D3\u05D4\u05D5|</div>', selection => selection.modify('move', 'right', 'character'), - '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5|</div>', + usesBidiAffinity + ? '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4|\u05D5</div>' + : '<div contenteditable dir="ltr" style="white-space: pre;">\u05D0\u05D1\u05D2 \n \u05D3\u05D4\u05D5|</div>', '42-9 ltr right character'); </script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_42_rtl.html b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_42_rtl.html index 795de77..cd09342 100644 --- a/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_42_rtl.html +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_right_character_42_rtl.html
@@ -3,6 +3,8 @@ <script src="../../../resources/testharnessreport.js"></script> <script src="../../assert_selection.js"></script> <script> +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + selection_test( '<div contenteditable dir="rtl" style="white-space: pre;">|\u05D0\u05D1\u05D2<!-- -->\n<!-- -->\u05D3\u05D4\u05D5</div>', selection => selection.modify('move', 'right', 'character'),
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index 7aa93ae..cc638a3f 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -34703,6 +34703,18 @@ {} ] ], + "css/css-backgrounds/child-move-reveals-parent-background.html": [ + [ + "/css/css-backgrounds/child-move-reveals-parent-background.html", + [ + [ + "/css/css-backgrounds/child-move-reveals-parent-background-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-backgrounds/css-border-radius-001.html": [ [ "/css/css-backgrounds/css-border-radius-001.html", @@ -125794,6 +125806,11 @@ {} ] ], + "css/css-backgrounds/child-move-reveals-parent-background-ref.html": [ + [ + {} + ] + ], "css/css-backgrounds/justfortest.html": [ [ {} @@ -184619,6 +184636,26 @@ {} ] ], + "streams/writable-streams/aborting.any-expected.txt": [ + [ + {} + ] + ], + "streams/writable-streams/aborting.any.serviceworker-expected.txt": [ + [ + {} + ] + ], + "streams/writable-streams/aborting.any.sharedworker-expected.txt": [ + [ + {} + ] + ], + "streams/writable-streams/aborting.any.worker-expected.txt": [ + [ + {} + ] + ], "streams/writable-streams/properties.any-expected.txt": [ [ {} @@ -186449,117 +186486,117 @@ {} ] ], - "wasm/serialization/incrementer.wasm": [ + "wasm/serialization/module/incrementer.wasm": [ [ {} ] ], - "wasm/serialization/nested-worker-success-sharedworker-expected.txt": [ + "wasm/serialization/module/nested-worker-success-sharedworker-expected.txt": [ [ {} ] ], - "wasm/serialization/nested-worker-success.any.sharedworker-expected.txt": [ + "wasm/serialization/module/nested-worker-success.any.sharedworker-expected.txt": [ [ {} ] ], - "wasm/serialization/resources/blank.html": [ + "wasm/serialization/module/resources/blank.html": [ [ {} ] ], - "wasm/serialization/resources/broadcastchannel-iframe.html": [ + "wasm/serialization/module/resources/broadcastchannel-iframe.html": [ [ {} ] ], - "wasm/serialization/resources/broadcastchannel-sharedworker.js": [ + "wasm/serialization/module/resources/broadcastchannel-sharedworker.js": [ [ {} ] ], - "wasm/serialization/resources/broadcastchannel-worker.js": [ + "wasm/serialization/module/resources/broadcastchannel-worker.js": [ [ {} ] ], - "wasm/serialization/resources/create-empty-wasm-module.js": [ + "wasm/serialization/module/resources/create-empty-wasm-module.js": [ [ {} ] ], - "wasm/serialization/resources/echo-iframe.html": [ + "wasm/serialization/module/resources/echo-iframe.html": [ [ {} ] ], - "wasm/serialization/resources/echo-worker.js": [ + "wasm/serialization/module/resources/echo-worker.js": [ [ {} ] ], - "wasm/serialization/resources/incrementer-iframe-domain.sub.html": [ + "wasm/serialization/module/resources/incrementer-iframe-domain.sub.html": [ [ {} ] ], - "wasm/serialization/resources/incrementer-iframe.html": [ + "wasm/serialization/module/resources/incrementer-iframe.html": [ [ {} ] ], - "wasm/serialization/resources/incrementer-popup.html": [ + "wasm/serialization/module/resources/incrementer-popup.html": [ [ {} ] ], - "wasm/serialization/resources/incrementer-worker-with-channel.js": [ + "wasm/serialization/module/resources/incrementer-worker-with-channel.js": [ [ {} ] ], - "wasm/serialization/resources/incrementer-worker.js": [ + "wasm/serialization/module/resources/incrementer-worker.js": [ [ {} ] ], - "wasm/serialization/resources/incrementer.wasm": [ + "wasm/serialization/module/resources/incrementer.wasm": [ [ {} ] ], - "wasm/serialization/resources/nested-iframe-1.html": [ + "wasm/serialization/module/resources/nested-iframe-1.html": [ [ {} ] ], - "wasm/serialization/resources/nested-iframe-2.html": [ + "wasm/serialization/module/resources/nested-iframe-2.html": [ [ {} ] ], - "wasm/serialization/resources/nested-iframe-3.html": [ + "wasm/serialization/module/resources/nested-iframe-3.html": [ [ {} ] ], - "wasm/serialization/resources/nested-iframe-4-incrementer.html": [ + "wasm/serialization/module/resources/nested-iframe-4-incrementer.html": [ [ {} ] ], - "wasm/serialization/resources/serviceworker-failure.js": [ + "wasm/serialization/module/resources/serviceworker-failure.js": [ [ {} ] ], - "wasm/serialization/resources/sharedworker-failure.js": [ + "wasm/serialization/module/resources/sharedworker-failure.js": [ [ {} ] ], - "wasm/serialization/resources/test-incrementer.js": [ + "wasm/serialization/module/resources/test-incrementer.js": [ [ {} ] @@ -238881,6 +238918,18 @@ {} ] ], + "html/semantics/document-metadata/the-link-element/link-multiple-error-events.html": [ + [ + "/html/semantics/document-metadata/the-link-element/link-multiple-error-events.html", + {} + ] + ], + "html/semantics/document-metadata/the-link-element/link-multiple-load-events.html": [ + [ + "/html/semantics/document-metadata/the-link-element/link-multiple-load-events.html", + {} + ] + ], "html/semantics/document-metadata/the-link-element/link-rel-attribute.html": [ [ "/html/semantics/document-metadata/the-link-element/link-rel-attribute.html", @@ -281517,99 +281566,99 @@ {} ] ], - "wasm/serialization/broadcastchannel-success-and-failure.html": [ + "wasm/serialization/module/broadcastchannel-success-and-failure.html": [ [ - "/wasm/serialization/broadcastchannel-success-and-failure.html", + "/wasm/serialization/module/broadcastchannel-success-and-failure.html", {} ] ], - "wasm/serialization/broadcastchannel-success.html": [ + "wasm/serialization/module/broadcastchannel-success.html": [ [ - "/wasm/serialization/broadcastchannel-success.html", + "/wasm/serialization/module/broadcastchannel-success.html", {} ] ], - "wasm/serialization/identity-not-preserved.html": [ + "wasm/serialization/module/identity-not-preserved.html": [ [ - "/wasm/serialization/identity-not-preserved.html", + "/wasm/serialization/module/identity-not-preserved.html", {} ] ], - "wasm/serialization/nested-worker-success.any.js": [ + "wasm/serialization/module/nested-worker-success.any.js": [ [ - "/wasm/serialization/nested-worker-success.any.sharedworker.html", + "/wasm/serialization/module/nested-worker-success.any.sharedworker.html", {} ], [ - "/wasm/serialization/nested-worker-success.any.worker.html", + "/wasm/serialization/module/nested-worker-success.any.worker.html", {} ] ], - "wasm/serialization/no-transferring.html": [ + "wasm/serialization/module/no-transferring.html": [ [ - "/wasm/serialization/no-transferring.html", + "/wasm/serialization/module/no-transferring.html", {} ] ], - "wasm/serialization/serialization-via-history.html": [ + "wasm/serialization/module/serialization-via-history.html": [ [ - "/wasm/serialization/serialization-via-history.html", + "/wasm/serialization/module/serialization-via-history.html", {} ] ], - "wasm/serialization/serialization-via-idb.any.js": [ + "wasm/serialization/module/serialization-via-idb.any.js": [ [ - "/wasm/serialization/serialization-via-idb.any.html", + "/wasm/serialization/module/serialization-via-idb.any.html", {} ], [ - "/wasm/serialization/serialization-via-idb.any.worker.html", + "/wasm/serialization/module/serialization-via-idb.any.worker.html", {} ] ], - "wasm/serialization/serialization-via-notifications-api.any.js": [ + "wasm/serialization/module/serialization-via-notifications-api.any.js": [ [ - "/wasm/serialization/serialization-via-notifications-api.any.html", + "/wasm/serialization/module/serialization-via-notifications-api.any.html", {} ], [ - "/wasm/serialization/serialization-via-notifications-api.any.worker.html", + "/wasm/serialization/module/serialization-via-notifications-api.any.worker.html", {} ] ], - "wasm/serialization/window-domain-success.sub.html": [ + "wasm/serialization/module/window-domain-success.sub.html": [ [ - "/wasm/serialization/window-domain-success.sub.html", + "/wasm/serialization/module/window-domain-success.sub.html", {} ] ], - "wasm/serialization/window-messagechannel-success.html": [ + "wasm/serialization/module/window-messagechannel-success.html": [ [ - "/wasm/serialization/window-messagechannel-success.html", + "/wasm/serialization/module/window-messagechannel-success.html", {} ] ], - "wasm/serialization/window-serviceworker-failure.https.html": [ + "wasm/serialization/module/window-serviceworker-failure.https.html": [ [ - "/wasm/serialization/window-serviceworker-failure.https.html", + "/wasm/serialization/module/window-serviceworker-failure.https.html", {} ] ], - "wasm/serialization/window-sharedworker-failure.html": [ + "wasm/serialization/module/window-sharedworker-failure.html": [ [ - "/wasm/serialization/window-sharedworker-failure.html", + "/wasm/serialization/module/window-sharedworker-failure.html", {} ] ], - "wasm/serialization/window-similar-but-cross-origin-success.sub.html": [ + "wasm/serialization/module/window-similar-but-cross-origin-success.sub.html": [ [ - "/wasm/serialization/window-similar-but-cross-origin-success.sub.html", + "/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html", {} ] ], - "wasm/serialization/window-simple-success.html": [ + "wasm/serialization/module/window-simple-success.html": [ [ - "/wasm/serialization/window-simple-success.html", + "/wasm/serialization/module/window-simple-success.html", {} ] ], @@ -330738,6 +330787,14 @@ "8a48fe357b9f4cab09d7e59e28f0560cf2235e41", "support" ], + "css/css-backgrounds/child-move-reveals-parent-background-ref.html": [ + "10324966edb042c1c7298ce22dad76766c2a777b", + "support" + ], + "css/css-backgrounds/child-move-reveals-parent-background.html": [ + "e369eccd07f3c7c4146b1a419d5b110ff6d0eb7c", + "reftest" + ], "css/css-backgrounds/color-behind-images.htm": [ "170380aa8e12ad2685e31d507851de352b90d1f8", "visual" @@ -334403,7 +334460,7 @@ "testharness" ], "css/css-env/supports-script.tentative.html": [ - "ec9b6d0dfe61f91d8e8869e71cd170f45c6631f3", + "7ab4db23a373ac5cea9e217b2dc3b15fab12fbb0", "testharness" ], "css/css-env/syntax.tentative.html": [ @@ -358271,39 +358328,39 @@ "reftest" ], "css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html": [ - "cf7c5a44415f3514598bbf386ac6fadebd63a2c5", + "def6adf0da7d6e35a7a88d086d3df19cfaca7b3e", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-cj-normal.html": [ - "7c701c8546d3d057d9fdf65c12bd4a43ac68dc64", + "bc204f5377d9a8477e81d7215148612f4805ddc8", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-cj-strict.html": [ - "9fe18046fcd897eb3c7acd66785e9d8afea7075c", + "cdb8398248238c6266c883db8aeaaa243013694a", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose.html": [ - "6120e62cc9b39b0197b171b51b6e45937f5a1684", + "c932cb4fa3f5b01284f4e4ae2b0fc0637d0b12a5", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-cpm-normal.html": [ - "1e1d4bb683b5c87d609418640d6bd000f2545d9c", + "7816fb53b0bca5cf52672802fb005be89c9f3b8b", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-cpm-strict.html": [ - "ddf3c2cc9609e650a5f3816a61a5eb6acd71633d", + "833e45e6b58ac2aee90967a706a3ae82d122a224", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-hyphens-loose.html": [ - "647bfc8a675942d299647c32e3730fe61d2afa33", + "fbb13ec8c34e43e57273e3b826598f9cfaa84ef2", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-hyphens-normal.html": [ - "5e22458f9351669b38d90632f475ca25682db2bb", + "dc22d6161f08ed57baec7ed41f0f62cb1222327e", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html": [ - "3db8bb8804daade32849334e21cea38e758671fa", + "cd5d5aa939535f5b52f579c35e2bfa1730918875", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt": [ @@ -358311,39 +358368,39 @@ "support" ], "css/css-text/i18n/ja/css-text-line-break-ja-in-loose.html": [ - "09c5758d79aa386817ac2e7e6c7a162399f8790d", + "235d38177cbb91cf6f6f3f4d512593516409f770", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-in-normal.html": [ - "8bf3aa9016d1f213f340a5c4a7fa0a09a8b6ea7d", + "7bdedd5a82f8ce37cb2ea57f24efd9058eebf8ef", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-in-strict.html": [ - "3c14e183d84bc048954a9474b07aae01e87f12b9", + "58c05bb0868a0154c8caabb9bb744786c59a527e", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-iteration-loose.html": [ - "dbf77a0f806410c8d6fb95c3ce260a57c5716a21", + "49f51f4b7d29107a20b31d81131459cf86d84d9d", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-iteration-normal.html": [ - "ecdcdc31733b3b765fbb087a5c22c1dfde98531a", + "55f54ea84b193a9595287baa12231c7fa3ae754d", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-iteration-strict.html": [ - "3b2a2ee9eb19b49c17c3ead23cdae9d84ef36961", + "1c2cd9a5d430fbc3df261b107c47614477f52fae", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-po-loose.html": [ - "795cb0230b6eaed306a621a7b9ef7c2cb626a04f", + "4d79a1227801f47b317d5b18e117b38a8bc65d86", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-po-normal.html": [ - "7c591eb936a13a8a4de8a83ec5d40fe07de183b2", + "eb3003c27212b637df0b5f390447d5c3ee62928b", "testharness" ], "css/css-text/i18n/ja/css-text-line-break-ja-po-strict.html": [ - "c41ea732a8919954ebd77fe76c883f9e6379f08e", + "08e16f26321bab7ca03f2cfe6eddd0c324d765dc", "testharness" ], "css/css-text/i18n/reference/css3-text-line-break-opclns-001-ref.html": [ @@ -359063,27 +359120,27 @@ "support" ], "css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose.html": [ - "b9f81eeecf5b0341da049f6f1b0eabec29b4f601", + "4044e10666d15573fa4d7b3d455b956895eae19e", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-cpm-normal.html": [ - "7d2af701422cad0e054aead632ae24c2dae9ffe9", + "01096b26bae5e195788d6f87f55bb267c73cd938", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-cpm-strict.html": [ - "069212e628e376276159795c1da4335c76e6f141", + "8460aaa0de7137999b9f2ca89435d9e71ccb6902", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-hyphens-loose.html": [ - "70ebdc0898b19e8af303f2a7c3769f8305946ca6", + "724f77692a47b6c3fa9d97955cd5f1f1ce446924", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-hyphens-normal.html": [ - "8fd631efb3f2dcad9a44fbef8fb722a27dc1cd25", + "e89c9b8b85cf4a5f404965e777d4bfeeb9a98186", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-hyphens-strict.html": [ - "91f261018b174d352a50829cc9e830201893d660", + "b9585d77aba7c830fc95ecaab51115931acf85dd", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt": [ @@ -359091,39 +359148,39 @@ "support" ], "css/css-text/i18n/zh/css-text-line-break-zh-in-loose.html": [ - "4f163719ae7ef7d95d360c68db9e84da660bef5b", + "e7686617a0a893f2280efe794095776961cce164", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-in-normal.html": [ - "bb0df2e8fc1dea46c97f7c76bcaab59631374b5c", + "a9409cfe8d7aab5b8308fca9b56d6addf6f30a83", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-in-strict.html": [ - "965d5133fab10083f6772502f7e4b7855dedfa07", + "defdf223074b76ef4783bb63c7bafbd226927b67", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-iteration-loose.html": [ - "72c476cdce7db0d2e97cdb4a6c38ccf53590bf64", + "64f821925c01fa471ac31c20f802b75a349c24a4", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-iteration-normal.html": [ - "92ac2e020911c3d6dc2b9a9df6c7816e07d46521", + "a7f66ea2b6b027ec8afcffc3983e6e5f939b9d02", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-iteration-strict.html": [ - "22ac4baf03bf59f9f0a4623bcd83a004a33f1db9", + "0b1ca2a6c16beaa6f557add655b9d12a5833bb12", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-po-loose.html": [ - "0e0280505fa2219b6c0ac7a1e0ef0838e72cc228", + "04a0f4d620f4a450db84fc4cea627191f0b840f4", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-po-normal.html": [ - "490e4067a4042b81304d8b6c4925da7371142762", + "5a52cf853e29e7c056e6f092252d2bbefc2e8704", "testharness" ], "css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html": [ - "ec44c093a32decdc7bd39b77d7409fff36b62f4b", + "d85b74a54056166cedbf04f694d681ef95fff9b4", "testharness" ], "css/css-text/inheritance-expected.txt": [ @@ -380315,7 +380372,7 @@ "support" ], "css/cssom/CSS.html": [ - "7d558f04466ffad77e36f8aaa90abd220a24c27b", + "ba048c58acaac5cd2550fb21cb9b6e9ee8fb0bb1", "testharness" ], "css/cssom/CSSKeyframeRule.html": [ @@ -407682,6 +407739,14 @@ "a809cc44b19796e50b7564b852a3234cca7e51f0", "testharness" ], + "html/semantics/document-metadata/the-link-element/link-multiple-error-events.html": [ + "ea7e496ae8ea36f4241f565714952f4ac2c1968a", + "testharness" + ], + "html/semantics/document-metadata/the-link-element/link-multiple-load-events.html": [ + "24cd5ba701184308d7fe28195119552d6431b87d", + "testharness" + ], "html/semantics/document-metadata/the-link-element/link-rel-attribute.html": [ "14d06227ac862be169c2c1745fd6ec8913836394", "testharness" @@ -447258,10 +447323,26 @@ "2bf9eabed8410c9352a70163c8f40e25811dfd0f", "testharness" ], + "streams/writable-streams/aborting.any-expected.txt": [ + "f2ded616cec362b3d8e95eea45ad9e15a7fdd01f", + "support" + ], "streams/writable-streams/aborting.any.js": [ - "18fb58edf6de41d5d6208997d94fb5ed9e00a1e0", + "ea47a55fa9ff61cdc2f0ac3caca1e98c7b2c719d", "testharness" ], + "streams/writable-streams/aborting.any.serviceworker-expected.txt": [ + "f2ded616cec362b3d8e95eea45ad9e15a7fdd01f", + "support" + ], + "streams/writable-streams/aborting.any.sharedworker-expected.txt": [ + "f2ded616cec362b3d8e95eea45ad9e15a7fdd01f", + "support" + ], + "streams/writable-streams/aborting.any.worker-expected.txt": [ + "f2ded616cec362b3d8e95eea45ad9e15a7fdd01f", + "support" + ], "streams/writable-streams/bad-strategies.any.js": [ "d67ee6b5039dc98e5093aef0c3f2820462112a4c", "testharness" @@ -447299,7 +447380,7 @@ "testharness" ], "streams/writable-streams/general.any.js": [ - "253909f27b42406f099f4539311fde0280a482fa", + "96670448a9da68ce54d1f3ecf8b2ba38b2673c73", "testharness" ], "streams/writable-streams/properties.any-expected.txt": [ @@ -450910,151 +450991,151 @@ "8316dcfbc89bd02073e4e08db1bee7f65d37e86c", "support" ], - "wasm/serialization/broadcastchannel-success-and-failure.html": [ + "wasm/serialization/module/broadcastchannel-success-and-failure.html": [ "0d11cc595be2d16ad795be8199ed2ae7abe79974", "testharness" ], - "wasm/serialization/broadcastchannel-success.html": [ + "wasm/serialization/module/broadcastchannel-success.html": [ "cd5f8d0b56a19148dbd01b4218869f1f0c3526fd", "testharness" ], - "wasm/serialization/identity-not-preserved.html": [ + "wasm/serialization/module/identity-not-preserved.html": [ "24bb3b16d8c50600a634d62d4c48c49dfb3b120e", "testharness" ], - "wasm/serialization/incrementer.wasm": [ + "wasm/serialization/module/incrementer.wasm": [ "47afcdef2a2812acccecd0f203d30d3023593f3d", "support" ], - "wasm/serialization/nested-worker-success-sharedworker-expected.txt": [ + "wasm/serialization/module/nested-worker-success-sharedworker-expected.txt": [ "7b70ea298989ba1aeafd5cadeff2dd50b97c56e2", "support" ], - "wasm/serialization/nested-worker-success.any.js": [ + "wasm/serialization/module/nested-worker-success.any.js": [ "5388ebcc39b22946957250004577a1966c264a5a", "testharness" ], - "wasm/serialization/nested-worker-success.any.sharedworker-expected.txt": [ + "wasm/serialization/module/nested-worker-success.any.sharedworker-expected.txt": [ "7b70ea298989ba1aeafd5cadeff2dd50b97c56e2", "support" ], - "wasm/serialization/no-transferring.html": [ + "wasm/serialization/module/no-transferring.html": [ "a0bf11f01dd459b2e3abeb249f725e1e05d1532f", "testharness" ], - "wasm/serialization/resources/blank.html": [ + "wasm/serialization/module/resources/blank.html": [ "a3c3a4689a62b45b1e429f6b7a94690e556a1259", "support" ], - "wasm/serialization/resources/broadcastchannel-iframe.html": [ + "wasm/serialization/module/resources/broadcastchannel-iframe.html": [ "83e347b5cb35c92aa3cd96263a68b56af366f0e3", "support" ], - "wasm/serialization/resources/broadcastchannel-sharedworker.js": [ + "wasm/serialization/module/resources/broadcastchannel-sharedworker.js": [ "310e0e9358446acaec0f13d8e2fb4437316953c2", "support" ], - "wasm/serialization/resources/broadcastchannel-worker.js": [ + "wasm/serialization/module/resources/broadcastchannel-worker.js": [ "76a8177060498547ab1661319c20d5d5288cd96f", "support" ], - "wasm/serialization/resources/create-empty-wasm-module.js": [ + "wasm/serialization/module/resources/create-empty-wasm-module.js": [ "7326710c9e47d756bbdab1ead2303b108b8f04db", "support" ], - "wasm/serialization/resources/echo-iframe.html": [ + "wasm/serialization/module/resources/echo-iframe.html": [ "c4fd5824a1c617c21fe8b92483b388d586edf06e", "support" ], - "wasm/serialization/resources/echo-worker.js": [ + "wasm/serialization/module/resources/echo-worker.js": [ "cbbde8a73c8c2a63cc97cbe2b6cd7c6d81585b5c", "support" ], - "wasm/serialization/resources/incrementer-iframe-domain.sub.html": [ + "wasm/serialization/module/resources/incrementer-iframe-domain.sub.html": [ "d2d18de49950c2508a69545ad95a937898b04532", "support" ], - "wasm/serialization/resources/incrementer-iframe.html": [ + "wasm/serialization/module/resources/incrementer-iframe.html": [ "5c8bc0735e207a7c18f12d578276ae3c3b999da5", "support" ], - "wasm/serialization/resources/incrementer-popup.html": [ + "wasm/serialization/module/resources/incrementer-popup.html": [ "660e472b27c086068edeb7fd2bcade536c4bd5e9", "support" ], - "wasm/serialization/resources/incrementer-worker-with-channel.js": [ + "wasm/serialization/module/resources/incrementer-worker-with-channel.js": [ "0323b3e52e75e894ae40ffc68e904ffc81ded024", "support" ], - "wasm/serialization/resources/incrementer-worker.js": [ + "wasm/serialization/module/resources/incrementer-worker.js": [ "1779ceea520ccfd07da6d595d8a34be62de89428", "support" ], - "wasm/serialization/resources/incrementer.wasm": [ + "wasm/serialization/module/resources/incrementer.wasm": [ "47afcdef2a2812acccecd0f203d30d3023593f3d", "support" ], - "wasm/serialization/resources/nested-iframe-1.html": [ + "wasm/serialization/module/resources/nested-iframe-1.html": [ "fe93cc0c4b0fe5b86bf1a12de84fb3fc48ea08a5", "support" ], - "wasm/serialization/resources/nested-iframe-2.html": [ + "wasm/serialization/module/resources/nested-iframe-2.html": [ "fad52ce9de3977c077b5a22e72ee7b23837ea302", "support" ], - "wasm/serialization/resources/nested-iframe-3.html": [ + "wasm/serialization/module/resources/nested-iframe-3.html": [ "7971022b2cdc315d598761a3694838494c2884a8", "support" ], - "wasm/serialization/resources/nested-iframe-4-incrementer.html": [ + "wasm/serialization/module/resources/nested-iframe-4-incrementer.html": [ "f419f4bc36cdffafa665e333a7e7bced3d153585", "support" ], - "wasm/serialization/resources/serviceworker-failure.js": [ + "wasm/serialization/module/resources/serviceworker-failure.js": [ "39796f9d94a39d2a13ed832544ce781373a20655", "support" ], - "wasm/serialization/resources/sharedworker-failure.js": [ + "wasm/serialization/module/resources/sharedworker-failure.js": [ "854c70b9e84e6e6fb1c59f64a06a79646a122576", "support" ], - "wasm/serialization/resources/test-incrementer.js": [ + "wasm/serialization/module/resources/test-incrementer.js": [ "65cb33227a37376c1a0134275d5079d442b443a9", "support" ], - "wasm/serialization/serialization-via-history.html": [ + "wasm/serialization/module/serialization-via-history.html": [ "35dc17b6701fadf920ce251ec6c63da1c26b6570", "testharness" ], - "wasm/serialization/serialization-via-idb.any.js": [ + "wasm/serialization/module/serialization-via-idb.any.js": [ "1d861c3d3aa1072b1c90332fec7ac993d3b59552", "testharness" ], - "wasm/serialization/serialization-via-notifications-api.any.js": [ + "wasm/serialization/module/serialization-via-notifications-api.any.js": [ "84105651d3b53192f453b9f16bb85163165495cb", "testharness" ], - "wasm/serialization/window-domain-success.sub.html": [ - "51d4c5cb0ea0c0c5cf69530876c2f7c19bb3830a", + "wasm/serialization/module/window-domain-success.sub.html": [ + "07360d8264df01e20123697bf2e635fc66ebacfe", "testharness" ], - "wasm/serialization/window-messagechannel-success.html": [ + "wasm/serialization/module/window-messagechannel-success.html": [ "e686c8113561d94e860a774771aa69b974696716", "testharness" ], - "wasm/serialization/window-serviceworker-failure.https.html": [ + "wasm/serialization/module/window-serviceworker-failure.https.html": [ "97c5a1decdb85317930508ece8f306fb80880ca2", "testharness" ], - "wasm/serialization/window-sharedworker-failure.html": [ + "wasm/serialization/module/window-sharedworker-failure.html": [ "667e985a30b53c0ecadfd4c68f6217b87a7a5b98", "testharness" ], - "wasm/serialization/window-similar-but-cross-origin-success.sub.html": [ - "070cf0a49a8f0c0ede81b6751e727b44f36c0043", + "wasm/serialization/module/window-similar-but-cross-origin-success.sub.html": [ + "a615547de09634632c1115180534bea5594835e3", "testharness" ], - "wasm/serialization/window-simple-success.html": [ + "wasm/serialization/module/window-simple-success.html": [ "6f2ccf465e93a160c73df548fc58774a5040f0e6", "testharness" ],
diff --git a/third_party/blink/web_tests/external/wpt/performance-timeline/po-observe-type.any.js b/third_party/blink/web_tests/external/wpt/performance-timeline/po-observe-type.any.js new file mode 100644 index 0000000..5cdac97 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/performance-timeline/po-observe-type.any.js
@@ -0,0 +1,54 @@ +// META: script=performanceobservers.js + +test(() => { + const obs = new PerformanceObserver(() =>{}); + obs.observe({entryTypes: ["mark"]}); + assert_throws('InvalidModificationError', function () { + obs.observe({type: "measure"}); + }); +}, "Calling observe() with entryTypes and then type should throw an InvalidModificationError"); + +test(() => { + const obs = new PerformanceObserver(() =>{}); + obs.observe({type: "mark"}); + assert_throws('InvalidModificationError', function () { + obs.observe({entryTypes: ["measure"]}); + }); +}, "Calling observe() with type and then entryTypes should throw an InvalidModificationError"); + +test(() => { + const obs = new PerformanceObserver(() =>{}); + assert_throws(new SyntaxError(), function () { + obs.observe({type: "mark", entryTypes: ["measure"]}); + }); +}, "Calling observe() with type and entryTypes should throw a SyntaxError"); + +test(function () { + const obs = new PerformanceObserver(() =>{}); + // Definitely not an entry type. + obs.observe({type: "this-cannot-match-an-entryType"}); + // Close to an entry type, but not quite. + obs.observe({type: "marks"}); +}, "Passing in unknown values to type does throw an exception."); + +async_test(function (t) { + let observedMark = false; + let observedMeasure = false; + const observer = new PerformanceObserver( + t.step_func(function (entryList, obs) { + observedMark |= entryList.getEntries().filter( + entry => entry.entryType === 'mark').length; + observedMeasure |= entryList.getEntries().filter( + entry => entry.entryType === 'measure').length + // Only conclude the test once we receive both entries! + if (observedMark && observedMeasure) { + observer.disconnect(); + t.done(); + } + }) + ); + observer.observe({type: "mark"}); + observer.observe({type: "measure"}); + self.performance.mark("mark1"); + self.performance.measure("measure1"); +}, "observe() with different type values stacks.");
diff --git a/third_party/blink/web_tests/external/wpt/performance-timeline/po-observe.any.js b/third_party/blink/web_tests/external/wpt/performance-timeline/po-observe.any.js index 8520c26..6a673db 100644 --- a/third_party/blink/web_tests/external/wpt/performance-timeline/po-observe.any.js +++ b/third_party/blink/web_tests/external/wpt/performance-timeline/po-observe.any.js
@@ -2,13 +2,13 @@ test(function () { var obs = new PerformanceObserver(function () { return true; }); - assert_throws(new TypeError(), function () { + assert_throws(new SyntaxError(), function () { obs.observe({}); }); - assert_throws(new TypeError(), function () { + assert_throws(new SyntaxError(), function () { obs.observe({entryType: []}); }); - }, "no entryTypes throws a TypeError"); + }, "no 'type' or 'entryTypes' throws a SyntaxError"); test(function () { var obs = new PerformanceObserver(function () { return true; }); assert_throws(new TypeError(), function () { @@ -19,13 +19,13 @@ test(function () { var obs = new PerformanceObserver(function () { return true; }); obs.observe({entryTypes: []}); - }, "Empty sequence entryTypes is a no-op"); + }, "Empty sequence entryTypes does not throw an exception."); test(function () { var obs = new PerformanceObserver(function () { return true; }); obs.observe({entryTypes: ["this-cannot-match-an-entryType"]}); obs.observe({entryTypes: ["marks","navigate", "resources"]}); - }, "Unknown entryTypes are no-op"); + }, "Unknown entryTypes do not throw an exception."); test(function () { var obs = new PerformanceObserver(function () { return true; });
diff --git a/third_party/blink/web_tests/external/wpt/portals/portals-cross-origin-load.sub.html b/third_party/blink/web_tests/external/wpt/portals/portals-cross-origin-load.sub.html new file mode 100644 index 0000000..f860ac5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/portals/portals-cross-origin-load.sub.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> + promise_test(async () => { + var bc = new BroadcastChannel("portals-cross-origin-load"); + var receiveMessage = new Promise((resolve, reject) => { + bc.onmessage = e => { + bc.close(); + resolve(); + } + }); + var portal = document.createElement("portal"); + portal.src = "http://{{hosts[alt][www]}}:{{ports[http][0]}}/portals/resources/portal-cross-origin.sub.html"; + document.body.appendChild(portal); + return receiveMessage; + }); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/portals/resources/portal-cross-origin.sub.html b/third_party/blink/web_tests/external/wpt/portals/resources/portal-cross-origin.sub.html new file mode 100644 index 0000000..145ab5a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/portals/resources/portal-cross-origin.sub.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<body> + <script> + var iframe = document.createElement("iframe"); + iframe.src = "http://{{host}}:{{ports[http][0]}}/portals/resources/portal-forward-with-broadcast.html?broadcastchannel=portals-cross-origin-load"; + iframe.onload = e => { + iframe.contentWindow.postMessage("loaded", "*"); + } + document.body.appendChild(iframe); + </script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/portals/resources/portal-forward-with-broadcast.html b/third_party/blink/web_tests/external/wpt/portals/resources/portal-forward-with-broadcast.html new file mode 100644 index 0000000..39bda69 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/portals/resources/portal-forward-with-broadcast.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<body> + <script> + function forwardMessage(e) { + let broadcastChannel = new BroadcastChannel(new URL(location).searchParams.get('broadcastchannel')); + try { + broadcastChannel.postMessage(e.data); + } finally { + broadcastChannel.close(); + } + } + window.addEventListener("message", forwardMessage); + </script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any-expected.txt new file mode 100644 index 0000000..f2ded61 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any-expected.txt
@@ -0,0 +1,59 @@ +This is a testharness.js-based test. +Found 55 tests; 54 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS Aborting a WritableStream before it starts should cause the writer's unsettled ready promise to reject +PASS Aborting a WritableStream should cause the writer's fulfilled ready promise to reset to a rejected one +PASS abort() on a released writer rejects +PASS Aborting a WritableStream immediately prevents future writes +PASS Aborting a WritableStream prevents further writes after any that are in progress +PASS Fulfillment value of ws.abort() call must be undefined even if the underlying sink returns a non-undefined value +PASS WritableStream if sink's abort throws, the promise returned by writer.abort() rejects +PASS WritableStream if sink's abort throws, the promise returned by multiple writer.abort()s is the same and rejects +PASS WritableStream if sink's abort throws, the promise returned by ws.abort() rejects +PASS WritableStream if sink's abort throws, for an abort performed during a write, the promise returned by ws.abort() rejects +PASS Aborting a WritableStream passes through the given reason +PASS Aborting a WritableStream puts it in an errored state with the error passed to abort() +PASS Aborting a WritableStream causes any outstanding write() promises to be rejected with the reason supplied +PASS Closing but then immediately aborting a WritableStream causes the stream to error +PASS Closing a WritableStream and aborting it while it closes causes the stream to ignore the abort attempt +PASS Aborting a WritableStream after it is closed is a no-op +PASS WritableStream should NOT call underlying sink's close if no abort is supplied (historical) +PASS returning a thenable from abort() should work +PASS .closed should not resolve before fulfilled write() +PASS .closed should not resolve before rejected write(); write() error should not overwrite abort() error +PASS writes should be satisfied in order when aborting +PASS writes should be satisfied in order after rejected write when aborting +PASS close() should reject with abort reason why abort() is first error +PASS underlying abort() should not be called until underlying write() completes +PASS underlying abort() should not be called if underlying close() has started +PASS if underlying close() has started and then rejects, the abort() and close() promises should reject with the underlying close rejection reason +PASS an abort() that happens during a write() should trigger the underlying abort() even with a close() queued +PASS if a writer is created for a stream with a pending abort, its ready should be rejected with the abort error +PASS writer close() promise should resolve before abort() promise +PASS writer.ready should reject on controller error without waiting for underlying write +PASS writer.abort() while there is an in-flight write, and then finish the write with rejection +PASS writer.abort(), controller.error() while there is an in-flight write, and then finish the write +PASS writer.abort(), controller.error() while there is an in-flight close, and then finish the close +PASS controller.error(), writer.abort() while there is an in-flight write, and then finish the write +PASS controller.error(), writer.abort() while there is an in-flight close, and then finish the close +PASS releaseLock() while aborting should reject the original closed promise +PASS releaseLock() during delayed async abort() should reject the writer.closed promise +PASS sink abort() should not be called until sink start() is done +PASS if start attempts to error the controller after abort() has been called, then it should lose +PASS stream abort() promise should still resolve if sink start() rejects +PASS writer abort() during sink start() should replace the writer.ready promise synchronously +PASS promises returned from other writer methods should be rejected when writer abort() happens during sink start() +PASS abort() should succeed despite rejection from write +PASS abort() should be rejected with the rejection returned from close() +PASS a rejecting sink.write() should not prevent sink.abort() from being called +PASS when start errors after stream abort(), underlying sink abort() should be called anyway +PASS when calling abort() twice on the same stream, both should give the same promise that fulfills with undefined +PASS when calling abort() twice on the same stream, but sequentially so so there's no pending abort the second time, both should fulfill with undefined +PASS calling abort() on an errored stream should fulfill with undefined +PASS sink abort() should not be called if stream was erroring due to controller.error() before abort() was called +PASS sink abort() should not be called if stream was erroring due to bad strategy before abort() was called +PASS abort with no arguments should set the stored error to undefined +PASS abort with an undefined argument should set the stored error to undefined +PASS abort with a string argument should set the stored error to that argument +FAIL abort on a locked stream should reject promise_test: Unhandled rejection with value: undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.js index 18fb58e..ea47a55 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.js
@@ -1368,3 +1368,10 @@ e => assert_equals(e, 'string argument', 'e should be \'string argument\'')); }); }, 'abort with a string argument should set the stored error to that argument'); + +promise_test(t => { + const ws = new WritableStream(); + const writer = ws.getWriter(); + return promise_rejects(t, new TypeError(), ws.abort(), 'abort should reject') + .then(() => writer.ready); +}, 'abort on a locked stream should reject');
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.serviceworker-expected.txt new file mode 100644 index 0000000..f2ded61 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.serviceworker-expected.txt
@@ -0,0 +1,59 @@ +This is a testharness.js-based test. +Found 55 tests; 54 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS Aborting a WritableStream before it starts should cause the writer's unsettled ready promise to reject +PASS Aborting a WritableStream should cause the writer's fulfilled ready promise to reset to a rejected one +PASS abort() on a released writer rejects +PASS Aborting a WritableStream immediately prevents future writes +PASS Aborting a WritableStream prevents further writes after any that are in progress +PASS Fulfillment value of ws.abort() call must be undefined even if the underlying sink returns a non-undefined value +PASS WritableStream if sink's abort throws, the promise returned by writer.abort() rejects +PASS WritableStream if sink's abort throws, the promise returned by multiple writer.abort()s is the same and rejects +PASS WritableStream if sink's abort throws, the promise returned by ws.abort() rejects +PASS WritableStream if sink's abort throws, for an abort performed during a write, the promise returned by ws.abort() rejects +PASS Aborting a WritableStream passes through the given reason +PASS Aborting a WritableStream puts it in an errored state with the error passed to abort() +PASS Aborting a WritableStream causes any outstanding write() promises to be rejected with the reason supplied +PASS Closing but then immediately aborting a WritableStream causes the stream to error +PASS Closing a WritableStream and aborting it while it closes causes the stream to ignore the abort attempt +PASS Aborting a WritableStream after it is closed is a no-op +PASS WritableStream should NOT call underlying sink's close if no abort is supplied (historical) +PASS returning a thenable from abort() should work +PASS .closed should not resolve before fulfilled write() +PASS .closed should not resolve before rejected write(); write() error should not overwrite abort() error +PASS writes should be satisfied in order when aborting +PASS writes should be satisfied in order after rejected write when aborting +PASS close() should reject with abort reason why abort() is first error +PASS underlying abort() should not be called until underlying write() completes +PASS underlying abort() should not be called if underlying close() has started +PASS if underlying close() has started and then rejects, the abort() and close() promises should reject with the underlying close rejection reason +PASS an abort() that happens during a write() should trigger the underlying abort() even with a close() queued +PASS if a writer is created for a stream with a pending abort, its ready should be rejected with the abort error +PASS writer close() promise should resolve before abort() promise +PASS writer.ready should reject on controller error without waiting for underlying write +PASS writer.abort() while there is an in-flight write, and then finish the write with rejection +PASS writer.abort(), controller.error() while there is an in-flight write, and then finish the write +PASS writer.abort(), controller.error() while there is an in-flight close, and then finish the close +PASS controller.error(), writer.abort() while there is an in-flight write, and then finish the write +PASS controller.error(), writer.abort() while there is an in-flight close, and then finish the close +PASS releaseLock() while aborting should reject the original closed promise +PASS releaseLock() during delayed async abort() should reject the writer.closed promise +PASS sink abort() should not be called until sink start() is done +PASS if start attempts to error the controller after abort() has been called, then it should lose +PASS stream abort() promise should still resolve if sink start() rejects +PASS writer abort() during sink start() should replace the writer.ready promise synchronously +PASS promises returned from other writer methods should be rejected when writer abort() happens during sink start() +PASS abort() should succeed despite rejection from write +PASS abort() should be rejected with the rejection returned from close() +PASS a rejecting sink.write() should not prevent sink.abort() from being called +PASS when start errors after stream abort(), underlying sink abort() should be called anyway +PASS when calling abort() twice on the same stream, both should give the same promise that fulfills with undefined +PASS when calling abort() twice on the same stream, but sequentially so so there's no pending abort the second time, both should fulfill with undefined +PASS calling abort() on an errored stream should fulfill with undefined +PASS sink abort() should not be called if stream was erroring due to controller.error() before abort() was called +PASS sink abort() should not be called if stream was erroring due to bad strategy before abort() was called +PASS abort with no arguments should set the stored error to undefined +PASS abort with an undefined argument should set the stored error to undefined +PASS abort with a string argument should set the stored error to that argument +FAIL abort on a locked stream should reject promise_test: Unhandled rejection with value: undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.sharedworker-expected.txt new file mode 100644 index 0000000..f2ded61 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.sharedworker-expected.txt
@@ -0,0 +1,59 @@ +This is a testharness.js-based test. +Found 55 tests; 54 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS Aborting a WritableStream before it starts should cause the writer's unsettled ready promise to reject +PASS Aborting a WritableStream should cause the writer's fulfilled ready promise to reset to a rejected one +PASS abort() on a released writer rejects +PASS Aborting a WritableStream immediately prevents future writes +PASS Aborting a WritableStream prevents further writes after any that are in progress +PASS Fulfillment value of ws.abort() call must be undefined even if the underlying sink returns a non-undefined value +PASS WritableStream if sink's abort throws, the promise returned by writer.abort() rejects +PASS WritableStream if sink's abort throws, the promise returned by multiple writer.abort()s is the same and rejects +PASS WritableStream if sink's abort throws, the promise returned by ws.abort() rejects +PASS WritableStream if sink's abort throws, for an abort performed during a write, the promise returned by ws.abort() rejects +PASS Aborting a WritableStream passes through the given reason +PASS Aborting a WritableStream puts it in an errored state with the error passed to abort() +PASS Aborting a WritableStream causes any outstanding write() promises to be rejected with the reason supplied +PASS Closing but then immediately aborting a WritableStream causes the stream to error +PASS Closing a WritableStream and aborting it while it closes causes the stream to ignore the abort attempt +PASS Aborting a WritableStream after it is closed is a no-op +PASS WritableStream should NOT call underlying sink's close if no abort is supplied (historical) +PASS returning a thenable from abort() should work +PASS .closed should not resolve before fulfilled write() +PASS .closed should not resolve before rejected write(); write() error should not overwrite abort() error +PASS writes should be satisfied in order when aborting +PASS writes should be satisfied in order after rejected write when aborting +PASS close() should reject with abort reason why abort() is first error +PASS underlying abort() should not be called until underlying write() completes +PASS underlying abort() should not be called if underlying close() has started +PASS if underlying close() has started and then rejects, the abort() and close() promises should reject with the underlying close rejection reason +PASS an abort() that happens during a write() should trigger the underlying abort() even with a close() queued +PASS if a writer is created for a stream with a pending abort, its ready should be rejected with the abort error +PASS writer close() promise should resolve before abort() promise +PASS writer.ready should reject on controller error without waiting for underlying write +PASS writer.abort() while there is an in-flight write, and then finish the write with rejection +PASS writer.abort(), controller.error() while there is an in-flight write, and then finish the write +PASS writer.abort(), controller.error() while there is an in-flight close, and then finish the close +PASS controller.error(), writer.abort() while there is an in-flight write, and then finish the write +PASS controller.error(), writer.abort() while there is an in-flight close, and then finish the close +PASS releaseLock() while aborting should reject the original closed promise +PASS releaseLock() during delayed async abort() should reject the writer.closed promise +PASS sink abort() should not be called until sink start() is done +PASS if start attempts to error the controller after abort() has been called, then it should lose +PASS stream abort() promise should still resolve if sink start() rejects +PASS writer abort() during sink start() should replace the writer.ready promise synchronously +PASS promises returned from other writer methods should be rejected when writer abort() happens during sink start() +PASS abort() should succeed despite rejection from write +PASS abort() should be rejected with the rejection returned from close() +PASS a rejecting sink.write() should not prevent sink.abort() from being called +PASS when start errors after stream abort(), underlying sink abort() should be called anyway +PASS when calling abort() twice on the same stream, both should give the same promise that fulfills with undefined +PASS when calling abort() twice on the same stream, but sequentially so so there's no pending abort the second time, both should fulfill with undefined +PASS calling abort() on an errored stream should fulfill with undefined +PASS sink abort() should not be called if stream was erroring due to controller.error() before abort() was called +PASS sink abort() should not be called if stream was erroring due to bad strategy before abort() was called +PASS abort with no arguments should set the stored error to undefined +PASS abort with an undefined argument should set the stored error to undefined +PASS abort with a string argument should set the stored error to that argument +FAIL abort on a locked stream should reject promise_test: Unhandled rejection with value: undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.worker-expected.txt new file mode 100644 index 0000000..f2ded61 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/aborting.any.worker-expected.txt
@@ -0,0 +1,59 @@ +This is a testharness.js-based test. +Found 55 tests; 54 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS Aborting a WritableStream before it starts should cause the writer's unsettled ready promise to reject +PASS Aborting a WritableStream should cause the writer's fulfilled ready promise to reset to a rejected one +PASS abort() on a released writer rejects +PASS Aborting a WritableStream immediately prevents future writes +PASS Aborting a WritableStream prevents further writes after any that are in progress +PASS Fulfillment value of ws.abort() call must be undefined even if the underlying sink returns a non-undefined value +PASS WritableStream if sink's abort throws, the promise returned by writer.abort() rejects +PASS WritableStream if sink's abort throws, the promise returned by multiple writer.abort()s is the same and rejects +PASS WritableStream if sink's abort throws, the promise returned by ws.abort() rejects +PASS WritableStream if sink's abort throws, for an abort performed during a write, the promise returned by ws.abort() rejects +PASS Aborting a WritableStream passes through the given reason +PASS Aborting a WritableStream puts it in an errored state with the error passed to abort() +PASS Aborting a WritableStream causes any outstanding write() promises to be rejected with the reason supplied +PASS Closing but then immediately aborting a WritableStream causes the stream to error +PASS Closing a WritableStream and aborting it while it closes causes the stream to ignore the abort attempt +PASS Aborting a WritableStream after it is closed is a no-op +PASS WritableStream should NOT call underlying sink's close if no abort is supplied (historical) +PASS returning a thenable from abort() should work +PASS .closed should not resolve before fulfilled write() +PASS .closed should not resolve before rejected write(); write() error should not overwrite abort() error +PASS writes should be satisfied in order when aborting +PASS writes should be satisfied in order after rejected write when aborting +PASS close() should reject with abort reason why abort() is first error +PASS underlying abort() should not be called until underlying write() completes +PASS underlying abort() should not be called if underlying close() has started +PASS if underlying close() has started and then rejects, the abort() and close() promises should reject with the underlying close rejection reason +PASS an abort() that happens during a write() should trigger the underlying abort() even with a close() queued +PASS if a writer is created for a stream with a pending abort, its ready should be rejected with the abort error +PASS writer close() promise should resolve before abort() promise +PASS writer.ready should reject on controller error without waiting for underlying write +PASS writer.abort() while there is an in-flight write, and then finish the write with rejection +PASS writer.abort(), controller.error() while there is an in-flight write, and then finish the write +PASS writer.abort(), controller.error() while there is an in-flight close, and then finish the close +PASS controller.error(), writer.abort() while there is an in-flight write, and then finish the write +PASS controller.error(), writer.abort() while there is an in-flight close, and then finish the close +PASS releaseLock() while aborting should reject the original closed promise +PASS releaseLock() during delayed async abort() should reject the writer.closed promise +PASS sink abort() should not be called until sink start() is done +PASS if start attempts to error the controller after abort() has been called, then it should lose +PASS stream abort() promise should still resolve if sink start() rejects +PASS writer abort() during sink start() should replace the writer.ready promise synchronously +PASS promises returned from other writer methods should be rejected when writer abort() happens during sink start() +PASS abort() should succeed despite rejection from write +PASS abort() should be rejected with the rejection returned from close() +PASS a rejecting sink.write() should not prevent sink.abort() from being called +PASS when start errors after stream abort(), underlying sink abort() should be called anyway +PASS when calling abort() twice on the same stream, both should give the same promise that fulfills with undefined +PASS when calling abort() twice on the same stream, but sequentially so so there's no pending abort the second time, both should fulfill with undefined +PASS calling abort() on an errored stream should fulfill with undefined +PASS sink abort() should not be called if stream was erroring due to controller.error() before abort() was called +PASS sink abort() should not be called if stream was erroring due to bad strategy before abort() was called +PASS abort with no arguments should set the stored error to undefined +PASS abort with an undefined argument should set the stored error to undefined +PASS abort with a string argument should set the stored error to that argument +FAIL abort on a locked stream should reject promise_test: Unhandled rejection with value: undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/streams/writable-streams/general.any.js b/third_party/blink/web_tests/external/wpt/streams/writable-streams/general.any.js index 253909f2..9667044 100644 --- a/third_party/blink/web_tests/external/wpt/streams/writable-streams/general.any.js +++ b/third_party/blink/web_tests/external/wpt/streams/writable-streams/general.any.js
@@ -268,3 +268,10 @@ assert_true(sub.extraFunction(), 'extraFunction() should be present on Subclass object'); }, 'Subclassing WritableStream should work'); + +test(() => { + const ws = new WritableStream(); + assert_false(ws.locked, 'stream should not be locked'); + ws.getWriter(); + assert_true(ws.locked, 'stream should be locked'); +}, 'the locked getter should return true if the stream has a writer');
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/js/helpers.js b/third_party/blink/web_tests/external/wpt/webaudio/js/helpers.js index 5970b7b..fbbfc8e 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/js/helpers.js +++ b/third_party/blink/web_tests/external/wpt/webaudio/js/helpers.js
@@ -159,13 +159,8 @@ function testOnNormalContext(callback) { function testOutput(nodeToInspect, expectedBuffers, callback) { testLength = 0; - // While the spec allows ScriptProcessorNode's to have no outputs, it's - // not well specified, and Chrome requires the ScriptProcessorNode to - // be connected (directly or indirectly) to the destination. So make it - // so. This doesn't affect the tests using the function because the - // ScriptProcessorNode is what verifies the test. - var sp = context.createScriptProcessor(expectedBuffers[0].length, gTest.numberOfChannels, 1); - nodeToInspect.connect(sp).connect(context.destination); + var sp = context.createScriptProcessor(expectedBuffers[0].length, gTest.numberOfChannels, 0); + nodeToInspect.connect(sp); sp.onaudioprocess = function(e) { var expectedBuffer = expectedBuffers.shift(); testLength += expectedBuffer.length;
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html index 1b5531b..62d90da1 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html
@@ -10,17 +10,13 @@ var ac = new AudioContext(); var analyser = ac.createAnalyser(); var constant = ac.createConstantSource(); - // Chrome requires a ScriptProcessorNode to be connected to destination - // (directly or indirectly), so create the node with one output and connect - // it to the destination. This doesn't affect the test because the - // ScriptProcessorNode itself verifies the results. - var sp = ac.createScriptProcessor(2048, 1, 1); + var sp = ac.createScriptProcessor(2048, 1, 0); constant.offset.value = 0.0; constant.connect(analyser).connect(ac.destination); - constant.connect(sp).connect(ac.destination); + constant.connect(sp); var buf = new Float32Array(analyser.frequencyBinCount); var iteration_count = 10;
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/xr/webxr-origin-trial-interfaces.html b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/xr/webxr-origin-trial-interfaces.html index 141273c..a1e86b7 100644 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/xr/webxr-origin-trial-interfaces.html +++ b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/xr/webxr-origin-trial-interfaces.html
@@ -1,30 +1,38 @@ <!DOCTYPE html> <meta charset="utf-8"> -<!-- Generate token with the command: -tools/origin_trials/generate_token.py http://127.0.0.1:8000 WebXRDeviceM69 --expire-timestamp=2000000000 - -To test whether the token is working, run virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/xr tests. ---> -<title>WebXRDeviceM69 - interfaces exposed by origin trial</title> +<title>WebXR - interfaces exposed by origin trial</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> <script src="../../../resources/origin-trials-helper.js"></script> <script> - -let token = "AkvrKmuIjbDoP4zBBuZLWVMJLzFCV+2l8Iv2RPYCSbeSjFRRidSbIgW41p+jnCcOukYZ3tE4ZvQsR6qNhiIW5QoAAABWeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiV2ViWFJEZXZpY2VNNjkiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0="; - let properties_to_check = {'Navigator': ['xr']}; -// Skip this test if flags are not set properly. -if(!self.internals.runtimeFlags.webXREnabled) { +// Can only run these two tests if webXR is not enabled via a Chrome flag. +// That is only the case when running this in a virtual test suite (by default, +// runtime enabled features are on for layout tests). +// To run in virtual test suite: +// tools/run_web_tests.py virtual/origin-trials-runtimeflags-disabled/http/tests/origin_trials/webexposed +if (!self.internals.runtimeFlags.webXREnabled) { test(t => { OriginTrialsHelper.check_properties_missing(this, properties_to_check); }, "WebXR's entrypoint properties are not available without a token."); + + // The WebXRDeviceM69 token has been disabled due to breaking webxr API + // changes made in M73. + // generated with command + // tools/origin_trials/generate_token.py http://127.0.0.1:8000 WebXRDeviceM69 --expire-timestamp=2000000000 + let token_m69 = "AkvrKmuIjbDoP4zBBuZLWVMJLzFCV+2l8Iv2RPYCSbeSjFRRidSbIgW41p+jnCcOukYZ3tE4ZvQsR6qNhiIW5QoAAABWeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiV2ViWFJEZXZpY2VNNjkiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0="; + OriginTrialsHelper.add_token(token_m69); + test(t => { + OriginTrialsHelper.check_properties_missing(this, properties_to_check); + }, "WebXR's entrypoint properties are not available with WebXRDeviceM69 token."); } -OriginTrialsHelper.add_token(token); - +// generated with command +// tools/origin_trials/generate_token.py http://127.0.0.1:8000 WebXRDeviceM73 --expire-timestamp=2000000000 +let token_m73 = "AkdUKG/76uPyi1gvtP+q4o8XF9C6DWpF45h6xzMHwBFS+cfXrgo0zMHkA1T9ovuz+VVtxacaS/dc8F8JeWpcqAoAAABWeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiV2ViWFJEZXZpY2VNNzMiLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0="; +OriginTrialsHelper.add_token(token_m73); test(t => { OriginTrialsHelper.check_properties(this, properties_to_check); -}, "WebXR's entrypoint properties are available."); +}, "WebXR's entrypoint properties are available with WebXRDeviceM73 token."); </script>
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index c150db9..685a749 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1531,7 +1531,15 @@ attribute MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS attribute MAX_COMPUTE_ATOMIC_COUNTERS attribute MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS + attribute MAX_COMPUTE_IMAGE_UNIFORMS attribute MAX_COMPUTE_SHADER_STORAGE_BLOCKS + attribute MAX_COMPUTE_SHARED_MEMORY_SIZE + attribute MAX_COMPUTE_TEXTURE_IMAGE_UNITS + attribute MAX_COMPUTE_UNIFORM_BLOCKS + attribute MAX_COMPUTE_UNIFORM_COMPONENTS + attribute MAX_COMPUTE_WORK_GROUP_COUNT + attribute MAX_COMPUTE_WORK_GROUP_INVOCATIONS + attribute MAX_COMPUTE_WORK_GROUP_SIZE attribute MAX_CUBE_MAP_TEXTURE_SIZE attribute MAX_DRAW_BUFFERS attribute MAX_ELEMENTS_INDICES
diff --git a/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/navigation/README.txt b/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/navigation/README.txt deleted file mode 100644 index 2ff197f5..0000000 --- a/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/navigation/README.txt +++ /dev/null
@@ -1,2 +0,0 @@ -This directory is for running navigation tests with the FeaturePolicyForSandbox -runtime flag.
diff --git a/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/security/README.txt b/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/security/README.txt deleted file mode 100644 index b71a013..0000000 --- a/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/security/README.txt +++ /dev/null
@@ -1,2 +0,0 @@ -This directory is for running tests with the FeaturePolicyForSandbox -runtime flag.
diff --git a/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/mhtml/README.txt b/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/mhtml/README.txt deleted file mode 100644 index b71a013..0000000 --- a/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/mhtml/README.txt +++ /dev/null
@@ -1,2 +0,0 @@ -This directory is for running tests with the FeaturePolicyForSandbox -runtime flag.
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt index 8fd0d0bd..00675d1 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
@@ -569,6 +569,7 @@ property contentDocument property contentWindow property csp + property featurePolicy property frameBorder property getSVGDocument property height
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index 507a7e2..76b3144d 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1173,6 +1173,7 @@ getter documentURI getter domain getter embeds + getter featurePolicy getter fgColor getter firstElementChild getter fonts @@ -2467,6 +2468,7 @@ getter contentDocument getter contentWindow getter csp + getter featurePolicy getter frameBorder getter height getter longDesc
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 557a346..73d387f 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -1578,7 +1578,15 @@ [Worker] attribute MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS [Worker] attribute MAX_COMPUTE_ATOMIC_COUNTERS [Worker] attribute MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS +[Worker] attribute MAX_COMPUTE_IMAGE_UNIFORMS [Worker] attribute MAX_COMPUTE_SHADER_STORAGE_BLOCKS +[Worker] attribute MAX_COMPUTE_SHARED_MEMORY_SIZE +[Worker] attribute MAX_COMPUTE_TEXTURE_IMAGE_UNITS +[Worker] attribute MAX_COMPUTE_UNIFORM_BLOCKS +[Worker] attribute MAX_COMPUTE_UNIFORM_COMPONENTS +[Worker] attribute MAX_COMPUTE_WORK_GROUP_COUNT +[Worker] attribute MAX_COMPUTE_WORK_GROUP_INVOCATIONS +[Worker] attribute MAX_COMPUTE_WORK_GROUP_SIZE [Worker] attribute MAX_CUBE_MAP_TEXTURE_SIZE [Worker] attribute MAX_DRAW_BUFFERS [Worker] attribute MAX_ELEMENTS_INDICES
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index f2b4067e..443981b 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -8219,7 +8219,15 @@ attribute MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS attribute MAX_COMPUTE_ATOMIC_COUNTERS attribute MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS + attribute MAX_COMPUTE_IMAGE_UNIFORMS attribute MAX_COMPUTE_SHADER_STORAGE_BLOCKS + attribute MAX_COMPUTE_SHARED_MEMORY_SIZE + attribute MAX_COMPUTE_TEXTURE_IMAGE_UNITS + attribute MAX_COMPUTE_UNIFORM_BLOCKS + attribute MAX_COMPUTE_UNIFORM_COMPONENTS + attribute MAX_COMPUTE_WORK_GROUP_COUNT + attribute MAX_COMPUTE_WORK_GROUP_INVOCATIONS + attribute MAX_COMPUTE_WORK_GROUP_SIZE attribute MAX_CUBE_MAP_TEXTURE_SIZE attribute MAX_DRAW_BUFFERS attribute MAX_ELEMENTS_INDICES
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index eab29218..02f0b257 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -1449,7 +1449,15 @@ [Worker] attribute MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS [Worker] attribute MAX_COMPUTE_ATOMIC_COUNTERS [Worker] attribute MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS +[Worker] attribute MAX_COMPUTE_IMAGE_UNIFORMS [Worker] attribute MAX_COMPUTE_SHADER_STORAGE_BLOCKS +[Worker] attribute MAX_COMPUTE_SHARED_MEMORY_SIZE +[Worker] attribute MAX_COMPUTE_TEXTURE_IMAGE_UNITS +[Worker] attribute MAX_COMPUTE_UNIFORM_BLOCKS +[Worker] attribute MAX_COMPUTE_UNIFORM_COMPONENTS +[Worker] attribute MAX_COMPUTE_WORK_GROUP_COUNT +[Worker] attribute MAX_COMPUTE_WORK_GROUP_INVOCATIONS +[Worker] attribute MAX_COMPUTE_WORK_GROUP_SIZE [Worker] attribute MAX_CUBE_MAP_TEXTURE_SIZE [Worker] attribute MAX_DRAW_BUFFERS [Worker] attribute MAX_ELEMENTS_INDICES
diff --git a/third_party/inspector_protocol/README.chromium b/third_party/inspector_protocol/README.chromium index f5d2c21e..b6eafdd 100644 --- a/third_party/inspector_protocol/README.chromium +++ b/third_party/inspector_protocol/README.chromium
@@ -2,7 +2,7 @@ Short Name: inspector_protocol URL: https://chromium.googlesource.com/deps/inspector_protocol/ Version: 0 -Revision: 9cba74155ff34f0695c1f975ee087049204d3dc5 +Revision: d6a19bda35159094ad1fbfd6d81ce8fdc043943b License: BSD License File: LICENSE Security Critical: no
diff --git a/third_party/inspector_protocol/check_protocol_compatibility.py b/third_party/inspector_protocol/check_protocol_compatibility.py index e23bd702..d2df244 100755 --- a/third_party/inspector_protocol/check_protocol_compatibility.py +++ b/third_party/inspector_protocol/check_protocol_compatibility.py
@@ -45,6 +45,7 @@ # # Adding --show_changes to the command line prints out a list of valid public API changes. +from __future__ import print_function import copy import os.path import optparse @@ -475,9 +476,9 @@ if arg_options.show_changes: changes = compare_schemas(domains, baseline_domains, True) if len(changes) > 0: - print " Public changes since %s:" % version + print(" Public changes since %s:" % version) for change in changes: - print " %s" % change + print(" %s" % change) if arg_options.stamp: with open(arg_options.stamp, 'a') as _:
diff --git a/third_party/inspector_protocol/code_generator.py b/third_party/inspector_protocol/code_generator.py index edf8c4de..bee9cce 100755 --- a/third_party/inspector_protocol/code_generator.py +++ b/third_party/inspector_protocol/code_generator.py
@@ -33,14 +33,14 @@ def json_object_hook(object_dict): items = [(k, os.path.join(config_base, v) if k == "path" else v) for (k, v) in object_dict.items()] items = [(k, os.path.join(output_base, v) if k == "output" else v) for (k, v) in items] - keys, values = zip(*items) + keys, values = list(zip(*items)) return collections.namedtuple('X', keys)(*values) return json.loads(data, object_hook=json_object_hook) def init_defaults(config_tuple, path, defaults): keys = list(config_tuple._fields) # pylint: disable=E1101 values = [getattr(config_tuple, k) for k in keys] - for i in xrange(len(keys)): + for i in range(len(keys)): if hasattr(values[i], "_fields"): values[i] = init_defaults(values[i], path + "." + keys[i], defaults) for optional in defaults: @@ -134,7 +134,7 @@ def to_snake_case(name): - return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name, sys.maxint).lower() + return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name, sys.maxsize).lower() def to_method_case(config, name): @@ -664,14 +664,14 @@ # Make gyp / make generatos happy, otherwise make rebuilds world. inputs_ts = max(map(os.path.getmtime, inputs)) up_to_date = True - for output_file in outputs.iterkeys(): + for output_file in outputs.keys(): if not os.path.exists(output_file) or os.path.getmtime(output_file) < inputs_ts: up_to_date = False break if up_to_date: sys.exit() - for file_name, content in outputs.iteritems(): + for file_name, content in outputs.items(): out_file = open(file_name, "w") out_file.write(content) out_file.close()
diff --git a/third_party/inspector_protocol/encoding/cbor.cc b/third_party/inspector_protocol/encoding/cbor.cc index fcdc8ff..105ccf31 100644 --- a/third_party/inspector_protocol/encoding/cbor.cc +++ b/third_party/inspector_protocol/encoding/cbor.cc
@@ -48,6 +48,19 @@ static constexpr uint8_t kInitialByteForDouble = EncodeInitialByte(MajorType::SIMPLE_VALUE, 27); +// TAG 24 indicates that what follows is a byte string which is +// encoded in CBOR format. We use this as a wrapper for +// maps and arrays, allowing us to skip them, because the +// byte string carries its size (byte length). +// https://tools.ietf.org/html/rfc7049#section-2.4.4.1 +static constexpr uint8_t kInitialByteForEnvelope = + EncodeInitialByte(MajorType::TAG, 24); +// The initial byte for a byte string with at most 2^32 bytes +// of payload. This is used for envelope encoding, even if +// the byte string is shorter. +static constexpr uint8_t kInitialByteFor32BitLengthByteString = + EncodeInitialByte(MajorType::BYTE_STRING, 26); + // See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional // info = 31. static constexpr uint8_t kInitialByteIndefiniteLengthArray = @@ -73,7 +86,7 @@ template <typename T> void WriteBytesMostSignificantByteFirst(T v, std::vector<uint8_t>* out) { for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes) - out->push_back(0xff & v >> (shift_bytes * 8)); + out->push_back(0xff & (v >> (shift_bytes * 8))); } } // namespace @@ -215,6 +228,11 @@ // (kInitialByteForDouble) plus the 64 bits of payload for its value. constexpr int kEncodedDoubleSize = 1 + sizeof(uint64_t); +// An envelope is encoded with a specific initial byte +// (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32 +// bit wide length, plus a 32 bit length for that string. +constexpr int kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t); + void EncodeDouble(double value, std::vector<uint8_t>* out) { // The additional_info=27 indicates 64 bits for the double follow. // See RFC 7049 Section 2.3, Table 1. @@ -227,25 +245,62 @@ WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out); } +void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) { + assert(byte_size_pos_ == 0); + out->push_back(kInitialByteForEnvelope); + out->push_back(kInitialByteFor32BitLengthByteString); + byte_size_pos_ = out->size(); + out->resize(out->size() + sizeof(uint32_t)); +} + +bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) { + assert(byte_size_pos_ != 0); + // The byte size is the size of the payload, that is, all the + // bytes that were written past the byte size position itself. + uint64_t byte_size = out->size() - (byte_size_pos_ + sizeof(uint32_t)); + // We store exactly 4 bytes, so at most INT32MAX, with most significant + // byte first. + if (byte_size > std::numeric_limits<uint32_t>::max()) return false; + for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0; + --shift_bytes) { + (*out)[byte_size_pos_++] = 0xff & (byte_size >> (shift_bytes * 8)); + } + return true; +} + namespace { -class JsonToCBOREncoder : public JsonParserHandler { +class JSONToCBOREncoder : public JSONParserHandler { public: - JsonToCBOREncoder(std::vector<uint8_t>* out, Status* status) + JSONToCBOREncoder(std::vector<uint8_t>* out, Status* status) : out_(out), status_(status) { *status_ = Status(); } void HandleObjectBegin() override { + envelopes_.emplace_back(); + envelopes_.back().EncodeStart(out_); out_->push_back(kInitialByteIndefiniteLengthMap); } - void HandleObjectEnd() override { out_->push_back(kStopByte); }; + void HandleObjectEnd() override { + out_->push_back(kStopByte); + assert(!envelopes_.empty()); + envelopes_.back().EncodeStop(out_); + envelopes_.pop_back(); + }; void HandleArrayBegin() override { + envelopes_.emplace_back(); + envelopes_.back().EncodeStart(out_); out_->push_back(kInitialByteIndefiniteLengthArray); } - void HandleArrayEnd() override { out_->push_back(kStopByte); }; + void HandleArrayEnd() override { + out_->push_back(kStopByte); + assert(!envelopes_.empty()); + envelopes_.back().EncodeStop(out_); + envelopes_.pop_back(); + }; void HandleString16(std::vector<uint16_t> chars) override { for (uint16_t ch : chars) { @@ -286,26 +341,27 @@ private: std::vector<uint8_t>* out_; + std::vector<EnvelopeEncoder> envelopes_; Status* status_; }; } // namespace -std::unique_ptr<JsonParserHandler> NewJsonToCBOREncoder( +std::unique_ptr<JSONParserHandler> NewJSONToCBOREncoder( std::vector<uint8_t>* out, Status* status) { - return std::make_unique<JsonToCBOREncoder>(out, status); + return std::make_unique<JSONToCBOREncoder>(out, status); } namespace { // Below are three parsing routines for CBOR, which cover enough // to roundtrip JSON messages. bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer, - JsonParserHandler* out); + JSONParserHandler* out); bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer, - JsonParserHandler* out); + JSONParserHandler* out); bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer, - JsonParserHandler* out); + JSONParserHandler* out); -void ParseUTF16String(CBORTokenizer* tokenizer, JsonParserHandler* out) { +void ParseUTF16String(CBORTokenizer* tokenizer, JSONParserHandler* out) { std::vector<uint16_t> value; span<uint8_t> rep = tokenizer->GetString16WireRep(); for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2) @@ -315,7 +371,7 @@ } // For now this method only covers US-ASCII. Later, we may allow UTF8. -bool ParseASCIIString(CBORTokenizer* tokenizer, JsonParserHandler* out) { +bool ParseASCIIString(CBORTokenizer* tokenizer, JSONParserHandler* out) { assert(tokenizer->TokenTag() == CBORTokenTag::STRING8); std::vector<uint16_t> value16; for (uint8_t ch : tokenizer->GetString8()) { @@ -334,12 +390,15 @@ } bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer, - JsonParserHandler* out) { + JSONParserHandler* out) { if (stack_depth > kStackLimit) { out->HandleError( Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos}); return false; } + // Skip past the envelope to get to what's inside. + if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE) + tokenizer->EnterEnvelope(); switch (tokenizer->TokenTag()) { case CBORTokenTag::ERROR: out->HandleError(tokenizer->Status()); @@ -394,7 +453,7 @@ // ParseArray may only be called after an indefinite length array has been // detected. bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer, - JsonParserHandler* out) { + JSONParserHandler* out) { assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START); tokenizer->Next(); out->HandleArrayBegin(); @@ -420,7 +479,7 @@ // ParseArray may only be called after an indefinite length array has been // detected. bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer, - JsonParserHandler* out) { + JSONParserHandler* out) { assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START); out->HandleObjectBegin(); tokenizer->Next(); @@ -453,16 +512,29 @@ } } // namespace -void ParseCBOR(span<uint8_t> bytes, JsonParserHandler* json_out) { - CBORTokenizer tokenizer(bytes); - if (tokenizer.TokenTag() == CBORTokenTag::DONE) { +void ParseCBOR(span<uint8_t> bytes, JSONParserHandler* json_out) { + if (bytes.empty()) { json_out->HandleError(Status{Error::CBOR_NO_INPUT, 0}); return; } - if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) { + if (bytes[0] != kInitialByteForEnvelope) { json_out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0}); return; } + CBORTokenizer tokenizer(bytes); + if (tokenizer.TokenTag() == CBORTokenTag::ERROR) { + json_out->HandleError(tokenizer.Status()); + return; + } + // We checked for the envelope start byte above, so the tokenizer + // must agree here, since it's not an error. + assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE); + tokenizer.EnterEnvelope(); + if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) { + json_out->HandleError( + Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos}); + return; + } if (!ParseMap(/*stack_depth=*/1, &tokenizer, json_out)) return; if (tokenizer.TokenTag() == CBORTokenTag::DONE) return; if (tokenizer.TokenTag() == CBORTokenTag::ERROR) { @@ -474,7 +546,7 @@ } CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) { - ReadNextToken(); + ReadNextToken(/*enter_envelope=*/false); } CBORTokenizer::~CBORTokenizer() {} @@ -483,7 +555,12 @@ void CBORTokenizer::Next() { if (token_tag_ == CBORTokenTag::ERROR || token_tag_ == CBORTokenTag::DONE) return; - ReadNextToken(); + ReadNextToken(/*enter_envelope=*/false); +} + +void CBORTokenizer::EnterEnvelope() { + assert(token_tag_ == CBORTokenTag::ENVELOPE); + ReadNextToken(/*enter_envelope=*/true); } Status CBORTokenizer::Status() const { return status_; } @@ -528,9 +605,13 @@ token_start_internal_value_); } -void CBORTokenizer::ReadNextToken() { - status_.pos = - status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_; +void CBORTokenizer::ReadNextToken(bool enter_envelope) { + if (enter_envelope) { + status_.pos += kEncodedEnvelopeHeaderSize; + } else { + status_.pos = + status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_; + } status_.error = Error::OK; if (status_.pos >= bytes_.size()) { token_tag_ = CBORTokenTag::DONE; @@ -576,6 +657,30 @@ SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize); return; } + case kInitialByteForEnvelope: { // ENVELOPE + if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) { + SetError(Error::CBOR_INVALID_ENVELOPE); + return; + } + // The envelope must be a byte string with 32 bit length. + if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) { + SetError(Error::CBOR_INVALID_ENVELOPE); + return; + } + // Read the length of the byte string. + token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>( + bytes_.subspan(status_.pos + 2)); + // Make sure the payload is contained within the message. + if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize + + status_.pos > + size_t(bytes_.size())) { + SetError(Error::CBOR_INVALID_ENVELOPE); + return; + } + SetToken(CBORTokenTag::ENVELOPE, + kEncodedEnvelopeHeaderSize + token_start_internal_value_); + return; + } default: { span<uint8_t> remainder = bytes_.subspan(status_.pos, bytes_.size() - status_.pos);
diff --git a/third_party/inspector_protocol/encoding/cbor.h b/third_party/inspector_protocol/encoding/cbor.h index 6e7aa34..bf92a59 100644 --- a/third_party/inspector_protocol/encoding/cbor.h +++ b/third_party/inspector_protocol/encoding/cbor.h
@@ -17,7 +17,13 @@ // The binary encoding for the inspector protocol follows the CBOR specification // (RFC 7049). Additional constraints: // - Only indefinite length maps and arrays are supported. -// - At the top level, a message must be an indefinite length map. +// - Maps and arrays are wrapped with an envelope, that is, a +// CBOR tag with value 24 followed by a byte string specifying +// the byte length of the enclosed map / array. The byte string +// must use a 32 bit wide length. +// - At the top level, a message must be an indefinite length map +// wrapped by an envelope. +// - Maximal size for messages is 2^32 (4 GB). // - For scalars, we support only the int32_t range, encoded as // UNSIGNED/NEGATIVE (major types 0 / 1). // - UTF16 strings, including with unbalanced surrogate pairs, are encoded @@ -50,18 +56,39 @@ // with additional info = 27, followed by 8 bytes in big endian. void EncodeDouble(double value, std::vector<uint8_t>* out); +// An envelope indicates the byte length of a wrapped item. +// We use this for maps and array, which allows the decoder +// to skip such (nested) values whole sale. +// It's implemented as a CBOR tag (major type 6) with additional +// info = 24, followed by a byte string with a 32 bit length value; +// so the maximal structure that we can wrap is 2^32 bits long. +// See also: https://tools.ietf.org/html/rfc7049#section-2.4.4.1 +class EnvelopeEncoder { + public: + // Emits the envelope start bytes and records the position for the + // byte size in |byte_size_pos_|. Also emits empty bytes for the + // byte sisze so that encoding can continue. + void EncodeStart(std::vector<uint8_t>* out); + // This records the current size in |out| at position byte_size_pos_. + // Returns true iff successful. + bool EncodeStop(std::vector<uint8_t>* out); + + private: + uint64_t byte_size_pos_ = 0; +}; + // This can be used to convert from JSON to CBOR, by passing the // return value to the routines in json_parser.h. The handler will encode into // |out|, and iff an error occurs it will set |status| to an error and clear // |out|. Otherwise, |status.ok()| will be |true|. -std::unique_ptr<JsonParserHandler> NewJsonToCBOREncoder( +std::unique_ptr<JSONParserHandler> NewJSONToCBOREncoder( std::vector<uint8_t>* out, Status* status); // Parses a CBOR encoded message from |bytes|, sending JSON events to // |json_out|. If an error occurs, sends |out->HandleError|, and parsing stops. // The client is responsible for discarding the already received information in // that case. -void ParseCBOR(span<uint8_t> bytes, JsonParserHandler* json_out); +void ParseCBOR(span<uint8_t> bytes, JSONParserHandler* json_out); // Tags for the tokens within a CBOR message that CBORStream understands. // Note that this is not the same terminology as the CBOR spec (RFC 7049), @@ -93,6 +120,12 @@ ARRAY_START, // Ends a map or an array. STOP, + // An envelope indicator, wrapping a map or array. + // Internally this carries the byte length of the wrapped + // map or array. While CBORTokenizer::Next() will read / skip the entire + // envelope, CBORTokenizer::EnterEnvelope() reads the tokens + // inside of it. + ENVELOPE, // We've reached the end there is nothing else to read. DONE, }; @@ -113,6 +146,11 @@ // Advances to the next token. void Next(); + // Can only be called if TokenTag() == CBORTokenTag::ENVELOPE. + // While Next() would skip past the entire envelope / what it's + // wrapping, EnterEnvelope positions the cursor inside of the envelope, + // letting the client explore the nested structure. + void EnterEnvelope(); // If TokenTag() is CBORTokenTag::ERROR, then Status().error describes // the error more precisely; otherwise it'll be set to Error::OK. @@ -139,7 +177,7 @@ span<uint8_t> GetBinary() const; private: - void ReadNextToken(); + void ReadNextToken(bool enter_envelope); void SetToken(CBORTokenTag token, int64_t token_byte_length); void SetError(Error error);
diff --git a/third_party/inspector_protocol/encoding/cbor_test.cc b/third_party/inspector_protocol/encoding/cbor_test.cc index 7f46c7d4..1b928f1 100644 --- a/third_party/inspector_protocol/encoding/cbor_test.cc +++ b/third_party/inspector_protocol/encoding/cbor_test.cc
@@ -404,7 +404,7 @@ } // -// NewJsonToCBOREncoder +// NewJSONToCBOREncoder // void EncodeSevenBitStringForTest(const std::string& key, std::vector<uint8_t>* out) { @@ -414,14 +414,14 @@ out); } -TEST(JsonToCborEncoderTest, SevenBitStrings) { +TEST(JSONToCBOREncoderTest, SevenBitStrings) { // When a string can be represented as 7 bit ASCII, the encoder will use the // STRING (major Type 3) type, so the actual characters end up as bytes on the // wire. std::vector<uint8_t> encoded; Status status; - std::unique_ptr<JsonParserHandler> encoder = - NewJsonToCBOREncoder(&encoded, &status); + std::unique_ptr<JSONParserHandler> encoder = + NewJSONToCBOREncoder(&encoded, &status); std::vector<uint16_t> utf16 = {'f', 'o', 'o'}; encoder->HandleString16(utf16); EXPECT_EQ(Error::OK, status.error); @@ -433,7 +433,7 @@ } TEST(JsonCborRoundtrip, EncodingDecoding) { - // Hits all the cases except binary and error in JsonParserHandler, first + // Hits all the cases except binary and error in JSONParserHandler, first // parsing a JSON message into CBOR, then parsing it back from CBOR into JSON. std::string json = "{" @@ -447,12 +447,16 @@ "}"; std::vector<uint8_t> encoded; Status status; - std::unique_ptr<JsonParserHandler> encoder = - NewJsonToCBOREncoder(&encoded, &status); + std::unique_ptr<JSONParserHandler> encoder = + NewJSONToCBOREncoder(&encoded, &status); span<uint8_t> ascii_in(reinterpret_cast<const uint8_t*>(json.data()), json.size()); - parseJSONChars(GetLinuxDevPlatform(), ascii_in, encoder.get()); - std::vector<uint8_t> expected; + ParseJSONChars(GetLinuxDevPlatform(), ascii_in, encoder.get()); + std::vector<uint8_t> expected = { + 0xd8, // envelope + 0x5a, // byte string with 32 bit length + 0, 0, 0, 94, // length is 94 bytes + }; expected.push_back(0xbf); // indef length map start EncodeSevenBitStringForTest("string", &expected); // This is followed by the encoded string for "Hello, 🌎." @@ -474,6 +478,11 @@ EncodeSevenBitStringForTest("null", &expected); expected.push_back(7 << 5 | 22); // RFC 7049 Section 2.3, Table 2: null EncodeSevenBitStringForTest("array", &expected); + expected.push_back(0xd8); // envelope + expected.push_back(0x5a); // byte string with 32 bit length + // the length is 5 bytes (that's up to end indef length array below). + for (uint8_t ch : std::array<uint8_t, 4>{{0, 0, 0, 5}}) + expected.push_back(ch); expected.push_back(0x9f); // RFC 7049 Section 2.2.1, indef length array start expected.push_back(1); // Three UNSIGNED values (easy since Major Type 0) expected.push_back(2); @@ -485,8 +494,8 @@ // And now we roundtrip, decoding the message we just encoded. std::string decoded; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &decoded, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &decoded, &status); ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_writer.get()); EXPECT_EQ(Error::OK, status.error); EXPECT_EQ(json, decoded); @@ -501,22 +510,22 @@ SCOPED_TRACE(std::string("example: ") + json); std::vector<uint8_t> encoded; Status status; - std::unique_ptr<JsonParserHandler> encoder = - NewJsonToCBOREncoder(&encoded, &status); + std::unique_ptr<JSONParserHandler> encoder = + NewJSONToCBOREncoder(&encoded, &status); span<uint8_t> ascii_in(reinterpret_cast<const uint8_t*>(json.data()), json.size()); - parseJSONChars(GetLinuxDevPlatform(), ascii_in, encoder.get()); + ParseJSONChars(GetLinuxDevPlatform(), ascii_in, encoder.get()); std::string decoded; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &decoded, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &decoded, &status); ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_writer.get()); EXPECT_EQ(Error::OK, status.error); EXPECT_EQ(json, decoded); } } -TEST(JsonToCborEncoderTest, HelloWorldBinary_WithTripToJson) { - // The JsonParserHandler::HandleBinary is a special case: The JSON parser will +TEST(JSONToCBOREncoderTest, HelloWorldBinary_WithTripToJson) { + // The JSONParserHandler::HandleBinary is a special case: The JSON parser will // never call this method, because JSON does not natively support the binary // type. So, we can't fully roundtrip. However, the other direction works: // binary will be rendered in JSON, as a base64 string. So, we make calls to @@ -525,8 +534,8 @@ // world.". std::vector<uint8_t> encoded; Status status; - std::unique_ptr<JsonParserHandler> encoder = - NewJsonToCBOREncoder(&encoded, &status); + std::unique_ptr<JSONParserHandler> encoder = + NewJSONToCBOREncoder(&encoded, &status); encoder->HandleObjectBegin(); // Emit a key. encoder->HandleString16(std::vector<uint16_t>{'f', 'o', 'o'}); @@ -539,8 +548,8 @@ // Now drive the json writer via the CBOR decoder. std::string decoded; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &decoded, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &decoded, &status); ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_writer.get()); EXPECT_EQ(Error::OK, status.error); EXPECT_EQ(Status::npos(), status.pos); @@ -552,20 +561,22 @@ // ParseCBOR // TEST(ParseCBORTest, ParseEmptyCBORMessage) { - // Just an indefinite length map that's empty (0xff = stop byte). - std::vector<uint8_t> in = {0xbf, 0xff}; + // An envelope starting with 0xd8, 0x5a, with the byte length + // of 2, containing a map that's empty (0xbf for map + // start, and 0xff for map end). + std::vector<uint8_t> in = {0xd8, 0x5a, 0, 0, 0, 2, 0xbf, 0xff}; std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(in.data(), in.size()), json_writer.get()); EXPECT_EQ(Error::OK, status.error); EXPECT_EQ("{}", out); } TEST(ParseCBORTest, ParseCBORHelloWorld) { - std::vector<uint8_t> bytes; - + const uint8_t kPayloadLen = 27; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen}; bytes.push_back(0xbf); // start indef length map. EncodeSevenBitStringForTest("msg", &bytes); // key: msg // Now write the value, the familiar "Hello, 🌎." where the globe is expressed @@ -576,11 +587,12 @@ ',', 0, ' ', 0, 0x3c, 0xd8, 0x0e, 0xdf, '.', 0}}) bytes.push_back(ch); bytes.push_back(0xff); // stop byte + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::OK, status.error); EXPECT_EQ("{\"msg\":\"Hello, \\ud83c\\udf0e.\"}", out); @@ -590,8 +602,8 @@ std::vector<uint8_t> in = {}; std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(in.data(), in.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_NO_INPUT, status.error); EXPECT_EQ("", out); @@ -599,13 +611,13 @@ TEST(ParseCBORTest, InvalidStartByteError) { // Here we test that some actual json, which usually starts with {, - // is not considered CBOR. CBOR messages must start with 0xbf, the - // indefinite length map start byte. + // is not considered CBOR. CBOR messages must start with 0x5a, the + // envelope start byte. std::string json = "{\"msg\": \"Hello, world.\"}"; std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR( span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), json_writer.get()); @@ -614,12 +626,15 @@ } TEST(ParseCBORTest, UnexpectedEofExpectedValueError) { - std::vector<uint8_t> bytes = {0xbf}; // The byte for starting a map. + constexpr uint8_t kPayloadLen = 5; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start EncodeSevenBitStringForTest("key", &bytes); // A key; so value would be next. + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE, status.error); EXPECT_EQ(int64_t(bytes.size()), status.pos); @@ -627,14 +642,17 @@ } TEST(ParseCBORTest, UnexpectedEofInArrayError) { - std::vector<uint8_t> bytes = {0xbf}; // The byte for starting a map. + constexpr uint8_t kPayloadLen = 8; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // The byte for starting a map. EncodeSevenBitStringForTest("array", &bytes); // A key; so value would be next. bytes.push_back(0x9f); // byte for indefinite length array start. + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, status.error); EXPECT_EQ(int64_t(bytes.size()), status.pos); @@ -642,40 +660,52 @@ } TEST(ParseCBORTest, UnexpectedEofInMapError) { - std::vector<uint8_t> bytes = {0xbf}; // The byte for starting a map. + constexpr uint8_t kPayloadLen = 1; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // The byte for starting a map. + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_IN_MAP, status.error); - EXPECT_EQ(1, status.pos); + EXPECT_EQ(7, status.pos); EXPECT_EQ("", out); } TEST(ParseCBORTest, InvalidMapKeyError) { - // The byte for starting a map, followed by a byte representing null. - // null is not a valid map key. - std::vector<uint8_t> bytes = {0xbf, 7 << 5 | 22}; + constexpr uint8_t kPayloadLen = 2; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, + 0, 0, kPayloadLen, // envelope + 0xbf, // map start + 7 << 5 | 22}; // null (not a valid map key) + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_INVALID_MAP_KEY, status.error); - EXPECT_EQ(1, status.pos); + EXPECT_EQ(7, status.pos); EXPECT_EQ("", out); } std::vector<uint8_t> MakeNestedCBOR(int depth) { std::vector<uint8_t> bytes; + std::vector<EnvelopeEncoder> envelopes; for (int ii = 0; ii < depth; ++ii) { + envelopes.emplace_back(); + envelopes.back().EncodeStart(&bytes); bytes.push_back(0xbf); // indef length map start EncodeSevenBitStringForTest("key", &bytes); } EncodeSevenBitStringForTest("innermost_value", &bytes); - for (int ii = 0; ii < depth; ++ii) + for (int ii = 0; ii < depth; ++ii) { bytes.push_back(0xff); // stop byte, finishes map. + envelopes.back().EncodeStop(&bytes); + envelopes.pop_back(); + } return bytes; } @@ -684,8 +714,8 @@ std::vector<uint8_t> bytes = MakeNestedCBOR(3); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::OK, status.error); EXPECT_EQ(Status::npos(), status.pos); @@ -695,49 +725,57 @@ std::vector<uint8_t> bytes = MakeNestedCBOR(1000); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::OK, status.error); EXPECT_EQ(Status::npos(), status.pos); } // We just want to know the length of one opening map so we can compute - // where the error is encountered. - std::vector<uint8_t> opening_segment = {0xbf}; - EncodeSevenBitStringForTest("key", &opening_segment); + // where the error is encountered. So we look at a small example and find + // the second envelope start. + std::vector<uint8_t> small_example = MakeNestedCBOR(3); + int64_t opening_segment_size = 1; // Start after the first envelope start. + while (opening_segment_size < int64_t(small_example.size()) && + small_example[opening_segment_size] != 0xd8) + opening_segment_size++; { // Depth 1001: limit exceeded. std::vector<uint8_t> bytes = MakeNestedCBOR(1001); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_STACK_LIMIT_EXCEEDED, status.error); - EXPECT_EQ(int64_t(opening_segment.size()) * 1001, status.pos); + EXPECT_EQ(opening_segment_size * 1001, status.pos); } { // Depth 1200: still limit exceeded, and at the same pos as for 1001 std::vector<uint8_t> bytes = MakeNestedCBOR(1200); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_STACK_LIMIT_EXCEEDED, status.error); - EXPECT_EQ(int64_t(opening_segment.size()) * 1001, status.pos); + EXPECT_EQ(opening_segment_size * 1001, status.pos); } } TEST(ParseCBORTest, UnsupportedValueError) { - std::vector<uint8_t> bytes = {0xbf}; // start indef length map. + constexpr uint8_t kPayloadLen = 6; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start EncodeSevenBitStringForTest("key", &bytes); int64_t error_pos = bytes.size(); bytes.push_back(6 << 5 | 5); // tags aren't supported yet. + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_UNSUPPORTED_VALUE, status.error); EXPECT_EQ(error_pos, status.pos); @@ -745,7 +783,9 @@ } TEST(ParseCBORTest, InvalidString16Error) { - std::vector<uint8_t> bytes = {0xbf}; // start indef length map. + constexpr uint8_t kPayloadLen = 11; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start EncodeSevenBitStringForTest("key", &bytes); int64_t error_pos = bytes.size(); // a BYTE_STRING of length 5 as value; since we interpret these as string16, @@ -753,10 +793,11 @@ // 5 isn't divisible by 2. bytes.push_back(2 << 5 | 5); for (int ii = 0; ii < 5; ++ii) bytes.push_back(' '); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_INVALID_STRING16, status.error); EXPECT_EQ(error_pos, status.pos); @@ -764,16 +805,19 @@ } TEST(ParseCBORTest, InvalidString8Error) { - std::vector<uint8_t> bytes = {0xbf}; // start indef length map. + constexpr uint8_t kPayloadLen = 6; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start EncodeSevenBitStringForTest("key", &bytes); int64_t error_pos = bytes.size(); // a STRING of length 5 as value, but we're at the end of the bytes array // so it can't be decoded successfully. bytes.push_back(3 << 5 | 5); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_INVALID_STRING8, status.error); EXPECT_EQ(error_pos, status.pos); @@ -781,17 +825,20 @@ } TEST(ParseCBORTest, String8MustBe7BitError) { - std::vector<uint8_t> bytes = {0xbf}; // start indef length map. + constexpr uint8_t kPayloadLen = 11; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start EncodeSevenBitStringForTest("key", &bytes); int64_t error_pos = bytes.size(); // a STRING of length 5 as value, with a payload that has bytes outside // 7 bit (> 0x7f). bytes.push_back(3 << 5 | 5); for (int ii = 0; ii < 5; ++ii) bytes.push_back(0xf0); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_STRING8_MUST_BE_7BIT, status.error); EXPECT_EQ(error_pos, status.pos); @@ -799,7 +846,9 @@ } TEST(ParseCBORTest, InvalidBinaryError) { - std::vector<uint8_t> bytes = {0xbf}; // start indef length map. + constexpr uint8_t kPayloadLen = 9; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start EncodeSevenBitStringForTest("key", &bytes); int64_t error_pos = bytes.size(); bytes.push_back(6 << 5 | 22); // base64 hint for JSON; indicates binary @@ -807,10 +856,11 @@ // Just two garbage bytes, not enough for the binary. bytes.push_back(0x31); bytes.push_back(0x23); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_INVALID_BINARY, status.error); EXPECT_EQ(error_pos, status.pos); @@ -818,17 +868,20 @@ } TEST(ParseCBORTest, InvalidDoubleError) { - std::vector<uint8_t> bytes = {0xbf}; // start indef length map. + constexpr uint8_t kPayloadLen = 8; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start EncodeSevenBitStringForTest("key", &bytes); int64_t error_pos = bytes.size(); bytes.push_back(7 << 5 | 27); // initial byte for double // Just two garbage bytes, not enough to represent an actual double. bytes.push_back(0x31); bytes.push_back(0x23); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_INVALID_DOUBLE, status.error); EXPECT_EQ(error_pos, status.pos); @@ -836,17 +889,20 @@ } TEST(ParseCBORTest, InvalidSignedError) { - std::vector<uint8_t> bytes = {0xbf}; // start indef length map. + constexpr uint8_t kPayloadLen = 14; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start EncodeSevenBitStringForTest("key", &bytes); int64_t error_pos = bytes.size(); // uint64_t max is a perfectly fine value to encode as CBOR unsigned, // but we don't support this since we only cover the int32_t range. cbor_internals::WriteTokenStart(cbor_internals::MajorType::UNSIGNED, std::numeric_limits<uint64_t>::max(), &bytes); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_INVALID_INT32, status.error); EXPECT_EQ(error_pos, status.pos); @@ -854,7 +910,9 @@ } TEST(ParseCBORTest, TrailingJunk) { - std::vector<uint8_t> bytes = {0xbf}; // start indef length map. + constexpr uint8_t kPayloadLen = 35; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start EncodeSevenBitStringForTest("key", &bytes); EncodeSevenBitStringForTest("value", &bytes); bytes.push_back(0xff); // Up to here, it's a perfectly fine msg. @@ -863,10 +921,11 @@ cbor_internals::WriteTokenStart(cbor_internals::MajorType::UNSIGNED, std::numeric_limits<uint64_t>::max(), &bytes); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; - std::unique_ptr<JsonParserHandler> json_writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> json_writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); EXPECT_EQ(Error::CBOR_TRAILING_JUNK, status.error); EXPECT_EQ(error_pos, status.pos);
diff --git a/third_party/inspector_protocol/encoding/json_parser.cc b/third_party/inspector_protocol/encoding/json_parser.cc index 333275b..82bd184 100644 --- a/third_party/inspector_protocol/encoding/json_parser.cc +++ b/third_party/inspector_protocol/encoding/json_parser.cc
@@ -36,7 +36,7 @@ template <typename Char> class JsonParser { public: - JsonParser(const Platform* platform, JsonParserHandler* handler) + JsonParser(const Platform* platform, JSONParserHandler* handler) : platform_(platform), handler_(handler) {} void Parse(const Char* start, size_t length) { @@ -567,18 +567,18 @@ const Char* start_pos_ = nullptr; bool error_ = false; const Platform* platform_; - JsonParserHandler* handler_; + JSONParserHandler* handler_; }; } // namespace -void parseJSONChars(const Platform* platform, span<uint8_t> chars, - JsonParserHandler* handler) { +void ParseJSONChars(const Platform* platform, span<uint8_t> chars, + JSONParserHandler* handler) { JsonParser<uint8_t> parser(platform, handler); parser.Parse(chars.data(), chars.size()); } -void parseJSONChars(const Platform* platform, span<uint16_t> chars, - JsonParserHandler* handler) { +void ParseJSONChars(const Platform* platform, span<uint16_t> chars, + JSONParserHandler* handler) { JsonParser<uint16_t> parser(platform, handler); parser.Parse(chars.data(), chars.size()); }
diff --git a/third_party/inspector_protocol/encoding/json_parser.h b/third_party/inspector_protocol/encoding/json_parser.h index 1241f26..e5a8b03 100644 --- a/third_party/inspector_protocol/encoding/json_parser.h +++ b/third_party/inspector_protocol/encoding/json_parser.h
@@ -13,10 +13,10 @@ namespace inspector_protocol { // JSON parsing routines. -void parseJSONChars(const Platform* deps, span<uint8_t> chars, - JsonParserHandler* handler); -void parseJSONChars(const Platform* deps, span<uint16_t> chars, - JsonParserHandler* handler); +void ParseJSONChars(const Platform* deps, span<uint8_t> chars, + JSONParserHandler* handler); +void ParseJSONChars(const Platform* deps, span<uint16_t> chars, + JSONParserHandler* handler); } // namespace inspector_protocol #endif // INSPECTOR_PROTOCOL_ENCODING_JSON_PARSER_H_
diff --git a/third_party/inspector_protocol/encoding/json_parser_handler.h b/third_party/inspector_protocol/encoding/json_parser_handler.h index 95b9ea8..c501d99f 100644 --- a/third_party/inspector_protocol/encoding/json_parser_handler.h +++ b/third_party/inspector_protocol/encoding/json_parser_handler.h
@@ -11,9 +11,9 @@ namespace inspector_protocol { // Handler interface for JSON parser events. See also json_parser.h. -class JsonParserHandler { +class JSONParserHandler { public: - virtual ~JsonParserHandler() = default; + virtual ~JSONParserHandler() = default; virtual void HandleObjectBegin() = 0; virtual void HandleObjectEnd() = 0; virtual void HandleArrayBegin() = 0;
diff --git a/third_party/inspector_protocol/encoding/json_parser_test.cc b/third_party/inspector_protocol/encoding/json_parser_test.cc index cee0eac..38b0826b 100644 --- a/third_party/inspector_protocol/encoding/json_parser_test.cc +++ b/third_party/inspector_protocol/encoding/json_parser_test.cc
@@ -12,7 +12,7 @@ #include "linux_dev_platform.h" namespace inspector_protocol { -class Log : public JsonParserHandler { +class Log : public JSONParserHandler { public: void HandleObjectBegin() override { log_ << "object begin\n"; } @@ -62,7 +62,7 @@ TEST_F(JsonParserTest, SimpleDictionary) { std::string json = "{\"foo\": 42}"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -77,7 +77,7 @@ TEST_F(JsonParserTest, NestedDictionary) { std::string json = "{\"foo\": {\"bar\": {\"baz\": 1}, \"bar2\": 2}}"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -100,7 +100,7 @@ TEST_F(JsonParserTest, Doubles) { std::string json = "{\"foo\": 3.1415, \"bar\": 31415e-4}"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -118,7 +118,7 @@ TEST_F(JsonParserTest, Unicode) { // Globe character. 0xF0 0x9F 0x8C 0x8E in utf8, 0xD83C 0xDF0E in utf16. std::string json = "{\"msg\": \"Hello, \\uD83C\\uDF0E.\"}"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -138,7 +138,7 @@ // We provide the moon with json escape, but the earth as utf16 input. // Either way they arrive as utf8 (after decoding in log_.str()). base::string16 json = base::UTF8ToUTF16("{\"space\": \"🌎 \\uD83C\\uDF19.\"}"); - parseJSONChars(GetLinuxDevPlatform(), + ParseJSONChars(GetLinuxDevPlatform(), span<uint16_t>(reinterpret_cast<const uint16_t*>(json.data()), json.size()), &log_); @@ -167,7 +167,7 @@ "\"3 byte\":\"屋\"," "\"4 byte\":\"🌎\"" "}"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -191,7 +191,7 @@ std::string json = "{\"foo\": 3.1415} junk"; int64_t junk_idx = json.find("junk"); EXPECT_GT(junk_idx, 0); - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -212,7 +212,7 @@ // kStackLimit is 1000 (see json_parser.cc). First let's // try with a small nested example. std::string json_3 = MakeNestedJson(3); - parseJSONChars(GetLinuxDevPlatform(), + ParseJSONChars(GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json_3.data()), json_3.size()), &log_); @@ -233,7 +233,7 @@ // Now with kStackLimit (1000). log_ = Log(); std::string json_limit = MakeNestedJson(1000); - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json_limit.data()), json_limit.size()), @@ -242,7 +242,7 @@ // Now with kStackLimit + 1 (1001) - it exceeds in the innermost instance. log_ = Log(); std::string exceeded = MakeNestedJson(1001); - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(exceeded.data()), exceeded.size()), @@ -252,7 +252,7 @@ // Now way past the limit. Still, the point of exceeding is 1001. log_ = Log(); std::string far_out = MakeNestedJson(10000); - parseJSONChars(GetLinuxDevPlatform(), + ParseJSONChars(GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(far_out.data()), far_out.size()), &log_); @@ -262,7 +262,7 @@ TEST_F(JsonParserTest, NoInputError) { std::string json = ""; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -273,7 +273,7 @@ TEST_F(JsonParserTest, InvalidTokenError) { std::string json = "|"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -285,7 +285,7 @@ TEST_F(JsonParserTest, InvalidNumberError) { // Mantissa exceeds max (the constant used here is int64_t max). std::string json = "1E9223372036854775807"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -297,7 +297,7 @@ TEST_F(JsonParserTest, InvalidStringError) { // \x22 is an unsupported escape sequence std::string json = "\"foo\\x22\""; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -308,7 +308,7 @@ TEST_F(JsonParserTest, UnexpectedArrayEndError) { std::string json = "[1,2,]"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -319,7 +319,7 @@ TEST_F(JsonParserTest, CommaOrArrayEndExpectedError) { std::string json = "[1,2 2"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -332,7 +332,7 @@ TEST_F(JsonParserTest, StringLiteralExpectedError) { // There's an error because the key bar, a string, is not terminated. std::string json = "{\"foo\": 3.1415, \"bar: 31415e-4}"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -343,7 +343,7 @@ TEST_F(JsonParserTest, ColonExpectedError) { std::string json = "{\"foo\", 42}"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -354,7 +354,7 @@ TEST_F(JsonParserTest, UnexpectedObjectEndError) { std::string json = "{\"foo\": 42, }"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -366,7 +366,7 @@ TEST_F(JsonParserTest, CommaOrObjectEndExpectedError) { // The second separator should be a comma. std::string json = "{\"foo\": 3.1415: \"bar\": 0}"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_); @@ -378,7 +378,7 @@ TEST_F(JsonParserTest, ValueExpectedError) { std::string json = "}"; - parseJSONChars( + ParseJSONChars( GetLinuxDevPlatform(), span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), &log_);
diff --git a/third_party/inspector_protocol/encoding/json_std_string_writer.cc b/third_party/inspector_protocol/encoding/json_std_string_writer.cc index 37c8424..6e899e16 100644 --- a/third_party/inspector_protocol/encoding/json_std_string_writer.cc +++ b/third_party/inspector_protocol/encoding/json_std_string_writer.cc
@@ -81,7 +81,7 @@ } // Implements a handler for JSON parser events to emit a JSON string. -class Writer : public JsonParserHandler { +class Writer : public JSONParserHandler { public: Writer(Platform* platform, std::string* out, Status* status) : platform_(platform), out_(out), status_(status) { @@ -207,7 +207,7 @@ }; } // namespace -std::unique_ptr<JsonParserHandler> NewJsonWriter(Platform* platform, +std::unique_ptr<JSONParserHandler> NewJSONWriter(Platform* platform, std::string* out, Status* status) { return std::make_unique<Writer>(platform, out, status);
diff --git a/third_party/inspector_protocol/encoding/json_std_string_writer.h b/third_party/inspector_protocol/encoding/json_std_string_writer.h index 33250bbf..b2c9b634 100644 --- a/third_party/inspector_protocol/encoding/json_std_string_writer.h +++ b/third_party/inspector_protocol/encoding/json_std_string_writer.h
@@ -17,7 +17,7 @@ // Except for calling the HandleError routine at any time, the client // code must call the Handle* methods in an order in which they'd occur // in valid JSON; otherwise we may crash (the code uses assert). -std::unique_ptr<JsonParserHandler> NewJsonWriter(Platform* platform, +std::unique_ptr<JSONParserHandler> NewJSONWriter(Platform* platform, std::string* out, Status* status); } // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/json_std_string_writer_test.cc b/third_party/inspector_protocol/encoding/json_std_string_writer_test.cc index 7c45c65..0baa4d5 100644 --- a/third_party/inspector_protocol/encoding/json_std_string_writer_test.cc +++ b/third_party/inspector_protocol/encoding/json_std_string_writer_test.cc
@@ -19,8 +19,8 @@ TEST(JsonStdStringWriterTest, HelloWorld) { std::string out; Status status; - std::unique_ptr<JsonParserHandler> writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); writer->HandleObjectBegin(); writer->HandleString16(UTF16String("msg1")); writer->HandleString16(UTF16String("Hello, 🌎.")); @@ -54,14 +54,14 @@ } TEST(JsonStdStringWriterTest, BinaryEncodedAsJsonString) { - // The encoder emits binary submitted to JsonParserHandler::HandleBinary + // The encoder emits binary submitted to JSONParserHandler::HandleBinary // as base64. The following three examples are taken from // https://en.wikipedia.org/wiki/Base64. { std::string out; Status status; - std::unique_ptr<JsonParserHandler> writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); writer->HandleBinary({'M', 'a', 'n'}); EXPECT_TRUE(status.ok()); EXPECT_EQ("\"TWFu\"", out); @@ -69,8 +69,8 @@ { std::string out; Status status; - std::unique_ptr<JsonParserHandler> writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); writer->HandleBinary({'M', 'a'}); EXPECT_TRUE(status.ok()); EXPECT_EQ("\"TWE=\"", out); @@ -78,8 +78,8 @@ { std::string out; Status status; - std::unique_ptr<JsonParserHandler> writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); writer->HandleBinary({'M'}); EXPECT_TRUE(status.ok()); EXPECT_EQ("\"TQ==\"", out); @@ -87,8 +87,8 @@ { // "Hello, world.", verified with base64decode.org. std::string out; Status status; - std::unique_ptr<JsonParserHandler> writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); writer->HandleBinary( {'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.'}); EXPECT_TRUE(status.ok()); @@ -101,8 +101,8 @@ // status and clears the output. std::string out; Status status; - std::unique_ptr<JsonParserHandler> writer = - NewJsonWriter(GetLinuxDevPlatform(), &out, &status); + std::unique_ptr<JSONParserHandler> writer = + NewJSONWriter(GetLinuxDevPlatform(), &out, &status); writer->HandleObjectBegin(); writer->HandleString16(UTF16String("msg1")); writer->HandleError(Status{Error::JSON_PARSER_VALUE_EXPECTED, 42}); @@ -139,8 +139,8 @@ std::string out; Status status; - std::unique_ptr<JsonParserHandler> writer = - NewJsonWriter(&platform, &out, &status); + std::unique_ptr<JSONParserHandler> writer = + NewJSONWriter(&platform, &out, &status); writer->HandleArrayBegin(); writer->HandleDouble(.1); writer->HandleDouble(-.7);
diff --git a/third_party/inspector_protocol/encoding/status.h b/third_party/inspector_protocol/encoding/status.h index b5c5f609..bd20f4f 100644 --- a/third_party/inspector_protocol/encoding/status.h +++ b/third_party/inspector_protocol/encoding/status.h
@@ -28,19 +28,21 @@ CBOR_INVALID_INT32 = 0x0e, CBOR_INVALID_DOUBLE = 0x0f, - CBOR_INVALID_STRING8 = 0x10, - CBOR_INVALID_STRING16 = 0x11, - CBOR_INVALID_BINARY = 0x12, - CBOR_UNSUPPORTED_VALUE = 0x13, - CBOR_NO_INPUT = 0x14, - CBOR_INVALID_START_BYTE = 0x15, - CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x16, - CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x17, - CBOR_UNEXPECTED_EOF_IN_MAP = 0x18, - CBOR_INVALID_MAP_KEY = 0x19, - CBOR_STACK_LIMIT_EXCEEDED = 0x1a, - CBOR_STRING8_MUST_BE_7BIT = 0x1b, - CBOR_TRAILING_JUNK = 0x1c, + CBOR_INVALID_ENVELOPE = 0x10, + CBOR_INVALID_STRING8 = 0x11, + CBOR_INVALID_STRING16 = 0x12, + CBOR_INVALID_BINARY = 0x13, + CBOR_UNSUPPORTED_VALUE = 0x14, + CBOR_NO_INPUT = 0x15, + CBOR_INVALID_START_BYTE = 0x16, + CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17, + CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18, + CBOR_UNEXPECTED_EOF_IN_MAP = 0x19, + CBOR_INVALID_MAP_KEY = 0x1a, + CBOR_STACK_LIMIT_EXCEEDED = 0x1b, + CBOR_STRING8_MUST_BE_7BIT = 0x1c, + CBOR_TRAILING_JUNK = 0x1d, + CBOR_MAP_START_EXPECTED = 0x1e, }; // A status value with position that can be copied. The default status
diff --git a/third_party/inspector_protocol/lib/Maybe_h.template b/third_party/inspector_protocol/lib/Maybe_h.template index 15626ab..68b166f 100644 --- a/third_party/inspector_protocol/lib/Maybe_h.template +++ b/third_party/inspector_protocol/lib/Maybe_h.template
@@ -83,7 +83,7 @@ template<> class Maybe<bool> : public MaybeBase<bool> { public: - Maybe() { } + Maybe() { m_value = false; } Maybe(bool value) : MaybeBase(value) { } Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {} using MaybeBase::operator=; @@ -92,7 +92,7 @@ template<> class Maybe<int> : public MaybeBase<int> { public: - Maybe() { } + Maybe() { m_value = 0; } Maybe(int value) : MaybeBase(value) { } Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {} using MaybeBase::operator=; @@ -101,7 +101,7 @@ template<> class Maybe<double> : public MaybeBase<double> { public: - Maybe() { } + Maybe() { m_value = 0; } Maybe(double value) : MaybeBase(value) { } Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {} using MaybeBase::operator=;
diff --git a/third_party/inspector_protocol/pdl.py b/third_party/inspector_protocol/pdl.py index 652e99c..43111e9 100644 --- a/third_party/inspector_protocol/pdl.py +++ b/third_party/inspector_protocol/pdl.py
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function import collections import json import os.path @@ -159,7 +160,7 @@ enumliterals.append(trimLine) continue - print 'Error in %s:%s, illegal token: \t%s' % (file_name, i, line) + print('Error in %s:%s, illegal token: \t%s' % (file_name, i, line)) sys.exit(1) return protocol
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index 79996f4..a3d9262 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -5,9 +5,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Wednesday January 16 2019 +Date: Thursday January 31 2019 Branch: master -Commit: 9ecc0e779a29281e5698451bfd1b3ebe8f053bfd +Commit: cde3da57b9a18636026531694ca76671894d1dce Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/libvpx_srcs.gni b/third_party/libvpx/libvpx_srcs.gni index 1b76cc9..376acb9 100644 --- a/third_party/libvpx/libvpx_srcs.gni +++ b/third_party/libvpx/libvpx_srcs.gni
@@ -188,6 +188,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.c", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_360.c", @@ -664,6 +666,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.c", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_360.c", @@ -1143,6 +1147,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.c", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_360.c", @@ -1507,6 +1513,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_dct_neon.c", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_denoiser_neon.c", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_error_neon.c", @@ -1909,6 +1917,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.c", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_360.c", @@ -2352,6 +2362,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_dct_neon.c", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_denoiser_neon.c", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_error_neon.c", @@ -2762,6 +2774,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_dct_neon.c", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_denoiser_neon.c", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_frame_scale_neon.c", @@ -3200,6 +3214,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_dct_neon.c", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_denoiser_neon.c", "//third_party/libvpx/source/libvpx/vp9/encoder/arm/neon/vp9_frame_scale_neon.c", @@ -3597,6 +3613,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.c", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_360.c", @@ -3937,6 +3955,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.c", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_360.c", @@ -4276,6 +4296,8 @@ "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_detokenize.h", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.c", "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_dsubexp.h", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.c", + "//third_party/libvpx/source/libvpx/vp9/decoder/vp9_job_queue.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.c", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_alt_ref_aq.h", "//third_party/libvpx/source/libvpx/vp9/encoder/vp9_aq_360.c",
diff --git a/third_party/libvpx/source/config/ios/arm-neon/vpx_config.asm b/third_party/libvpx/source/config/ios/arm-neon/vpx_config.asm index beb3351..8a79f63d 100644 --- a/third_party/libvpx/source/config/ios/arm-neon/vpx_config.asm +++ b/third_party/libvpx/source/config/ios/arm-neon/vpx_config.asm
@@ -3,7 +3,6 @@ .set WIDE_REFERENCE, 0 .set ARCHITECTURE, 5 - .set DO1STROUNDING, 0 .syntax unified .set ARCH_ARM , 1 .set ARCH_MIPS , 0
diff --git a/third_party/libvpx/source/config/ios/arm64/vpx_config.asm b/third_party/libvpx/source/config/ios/arm64/vpx_config.asm index 2a02bb3a..ab563f8a 100644 --- a/third_party/libvpx/source/config/ios/arm64/vpx_config.asm +++ b/third_party/libvpx/source/config/ios/arm64/vpx_config.asm
@@ -3,7 +3,6 @@ .set WIDE_REFERENCE, 0 .set ARCHITECTURE, 5 - .set DO1STROUNDING, 0 .syntax unified .set ARCH_ARM , 1 .set ARCH_MIPS , 0
diff --git a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.asm b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.asm index 1733c41..241f370 100644 --- a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.asm +++ b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.asm
@@ -1,6 +1,5 @@ @ This file was created from a .asm file @ using the ads2gas.pl script. - .equ DO1STROUNDING, 0 .syntax unified .equ ARCH_ARM , 1 .equ ARCH_MIPS , 0
diff --git a/third_party/libvpx/source/config/linux/arm-neon-highbd/vpx_config.asm b/third_party/libvpx/source/config/linux/arm-neon-highbd/vpx_config.asm index 75e9f0f..225e0896 100644 --- a/third_party/libvpx/source/config/linux/arm-neon-highbd/vpx_config.asm +++ b/third_party/libvpx/source/config/linux/arm-neon-highbd/vpx_config.asm
@@ -1,6 +1,5 @@ @ This file was created from a .asm file @ using the ads2gas.pl script. - .equ DO1STROUNDING, 0 .syntax unified .equ ARCH_ARM , 1 .equ ARCH_MIPS , 0
diff --git a/third_party/libvpx/source/config/linux/arm-neon/vpx_config.asm b/third_party/libvpx/source/config/linux/arm-neon/vpx_config.asm index 9887adf..34101dab 100644 --- a/third_party/libvpx/source/config/linux/arm-neon/vpx_config.asm +++ b/third_party/libvpx/source/config/linux/arm-neon/vpx_config.asm
@@ -1,6 +1,5 @@ @ This file was created from a .asm file @ using the ads2gas.pl script. - .equ DO1STROUNDING, 0 .syntax unified .equ ARCH_ARM , 1 .equ ARCH_MIPS , 0
diff --git a/third_party/libvpx/source/config/linux/arm/vpx_config.asm b/third_party/libvpx/source/config/linux/arm/vpx_config.asm index 13377ed..b9450db 100644 --- a/third_party/libvpx/source/config/linux/arm/vpx_config.asm +++ b/third_party/libvpx/source/config/linux/arm/vpx_config.asm
@@ -1,6 +1,5 @@ @ This file was created from a .asm file @ using the ads2gas.pl script. - .equ DO1STROUNDING, 0 .syntax unified .equ ARCH_ARM , 1 .equ ARCH_MIPS , 0
diff --git a/third_party/libvpx/source/config/linux/arm64-highbd/vpx_config.asm b/third_party/libvpx/source/config/linux/arm64-highbd/vpx_config.asm index 8863b2c..f728cb2 100644 --- a/third_party/libvpx/source/config/linux/arm64-highbd/vpx_config.asm +++ b/third_party/libvpx/source/config/linux/arm64-highbd/vpx_config.asm
@@ -1,6 +1,5 @@ @ This file was created from a .asm file @ using the ads2gas.pl script. - .equ DO1STROUNDING, 0 .syntax unified .equ ARCH_ARM , 1 .equ ARCH_MIPS , 0
diff --git a/third_party/libvpx/source/config/linux/arm64/vpx_config.asm b/third_party/libvpx/source/config/linux/arm64/vpx_config.asm index d4de564..648ea113 100644 --- a/third_party/libvpx/source/config/linux/arm64/vpx_config.asm +++ b/third_party/libvpx/source/config/linux/arm64/vpx_config.asm
@@ -1,6 +1,5 @@ @ This file was created from a .asm file @ using the ads2gas.pl script. - .equ DO1STROUNDING, 0 .syntax unified .equ ARCH_ARM , 1 .equ ARCH_MIPS , 0
diff --git a/third_party/libvpx/source/config/linux/generic/vpx_config.asm b/third_party/libvpx/source/config/linux/generic/vpx_config.asm index 9bae4f7..20c7b9b 100644 --- a/third_party/libvpx/source/config/linux/generic/vpx_config.asm +++ b/third_party/libvpx/source/config/linux/generic/vpx_config.asm
@@ -1,6 +1,5 @@ @ This file was created from a .asm file @ using the ads2gas.pl script. - .equ DO1STROUNDING, 0 .syntax unified .equ ARCH_ARM , 0 .equ ARCH_MIPS , 0
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index 5e0b583..b279009 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,7 +2,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 7 #define VERSION_PATCH 0 -#define VERSION_EXTRA "1676-g9ecc0e779a" +#define VERSION_EXTRA "1741-gcde3da57b9" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.7.0-1676-g9ecc0e779a" -#define VERSION_STRING " v1.7.0-1676-g9ecc0e779a" +#define VERSION_STRING_NOSP "v1.7.0-1741-gcde3da57b9" +#define VERSION_STRING " v1.7.0-1741-gcde3da57b9"
diff --git a/third_party/libvpx/source/config/win/arm64/vpx_config.asm b/third_party/libvpx/source/config/win/arm64/vpx_config.asm index f0976ca7..5eeb841 100644 --- a/third_party/libvpx/source/config/win/arm64/vpx_config.asm +++ b/third_party/libvpx/source/config/win/arm64/vpx_config.asm
@@ -3,7 +3,6 @@ .set WIDE_REFERENCE, 0 .set ARCHITECTURE, 5 - .set DO1STROUNDING, 0 .syntax unified .set ARCH_ARM , 1 .set ARCH_MIPS , 0
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index cb09cb6..99c531c 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -5393,6 +5393,11 @@ <int value="1" label="Stale"/> </enum> +<enum name="BooleanStarsSalientImageFound"> + <int value="0" label="Salient image was not found."/> + <int value="1" label="Salient image was found."/> +</enum> + <enum name="BooleanStartedCompleted"> <int value="0" label="Started"/> <int value="1" label="Completed"/> @@ -31797,6 +31802,7 @@ <int value="7533886" label="disable-offer-store-unmasked-wallet-cards"/> <int value="10458238" label="disable-print-preview-simplify"/> <int value="11698808" label="enable-dom-distiller-button-animation"/> + <int value="19629326" label="OmniboxExperimentalKeywordMode:enabled"/> <int value="19815558" label="EnableSettingsShortcutSearch:disabled"/> <int value="23556595" label="MarkHttpAs:enabled"/> <int value="26875005" label="disable-explicit-dma-fences"/> @@ -31896,6 +31902,7 @@ <int value="201343576" label="enable-password-change-support:enabled"/> <int value="203239167" label="ImprovedGeoLanguageData:enabled"/> <int value="203776499" label="enable-virtual-keyboard-overscroll"/> + <int value="212489101" label="AutofillAssistantChromeEntry:enabled"/> <int value="215328738" label="ImprovedGeoLanguageData:disabled"/> <int value="217455219" label="SyncStandaloneTransport:enabled"/> <int value="218890378" label="ManualSaving:disabled"/> @@ -32542,6 +32549,7 @@ <int value="1330264457" label="OmniboxUIExperimentVerticalLayout:disabled"/> <int value="1332120969" label="ChromeDuet:disabled"/> <int value="1333847867" label="NoScriptPreviews:enabled"/> + <int value="1338356182" label="AutofillAssistantChromeEntry:disabled"/> <int value="1338864675" label="EnableTouchableAppContextMenu:disabled"/> <int value="1339426771" label="TopSitesFromSiteEngagement:disabled"/> <int value="1340690624" label="WebPaymentsMethodSectionOrderV2:disabled"/> @@ -32739,6 +32747,7 @@ <int value="1677167062" label="AutomaticPasswordGeneration:enabled"/> <int value="1677258310" label="DragAppsInTabletMode:disabled"/> <int value="1679558835" label="ArcAvailableForChildAccount:enabled"/> + <int value="1688075820" label="OmniboxExperimentalKeywordMode:disabled"/> <int value="1689123607" label="enable-app-link"/> <int value="1689183477" label="enable-merge-key-char-events"/> <int value="1690837904" label="save-previous-document-resources"/> @@ -50376,6 +50385,14 @@ <int value="6" label="Omnibox"/> </enum> +<enum name="StarsPromoActions"> + <int value="0" label="Displayed"> + The promo panel has been presented to the user. + </int> + <int value="1" label="Dismissed">The user selected the not now button.</int> + <int value="2" label="Completed">The user selected the sign-in button.</int> +</enum> + <enum name="StartupProfilingFinishReason"> <int value="0" label="Done (all metrics gathered)"/> <int value="1"
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 2132b39..2d67d05 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -42001,6 +42001,15 @@ </summary> </histogram> +<histogram name="Installer.PowerwashCount" units="powerwashes"> + <owner>zeuthen@chromium.org</owner> + <summary> + The number of times a Chrome OS device has been powerwashed (factory reset) + without subsequently going through recovery and/or changing the dev mode + switch. Reported once after each powerwash. + </summary> +</histogram> + <histogram name="Installer.RebootToNewPartitionAttempt" units="count" expires_after="2019-01-30"> <owner>zeuthen@chromium.org</owner> @@ -42116,6 +42125,15 @@ </summary> </histogram> +<histogram name="Installer.UpdateTime" units="seconds" + expires_after="2019-01-30"> + <owner>zeuthen@chromium.org</owner> + <summary> + The time in seconds it took to update a Chrome OS system -- from completing + an update check to reboot pending. + </summary> +</histogram> + <histogram name="Installer.UpdateURLSwitches" units="count" expires_after="2019-01-30"> <owner>zeuthen@chromium.org</owner> @@ -110576,6 +110594,44 @@ <summary>Amount of time taken to serialize a call stack profile.</summary> </histogram> +<histogram name="Stars.BookmarksBar_Active_Clip_Count" + expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when the bookmarks bar view is activated. + </summary> +</histogram> + +<histogram name="Stars.Clipper_Folio_Selected_Depth_Count" + expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the depth of a folio when it is selected in the clipper. + </summary> +</histogram> + +<histogram name="Stars.Clipper_Folio_Selected_Visible_Folio_Count" + expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the number of folios visible when a folio is selected in the clipper. + </summary> +</histogram> + +<histogram name="Stars.Clipper_Open_Folio_Count" expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of folios when the clipper is opened. + </summary> +</histogram> + +<histogram name="Stars.Folio_Active_Clip_Count" expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when the folio view is activated. + </summary> +</histogram> + <histogram name="Stars.Goog_Related" units="%" expires_after="2019-01-30"> <owner>yefim@chromium.org</owner> <summary> @@ -110610,10 +110666,58 @@ </summary> </histogram> +<histogram name="Stars.Launch_Bookmark_BookmarksBar_Clip_Count" + expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when a bookmark is launched from the + bookmarks bar view. + </summary> +</histogram> + +<histogram name="Stars.Launch_Bookmark_Folio_Clip_Count" + expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when a bookmark is launched from the folio + view. + </summary> +</histogram> + +<histogram name="Stars.Launch_Bookmark_Search_Clip_Count" + expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when a bookmark is launched from the search + view. + </summary> +</histogram> + +<histogram name="Stars.Launch_Bookmark_SmartGroup_Clip_Count" + expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when a bookmark is launched from the smart + group view. + </summary> +</histogram> + +<histogram name="Stars.Launch_Bookmark_Timeline_Clip_Count" + expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when a bookmark is launched from the + timeline view. + </summary> +</histogram> + <histogram name="Stars.LaunchLocation" enum="StarsLaunchLocation" expires_after="2019-01-30"> - <owner>ianwen@chromium.org</owner> - <summary>Logs a UI location from which a bookmark is launched.</summary> + <owner>lpromero@chromium.org</owner> + <summary> + Logs every time a bookmark is launched from an assortment of different UI + surfaces with Stars, the new bookmarks UI. + </summary> </histogram> <histogram name="Stars.No_Images_Snippets" units="%" expires_after="2019-01-30"> @@ -110633,6 +110737,66 @@ </summary> </histogram> +<histogram name="Stars.Number_Of_Nodes" expires_after="2019-01-30"> + <owner>yefim@chromium.org</owner> + <summary> + Logs number of bookmark nodes every time stars extension is loaded. + </summary> +</histogram> + +<histogram name="Stars.Profile_Active_Clip_Count" expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when the profile view is activated. + </summary> +</histogram> + +<histogram name="Stars.PromoActions" enum="StarsPromoActions" + expires_after="2019-01-30"> + <owner>jbbegue@chromium.org</owner> + <summary> + Count the actions performed by the user on the stars promo panel currently + only on android and ios. + </summary> +</histogram> + +<histogram name="Stars.SalientImageFound" enum="BooleanStarsSalientImageFound" + expires_after="2019-01-30"> + <owner>lpromero@chromium.org</owner> + <summary> + A boolean that indicates if a salient image was found for a displayed + bookmark. It is recorded every single time a bookmark is displayed. That + way, this histogram shows the proportion of bookmarks the user sees with an + image. This is used only with Stars, the new bookmarks UI. + </summary> +</histogram> + +<histogram name="Stars.Search_Active_Clip_Count" expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when the search view is activated. + </summary> +</histogram> + +<histogram name="Stars.SmartGroup_Active_Clip_Count" expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when the smart group view is activated. + </summary> +</histogram> + +<histogram name="Stars.Timeline_Active_Clip_Count" expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary> + Logs the approx number of clips when the timeline view is activated. + </summary> +</histogram> + +<histogram name="Stars.Version" expires_after="2019-01-30"> + <owner>accamed@google.com</owner> + <summary>Logs the extension version the user is using.</summary> +</histogram> + <histogram name="Startup.AfterStartupTaskCount"> <owner>michaeln@chromium.org</owner> <summary>
diff --git a/tools/perf/contrib/leak_detection/page_sets.py b/tools/perf/contrib/leak_detection/page_sets.py index ec1b2b0..0130e0c 100644 --- a/tools/perf/contrib/leak_detection/page_sets.py +++ b/tools/perf/contrib/leak_detection/page_sets.py
@@ -117,7 +117,8 @@ 'https://www.blizzard.com', 'https://ign.com/', 'https://www.yelp.com/', - 'https://gizmodo.com/', + # Times out waiting for HasReachedQuiescence - crbug.com/927427 + # 'https://gizmodo.com/', 'https://www.gsmarena.com/', 'https://www.theverge.com/', 'https://www.nlm.nih.gov/',
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py index 2146fae..fb92d52 100755 --- a/tools/perf/process_perf_results.py +++ b/tools/perf/process_perf_results.py
@@ -48,6 +48,15 @@ DATA_FORMAT_HISTOGRAMS = 'histograms' DATA_FORMAT_UNKNOWN = 'unknown' +# See https://crbug.com/923564. +# We want to switch over to using histograms for everything, but converting from +# the format output by gtest perf tests to histograms has introduced several +# problems. So, only perform the conversion on tests that are whitelisted and +# are okay with potentially encountering issues. +GTEST_CONVERSION_WHITELIST = [ + 'xr.vr.common_perftests', +] + def _GetMachineGroup(build_properties): machine_group = None @@ -95,6 +104,13 @@ buildbucket['build'].get('bucket') == 'luci.chrome.ci'): is_luci = True + if is_luci and _is_gtest(json_to_upload) and ( + name in GTEST_CONVERSION_WHITELIST): + path_util.AddTracingToPath() + from tracing.value import gtest_json_converter + gtest_json_converter.ConvertGtestJsonFile(json_to_upload) + _data_format_cache[json_to_upload] = DATA_FORMAT_HISTOGRAMS + if 'build' in buildbucket: args += [ '--project', buildbucket['build'].get('project'),
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn index 47fb630..d2e351d 100644 --- a/ui/base/ime/BUILD.gn +++ b/ui/base/ime/BUILD.gn
@@ -41,6 +41,18 @@ ":text_input_types", "//skia", ] + + if (is_chromeos || use_ozone) { + sources += [ + "character_composer.cc", + "character_composer.h", + ] + deps += [ + "//ui/events:dom_keycode_converter", + "//ui/events:events", + "//ui/events:events_base", + ] + } } jumbo_component("ime") { @@ -173,14 +185,6 @@ ] } - if (is_chromeos || use_ozone) { - sources += [ - "character_composer.cc", - "character_composer.h", - ] - deps += [ "//ui/events:dom_keycode_converter" ] - } - if (!toolkit_views && !use_aura) { sources -= [ "input_method_factory.cc",
diff --git a/ui/base/ime/character_composer.h b/ui/base/ime/character_composer.h index b3845c3..9f7967e 100644 --- a/ui/base/ime/character_composer.h +++ b/ui/base/ime/character_composer.h
@@ -12,7 +12,7 @@ #include "base/macros.h" #include "base/strings/string_util.h" -#include "ui/base/ime/ui_base_ime_export.h" +#include "ui/base/ime/ui_base_ime_types_export.h" #include "ui/events/keycodes/dom/dom_key.h" namespace ui { @@ -20,7 +20,7 @@ // A class to recognize compose and dead key sequence. // Outputs composed character. -class UI_BASE_IME_EXPORT CharacterComposer { +class UI_BASE_IME_TYPES_EXPORT CharacterComposer { public: using ComposeBuffer = std::vector<DomKey>;
diff --git a/ui/events/keycodes/platform_key_map_win_unittest.cc b/ui/events/keycodes/platform_key_map_win_unittest.cc index da2459c..34f13dc 100644 --- a/ui/events/keycodes/platform_key_map_win_unittest.cc +++ b/ui/events/keycodes/platform_key_map_win_unittest.cc
@@ -408,10 +408,10 @@ } } -INSTANTIATE_TEST_CASE_P(VerifyAltGraph, - AltGraphModifierTest, - ::testing::Values(KEYBOARD_LAYOUT_ENGLISH_US, - KEYBOARD_LAYOUT_FRENCH)); +INSTANTIATE_TEST_SUITE_P(VerifyAltGraph, + AltGraphModifierTest, + ::testing::Values(KEYBOARD_LAYOUT_ENGLISH_US, + KEYBOARD_LAYOUT_FRENCH)); } // namespace
diff --git a/ui/ozone/platform/scenic/scenic_screen.cc b/ui/ozone/platform/scenic/scenic_screen.cc index e7658c5c..170db83 100644 --- a/ui/ozone/platform/scenic/scenic_screen.cc +++ b/ui/ozone/platform/scenic/scenic_screen.cc
@@ -91,13 +91,13 @@ } gfx::Point ScenicScreen::GetCursorScreenPoint() const { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return gfx::Point(); } gfx::AcceleratedWidget ScenicScreen::GetAcceleratedWidgetAtScreenPoint( const gfx::Point& point) const { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return gfx::kNullAcceleratedWidget; }
diff --git a/ui/ozone/platform/scenic/scenic_surface_factory.cc b/ui/ozone/platform/scenic/scenic_surface_factory.cc index cce2266..5bca937 100644 --- a/ui/ozone/platform/scenic/scenic_surface_factory.cc +++ b/ui/ozone/platform/scenic/scenic_surface_factory.cc
@@ -69,7 +69,7 @@ gfx::Size size, gfx::BufferFormat format) : size_(size), format_(format) { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } bool AreDmaBufFdsValid() const override { return false; }
diff --git a/ui/ozone/platform/scenic/scenic_window.cc b/ui/ozone/platform/scenic/scenic_window.cc index 5403f8e..60537dc 100644 --- a/ui/ozone/platform/scenic/scenic_window.cc +++ b/ui/ozone/platform/scenic/scenic_window.cc
@@ -121,15 +121,15 @@ } void ScenicWindow::SetCapture() { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void ScenicWindow::ReleaseCapture() { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } bool ScenicWindow::HasCapture() const { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return false; } @@ -154,11 +154,11 @@ } void ScenicWindow::SetCursor(PlatformCursor cursor) { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void ScenicWindow::MoveCursorTo(const gfx::Point& location) { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void ScenicWindow::ConfineCursorToBounds(const gfx::Rect& bounds) {
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 39b326f..29a47cd 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -192,6 +192,8 @@ "test/test_pointer.h", "test/test_positioner.cc", "test/test_positioner.h", + "test/test_region.cc", + "test/test_region.h", "test/test_seat.cc", "test/test_seat.h", "test/test_touch.cc", @@ -202,6 +204,7 @@ deps = [ "//base:base", + "//skia", "//testing/gmock", "//third_party/wayland:wayland_server", "//third_party/wayland-protocols:linux_dmabuf_protocol",
diff --git a/ui/ozone/platform/wayland/test/mock_surface.cc b/ui/ozone/platform/wayland/test/mock_surface.cc index 7f266b69..bab5b77 100644 --- a/ui/ozone/platform/wayland/test/mock_surface.cc +++ b/ui/ozone/platform/wayland/test/mock_surface.cc
@@ -16,6 +16,18 @@ GetUserDataAs<MockSurface>(resource)->Attach(buffer_resource, x, y); } +void SetOpaqueRegion(wl_client* client, + wl_resource* resource, + wl_resource* region) { + GetUserDataAs<MockSurface>(resource)->SetOpaqueRegion(region); +} + +void SetInputRegion(wl_client* client, + wl_resource* resource, + wl_resource* region) { + GetUserDataAs<MockSurface>(resource)->SetInputRegion(region); +} + void Damage(wl_client* client, wl_resource* resource, int32_t x, @@ -32,16 +44,16 @@ } // namespace const struct wl_surface_interface kMockSurfaceImpl = { - &DestroyResource, // destroy - &Attach, // attach - &Damage, // damage - nullptr, // frame - nullptr, // set_opaque_region - nullptr, // set_input_region - &Commit, // commit - nullptr, // set_buffer_transform - nullptr, // set_buffer_scale - nullptr, // damage_buffer + DestroyResource, // destroy + Attach, // attach + Damage, // damage + nullptr, // frame + SetOpaqueRegion, // set_opaque_region + SetInputRegion, // set_input_region + Commit, // commit + nullptr, // set_buffer_transform + nullptr, // set_buffer_scale + nullptr, // damage_buffer }; MockSurface::MockSurface(wl_resource* resource) : ServerObject(resource) {}
diff --git a/ui/ozone/platform/wayland/test/mock_surface.h b/ui/ozone/platform/wayland/test/mock_surface.h index a4ba746..1140ce2 100644 --- a/ui/ozone/platform/wayland/test/mock_surface.h +++ b/ui/ozone/platform/wayland/test/mock_surface.h
@@ -27,6 +27,8 @@ static MockSurface* FromResource(wl_resource* resource); MOCK_METHOD3(Attach, void(wl_resource* buffer, int32_t x, int32_t y)); + MOCK_METHOD1(SetOpaqueRegion, void(wl_resource* region)); + MOCK_METHOD1(SetInputRegion, void(wl_resource* region)); MOCK_METHOD4(Damage, void(int32_t x, int32_t y, int32_t width, int32_t height)); MOCK_METHOD0(Commit, void());
diff --git a/ui/ozone/platform/wayland/test/test_compositor.cc b/ui/ozone/platform/wayland/test/test_compositor.cc index a8195d9..0d22217 100644 --- a/ui/ozone/platform/wayland/test/test_compositor.cc +++ b/ui/ozone/platform/wayland/test/test_compositor.cc
@@ -6,8 +6,10 @@ #include <wayland-server-core.h> +#include "base/logging.h" #include "ui/ozone/platform/wayland/test/mock_surface.h" #include "ui/ozone/platform/wayland/test/server_object.h" +#include "ui/ozone/platform/wayland/test/test_region.h" namespace wl { @@ -16,7 +18,6 @@ constexpr uint32_t kCompositorVersion = 4; void CreateSurface(wl_client* client, wl_resource* resource, uint32_t id) { - auto* compositor = GetUserDataAs<TestCompositor>(resource); wl_resource* surface_resource = wl_resource_create( client, &wl_surface_interface, wl_resource_get_version(resource), id); if (!surface_resource) { @@ -25,14 +26,23 @@ } SetImplementation(surface_resource, &kMockSurfaceImpl, std::make_unique<MockSurface>(surface_resource)); + + auto* compositor = GetUserDataAs<TestCompositor>(resource); compositor->AddSurface(GetUserDataAs<MockSurface>(surface_resource)); } +void CreateRegion(wl_client* client, wl_resource* resource, uint32_t id) { + wl_resource* region_resource = + wl_resource_create(client, &wl_region_interface, 1, id); + SetImplementation(region_resource, &kTestWlRegionImpl, + std::make_unique<TestRegion>()); +} + } // namespace const struct wl_compositor_interface kTestCompositorImpl = { - &CreateSurface, // create_surface - nullptr, // create_region + CreateSurface, // create_surface + CreateRegion, // create_region }; TestCompositor::TestCompositor()
diff --git a/ui/ozone/platform/wayland/test/test_region.cc b/ui/ozone/platform/wayland/test/test_region.cc new file mode 100644 index 0000000..ff1fbd0c --- /dev/null +++ b/ui/ozone/platform/wayland/test/test_region.cc
@@ -0,0 +1,43 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/ozone/platform/wayland/test/test_region.h" + +#include <wayland-server-core.h> + +#include "ui/ozone/platform/wayland/test/server_object.h" + +namespace wl { + +namespace { + +void Destroy(wl_client* client, wl_resource* resource) { + wl_resource_destroy(resource); +} + +void Add(wl_client* client, + wl_resource* resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) { + GetUserDataAs<SkRegion>(resource)->op(SkIRect::MakeXYWH(x, y, width, height), + SkRegion::kUnion_Op); +} + +static void Subtract(wl_client* client, + wl_resource* resource, + int32_t x, + int32_t y, + int32_t width, + int32_t height) { + GetUserDataAs<SkRegion>(resource)->op(SkIRect::MakeXYWH(x, y, width, height), + SkRegion::kDifference_Op); +} + +} // namespace + +const struct wl_region_interface kTestWlRegionImpl = {Destroy, Add, Subtract}; + +} // namespace wl
diff --git a/ui/ozone/platform/wayland/test/test_region.h b/ui/ozone/platform/wayland/test/test_region.h new file mode 100644 index 0000000..a0dd582 --- /dev/null +++ b/ui/ozone/platform/wayland/test/test_region.h
@@ -0,0 +1,20 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_REGION_H_ +#define UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_REGION_H_ + +#include <wayland-server-protocol-core.h> + +#include "third_party/skia/include/core/SkRegion.h" + +namespace wl { + +extern const struct wl_region_interface kTestWlRegionImpl; + +using TestRegion = SkRegion; + +} // namespace wl + +#endif // UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_REGION_H_
diff --git a/ui/views/mus/desktop_window_tree_host_mus.cc b/ui/views/mus/desktop_window_tree_host_mus.cc index b550b31..f48d31b 100644 --- a/ui/views/mus/desktop_window_tree_host_mus.cc +++ b/ui/views/mus/desktop_window_tree_host_mus.cc
@@ -309,6 +309,25 @@ Hide(); } +void DesktopWindowTreeHostMus::UpdateMinAndMaxSize() { + gfx::Size min_size = content_window()->delegate()->GetMinimumSize(); + gfx::Size max_size = content_window()->delegate()->GetMaximumSize(); + if (min_size_ == min_size && max_size_ == max_size) + return; + min_size_ = min_size; + max_size_ = max_size; + // Setting the property to |window()| to propagate those properties to the + // window server. + if (min_size_ == gfx::Size()) + window()->ClearProperty(aura::client::kMinimumSize); + else + window()->SetProperty(aura::client::kMinimumSize, new gfx::Size(min_size_)); + if (max_size_ == gfx::Size()) + window()->ClearProperty(aura::client::kMaximumSize); + else + window()->SetProperty(aura::client::kMaximumSize, new gfx::Size(max_size_)); +} + void DesktopWindowTreeHostMus::Init(const Widget::InitParams& params) { const bool translucent = MusClient::ShouldMakeWidgetWindowsTranslucent(params); @@ -529,6 +548,9 @@ // otherwise focus goes to window(). content_window()->Show(); + if (show_state != ui::SHOW_STATE_MINIMIZED) + UpdateMinAndMaxSize(); + if (notify_visibility_change) native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); @@ -873,6 +895,7 @@ if (widget->widget_delegate()) behavior = widget->widget_delegate()->GetResizeBehavior(); window()->SetProperty(aura::client::kResizeBehaviorKey, behavior); + UpdateMinAndMaxSize(); } bool DesktopWindowTreeHostMus::ShouldUpdateWindowTransparency() const { @@ -985,6 +1008,7 @@ if (!max_size_in_pixels.IsEmpty()) size.SetToMin(max_size_in_pixels); final_bounds_in_pixels.set_size(size); + UpdateMinAndMaxSize(); } WindowTreeHostMus::SetBoundsInPixels(final_bounds_in_pixels, local_surface_id_allocation);
diff --git a/ui/views/mus/desktop_window_tree_host_mus.h b/ui/views/mus/desktop_window_tree_host_mus.h index 4674a08..a95e38e 100644 --- a/ui/views/mus/desktop_window_tree_host_mus.h +++ b/ui/views/mus/desktop_window_tree_host_mus.h
@@ -80,6 +80,9 @@ // WindowObserver::OnWindowVisibilityChanged(). void OnWindowTreeHostWindowVisibilityChanged(bool visible); + // Checks the minimum and the maximum size and notifies to the window service. + void UpdateMinAndMaxSize(); + // DesktopWindowTreeHost: void Init(const Widget::InitParams& params) override; void OnNativeWidgetCreated(const Widget::InitParams& params) override; @@ -196,6 +199,10 @@ // a change in the visibility of window(). bool is_updating_window_visibility_ = false; + // The maximum size and the minimum size of the window. + gfx::Size max_size_; + gfx::Size min_size_; + // aura::WindowObserver on window(). std::unique_ptr<WindowTreeHostWindowObserver> window_tree_host_window_observer_;
diff --git a/ui/views/mus/desktop_window_tree_host_mus_unittest.cc b/ui/views/mus/desktop_window_tree_host_mus_unittest.cc index d4b6ac1..a0e976c 100644 --- a/ui/views/mus/desktop_window_tree_host_mus_unittest.cc +++ b/ui/views/mus/desktop_window_tree_host_mus_unittest.cc
@@ -933,6 +933,83 @@ transient_child->RemoveObserver(&observer); } +class StaticSizedWidgetDelegate : public WidgetDelegateView { + public: + StaticSizedWidgetDelegate(const gfx::Size& min_size, + const gfx::Size& max_size) + : min_size_(min_size), max_size_(max_size) {} + ~StaticSizedWidgetDelegate() override = default; + + void SetMinMaxSize(const gfx::Size& min_size, const gfx::Size& max_size) { + min_size_ = min_size; + max_size_ = max_size; + } + + private: + // View: + gfx::Size GetMinimumSize() const override { return min_size_; } + gfx::Size GetMaximumSize() const override { return max_size_; } + + gfx::Size min_size_; + gfx::Size max_size_; + + DISALLOW_COPY_AND_ASSIGN(StaticSizedWidgetDelegate); +}; + +TEST_F(DesktopWindowTreeHostMusTest, MinMaxSize) { + gfx::Size min_size(100, 100); + gfx::Size max_size(200, 200); + auto* delegate = new StaticSizedWidgetDelegate(min_size, max_size); + std::unique_ptr<Widget> widget = CreateWidget(delegate); + aura::Window* window = widget->GetNativeWindow()->GetRootWindow(); + + // min/max sizes are not yet set. + EXPECT_FALSE(window->GetProperty(aura::client::kMinimumSize)); + EXPECT_FALSE(window->GetProperty(aura::client::kMaximumSize)); + + widget->Show(); + EXPECT_EQ(min_size, *window->GetProperty(aura::client::kMinimumSize)); + EXPECT_EQ(max_size, *window->GetProperty(aura::client::kMaximumSize)); + + // Changing the min/max size isn't propagated immediately. + gfx::Size min_size2(120, 130); + gfx::Size max_size2(190, 180); + delegate->SetMinMaxSize(min_size2, max_size2); + EXPECT_EQ(min_size, *window->GetProperty(aura::client::kMinimumSize)); + EXPECT_EQ(max_size, *window->GetProperty(aura::client::kMaximumSize)); + + // Propagated when the widget gets resized. + widget->SetBounds(gfx::Rect(0, 0, 150, 150)); + EXPECT_EQ(min_size2, *window->GetProperty(aura::client::kMinimumSize)); + EXPECT_EQ(max_size2, *window->GetProperty(aura::client::kMaximumSize)); + + delegate->SetMinMaxSize(min_size, max_size); + // SizeConstraintsChanged should cause the update of min/max size. + widget->OnSizeConstraintsChanged(); + EXPECT_EQ(min_size, *window->GetProperty(aura::client::kMinimumSize)); + EXPECT_EQ(max_size, *window->GetProperty(aura::client::kMaximumSize)); + + // Re-show should propagate the information. + delegate->SetMinMaxSize(min_size2, max_size2); + widget->Hide(); + widget->Show(); + EXPECT_EQ(min_size2, *window->GetProperty(aura::client::kMinimumSize)); + EXPECT_EQ(max_size2, *window->GetProperty(aura::client::kMaximumSize)); + + // If not changed, properties shouldn't be updated. + gfx::Size* min_ptr = window->GetProperty(aura::client::kMinimumSize); + gfx::Size* max_ptr = window->GetProperty(aura::client::kMaximumSize); + widget->OnSizeConstraintsChanged(); + EXPECT_EQ(min_ptr, window->GetProperty(aura::client::kMinimumSize)); + EXPECT_EQ(max_ptr, window->GetProperty(aura::client::kMaximumSize)); + + // If there are no limits, properties should be cleared. + delegate->SetMinMaxSize(gfx::Size(), gfx::Size()); + widget->OnSizeConstraintsChanged(); + EXPECT_FALSE(window->GetProperty(aura::client::kMinimumSize)); + EXPECT_FALSE(window->GetProperty(aura::client::kMaximumSize)); +} + // DesktopWindowTreeHostMusTest with --force-device-scale-factor=1.25. class DesktopWindowTreeHostMusTestFractionalDPI : public DesktopWindowTreeHostMusTest {
diff --git a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.html b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.html index 4bcb282..edf7f63 100644 --- a/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.html +++ b/ui/webui/resources/cr_elements/cr_search_field/cr_search_field.html
@@ -12,8 +12,6 @@ <template> <style include="cr-shared-style"> :host { - /* TODO(crbug/925209): GG 900 in light mode seems overly dark. */ - --cr-search-field-border-color: var(--cr-primary-text-color); display: flex; user-select: none; } @@ -41,7 +39,7 @@ --cr-input-error-display: none; --cr-input-input: { height: 100%; - border-bottom: 1px solid var(--cr-search-field-border-color); + border-bottom: 1px solid var(--cr-secondary-text-color); } --cr-input-padding-end: 0; --cr-input-padding-start: 0; @@ -60,7 +58,6 @@ * background of the container cr-input to white). Can we just not set * these rules? */ --cr-input-background-color: inherit; - --cr-search-field-border-color: var(--cr-secondary-text-color); } :host([has-search-text]) cr-input {
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html index 8c3df8bf..5b8ba4f 100644 --- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html +++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar.html
@@ -14,13 +14,13 @@ --cr-toolbar-height: 56px; --paper-icon-button-ink-color: white; align-items: center; + /* TODO(dbeam): default background-color instead of external styling. */ color: #fff; display: flex; height: var(--cr-toolbar-height); } :host-context([dark]) { - border-bottom: var(--cr-separator-line); color: var(--cr-secondary-text-color); }
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.html b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.html index 217cc5a..e750064 100644 --- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.html +++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.html
@@ -11,7 +11,7 @@ <template> <style include="cr-icons paper-button-style"> :host { - background: white; + background-color: white; border-bottom: 1px solid var(--google-grey-300); bottom: 0; color: var(--google-grey-900); @@ -29,10 +29,10 @@ } :host-context([dark]) { - background: var(--google-grey-900); + background-color: var(--google-grey-900); background-image: linear-gradient(rgba(255, 255, 255, .04), rgba(255, 255, 255, .04)); - border-bottom-color: var(--google-grey-refresh-700); + border-bottom-color: var(--cr-separator-color); color: var(--cr-secondary-text-color); }
diff --git a/ui/webui/resources/cr_elements/paper_button_style_css.html b/ui/webui/resources/cr_elements/paper_button_style_css.html index 608cf8a1..e1a7665181 100644 --- a/ui/webui/resources/cr_elements/paper_button_style_css.html +++ b/ui/webui/resources/cr_elements/paper_button_style_css.html
@@ -80,7 +80,7 @@ color: var(--text-color); flex-shrink: 0; font-weight: 500; - height: 32px; + height: var(--cr-button-height); margin: 0; padding: 8px 16px; text-decoration: none;
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html index fc8a660..0650ade 100644 --- a/ui/webui/resources/cr_elements/shared_vars_css.html +++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -34,6 +34,8 @@ --google-blue-refresh-500-rgb: 66, 133, 244; /* #4285f4 */ --google-blue-refresh-500: rgb(var(--google-blue-refresh-500-rgb)); + --google-green-refresh-300-rgb: 129, 201, 149; /* #81c995 */ + --google-green-refresh-300: rgb(var(--google-green-refresh-300-rgb)); --google-green-refresh-700-rgb: 24, 128, 56; /* #188038 */ --google-green-refresh-700: rgb(var(--google-green-refresh-700-rgb)); @@ -111,6 +113,7 @@ } --cr-button-edge-spacing: 12px; + --cr-button-height: 32px; /* Spacing between policy (controlledBy) indicator and control. */ --cr-controlled-by-spacing: 24px;
diff --git a/ui/webui/resources/css/md_colors.css b/ui/webui/resources/css/md_colors.css index 4166c6422..28a2dc1 100644 --- a/ui/webui/resources/css/md_colors.css +++ b/ui/webui/resources/css/md_colors.css
@@ -2,23 +2,17 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -:root { +html { /* This is a custom, Chrome-specific color that does not have a --paper or * --google equivalent. */ --md-background-color: rgb(248, 249, 250); --md-loading-message-color: #6e6e6e; - /* This is --google-blue-700, rewritten as a native custom property for speed. - */ + /* --google-blue-700, rewritten as a native custom property for speed. */ --md-toolbar-color: rgb(51, 103, 214); } -html[dark], -:host-context(html[dark]) { +html[dark] { --md-background-color: rgb(32, 33, 36); /* --google-grey-900 */ --md-loading-message-color: #9AA0A6; /* --google-grey-refresh-500 */ - --md-toolbar-border-color: rgb(95, 99, 104); /* --google-grey-refresh-700 */ - /* Dark mode doesn't currently have a different toolbar background color. - * Instead, it uses a 1px grey border at the bottom. We set it just in case - * opaqueness is required for some reason. */ - --md-toolbar-color: var(--md-background-color); + --md-toolbar-color: rgba(255, 255, 255, .04); }