diff --git a/DEPS b/DEPS index 35c747f5..bada0b49 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'fc75b5afdef9bf896e20de9e88ca99f336616559', + 'skia_revision': '5128bd4b184b4572321821ad14def1a910159d6b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '03ab3db7e516b4d71a0d372bc1fa7dc79ecefe31', + 'v8_revision': '70995dbfd413e096476967b8780022e6cfe507bf', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '2de8e90be0fce0badb911dfdc460dc1688797bd8', + 'catapult_revision': '353ee60a4567ec80252bb4047e54b2df3151717e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -236,7 +236,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'c7166594d0397a894962f6ba6a0c02effba3767b', # commit position 17031 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '17d9d862b82ff297f2338f36717296067b5a6952', # commit position 17066 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/base/android/java/src/org/chromium/base/ResourceExtractor.java b/base/android/java/src/org/chromium/base/ResourceExtractor.java index 898b4910..c1d18560 100644 --- a/base/android/java/src/org/chromium/base/ResourceExtractor.java +++ b/base/android/java/src/org/chromium/base/ResourceExtractor.java
@@ -17,6 +17,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.concurrent.CancellationException; @@ -187,6 +188,10 @@ activeLocalePakFiles.add(locale + ".pak"); } } + if (activeLocalePakFiles.isEmpty() && BuildConfig.COMPRESSED_LOCALES.length > 0) { + assert Arrays.asList(BuildConfig.COMPRESSED_LOCALES).contains(FALLBACK_LOCALE); + activeLocalePakFiles.add(FALLBACK_LOCALE + ".pak"); + } return activeLocalePakFiles.toArray(new String[activeLocalePakFiles.size()]); }
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc index 5c918f8..84a7a45 100644 --- a/base/files/file_util_unittest.cc +++ b/base/files/file_util_unittest.cc
@@ -1744,7 +1744,7 @@ TEST_F(FileUtilTest, OpenFileNoInheritance) { FilePath file_path(temp_dir_.GetPath().Append(FPL("a_file"))); - for (const char* mode : {"wb", "r,ccs=UNICODE"}) { + for (const char* mode : {"wb", "r,ccs=UTF-8"}) { SCOPED_TRACE(mode); ASSERT_NO_FATAL_FAILURE(CreateTextFile(file_path, L"Geepers")); FILE* file = OpenFile(file_path, mode);
diff --git a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc index 01008ae..259f34f 100644 --- a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc +++ b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc
@@ -265,6 +265,12 @@ content::WindowedNotificationObserver( extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND, content::NotificationService::AllSources()).Wait(); + // Temporary solution to mimic the old behavior of + // WindowedNotificationObserver. + // TODO(https://crbug.com/695073): Likely this has to be removed, and the + // IsIdleForTesting check at the end of this test has to be either changed to + // a more specific check or removed. + content::RunAllPendingInMessageLoop(); // Verify that the downloader is attempting to download a CRX file. fetcher = factory.GetFetcherByID(
diff --git a/chrome/browser/chromeos/login/login_manager_test.cc b/chrome/browser/chromeos/login/login_manager_test.cc index ac0b973..cc76175 100644 --- a/chrome/browser/chromeos/login/login_manager_test.cc +++ b/chrome/browser/chromeos/login/login_manager_test.cc
@@ -201,6 +201,8 @@ const UserContext user_context = CreateUserContext(user_id); SetExpectedCredentials(user_context); EXPECT_TRUE(TryToLogin(user_context)); + // Let LoginDisplayHostImpl delete itself. + content::RunAllPendingInMessageLoop(); } void LoginManagerTest::AddUser(const std::string& user_id) {
diff --git a/chrome/browser/password_manager/credential_manager_browsertest.cc b/chrome/browser/password_manager/credential_manager_browsertest.cc index be572bb..4520685 100644 --- a/chrome/browser/password_manager/credential_manager_browsertest.cc +++ b/chrome/browser/password_manager/credential_manager_browsertest.cc
@@ -118,16 +118,8 @@ IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, StoreSavesPSLMatchedCredential) { - // Setup HTTPS server serving files from standard test directory. - static constexpr base::FilePath::CharType kDocRoot[] = - FILE_PATH_LITERAL("chrome/test/data"); - net::EmbeddedTestServer https_test_server( - net::EmbeddedTestServer::TYPE_HTTPS); - https_test_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); - ASSERT_TRUE(https_test_server.Start()); - // Setup mock certificate for all origins. - auto cert = https_test_server.GetCertificate(); + auto cert = https_test_server().GetCertificate(); net::CertVerifyResult verify_result; verify_result.cert_status = 0; verify_result.is_issued_by_known_root = true; @@ -144,7 +136,7 @@ .get()); // The call to |GetURL| is needed to get the correct port. - GURL psl_url = https_test_server.GetURL("psl.example.com", "/"); + GURL psl_url = https_test_server().GetURL("psl.example.com", "/"); autofill::PasswordForm signin_form; signin_form.signon_realm = psl_url.spec(); @@ -153,7 +145,7 @@ signin_form.origin = psl_url; password_store->AddLogin(signin_form); - NavigateToURL(https_test_server, "www.example.com", + NavigateToURL(https_test_server(), "www.example.com", "/password/password_form.html"); // Call the API to trigger |get| and |store| and redirect. @@ -187,7 +179,7 @@ // There should be an entry for both psl.example.com and www.example.com. password_manager::TestPasswordStore::PasswordMap passwords = password_store->stored_passwords(); - GURL www_url = https_test_server.GetURL("www.example.com", "/"); + GURL www_url = https_test_server().GetURL("www.example.com", "/"); EXPECT_EQ(2U, passwords.size()); EXPECT_TRUE(base::ContainsKey(passwords, psl_url.spec())); EXPECT_TRUE(base::ContainsKey(passwords, www_url.spec()));
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index bb692e70..3598b35 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -52,7 +52,6 @@ #include "content/public/test/test_utils.h" #include "net/base/filename_util.h" #include "net/dns/mock_host_resolver.h" -#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "net/url_request/test_url_fetcher_factory.h" @@ -1386,19 +1385,13 @@ ::switches::kAllowRunningInsecureContent); base::CommandLine::ForCurrentProcess()->AppendSwitch( ::switches::kIgnoreCertificateErrors); - const base::FilePath::CharType kDocRoot[] = - FILE_PATH_LITERAL("chrome/test/data"); - net::EmbeddedTestServer https_test_server( - net::EmbeddedTestServer::TYPE_HTTPS); - https_test_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); - ASSERT_TRUE(https_test_server.Start()); // This test case cannot inject the scripts via content::ExecuteScript() in // files served through HTTPS. Therefore the scripts are made part of the HTML // site and executed on load. std::string path = "/password/separate_login_form_with_onload_submit_script.html"; - GURL https_url(https_test_server.GetURL(path)); + GURL https_url(https_test_server().GetURL(path)); ASSERT_TRUE(https_url.SchemeIs(url::kHttpsScheme)); NavigationObserver observer(WebContents()); @@ -1421,15 +1414,9 @@ ::switches::kAllowRunningInsecureContent); base::CommandLine::ForCurrentProcess()->AppendSwitch( ::switches::kIgnoreCertificateErrors); - const base::FilePath::CharType kDocRoot[] = - FILE_PATH_LITERAL("chrome/test/data"); - net::EmbeddedTestServer https_test_server( - net::EmbeddedTestServer::TYPE_HTTPS); - https_test_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); - ASSERT_TRUE(https_test_server.Start()); std::string path = "/password/password_form.html"; - GURL https_url(https_test_server.GetURL(path)); + GURL https_url(https_test_server().GetURL(path)); ASSERT_TRUE(https_url.SchemeIs(url::kHttpsScheme)); NavigationObserver form_observer(WebContents()); @@ -1490,14 +1477,8 @@ // Tests that after HTTP -> HTTPS migration the credential is autofilled. IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, HttpMigratedCredentialAutofilled) { - net::EmbeddedTestServer https_test_server( - net::EmbeddedTestServer::TYPE_HTTPS); - https_test_server.ServeFilesFromSourceDirectory( - base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); - ASSERT_TRUE(https_test_server.Start()); - // Add an http credential to the password store. - GURL https_origin = https_test_server.base_url(); + GURL https_origin = https_test_server().base_url(); ASSERT_TRUE(https_origin.SchemeIs(url::kHttpsScheme)); GURL::Replacements rep; rep.SetSchemeStr(url::kHttpScheme); @@ -1518,7 +1499,7 @@ NavigationObserver form_observer(WebContents()); ui_test_utils::NavigateToURL( - browser(), https_test_server.GetURL("/password/password_form.html")); + browser(), https_test_server().GetURL("/password/password_form.html")); form_observer.Wait(); WaitForPasswordStore();
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc index 5d46088..c398a21 100644 --- a/chrome/browser/password_manager/password_manager_test_base.cc +++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -115,8 +115,8 @@ EXPECT_FALSE(IsShowingUpdatePrompt()); } -PasswordManagerBrowserTestBase::PasswordManagerBrowserTestBase() { -} +PasswordManagerBrowserTestBase::PasswordManagerBrowserTestBase() + : https_test_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} PasswordManagerBrowserTestBase::~PasswordManagerBrowserTestBase() { } @@ -131,6 +131,12 @@ password_manager::BuildPasswordStore< content::BrowserContext, password_manager::TestPasswordStore>); ASSERT_TRUE(embedded_test_server()->Start()); + + // Setup HTTPS server serving files from standard test directory. + static constexpr base::FilePath::CharType kDocRoot[] = + FILE_PATH_LITERAL("chrome/test/data"); + https_test_server().ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); + ASSERT_TRUE(https_test_server().Start()); } void PasswordManagerBrowserTestBase::TearDownOnMainThread() {
diff --git a/chrome/browser/password_manager/password_manager_test_base.h b/chrome/browser/password_manager/password_manager_test_base.h index 96180c9..bb095d7 100644 --- a/chrome/browser/password_manager/password_manager_test_base.h +++ b/chrome/browser/password_manager/password_manager_test_base.h
@@ -12,6 +12,7 @@ #include "components/password_manager/core/browser/password_store_consumer.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/test_utils.h" +#include "net/test/embedded_test_server/embedded_test_server.h" namespace autofill { struct PasswordForm; @@ -138,8 +139,10 @@ // Accessors content::WebContents* WebContents(); content::RenderViewHost* RenderViewHost(); + net::EmbeddedTestServer& https_test_server() { return https_test_server_; } private: + net::EmbeddedTestServer https_test_server_; DISALLOW_COPY_AND_ASSIGN(PasswordManagerBrowserTestBase); };
diff --git a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc index 335becff..62c6a0a 100644 --- a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc +++ b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
@@ -266,6 +266,9 @@ chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); content::WaitForLoadStop( browser()->tab_strip_model()->GetActiveWebContents()); + // Load stop may occure right after the reload commits, and the dialog is + // destroyed in a task posted during commit. Make sure that task is executed. + base::RunLoop().RunUntilIdle(); ASSERT_TRUE(dialog_destroyed_observer.dialog_destroyed()); // Try printing again.
diff --git a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc index c9da53c..e4eac62b 100644 --- a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc +++ b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
@@ -525,21 +525,21 @@ class WindowDestroyer : public content::WebContentsObserver { public: WindowDestroyer(content::WebContents* web_contents, TabStripModel* model) - : content::WebContentsObserver(web_contents), tab_strip_model_(model) {} + : content::WebContentsObserver(web_contents), + tab_strip_model_(model), + browser_closed_observer_(chrome::NOTIFICATION_BROWSER_CLOSED, + content::NotificationService::AllSources()) {} + + // Wait for the browser window to be destroyed. + void Wait() { browser_closed_observer_.Wait(); } void RenderProcessGone(base::TerminationStatus status) override { - // Wait for the window to be destroyed, which will ensure all other - // RenderViewHost objects are deleted before we return and proceed with - // the next iteration of notifications. - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_BROWSER_CLOSED, - content::NotificationService::AllSources()); tab_strip_model_->CloseAllTabs(); - observer.Wait(); } private: TabStripModel* tab_strip_model_; + content::WindowedNotificationObserver browser_closed_observer_; DISALLOW_COPY_AND_ASSIGN(WindowDestroyer); }; @@ -572,16 +572,12 @@ // Create an object that will close the window on a process crash. WindowDestroyer destroyer(wc1, browser()->tab_strip_model()); - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_BROWSER_CLOSED, - content::NotificationService::AllSources()); - // Kill the renderer process, simulating a crash. This should the ProcessDied // method to be called. Alternatively, RenderProcessHost::OnChannelError can // be called to directly force a call to ProcessDied. wc1->GetRenderProcessHost()->Shutdown(-1, true); - observer.Wait(); + destroyer.Wait(); } // Sets up the browser in order to start the tests with two tabs open: one
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc index d3e1ca5..63cd691 100644 --- a/chrome/browser/ui/login/login_handler_browsertest.cc +++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -98,6 +98,7 @@ const char kMultiRealmTestPage[] = "/login/multi_realm.html"; const int kMultiRealmTestRealmCount = 2; +const int kMultiRealmTestAuthRequestsCount = 4; const char kSingleRealmTestPage[] = "/login/single_realm.html"; @@ -460,104 +461,102 @@ // Test handling of resources that require authentication even though // the page they are included on doesn't. In this case we should only // present the minimal number of prompts necessary for successfully -// displaying the page. First we check whether cancelling works as -// expected. -IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmCancellation) { +// displaying the page. +class MultiRealmLoginPromptBrowserTest : public LoginPromptBrowserTest { + public: + void TearDownOnMainThread() override { + login_prompt_observer_.UnregisterAll(); + LoginPromptBrowserTest::TearDownOnMainThread(); + } + + // Load the multi-realm test page, waits for LoginHandlers to be created, then + // calls |for_each_realm_func| once for each authentication realm, passing a + // LoginHandler for the realm as an argument. The page should stop loading + // after that. + template <class F> + void RunTest(const F& for_each_realm_func); + + NavigationController* GetNavigationController() { + return &browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetController(); + } + + LoginPromptBrowserTestObserver* login_prompt_observer() { + return &login_prompt_observer_; + } + + private: + LoginPromptBrowserTestObserver login_prompt_observer_; +}; + +template <class F> +void MultiRealmLoginPromptBrowserTest::RunTest(const F& for_each_realm_func) { ASSERT_TRUE(embedded_test_server()->Start()); GURL test_page = embedded_test_server()->GetURL(kMultiRealmTestPage); - content::WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); - NavigationController* controller = &contents->GetController(); - LoginPromptBrowserTestObserver observer; + NavigationController* controller = GetNavigationController(); - observer.Register(content::Source<NavigationController>(controller)); + login_prompt_observer_.Register( + content::Source<NavigationController>(controller)); WindowedLoadStopObserver load_stop_waiter(controller, 1); - { - WindowedAuthNeededObserver auth_needed_waiter(controller); - browser()->OpenURL(OpenURLParams(test_page, Referrer(), - WindowOpenDisposition::CURRENT_TAB, - ui::PAGE_TRANSITION_TYPED, false)); - auth_needed_waiter.Wait(); - } + browser()->OpenURL(OpenURLParams(test_page, Referrer(), + WindowOpenDisposition::CURRENT_TAB, + ui::PAGE_TRANSITION_TYPED, false)); - int n_handlers = 0; + // Need to have LoginHandlers created for all requests that need + // authentication. + while (login_prompt_observer_.handlers().size() < + kMultiRealmTestAuthRequestsCount) + WindowedAuthNeededObserver(controller).Wait(); - while (n_handlers < kMultiRealmTestRealmCount) { - WindowedAuthNeededObserver auth_needed_waiter(controller); + // Now confirm or cancel auth once per realm. + std::set<std::string> seen_realms; + for (int i = 0; i < kMultiRealmTestRealmCount; ++i) { + auto it = std::find_if( + login_prompt_observer_.handlers().begin(), + login_prompt_observer_.handlers().end(), + [&seen_realms](LoginHandler* handler) { + return seen_realms.count(handler->auth_info()->realm) == 0; + }); + ASSERT_TRUE(it != login_prompt_observer_.handlers().end()); + seen_realms.insert((*it)->auth_info()->realm); - while (!observer.handlers().empty()) { - WindowedAuthCancelledObserver auth_cancelled_waiter(controller); - LoginHandler* handler = *observer.handlers().begin(); - - ASSERT_TRUE(handler); - n_handlers++; - handler->CancelAuth(); - auth_cancelled_waiter.Wait(); - } - - if (n_handlers < kMultiRealmTestRealmCount) - auth_needed_waiter.Wait(); + for_each_realm_func(*it); } load_stop_waiter.Wait(); - - EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers); - EXPECT_EQ(0, observer.auth_supplied_count()); - EXPECT_LT(0, observer.auth_needed_count()); - EXPECT_LT(0, observer.auth_cancelled_count()); } -// Similar to the MultipleRealmCancellation test above, but tests -// whether supplying credentials work as exepcted. -IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmConfirmation) { - ASSERT_TRUE(embedded_test_server()->Start()); - GURL test_page = embedded_test_server()->GetURL(kMultiRealmTestPage); +// Checks that cancelling works as expected. +IN_PROC_BROWSER_TEST_F(MultiRealmLoginPromptBrowserTest, + MultipleRealmCancellation) { + RunTest([this](LoginHandler* handler) { + WindowedAuthCancelledObserver waiter(GetNavigationController()); + handler->CancelAuth(); + waiter.Wait(); + }); - content::WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); - NavigationController* controller = &contents->GetController(); - LoginPromptBrowserTestObserver observer; + EXPECT_EQ(0, login_prompt_observer()->auth_supplied_count()); + EXPECT_LT(0, login_prompt_observer()->auth_needed_count()); + EXPECT_LT(0, login_prompt_observer()->auth_cancelled_count()); +} - observer.Register(content::Source<NavigationController>(controller)); +// Checks that supplying credentials works as exepcted. +IN_PROC_BROWSER_TEST_F(MultiRealmLoginPromptBrowserTest, + MultipleRealmConfirmation) { + RunTest([this](LoginHandler* handler) { + WindowedAuthSuppliedObserver waiter(GetNavigationController()); + SetAuthFor(handler); + waiter.Wait(); + }); - WindowedLoadStopObserver load_stop_waiter(controller, 1); - int n_handlers = 0; - - { - WindowedAuthNeededObserver auth_needed_waiter(controller); - - browser()->OpenURL(OpenURLParams(test_page, Referrer(), - WindowOpenDisposition::CURRENT_TAB, - ui::PAGE_TRANSITION_TYPED, false)); - auth_needed_waiter.Wait(); - } - - while (n_handlers < kMultiRealmTestRealmCount) { - WindowedAuthNeededObserver auth_needed_waiter(controller); - - while (!observer.handlers().empty()) { - WindowedAuthSuppliedObserver auth_supplied_waiter(controller); - LoginHandler* handler = *observer.handlers().begin(); - - ASSERT_TRUE(handler); - n_handlers++; - SetAuthFor(handler); - auth_supplied_waiter.Wait(); - } - - if (n_handlers < kMultiRealmTestRealmCount) - auth_needed_waiter.Wait(); - } - - load_stop_waiter.Wait(); - - EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers); - EXPECT_LT(0, observer.auth_needed_count()); - EXPECT_LT(0, observer.auth_supplied_count()); - EXPECT_EQ(0, observer.auth_cancelled_count()); + EXPECT_LT(0, login_prompt_observer()->auth_needed_count()); + EXPECT_LT(0, login_prompt_observer()->auth_supplied_count()); + EXPECT_EQ(0, login_prompt_observer()->auth_cancelled_count()); } // Testing for recovery from an incorrect password for the case where
diff --git a/chrome/browser/ui/login/login_handler_test_utils.cc b/chrome/browser/ui/login/login_handler_test_utils.cc index a0814c6b..d1c419d7 100644 --- a/chrome/browser/ui/login/login_handler_test_utils.cc +++ b/chrome/browser/ui/login/login_handler_test_utils.cc
@@ -57,6 +57,10 @@ registrar_.Add(this, chrome::NOTIFICATION_AUTH_CANCELLED, source); } +void LoginPromptBrowserTestObserver::UnregisterAll() { + registrar_.RemoveAll(); +} + WindowedLoadStopObserver::WindowedLoadStopObserver( content::NavigationController* controller, int notification_count)
diff --git a/chrome/browser/ui/login/login_handler_test_utils.h b/chrome/browser/ui/login/login_handler_test_utils.h index 8f32a54f..bf277a0 100644 --- a/chrome/browser/ui/login/login_handler_test_utils.h +++ b/chrome/browser/ui/login/login_handler_test_utils.h
@@ -31,6 +31,7 @@ void RemoveHandler(LoginHandler* handler); void Register(const content::NotificationSource& source); + void UnregisterAll(); const std::list<LoginHandler*>& handlers() const { return handlers_; }
diff --git a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc index 497aa60f..aa13796b 100644 --- a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc +++ b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
@@ -85,6 +85,14 @@ return details; } + FindNotificationDetails WaitForFinalFindResult() { + while (true) { + auto details = WaitForFindResult(); + if (details.final_update()) + return details; + } + } + private: DISALLOW_COPY_AND_ASSIGN(FindInPageTest); }; @@ -183,28 +191,28 @@ // Clicking the next and previous buttons should not alter the focused view. ClickOnView(next_button); - EXPECT_EQ(2, WaitForFindResult().active_match_ordinal()); + EXPECT_EQ(2, WaitForFinalFindResult().active_match_ordinal()); EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); ClickOnView(previous_button); - EXPECT_EQ(1, WaitForFindResult().active_match_ordinal()); + EXPECT_EQ(1, WaitForFinalFindResult().active_match_ordinal()); EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); // Tapping the next and previous buttons should not alter the focused view. TapOnView(next_button); - EXPECT_EQ(2, WaitForFindResult().active_match_ordinal()); + EXPECT_EQ(2, WaitForFinalFindResult().active_match_ordinal()); EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); TapOnView(previous_button); - EXPECT_EQ(1, WaitForFindResult().active_match_ordinal()); + EXPECT_EQ(1, WaitForFinalFindResult().active_match_ordinal()); EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); // The same should be true even when the previous button is focused. previous_button->RequestFocus(); EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON)); ClickOnView(next_button); - EXPECT_EQ(2, WaitForFindResult().active_match_ordinal()); + EXPECT_EQ(2, WaitForFinalFindResult().active_match_ordinal()); EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON)); TapOnView(next_button); - EXPECT_EQ(3, WaitForFindResult().active_match_ordinal()); + EXPECT_EQ(3, WaitForFinalFindResult().active_match_ordinal()); EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON)); }
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc index 4ca4af2b..7f40719 100644 --- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc +++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -103,6 +103,12 @@ private: void RegisterMessages() override; + void RegisterMessage(const std::string& message, + const content::WebUI::MessageCallback& handler); + + void HandleMessage(const content::WebUI::MessageCallback& handler, + const base::ListValue* data); + // Runs NetInternalsTest.callback with the given value. void RunJavascriptCallback(base::Value* value); @@ -158,35 +164,56 @@ } void NetInternalsTest::MessageHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback("getTestServerURL", + RegisterMessage( + "getTestServerURL", base::Bind(&NetInternalsTest::MessageHandler::GetTestServerURL, base::Unretained(this))); - web_ui()->RegisterMessageCallback("addCacheEntry", - base::Bind(&NetInternalsTest::MessageHandler::AddCacheEntry, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("loadPage", - base::Bind(&NetInternalsTest::MessageHandler::LoadPage, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("prerenderPage", - base::Bind(&NetInternalsTest::MessageHandler::PrerenderPage, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("navigateToPrerender", + RegisterMessage("addCacheEntry", + base::Bind(&NetInternalsTest::MessageHandler::AddCacheEntry, + base::Unretained(this))); + RegisterMessage("loadPage", + base::Bind(&NetInternalsTest::MessageHandler::LoadPage, + base::Unretained(this))); + RegisterMessage("prerenderPage", + base::Bind(&NetInternalsTest::MessageHandler::PrerenderPage, + base::Unretained(this))); + RegisterMessage( + "navigateToPrerender", base::Bind(&NetInternalsTest::MessageHandler::NavigateToPrerender, base::Unretained(this))); - web_ui()->RegisterMessageCallback("createIncognitoBrowser", + RegisterMessage( + "createIncognitoBrowser", base::Bind(&NetInternalsTest::MessageHandler::CreateIncognitoBrowser, base::Unretained(this))); - web_ui()->RegisterMessageCallback("closeIncognitoBrowser", + RegisterMessage( + "closeIncognitoBrowser", base::Bind(&NetInternalsTest::MessageHandler::CloseIncognitoBrowser, base::Unretained(this))); - web_ui()->RegisterMessageCallback("getNetLogFileContents", - base::Bind( - &NetInternalsTest::MessageHandler::GetNetLogFileContents, - base::Unretained(this))); - web_ui()->RegisterMessageCallback("enableDataReductionProxy", - base::Bind( - &NetInternalsTest::MessageHandler::EnableDataReductionProxy, - base::Unretained(this))); + RegisterMessage( + "getNetLogFileContents", + base::Bind(&NetInternalsTest::MessageHandler::GetNetLogFileContents, + base::Unretained(this))); + RegisterMessage( + "enableDataReductionProxy", + base::Bind(&NetInternalsTest::MessageHandler::EnableDataReductionProxy, + base::Unretained(this))); +} + +void NetInternalsTest::MessageHandler::RegisterMessage( + const std::string& message, + const content::WebUI::MessageCallback& handler) { + web_ui()->RegisterMessageCallback( + message, base::Bind(&NetInternalsTest::MessageHandler::HandleMessage, + base::Unretained(this), handler)); +} + +void NetInternalsTest::MessageHandler::HandleMessage( + const content::WebUI::MessageCallback& handler, + const base::ListValue* data) { + // The handler might run a nested loop to wait for something. + base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower( + base::MessageLoop::current()); + handler.Run(data); } void NetInternalsTest::MessageHandler::RunJavascriptCallback(
diff --git a/components/signin/core/browser/android/BUILD.gn b/components/signin/core/browser/android/BUILD.gn index 400ccab..62cc07ab 100644 --- a/components/signin/core/browser/android/BUILD.gn +++ b/components/signin/core/browser/android/BUILD.gn
@@ -15,6 +15,7 @@ deps = [ "//base:base_java", "//net/android:net_java", + "//third_party/android_tools:android_support_annotations_java", google_play_services_library, ]
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java index 3c41ad0..436e0d1 100644 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java +++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
@@ -7,27 +7,32 @@ import android.accounts.Account; import android.accounts.AuthenticatorDescription; import android.app.Activity; +import android.support.annotation.AnyThread; +import android.support.annotation.WorkerThread; import org.chromium.base.Callback; /** - * Wrapper around the Android account manager, to facilitate dependency injection during testing. + * Abstraction of account management implementation. + * Provides methods for getting accounts and managing auth tokens. */ public interface AccountManagerDelegate { /** - * This method is deprecated; please use the asynchronous version below instead. - * - * See http://crbug.com/517697 for details. + * Get all the accounts for a given {@code type}. + * This method shouldn't be called on the UI thread (violated due to crbug.com/517697). */ + @WorkerThread Account[] getAccountsByType(String type); /** - * Get all the accounts for a given {@code type}. + * Async version of {@link #getAccountsByType} + * This method is deprecated and will be removed soon. */ + @AnyThread void getAccountsByType(String type, Callback<Account[]> callback); /** - * Get an auth token. This should only be called on a background thread. + * Get an auth token. * * @param account The {@link Account} for which the auth token is requested. * @param authTokenScope The scope of the authToken being requested. @@ -36,22 +41,34 @@ * transient error or when user intervention is required (like confirming the credentials) * which is expressed as an {@link Intent} to the handler. */ + @WorkerThread String getAuthToken(Account account, String authTokenScope) throws AuthException; /** * @param authToken The auth token to invalidate. * @throws AuthException Indicates a failure clearing the auth token; can be transient. */ + @WorkerThread void invalidateAuthToken(String authToken) throws AuthException; /** * Get all the available authenticator types. */ + @AnyThread AuthenticatorDescription[] getAuthenticatorTypes(); /** * Check whether the {@code account} has all the features listed in {@code features}. + * This method shouldn't be called on the UI thread. */ + @WorkerThread + boolean hasFeatures(Account account, String[] features); + + /** + * Asynchronous version of {@link #hasFeatures} + * This method is deprecated and will be removed soon. + */ + @AnyThread void hasFeatures(Account account, String[] features, Callback<Boolean> callback); /** @@ -62,5 +79,6 @@ * sub-Activity to prompt the user to enter a password. * @param callback The callback to indicate whether update is succeed or not. */ + @AnyThread void updateCredentials(Account account, Activity activity, Callback<Boolean> callback); }
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java index 2700cf05..f26590e8 100644 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java +++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
@@ -113,31 +113,35 @@ } @Override - public void hasFeatures(Account account, String[] features, final Callback<Boolean> callback) { + public boolean hasFeatures(Account account, String[] features) { if (!hasGetAccountsPermission()) { - ThreadUtils.postOnUiThread(new Runnable() { - @Override - public void run() { - callback.onResult(false); - } - }); - return; + return false; } - mAccountManager.hasFeatures(account, features, new AccountManagerCallback<Boolean>() { + try { + return mAccountManager.hasFeatures(account, features, null, null).getResult(); + } catch (AuthenticatorException | IOException e) { + Log.e(TAG, "Error while checking features: ", e); + } catch (OperationCanceledException e) { + Log.e(TAG, "Checking features was cancelled. This should not happen."); + } + return false; + } + + @Override + public void hasFeatures( + final Account account, final String[] features, final Callback<Boolean> callback) { + AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() { @Override - public void run(AccountManagerFuture<Boolean> future) { - assert future.isDone(); - boolean hasFeatures = false; - try { - hasFeatures = future.getResult(); - } catch (AuthenticatorException | IOException e) { - Log.e(TAG, "Error while checking features: ", e); - } catch (OperationCanceledException e) { - Log.e(TAG, "Checking features was cancelled. This should not happen."); - } - callback.onResult(hasFeatures); + public Boolean doInBackground(Void... params) { + return hasFeatures(account, features); } - }, null /* handler */); + + @Override + public void onPostExecute(Boolean value) { + callback.onResult(value); + } + }; + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } /**
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java index 6aa4198..df8486bf 100644 --- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java +++ b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java
@@ -179,21 +179,26 @@ } @Override - public void hasFeatures( - Account account, final String[] features, final Callback<Boolean> callback) { + public boolean hasFeatures(Account account, String[] features) { final AccountHolder accountHolder = getAccountHolder(account); - accountHolder.addFeaturesCallback(new Runnable() { + Set<String> accountFeatures = accountHolder.getFeatures(); + boolean hasAllFeatures = true; + for (String feature : features) { + if (!accountFeatures.contains(feature)) { + Log.d(TAG, accountFeatures + " does not contain " + feature); + hasAllFeatures = false; + } + } + return hasAllFeatures; + } + + @Override + public void hasFeatures( + final Account account, final String[] features, final Callback<Boolean> callback) { + ThreadUtils.postOnUiThread(new Runnable() { @Override public void run() { - Set<String> accountFeatures = accountHolder.getFeatures(); - boolean hasAllFeatures = true; - for (String feature : features) { - if (!accountFeatures.contains(feature)) { - Log.d(TAG, accountFeatures + " does not contain " + feature); - hasAllFeatures = false; - } - } - callback.onResult(hasAllFeatures); + callback.onResult(hasFeatures(account, features)); } }); }
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc index 28f30f1..415f03d3 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service.cc +++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -8,6 +8,7 @@ #include <queue> +#include "base/format_macros.h" #include "base/json/json_reader.h" #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" @@ -298,7 +299,12 @@ fetcher_retries_(0), source_(source), external_cc_result_fetched_(false), - list_accounts_stale_(true) { + list_accounts_stale_(true), + // |GaiaCookieManagerService| is created as soon as the profle is + // initialized so it is acceptable to use of this + // |GaiaCookieManagerService| as the time when the profile is loaded. + profile_load_time_(base::Time::Now()), + list_accounts_request_counter_(0) { DCHECK(!source_.empty()); } @@ -468,8 +474,21 @@ std::string GaiaCookieManagerService::GetSourceForRequest( const GaiaCookieManagerService::GaiaCookieRequest& request) { - return request.source().empty() ? GetDefaultSourceForRequest() : - request.source(); + std::string source = request.source().empty() ? GetDefaultSourceForRequest() + : request.source(); + if (request.request_type() != LIST_ACCOUNTS) + return source; + + // For list accounts requests, the source also includes the time since the + // profile was loaded and the number of the request in order to debug channel + // ID issues observed on Gaia. + // TODO(msarda): Remove this debug code once the investigations on Gaia side + // are over. + std::string source_with_debug_info = base::StringPrintf( + "%s,counter:%" PRId32 ",load_time_ms:%" PRId64, source.c_str(), + list_accounts_request_counter_++, + (base::Time::Now() - profile_load_time_).InMilliseconds()); + return source_with_debug_info; } std::string GaiaCookieManagerService::GetDefaultSourceForRequest() { @@ -754,6 +773,7 @@ void GaiaCookieManagerService::StartFetchingListAccounts() { VLOG(1) << "GaiaCookieManagerService::ListAccounts"; + gaia_auth_fetcher_.reset(signin_client_->CreateGaiaAuthFetcher( this, GetSourceForRequest(requests_.front()), signin_client_->GetURLRequestContext()));
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.h b/components/signin/core/browser/gaia_cookie_manager_service.h index ae42464..ae8a8947 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service.h +++ b/components/signin/core/browser/gaia_cookie_manager_service.h
@@ -327,6 +327,14 @@ bool list_accounts_stale_; + // The time when the profile was loaded and used to compute the time passed + // between the moment the profile was loaded and the moment a new list + // account request is started. + base::Time profile_load_time_; + + // Counter for list account requests. + int list_accounts_request_counter_; + DISALLOW_COPY_AND_ASSIGN(GaiaCookieManagerService); };
diff --git a/content/browser/webrtc/webrtc_internals.cc b/content/browser/webrtc/webrtc_internals.cc index dee0c97f..6f22232 100644 --- a/content/browser/webrtc/webrtc_internals.cc +++ b/content/browser/webrtc/webrtc_internals.cc
@@ -35,20 +35,26 @@ namespace { -static base::LazyInstance<WebRTCInternals>::Leaky g_webrtc_internals = +base::LazyInstance<WebRTCInternals>::Leaky g_webrtc_internals = LAZY_INSTANCE_INITIALIZER; // Makes sure that |dict| has a ListValue under path "log". -static base::ListValue* EnsureLogList(base::DictionaryValue* dict) { +base::ListValue* EnsureLogList(base::DictionaryValue* dict) { base::ListValue* log = NULL; if (!dict->GetList("log", &log)) { log = new base::ListValue(); - if (log) - dict->Set("log", log); + dict->Set("log", log); } return log; } +// Removes the log entry associated with a given record. +void FreeLogList(base::Value* value) { + DCHECK(value->IsType(base::Value::Type::DICTIONARY)); + auto* dict = static_cast<base::DictionaryValue*>(value); + dict->Remove("log", nullptr); +} + } // namespace WebRTCInternals::PendingUpdate::PendingUpdate( @@ -123,6 +129,9 @@ const string& constraints) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + // TODO(tommi): Consider changing this design so that webrtc-internals has + // minimal impact if chrome://webrtc-internals isn't open. + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("rid", render_process_id); dict->SetInteger("pid", static_cast<int>(pid)); @@ -148,28 +157,19 @@ void WebRTCInternals::OnRemovePeerConnection(ProcessId pid, int lid) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) { - base::DictionaryValue* dict = NULL; - peer_connection_data_.GetDictionary(i, &dict); - int this_pid = 0; - int this_lid = 0; - dict->GetInteger("pid", &this_pid); - dict->GetInteger("lid", &this_lid); - - if (this_pid != static_cast<int>(pid) || this_lid != lid) - continue; - + size_t index; + base::DictionaryValue* dict = FindRecord(pid, lid, &index); + if (dict) { MaybeClosePeerConnection(dict); - peer_connection_data_.Remove(i, NULL); + peer_connection_data_.Remove(index, NULL); + } - if (observers_.might_have_observers()) { - std::unique_ptr<base::DictionaryValue> id(new base::DictionaryValue()); - id->SetInteger("pid", static_cast<int>(pid)); - id->SetInteger("lid", lid); - SendUpdate("removePeerConnection", std::move(id)); - } - break; + if (observers_.might_have_observers()) { + std::unique_ptr<base::DictionaryValue> id(new base::DictionaryValue()); + id->SetInteger("pid", static_cast<int>(pid)); + id->SetInteger("lid", lid); + SendUpdate("removePeerConnection", std::move(id)); } } @@ -177,49 +177,34 @@ ProcessId pid, int lid, const string& type, const string& value) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) { - base::DictionaryValue* record = NULL; - peer_connection_data_.GetDictionary(i, &record); - - int this_pid = 0, this_lid = 0; - record->GetInteger("pid", &this_pid); - record->GetInteger("lid", &this_lid); - - if (this_pid != static_cast<int>(pid) || this_lid != lid) - continue; - - if (type == "stop") { - MaybeClosePeerConnection(record); - } - - // Append the update to the end of the log. - base::ListValue* log = EnsureLogList(record); - if (!log) - return; - - std::unique_ptr<base::DictionaryValue> log_entry( - new base::DictionaryValue()); - - double epoch_time = base::Time::Now().ToJsTime(); - string time = base::DoubleToString(epoch_time); - log_entry->SetString("time", time); - log_entry->SetString("type", type); - log_entry->SetString("value", value); - - if (observers_.might_have_observers()) { - std::unique_ptr<base::DictionaryValue> update( - new base::DictionaryValue()); - update->SetInteger("pid", static_cast<int>(pid)); - update->SetInteger("lid", lid); - update->MergeDictionary(log_entry.get()); - - SendUpdate("updatePeerConnection", std::move(update)); - } - - log->Append(std::move(log_entry)); - + base::DictionaryValue* record = FindRecord(pid, lid); + if (!record) return; - } + + if (type == "stop") + MaybeClosePeerConnection(record); + + // Don't update entries if there aren't any observers. + if (!observers_.might_have_observers()) + return; + + std::unique_ptr<base::DictionaryValue> log_entry(new base::DictionaryValue()); + + double epoch_time = base::Time::Now().ToJsTime(); + string time = base::DoubleToString(epoch_time); + log_entry->SetString("time", time); + log_entry->SetString("type", type); + log_entry->SetString("value", value); + + std::unique_ptr<base::DictionaryValue> update(new base::DictionaryValue()); + update->SetInteger("pid", static_cast<int>(pid)); + update->SetInteger("lid", lid); + update->MergeDictionary(log_entry.get()); + + SendUpdate("updatePeerConnection", std::move(update)); + + // Append the update to the end of the log. + EnsureLogList(record)->Append(std::move(log_entry)); } void WebRTCInternals::OnAddStats(base::ProcessId pid, int lid, @@ -274,14 +259,17 @@ void WebRTCInternals::RemoveObserver(WebRTCInternalsUIObserver* observer) { DCHECK_CURRENTLY_ON(BrowserThread::UI); observers_.RemoveObserver(observer); + if (observers_.might_have_observers()) + return; // Disables event log and audio debug recordings if enabled and the last // webrtc-internals page is going away. - if (!observers_.might_have_observers()) { - if (audio_debug_recordings_) - DisableAudioDebugRecordings(); - DisableEventLogRecordings(); - } + DisableAudioDebugRecordings(); + DisableEventLogRecordings(); + + // TODO(tommi): Consider removing all the peer_connection_data_. + for (auto& dictionary : peer_connection_data_) + FreeLogList(dictionary.get()); } void WebRTCInternals::UpdateObserver(WebRTCInternalsUIObserver* observer) { @@ -320,6 +308,9 @@ void WebRTCInternals::DisableAudioDebugRecordings() { DCHECK_CURRENTLY_ON(BrowserThread::UI); #if BUILDFLAG(ENABLE_WEBRTC) + if (!audio_debug_recordings_) + return; + audio_debug_recordings_ = false; // Tear down the dialog since the user has unchecked the audio debug @@ -577,4 +568,26 @@ } } +base::DictionaryValue* WebRTCInternals::FindRecord( + ProcessId pid, + int lid, + size_t* index /*= nullptr*/) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + base::DictionaryValue* record = nullptr; + for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) { + peer_connection_data_.GetDictionary(i, &record); + + int this_pid = 0, this_lid = 0; + record->GetInteger("pid", &this_pid); + record->GetInteger("lid", &this_lid); + + if (this_pid == static_cast<int>(pid) && this_lid == lid) { + if (index) + *index = i; + return record; + } + } + return nullptr; +} } // namespace content
diff --git a/content/browser/webrtc/webrtc_internals.h b/content/browser/webrtc/webrtc_internals.h index c20a5fb1..f2cde8a7 100644 --- a/content/browser/webrtc/webrtc_internals.h +++ b/content/browser/webrtc/webrtc_internals.h
@@ -175,6 +175,10 @@ // notifications. void ProcessPendingUpdates(); + base::DictionaryValue* FindRecord(base::ProcessId pid, + int lid, + size_t* index = nullptr); + base::ObserverList<WebRTCInternalsUIObserver> observers_; // |peer_connection_data_| is a list containing all the PeerConnection
diff --git a/content/browser/webrtc/webrtc_internals_unittest.cc b/content/browser/webrtc/webrtc_internals_unittest.cc index cfea70f1..d14eef08 100644 --- a/content/browser/webrtc/webrtc_internals_unittest.cc +++ b/content/browser/webrtc/webrtc_internals_unittest.cc
@@ -27,13 +27,9 @@ MockWebRtcInternalsProxy() : loop_(nullptr) {} explicit MockWebRtcInternalsProxy(base::RunLoop* loop) : loop_(loop) {} - const std::string& command() const { - return command_; - } + const std::string& command() const { return command_; } - base::Value* value() { - return value_.get(); - } + base::Value* value() { return value_.get(); } private: void OnUpdate(const char* command, const base::Value* value) override { @@ -116,12 +112,10 @@ webrtc_internals.RemoveObserver(&observer); // The observer should not get notified of this activity. - webrtc_internals.OnAddPeerConnection( - 0, 3, 4, kUrl, kRtcConfiguration, kContraints); + webrtc_internals.OnAddPeerConnection(0, 3, 4, kUrl, kRtcConfiguration, + kContraints); - BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, - loop.QuitClosure(), - base::TimeDelta::FromMilliseconds(5)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, loop.QuitClosure()); loop.Run(); EXPECT_EQ("", observer.command()); @@ -129,13 +123,74 @@ webrtc_internals.OnRemovePeerConnection(3, 4); } +TEST_F(WebRtcInternalsTest, EnsureNoLogWhenNoObserver) { + base::RunLoop loop; + WebRTCInternalsForTest webrtc_internals; + webrtc_internals.OnAddPeerConnection(0, 3, 4, kUrl, kRtcConfiguration, + kContraints); + webrtc_internals.OnUpdatePeerConnection(3, 4, "update_type", "update_value"); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, loop.QuitClosure()); + loop.Run(); + + // Make sure we don't have a log entry since there was no observer. + MockWebRtcInternalsProxy observer; + webrtc_internals.UpdateObserver(&observer); + EXPECT_EQ("updateAllPeerConnections", observer.command()); + + base::ListValue* list = nullptr; + ASSERT_TRUE(observer.value()->GetAsList(&list)); + EXPECT_EQ(1U, list->GetSize()); + base::DictionaryValue* dict = nullptr; + ASSERT_TRUE((*list->begin())->GetAsDictionary(&dict)); + base::ListValue* log = nullptr; + ASSERT_FALSE(dict->GetList("log", &log)); + + webrtc_internals.OnRemovePeerConnection(3, 4); +} + +TEST_F(WebRtcInternalsTest, EnsureLogIsRemovedWhenObserverIsRemoved) { + base::RunLoop loop; + WebRTCInternalsForTest webrtc_internals; + MockWebRtcInternalsProxy observer; + webrtc_internals.AddObserver(&observer); + webrtc_internals.OnAddPeerConnection(0, 3, 4, kUrl, kRtcConfiguration, + kContraints); + webrtc_internals.OnUpdatePeerConnection(3, 4, "update_type", "update_value"); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, loop.QuitClosure()); + loop.Run(); + + // Make sure we have a log entry since there was an observer. + webrtc_internals.UpdateObserver(&observer); + EXPECT_EQ("updateAllPeerConnections", observer.command()); + + base::ListValue* list = nullptr; + ASSERT_TRUE(observer.value()->GetAsList(&list)); + EXPECT_EQ(1U, list->GetSize()); + base::DictionaryValue* dict = nullptr; + ASSERT_TRUE((*list->begin())->GetAsDictionary(&dict)); + base::ListValue* log = nullptr; + ASSERT_TRUE(dict->GetList("log", &log)); + + // Make sure we the log entry was removed when the last observer was removed. + webrtc_internals.RemoveObserver(&observer); + webrtc_internals.UpdateObserver(&observer); + EXPECT_EQ("updateAllPeerConnections", observer.command()); + + ASSERT_TRUE(observer.value()->GetAsList(&list)); + EXPECT_EQ(1U, list->GetSize()); + ASSERT_TRUE((*list->begin())->GetAsDictionary(&dict)); + ASSERT_FALSE(dict->GetList("log", &log)); + + webrtc_internals.OnRemovePeerConnection(3, 4); +} + TEST_F(WebRtcInternalsTest, SendAddPeerConnectionUpdate) { base::RunLoop loop; MockWebRtcInternalsProxy observer(&loop); WebRTCInternalsForTest webrtc_internals; webrtc_internals.AddObserver(&observer); - webrtc_internals.OnAddPeerConnection( - 0, 1, 2, kUrl, kRtcConfiguration, kContraints); + webrtc_internals.OnAddPeerConnection(0, 1, 2, kUrl, kRtcConfiguration, + kContraints); loop.Run(); @@ -159,8 +214,8 @@ MockWebRtcInternalsProxy observer(&loop); WebRTCInternalsForTest webrtc_internals; webrtc_internals.AddObserver(&observer); - webrtc_internals.OnAddPeerConnection( - 0, 1, 2, kUrl, kRtcConfiguration, kContraints); + webrtc_internals.OnAddPeerConnection(0, 1, 2, kUrl, kRtcConfiguration, + kContraints); webrtc_internals.OnRemovePeerConnection(1, 2); loop.Run(); @@ -181,13 +236,12 @@ MockWebRtcInternalsProxy observer(&loop); WebRTCInternalsForTest webrtc_internals; webrtc_internals.AddObserver(&observer); - webrtc_internals.OnAddPeerConnection( - 0, 1, 2, kUrl, kRtcConfiguration, kContraints); + webrtc_internals.OnAddPeerConnection(0, 1, 2, kUrl, kRtcConfiguration, + kContraints); const std::string update_type = "fakeType"; const std::string update_value = "fakeValue"; - webrtc_internals.OnUpdatePeerConnection( - 1, 2, update_type, update_value); + webrtc_internals.OnUpdatePeerConnection(1, 2, update_type, update_value); loop.Run(); @@ -221,14 +275,14 @@ const int pid = 2; const std::string audio_constraint = "aaa"; const std::string video_constraint = "vvv"; - webrtc_internals.OnGetUserMedia( - rid, pid, kUrl, true, true, audio_constraint, video_constraint); + webrtc_internals.OnGetUserMedia(rid, pid, kUrl, true, true, audio_constraint, + video_constraint); loop.Run(); ASSERT_EQ("addGetUserMedia", observer.command()); - VerifyGetUserMediaData( - observer.value(), rid, pid, kUrl, audio_constraint, video_constraint); + VerifyGetUserMediaData(observer.value(), rid, pid, kUrl, audio_constraint, + video_constraint); webrtc_internals.RemoveObserver(&observer); } @@ -239,8 +293,8 @@ const std::string audio_constraint = "aaa"; const std::string video_constraint = "vvv"; WebRTCInternalsForTest webrtc_internals; - webrtc_internals.OnGetUserMedia( - rid, pid, kUrl, true, true, audio_constraint, video_constraint); + webrtc_internals.OnGetUserMedia(rid, pid, kUrl, true, true, audio_constraint, + video_constraint); MockWebRtcInternalsProxy observer; // Add one observer after "getUserMedia". @@ -248,8 +302,8 @@ webrtc_internals.UpdateObserver(&observer); EXPECT_EQ("addGetUserMedia", observer.command()); - VerifyGetUserMediaData( - observer.value(), rid, pid, kUrl, audio_constraint, video_constraint); + VerifyGetUserMediaData(observer.value(), rid, pid, kUrl, audio_constraint, + video_constraint); webrtc_internals.RemoveObserver(&observer); } @@ -261,14 +315,13 @@ WebRTCInternalsForTest webrtc_internals; - webrtc_internals.OnAddPeerConnection( - rid, pid, lid, kUrl, kRtcConfiguration, kContraints); - webrtc_internals.OnUpdatePeerConnection( - pid, lid, update_type, update_value); - MockWebRtcInternalsProxy observer; webrtc_internals.AddObserver(&observer); + webrtc_internals.OnAddPeerConnection(rid, pid, lid, kUrl, kRtcConfiguration, + kContraints); + webrtc_internals.OnUpdatePeerConnection(pid, lid, update_type, update_value); + webrtc_internals.UpdateObserver(&observer); EXPECT_EQ("updateAllPeerConnections", observer.command()); @@ -289,7 +342,7 @@ VerifyString(dict, "constraints", kContraints); base::ListValue* log = NULL; - EXPECT_TRUE(dict->GetList("log", &log)); + ASSERT_TRUE(dict->GetList("log", &log)); EXPECT_EQ(1U, log->GetSize()); EXPECT_TRUE((*log->begin())->GetAsDictionary(&dict)); @@ -306,8 +359,8 @@ MockWebRtcInternalsProxy observer(&loop); WebRTCInternalsForTest webrtc_internals; webrtc_internals.AddObserver(&observer); - webrtc_internals.OnAddPeerConnection( - rid, pid, lid, kUrl, kRtcConfiguration, kContraints); + webrtc_internals.OnAddPeerConnection(rid, pid, lid, kUrl, kRtcConfiguration, + kContraints); base::ListValue list; list.AppendString("xxx"); @@ -344,8 +397,8 @@ TEST_F(WebRtcInternalsTest, PowerSaveBlock) { int kRenderProcessId = 1; - int pid = 1; - int lid[] = {1, 2, 3}; + const int pid = 1; + const int lid[] = {1, 2, 3}; WebRTCInternalsForTest webrtc_internals;
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc index 4afe2321..1d2da32a 100644 --- a/content/public/test/test_utils.cc +++ b/content/public/test/test_utils.cc
@@ -292,8 +292,8 @@ return; running_ = true; - message_loop_runner_ = new MessageLoopRunner; - message_loop_runner_->Run(); + run_loop_.reset(new base::RunLoop); + run_loop_->Run(); EXPECT_TRUE(seen_); } @@ -310,7 +310,7 @@ if (!running_) return; - message_loop_runner_->Quit(); + run_loop_->Quit(); running_ = false; }
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h index 29f5965..ed1f8e6 100644 --- a/content/public/test/test_utils.h +++ b/content/public/test/test_utils.h
@@ -235,7 +235,7 @@ NotificationSource source_; NotificationDetails details_; - scoped_refptr<MessageLoopRunner> message_loop_runner_; + std::unique_ptr<base::RunLoop> run_loop_; DISALLOW_COPY_AND_ASSIGN(WindowedNotificationObserver); };
diff --git a/extensions/test/extension_test_notification_observer.cc b/extensions/test/extension_test_notification_observer.cc index 0e4d75d0c..8c79ac54 100644 --- a/extensions/test/extension_test_notification_observer.cc +++ b/extensions/test/extension_test_notification_observer.cc
@@ -141,6 +141,9 @@ void ExtensionTestNotificationObserver::Wait() { observer_->Wait(); + // TODO(https://crbug.com/695073): Find out why tests fail without it. + content::RunAllPendingInMessageLoop(); + registrar_.RemoveAll(); observer_.reset(); } @@ -187,16 +190,15 @@ return; condition_ = condition; - scoped_refptr<content::MessageLoopRunner> runner( - new content::MessageLoopRunner); - quit_closure_ = runner->QuitClosure(); + base::RunLoop run_loop; + quit_closure_ = run_loop.QuitClosure(); std::unique_ptr<base::CallbackList<void()>::Subscription> subscription; if (notification_set) { subscription = notification_set->callback_list().Add(base::Bind( &ExtensionTestNotificationObserver::MaybeQuit, base::Unretained(this))); } - runner->Run(); + run_loop.Run(); condition_.Reset(); quit_closure_.Reset();
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm index 46931b3..9618ce4 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
@@ -24,6 +24,9 @@ // Distillation indicator constants. const CGFloat kDistillationIndicatorSize = 18; + +// Margin for the elements displayed in the cell. +const CGFloat kMargin = 16; } // namespace #pragma mark - ReadingListCell Private interface @@ -191,37 +194,45 @@ _textLabel = [[UILabel alloc] init]; _textLabel.font = [fontLoader mediumFontOfSize:16]; _textLabel.textColor = [[MDCPalette greyPalette] tint900]; + _textLabel.translatesAutoresizingMaskIntoConstraints = NO; _detailTextLabel = [[UILabel alloc] init]; _detailTextLabel.font = [fontLoader mediumFontOfSize:14]; _detailTextLabel.textColor = [[MDCPalette greyPalette] tint500]; + _detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO; _faviconView = [[FaviconViewNew alloc] init]; CGFloat fontSize = floorf(faviconSize / 2); [_faviconView setFont:[fontLoader regularFontOfSize:fontSize]]; + _faviconView.translatesAutoresizingMaskIntoConstraints = NO; _downloadIndicator = [[UIImageView alloc] init]; [_downloadIndicator setTranslatesAutoresizingMaskIntoConstraints:NO]; [_faviconView addSubview:_downloadIndicator]; - UIStackView* labelsStack = [[UIStackView alloc] - initWithArrangedSubviews:@[ _textLabel, _detailTextLabel ]]; - labelsStack.axis = UILayoutConstraintAxisVertical; + [self.contentView addSubview:_textLabel]; + [self.contentView addSubview:_detailTextLabel]; + [self.contentView addSubview:_faviconView]; - UIStackView* stackView = [[UIStackView alloc] - initWithArrangedSubviews:@[ _faviconView, labelsStack ]]; - [self.contentView addSubview:stackView]; - stackView.layoutMarginsRelativeArrangement = YES; - stackView.layoutMargins = UIEdgeInsetsMake(16, 16, 16, 16); - stackView.alignment = UIStackViewAlignmentCenter; - stackView.spacing = 16; + ApplyVisualConstraintsWithMetrics( + @[ + @"V:|-(margin)-[title][text]-(margin)-|", + @"H:|-(margin)-[favicon]-(margin)-[title]-(>=margin)-|", + @"H:[favicon]-(margin)-[text]-(>=margin)-|" + ], + @{ + @"title" : _textLabel, + @"text" : _detailTextLabel, + @"favicon" : _faviconView + }, + @{ @"margin" : @(kMargin) }); - stackView.translatesAutoresizingMaskIntoConstraints = NO; - AddSameSizeConstraint(self.contentView, stackView); [NSLayoutConstraint activateConstraints:@[ // Favicons are always the same size. [_faviconView.widthAnchor constraintEqualToConstant:faviconSize], [_faviconView.heightAnchor constraintEqualToConstant:faviconSize], + [_faviconView.centerYAnchor + constraintEqualToAnchor:self.contentView.centerYAnchor], // Place the download indicator in the bottom right corner of the favicon. [[_downloadIndicator centerXAnchor] constraintEqualToAnchor:_faviconView.trailingAnchor],
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm b/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm index 360521e9..d3eaca49 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
@@ -108,7 +108,9 @@ NSString* accessibilityInstructionString = @":"; // Add the images inside the string. - if (IsCompact()) { + if (IsCompact() || !IsIPadIdiom()) { + // TODO(crbug.com/698726): When the share icon is displayed in the toolbar + // for landscape iPhone 6+, remove !IsIPadIdiom(). // If the device has a compact display the share menu is accessed from the // toolbar menu. If it is expanded, the share menu is directly accessible. [self attachIconNamed:kToolbarMenuIcon
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation index 8c23947..a7e3a80 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
@@ -4,9 +4,6 @@ # https://crbug.com/551000: PlzNavigate: DevTools support crbug.com/551000 http/tests/inspector/network/x-frame-options-deny.html [ Failure ] crbug.com/551000 virtual/mojo-loading/http/tests/inspector/network/x-frame-options-deny.html [ Failure ] -# Console error messages are wrongly ordered. -crbug.com/551000 http/tests/inspector/console-resource-errors.html [ Failure ] -crbug.com/551000 virtual/mojo-loading/http/tests/inspector/console-resource-errors.html [ Failure ] # Flipped order between diStartProvisionalLoad & willSendRequest crbug.com/647698 http/tests/loading/307-after-303-after-post.html [ Failure ] @@ -17,10 +14,8 @@ # https://crbug.com/555418: Move `X-Frame-Options` and CSP's `frame-ancestor` # checks up out of the renderer. crbug.com/555418 http/tests/security/contentSecurityPolicy/1.1/form-action-src-redirect-blocked.html [ Failure ] -crbug.com/555418 http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html [ Timeout ] crbug.com/555418 http/tests/security/isolatedWorld/bypass-main-world-csp-iframes.html [ Failure ] crbug.com/555418 virtual/mojo-loading/http/tests/security/contentSecurityPolicy/1.1/form-action-src-redirect-blocked.html [ Failure ] -crbug.com/555418 virtual/mojo-loading/http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html [ Timeout ] crbug.com/555418 virtual/mojo-loading/http/tests/security/isolatedWorld/bypass-main-world-csp-iframes.html [ Failure ] # Missing console warning about usage of legacy protocol. @@ -31,8 +26,15 @@ # https://crbug.com/695072: Preserve SourceLocation information. # This results in a missing line number in console error messages. -Bug(695072) http/tests/security/location-href-clears-username-password.html [ Failure ] -Bug(695072) virtual/mojo-loading/http/tests/security/location-href-clears-username-password.html [ Failure ] +# Fixed by https://codereview.chromium.org/2720763002/ +crbug.com/551000 http/tests/inspector/console-resource-errors.html [ Failure ] +crbug.com/555418 http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html [ Timeout ] +crbug.com/695072 http/tests/security/location-href-clears-username-password.html [ Failure ] +crbug.com/695072 http/tests/security/mixedContent/insecure-iframe-with-hsts.https.html [ Failure ] +crbug.com/551000 virtual/mojo-loading/http/tests/inspector/console-resource-errors.html [ Failure ] +crbug.com/555418 virtual/mojo-loading/http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html [ Timeout ] +crbug.com/695072 virtual/mojo-loading/http/tests/security/location-href-clears-username-password.html [ Failure ] +crbug.com/695072 virtual/mojo-loading/http/tests/security/mixedContent/insecure-iframe-with-hsts.https.html [ Failure ] # These tests are flaky. Bug(none) external/wpt/service-workers/service-worker/fetch-event-redirect.https.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index ababfc5..55f7756c 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2334,12 +2334,6 @@ # Added 2016-12-22 crbug.com/676537 fast/css/imageTileOpacity.html [ Pass Failure ] -crbug.com/642376 virtual/gpu/fast/canvas/canvas-arc-circumference-fill.html [ Failure ] -crbug.com/642376 virtual/gpu/fast/canvas/canvas-arc-circumference.html [ Failure ] -crbug.com/642376 virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill.html [ Failure ] -crbug.com/642376 virtual/gpu/fast/canvas/canvas-ellipse-circumference.html [ Failure ] -crbug.com/642376 virtual/gpu/fast/canvas/canvas-incremental-repaint.html [ Failure ] - # ====== Random order flaky tests from here ====== # These tests are flaky when run in random order, which is the default on Linux & Mac since since 2016-12-16.
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/parse-place-content.html b/third_party/WebKit/LayoutTests/fast/alignment/parse-place-content.html new file mode 100644 index 0000000..36cf4816 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/alignment/parse-place-content.html
@@ -0,0 +1,245 @@ +<!DOCTYPE html> +<html> +<head> +<style> +#placeContentNormal { + place-content: normal; +} +#placeContentBaseline { + place-content: baseline; +} +#placeContentStart { + place-content: start; +} +#placeContentFlexStart { + place-content: flex-start; +} +#placeContentEnd { + place-content: end; +} +#placeContentSpaceBetween { + place-content: space-between; +} +#placeContentStretch { + place-content: stretch; +} +#placeContentStartEnd { + place-content: start end; +} +#placeContentStartSpaceEvenly { + place-content: start space-evenly; +} +#placeContentStartBaseline { + place-content: start baseline; +} + +<!-- Invalid CSS cases --> +#placeContentEmpty { + place-content:; +} +#placeContentAuto { + place-content: auto; +} +#placeContentNone { + place-content: none; +} +#placeContentSafe { + place-content: safe; +} +#placeContentStartSafe { + place-content: start safe; +} +#placeContentStartEndLeft { + place-content: start end left; +} +</style> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/alignment-parsing-utils-th.js"></script> +</head> +<body> + <p>Test to verify that the new place-content alignment shorthand is parsed as expected and correctly sets the longhand values.</p> + <div id="log"></div> + + <div id="placeContentNormal"></div> + <div id="placeContentBaseline"></div> + <div id="placeContentStart"></div> + <div id="placeContentFlexStart"></div> + <div id="placeContentEnd"></div> + <div id="placeContentSpaceBetween"></div> + <div id="placeContentStretch"></div> + <div id="placeContentStartEnd"></div> + <div id="placeContentStartSpaceEvenly"></div> + <div id="placeContentStartBaseline"></div> + + <div id="placeContentEmpty"></div> + <div id="placeContentAuto"></div> + <div id="placeContentNone"></div> + <div id="placeContentSafe"></div> + <div id="placeContentStartSafe"></div> + <div id="placeContentBaselineSafe"></div> + <div id="placeContentStartEndLeft"></div> +<script> +function checkPlaceContentValues(element, value, alignValue, justifyValue) +{ + var res = value.split(" "); + if (res.length < 2) + res[1] = res[0]; + checkValues(element, "alignContent", "align-content", res[0], alignValue); + checkValues(element, "justifyContent", "justify-content", res[1], justifyValue); +} + +function checkPlaceContentValuesJS(value, alignValue, justifyValue) +{ + element = document.createElement("div"); + document.body.appendChild(element); + element.style.placeContent = value; + checkValues(element, "placeContent", "place-content", value, alignValue + ' ' + justifyValue) + checkPlaceContentValues(element, value, alignValue, justifyValue) +} + +function checkPlaceContentValuesBadJS(value) +{ + element.style.placeContent = ""; + element.style.placeContent = value; + checkPlaceContentValues(element, "", "normal", "normal") +} + +function checkPlaceContentInitialValue() +{ + element = document.createElement("div"); + document.body.appendChild(element); + checkValues(element, "placeContent", "place-content", "", "normal normal"); + element.style.placeContent = "center"; + checkPlaceContentValues(element, "center", "center", "center"); + element.style.placeContent = "initial"; + checkValues(element, "placeContent", "place-content", "initial", "normal normal"); + checkPlaceContentValues(element, "initial", "normal", "normal"); +} + +function checkPlaceContentInheritValue() +{ + document.body.style.placeContent = "start"; + var anotherElement = document.createElement("div"); + document.body.appendChild(anotherElement); + checkPlaceContentValues(anotherElement, "", "normal", "normal"); + anotherElement.style.placeContent = "inherit"; + checkPlaceContentValues(anotherElement, "inherit", "start", "start"); +} + + +test(function() { + checkValues(placeContentNormal, "placeContent", "place-content", "", "normal normal"); + checkPlaceContentValues(placeContentNormal, "", "normal", "normal"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'normal' value through CSS."); + +test(function() { + checkValues(placeContentBaseline, "placeContent", "place-content", "", "baseline baseline"); + checkPlaceContentValues(placeContentBaseline, "", "baseline", "baseline"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'baseline' value through CSS."); + +test(function() { + checkValues(placeContentStart, "placeContent", "place-content", "", "start start"); + checkPlaceContentValues(placeContentStart, "", "start", "start"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'start' value through CSS."); + +test(function() { + checkValues(placeContentFlexStart, "placeContent", "place-content", "", "flex-start flex-start"); + checkPlaceContentValues(placeContentFlexStart, "", "flex-start", "flex-start"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'flex-start' value through CSS."); + +test(function() { + checkValues(placeContentEnd, "placeContent", "place-content", "", "end end"); + checkPlaceContentValues(placeContentEnd, "", "end", "end"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'end' value through CSS."); + +test(function() { + checkValues(placeContentSpaceBetween, "placeContent", "place-content", "", "space-between space-between"); + checkPlaceContentValues(placeContentSpaceBetween, "", "space-between", "space-between"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'space-between' value through CSS."); + +test(function() { + checkValues(placeContentStretch, "placeContent", "place-content", "", "stretch stretch"); + checkPlaceContentValues(placeContentStretch, "", "stretch", "stretch"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'stretch' value through CSS."); + +test(function() { + checkValues(placeContentStartEnd, "placeContent", "place-content", "", "start end"); + checkPlaceContentValues(placeContentStartEnd, "", "start", "end"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'start end' value through CSS."); + +test(function() { + checkValues(placeContentStartSpaceEvenly, "placeContent", "place-content", "", "start space-evenly"); + checkPlaceContentValues(placeContentStartSpaceEvenly, "", "start", "space-evenly"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'start space-evenly' value through CSS."); + +test(function() { + checkValues(placeContentStartBaseline, "placeContent", "place-content", "", "start baseline"); + checkPlaceContentValues(placeContentStartBaseline, "", "start", "baseline"); +}, "Test getting the Computed Value of place-content's longhand properties when setting 'start baseline' value through CSS."); + +test(function() { + checkValues(placeContentAuto, "placeContent", "place-content", "", "normal normal"); + checkPlaceContentValues(placeContentAuto, "", "normal", "normal"); +}, "Test setting '' as incorrect value through CSS."); + +test(function() { + checkValues(placeContentAuto, "placeContent", "place-content", "", "normal normal"); + checkPlaceContentValues(placeContentAuto, "", "normal", "normal"); +}, "Test setting 'auto' as incorrect value through CSS."); + +test(function() { + checkValues(placeContentNone, "placeContent", "place-content", "", "normal normal"); + checkPlaceContentValues(placeContentNone, "", "normal", "normal"); +}, "Test setting 'none' as incorrect value through CSS."); + +test(function() { + checkValues(placeContentSafe, "placeContent", "place-content", "", "normal normal"); + checkPlaceContentValues(placeContentSafe, "", "normal", "normal"); +}, "Test setting 'safe' as incorrect value through CSS."); + +test(function() { + checkValues(placeContentStartSafe, "placeContent", "place-content", "", "normal normal"); + checkPlaceContentValues(placeContentStartSafe, "", "normal", "normal"); +}, "Test setting 'start safe' as incorrect value through CSS."); + +test(function() { + checkValues(placeContentStartSafe, "placeContent", "place-content", "", "normal normal"); + checkPlaceContentValues(placeContentStartSafe, "", "normal", "normal"); +}, "Test setting 'baseline safe' as incorrect value through CSS."); + +test(function() { + checkValues(placeContentStartEndLeft, "placeContent", "place-content", "", "normal normal"); + checkPlaceContentValues(placeContentStartEndLeft, "", "normal", "normal"); +}, "Test setting 'start end left' as incorrect value through CSS."); + +test(function() { + checkPlaceContentValuesJS("center", "center", "center"); + checkPlaceContentValuesJS("center start", "center", "start"); + checkPlaceContentValuesJS("space-between end", "space-between", "end"); + checkPlaceContentValuesJS("normal end", "normal", "end"); +}, "Test setting values through JS."); + +test(function() { + checkPlaceContentValuesBadJS("center safe", "normal", "normal"); + checkPlaceContentValuesBadJS("center space-between center", "normal", "normal"); + checkPlaceContentValuesBadJS("asrt", "normal", "normal"); + checkPlaceContentValuesBadJS("auto", "normal", "normal"); + checkPlaceContentValuesBadJS("10px", "normal", "normal"); + checkPlaceContentValuesBadJS("stretch safe", "normal", "normal"); + checkPlaceContentValuesBadJS("space-between start end", "normal", "normal"); + checkPlaceContentValuesBadJS("", "normal", "normal"); +}, "Test setting incorrect values through JS."); + +test(function() { + checkPlaceContentInitialValue(); +}, "Test the 'initial' value of the place-content shorthand and its longhand properties' Computed value"); + +test(function() { + checkPlaceContentInheritValue(); +}, "Test the 'inherit' value of the place-content shorthand and its longhand properties' Computed value"); + + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/resources/alignment-parsing-utils-th.js b/third_party/WebKit/LayoutTests/fast/alignment/resources/alignment-parsing-utils-th.js index ee35414d..43d3d57 100644 --- a/third_party/WebKit/LayoutTests/fast/alignment/resources/alignment-parsing-utils-th.js +++ b/third_party/WebKit/LayoutTests/fast/alignment/resources/alignment-parsing-utils-th.js
@@ -2,7 +2,7 @@ { window.element = element; var elementID = element.id || "element"; - assert_equals(eval("element.style." + property), value, property + " specified value is not what it should.."); + assert_equals(eval('element.style.' + property), value, property + ' specified value is not what it should..'); assert_equals(eval("window.getComputedStyle(" + elementID + ", '').getPropertyValue('" + propertyID + "')"), computedValue, property + " is not what is should."); }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png new file mode 100644 index 0000000..0a57ca31 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png deleted file mode 100644 index 5cd5cb1..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png index 38e7f272..4a240e8 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png new file mode 100644 index 0000000..0a57ca31 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png new file mode 100644 index 0000000..411b819 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png new file mode 100644 index 0000000..9f0bf823 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png new file mode 100644 index 0000000..ce87211 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png new file mode 100644 index 0000000..e27292e0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png new file mode 100644 index 0000000..0a57ca31 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png new file mode 100644 index 0000000..411b819 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png new file mode 100644 index 0000000..9f0bf823 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png new file mode 100644 index 0000000..ce87211 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png new file mode 100644 index 0000000..e27292e0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png new file mode 100644 index 0000000..285f605 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png index f1d41e6..411b819 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png new file mode 100644 index 0000000..9f0bf823 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png new file mode 100644 index 0000000..ce87211 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png index 54a21f4b..98bafae 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt index f4f541d..b4247c98 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt
@@ -226,6 +226,7 @@ parentRule perspective perspectiveOrigin +placeContent pointerEvents position quotes
diff --git a/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt b/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt index 41ca12bc..11bfac0 100644 --- a/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt
@@ -234,6 +234,7 @@ parentRule perspective perspectiveOrigin +placeContent pointerEvents position quotes
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5 index 73271fe7..d7cbdf5 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.json5 +++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -2681,6 +2681,11 @@ runtime_flag: "CSSGridLayout", }, { + name: "place-content", + longhands: "align-content;justify-content", + runtime_flag: "CSSGridLayout", + }, + { name: "grid-area", longhands: "grid-row-start;grid-column-start;grid-row-end;grid-column-end", runtime_flag: "CSSGridLayout",
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp index 7cf3f8ef..6c90124 100644 --- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp +++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -2316,6 +2316,13 @@ return CSSIdentifierValue::create(style.display()); case CSSPropertyEmptyCells: return CSSIdentifierValue::create(style.emptyCells()); + case CSSPropertyPlaceContent: { + // TODO (jfernandez): The spec states that we should return the specified + // value. + return valuesForShorthandProperty(placeContentShorthand(), style, + layoutObject, styledNode, + allowVisitedStyle); + } case CSSPropertyAlignContent: return valueForContentPositionAndDistributionWithOverflowAlignment( style.alignContent(), CSSValueStretch);
diff --git a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp index 70798f7..7ad9a76 100644 --- a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp +++ b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
@@ -454,6 +454,8 @@ return getShorthandValue(gridAreaShorthand(), " / "); case CSSPropertyGridGap: return getShorthandValue(gridGapShorthand()); + case CSSPropertyPlaceContent: + return placeContentPropertyValue(); case CSSPropertyFont: return fontValue(); case CSSPropertyFontVariant: @@ -848,6 +850,13 @@ return res; } +String StylePropertySerializer::placeContentPropertyValue() const { + String value = getCommonValue(placeContentShorthand()); + if (value.isNull() || value.isEmpty()) + return getShorthandValue(placeContentShorthand()); + return value; +} + String StylePropertySerializer::borderPropertyValue() const { const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borderStyleShorthand(), borderColorShorthand()};
diff --git a/third_party/WebKit/Source/core/css/StylePropertySerializer.h b/third_party/WebKit/Source/core/css/StylePropertySerializer.h index d4ecf27..baf4267 100644 --- a/third_party/WebKit/Source/core/css/StylePropertySerializer.h +++ b/third_party/WebKit/Source/core/css/StylePropertySerializer.h
@@ -44,6 +44,7 @@ private: String getCommonValue(const StylePropertyShorthand&) const; + String placeContentPropertyValue() const; String borderPropertyValue() const; String getLayeredShorthandValue(const StylePropertyShorthand&) const; String get4Values(const StylePropertyShorthand&) const;
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index 1e5b59d5..9f6856f9 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -3493,6 +3493,53 @@ return true; } +static CSSValue* consumeSimplifiedContentPosition(CSSParserTokenRange& range) { + CSSValueID id = range.peek().id(); + if (identMatches<CSSValueNormal, CSSValueBaseline, CSSValueLastBaseline>( + id)) { + return CSSContentDistributionValue::create( + CSSValueInvalid, range.consumeIncludingWhitespace().id(), + CSSValueInvalid); + } + if (identMatches<CSSValueSpaceBetween, CSSValueSpaceAround, + CSSValueSpaceEvenly, CSSValueStretch>(id)) { + return CSSContentDistributionValue::create( + range.consumeIncludingWhitespace().id(), CSSValueInvalid, + CSSValueInvalid); + } + if (identMatches<CSSValueStart, CSSValueEnd, CSSValueCenter, + CSSValueFlexStart, CSSValueFlexEnd, CSSValueLeft, + CSSValueRight>(id)) { + return CSSContentDistributionValue::create( + CSSValueInvalid, range.consumeIncludingWhitespace().id(), + CSSValueInvalid); + } + return nullptr; +} + +bool CSSPropertyParser::consumePlaceContentShorthand(bool important) { + DCHECK(RuntimeEnabledFeatures::cssGridLayoutEnabled()); + DCHECK_EQ(shorthandForProperty(CSSPropertyPlaceContent).length(), + static_cast<unsigned>(2)); + + CSSValue* alignContentValue = consumeSimplifiedContentPosition(m_range); + if (!alignContentValue) + return false; + CSSValue* justifyContentValue = + m_range.atEnd() ? alignContentValue + : consumeSimplifiedContentPosition(m_range); + if (!justifyContentValue) + return false; + if (!m_range.atEnd()) + return false; + + addProperty(CSSPropertyAlignContent, CSSPropertyPlaceContent, + *alignContentValue, important); + addProperty(CSSPropertyJustifyContent, CSSPropertyPlaceContent, + *justifyContentValue, important); + return true; +} + bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool important) { CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); @@ -3752,6 +3799,8 @@ return consumeGridTemplateShorthand(CSSPropertyGridTemplate, important); case CSSPropertyGrid: return consumeGridShorthand(important); + case CSSPropertyPlaceContent: + return consumePlaceContentShorthand(important); default: return false; }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h index 4f291e7..89f2abf 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -101,6 +101,8 @@ bool consumeGridShorthand(bool important); bool consumeGridAreaShorthand(bool important); + bool consumePlaceContentShorthand(bool important); + bool consumeFont(bool important); bool consumeFontVariantShorthand(bool important); bool consumeSystemFont(bool important);
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp index d6710d2..b6219c0 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -46,7 +46,7 @@ } // Make sure update_use_counter_css.py was run which updates histograms.xml. -constexpr int kMaximumCSSSampleId = 556; +constexpr int kMaximumCSSSampleId = 557; } // namespace @@ -1081,6 +1081,8 @@ return 555; case CSSPropertyAliasLineBreak: return 556; + case CSSPropertyPlaceContent: + return 557; // 1. Add new features above this line (don't change the assigned numbers of // the existing items). // 2. Update kMaximumCSSSampleId with the new maximum value.