diff --git a/DEPS b/DEPS index 1971b03..8277514 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'edfe4a5ca01858f47c4d12cc15ec36d606048704', + 'skia_revision': '7e872caaf618c8c5fc376515143a3176e09bced2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '4442d453f570fda76ec4852e2bb03e7ec8bfb825', + 'pdfium_revision': '67ccef73bf664b7cdb4c6eed7acbaa4163c22a80', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -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': '5f09d557a14bc3cacc3df8cf9b312b1603840de2', + 'catapult_revision': '7de63c29970bbe9460c5aa03b0297009ad8dee89', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -808,7 +808,7 @@ 'action': ['python', 'src/build/get_syzygy_binaries.py', '--output-dir=src/third_party/syzygy/binaries', - '--revision=9fe2e8224cea590f3bba83f244cb657785106c3b', + '--revision=190dbfe74c6f5b5913820fa66d9176877924d7c5', '--overwrite', '--copy-dia-binaries', ],
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index f1435f6..79acceff 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -547,10 +547,8 @@ content::RenderFrameHost* render_frame_host, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) { - if (frame_interfaces_.CanBindInterface(interface_name)) { - frame_interfaces_.BindInterface(interface_name, std::move(interface_pipe), - render_frame_host); - } + frame_interfaces_.TryBindInterface(interface_name, &interface_pipe, + render_frame_host); } } // namespace android_webview
diff --git a/android_webview/browser/aw_contents_statics.cc b/android_webview/browser/aw_contents_statics.cc index 91482bbd..8d70c06 100644 --- a/android_webview/browser/aw_contents_statics.cc +++ b/android_webview/browser/aw_contents_statics.cc
@@ -44,6 +44,13 @@ net::CertDatabase::GetInstance()->OnAndroidKeyStoreChanged(); } +void SafeBrowsingWhitelistAssigned(const JavaRef<jobject>& callback, + bool success) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + JNIEnv* env = AttachCurrentThread(); + Java_AwContentsStatics_safeBrowsingWhitelistAssigned(env, callback, success); +} + } // namespace // static @@ -93,14 +100,18 @@ } // static -void SetSafeBrowsingWhiteList(JNIEnv* env, +void SetSafeBrowsingWhitelist(JNIEnv* env, const JavaParamRef<jclass>&, - const JavaParamRef<jobjectArray>& jrules) { + const JavaParamRef<jobjectArray>& jrules, + const JavaParamRef<jobject>& callback) { std::vector<std::string> rules; base::android::AppendJavaStringArrayToStringVector(env, jrules, &rules); AwSafeBrowsingWhitelistManager* whitelist_manager = AwBrowserContext::GetDefault()->GetSafeBrowsingWhitelistManager(); - whitelist_manager->SetWhitelistOnUIThread(std::move(rules)); + whitelist_manager->SetWhitelistOnUIThread( + std::move(rules), + base::Bind(&SafeBrowsingWhitelistAssigned, + ScopedJavaGlobalRef<jobject>(env, callback))); } // static
diff --git a/android_webview/browser/aw_safe_browsing_whitelist_manager.cc b/android_webview/browser/aw_safe_browsing_whitelist_manager.cc index d4c5fa09..521bce6 100644 --- a/android_webview/browser/aw_safe_browsing_whitelist_manager.cc +++ b/android_webview/browser/aw_safe_browsing_whitelist_manager.cc
@@ -143,12 +143,14 @@ return true; } -void AddRules(const std::vector<std::string>& rules, TrieNode* root) { +bool AddRules(const std::vector<std::string>& rules, TrieNode* root) { for (auto rule : rules) { if (!AddRuleToWhitelist(rule, root)) { - LOG(ERROR) << " Dropping invalid whitelist rule " << rule; + LOG(ERROR) << " invalid whitelist rule " << rule; + return false; } } + return true; } bool IsWhitelisted(const GURL& url, const TrieNode* node) { @@ -193,30 +195,37 @@ // A task that builds the whitelist on a background thread. void AwSafeBrowsingWhitelistManager::BuildWhitelist( - const std::vector<std::string>& rules) { + const std::vector<std::string>& rules, + const base::Callback<void(bool)>& callback) { DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); std::unique_ptr<TrieNode> whitelist(base::MakeUnique<TrieNode>()); - AddRules(rules, whitelist.get()); + bool success = AddRules(rules, whitelist.get()); DCHECK(!whitelist->is_terminal); DCHECK(!whitelist->match_prefix); - // use base::Unretained as AwSafeBrowsingWhitelistManager is a singleton and - // not cleaned. - io_task_runner_->PostTask( - FROM_HERE, - base::Bind(&AwSafeBrowsingWhitelistManager::SetWhitelist, - base::Unretained(this), base::Passed(std::move(whitelist)))); + + ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, success)); + + if (success) { + // use base::Unretained as AwSafeBrowsingWhitelistManager is a singleton and + // not cleaned. + io_task_runner_->PostTask( + FROM_HERE, + base::Bind(&AwSafeBrowsingWhitelistManager::SetWhitelist, + base::Unretained(this), base::Passed(std::move(whitelist)))); + } } void AwSafeBrowsingWhitelistManager::SetWhitelistOnUIThread( - std::vector<std::string>&& rules) { + std::vector<std::string>&& rules, + const base::Callback<void(bool)>& callback) { DCHECK(ui_task_runner_->RunsTasksInCurrentSequence()); // use base::Unretained as AwSafeBrowsingWhitelistManager is a singleton and // not cleaned. background_task_runner_->PostTask( - FROM_HERE, - base::Bind(&AwSafeBrowsingWhitelistManager::BuildWhitelist, - base::Unretained(this), base::Passed(std::move(rules)))); + FROM_HERE, base::Bind(&AwSafeBrowsingWhitelistManager::BuildWhitelist, + base::Unretained(this), + base::Passed(std::move(rules)), callback)); } bool AwSafeBrowsingWhitelistManager::IsURLWhitelisted(const GURL& url) const {
diff --git a/android_webview/browser/aw_safe_browsing_whitelist_manager.h b/android_webview/browser/aw_safe_browsing_whitelist_manager.h index ade2354..e4dfcea 100644 --- a/android_webview/browser/aw_safe_browsing_whitelist_manager.h +++ b/android_webview/browser/aw_safe_browsing_whitelist_manager.h
@@ -65,11 +65,13 @@ bool IsURLWhitelisted(const GURL& url) const; // Replace the current host whitelist with a new one. - void SetWhitelistOnUIThread(std::vector<std::string>&& rules); + void SetWhitelistOnUIThread(std::vector<std::string>&& rules, + const base::Callback<void(bool)>& callback); private: // Builds whitelist on background thread. - void BuildWhitelist(const std::vector<std::string>& rules); + void BuildWhitelist(const std::vector<std::string>& rules, + const base::Callback<void(bool)>& callback); // Replaces the current whitelist. Must be called on the IO thread. void SetWhitelist(std::unique_ptr<TrieNode> whitelist);
diff --git a/android_webview/browser/aw_safe_browsing_whitelist_manager_unittest.cc b/android_webview/browser/aw_safe_browsing_whitelist_manager_unittest.cc index fa1663c..89546c9 100644 --- a/android_webview/browser/aw_safe_browsing_whitelist_manager_unittest.cc +++ b/android_webview/browser/aw_safe_browsing_whitelist_manager_unittest.cc
@@ -27,14 +27,27 @@ void TearDown() override { wm_.reset(); } + void SetWhitelist(std::vector<std::string>&& whitelist, bool expected); + base::MessageLoopForIO loop_; std::unique_ptr<AwSafeBrowsingWhitelistManager> wm_; }; +void VerifyWhitelistCallback(bool expected, bool success) { + EXPECT_EQ(expected, success); +} + +void AwSafeBrowsingWhitelistManagerTest::SetWhitelist( + std::vector<std::string>&& whitelist, + bool expected) { + wm_->SetWhitelistOnUIThread(std::move(whitelist), + base::Bind(&VerifyWhitelistCallback, expected)); +} + TEST_F(AwSafeBrowsingWhitelistManagerTest, WsSchemeCanBeWhitelisted) { std::vector<std::string> whitelist; whitelist.push_back("google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("ws://google.com"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("wss://google.com"))); @@ -43,7 +56,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, HttpSchemeCanBeWhitelisted) { std::vector<std::string> whitelist; whitelist.push_back("google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("https://google.com"))); @@ -55,7 +68,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, WsSchemeCanBeWhitelistedExactMatch) { std::vector<std::string> whitelist; whitelist.push_back(".google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("ws://google.com"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("wss://google.com"))); @@ -67,7 +80,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, ExactMatchWorks) { std::vector<std::string> whitelist; whitelist.push_back(".google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("https://google.com"))); @@ -82,7 +95,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, SchemeInWhitelistIsInvalid) { std::vector<std::string> whitelist; whitelist.push_back("http://google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), false); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://google.com"))); } @@ -92,7 +105,7 @@ std::vector<std::string> whitelist; whitelist.push_back("data:google.com"); whitelist.push_back("mailto:google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), false); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://google.com"))); } @@ -100,7 +113,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, PortInWhitelistIsInvalid) { std::vector<std::string> whitelist; whitelist.push_back("www.google.com:123"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), false); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://www.google.com"))); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://www.google.com:123"))); @@ -109,7 +122,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, PathInWhitelistIsInvalid) { std::vector<std::string> whitelist; whitelist.push_back("www.google.com/123"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), false); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://www.google.com/123"))); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://www.google.com"))); @@ -118,7 +131,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, PathQueryAndReferenceWorks) { std::vector<std::string> whitelist; whitelist.push_back("google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com/a"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com/a/b"))); @@ -130,7 +143,7 @@ std::vector<std::string> whitelist; whitelist.push_back("google.com."); whitelist.push_back("example.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://example.com."))); @@ -139,7 +152,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, DomainNameEmbeddedInPathIsIgnored) { std::vector<std::string> whitelist; whitelist.push_back("google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://example.com/google.com"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com"))); @@ -148,7 +161,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, URLsWithEmbeddedUserNamePassword) { std::vector<std::string> whitelist; whitelist.push_back("google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://user1:pass@google.com"))); } @@ -157,7 +170,7 @@ PathQueryAndReferenceWorksWithLeadingDot) { std::vector<std::string> whitelist; whitelist.push_back(".google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com/a"))); @@ -170,7 +183,7 @@ SubdomainsAreAllowedWhenNoLeadingDots) { std::vector<std::string> whitelist; whitelist.push_back("google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com"))); @@ -182,7 +195,7 @@ SubdomainsAreNotAllowedWhenLeadingDots) { std::vector<std::string> whitelist; whitelist.push_back(".google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com"))); @@ -190,20 +203,12 @@ EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://b.a.google.com/"))); } -TEST_F(AwSafeBrowsingWhitelistManagerTest, WildCardNotAccepted) { - std::vector<std::string> whitelist; - whitelist.push_back("*"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); -} - TEST_F(AwSafeBrowsingWhitelistManagerTest, MatchSubdomainsInMultipleWhitelists) { std::vector<std::string> whitelist; whitelist.push_back("a.google.com"); whitelist.push_back(".google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://b.a.google.com/"))); @@ -215,7 +220,7 @@ std::vector<std::string> whitelist; whitelist.push_back("a.google.com"); whitelist.push_back(".google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://.a.google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://.b.a.google.com/"))); @@ -227,14 +232,17 @@ std::vector<std::string> whitelist; whitelist.push_back(".com"); whitelist.push_back("co"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://b.a.google.co/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://com/"))); } -TEST_F(AwSafeBrowsingWhitelistManagerTest, VerifyRandomWildcardsAreIgnored) { +// It seems GURL is happy to accept "*" in hostname literal. Since we rely +// on GURL host validation, just be consistent on that but make sure +// that does not wildcard all the domains. +TEST_F(AwSafeBrowsingWhitelistManagerTest, VerifyStarDoesNotWildcardDomains) { std::vector<std::string> whitelist; whitelist.push_back("*.com"); whitelist.push_back("*co"); @@ -242,17 +250,24 @@ whitelist.push_back("b.*.*.co"); whitelist.push_back("b.*"); whitelist.push_back("c*"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://b.a.google.co/"))); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://com/"))); + + whitelist.clear(); + whitelist.push_back("*"); + SetWhitelist(std::move(whitelist), true); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); + EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://*/"))); } TEST_F(AwSafeBrowsingWhitelistManagerTest, VerifyPrefixOrSuffixOfDomains) { std::vector<std::string> whitelist; whitelist.push_back("google.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://ogle.com/"))); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://agoogle.com/"))); @@ -262,7 +277,7 @@ std::vector<std::string> whitelist; whitelist.push_back("google.com"); whitelist.push_back("192.168.1.1"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://192.168.1.1/"))); @@ -271,7 +286,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, VerifyIPV4IsNotSegmented) { std::vector<std::string> whitelist; whitelist.push_back("192.168.1.1"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://192.168.1.1/"))); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://1.192.168.1.1/"))); @@ -281,7 +296,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, VerifyLeadingDotInIPV4IsNotValid) { std::vector<std::string> whitelist; whitelist.push_back(".192.168.1.1"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), false); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://192.168.1.1/"))); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://1.192.168.1.1/"))); @@ -292,7 +307,7 @@ whitelist.push_back("192.168.1.1"); whitelist.push_back("192.168.1.2"); whitelist.push_back("194.168.1.1"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://192.168.1.1/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://192.168.1.2/"))); @@ -304,7 +319,7 @@ TEST_F(AwSafeBrowsingWhitelistManagerTest, VerifyIPV6CanBeWhitelisted) { std::vector<std::string> whitelist; whitelist.push_back("[10:20:30:40:50:60:70:80]"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://[10:20:30:40:50:60:70:80]"))); } @@ -313,7 +328,7 @@ VerifyIPV6CannotBeWhitelistedIfBroken) { std::vector<std::string> whitelist; whitelist.push_back("[10:20:30:40:50:60:]"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), false); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://[10:20:30:40:50:60:70:80]"))); } @@ -322,7 +337,7 @@ VerifyIPV6WithZerosCanBeWhitelisted) { std::vector<std::string> whitelist; whitelist.push_back("[20:0:0:0:0:0:0:0]"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://[20:0:0:0:0:0:0:0]"))); } @@ -331,7 +346,7 @@ std::vector<std::string> whitelist; whitelist.push_back("A.goOGle.Com"); whitelist.push_back(".GOOGLE.COM"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://b.a.google.com/"))); @@ -344,7 +359,7 @@ std::vector<std::string> whitelist; whitelist.push_back("com"); whitelist.push_back("example.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://example.com/"))); @@ -358,7 +373,7 @@ std::vector<std::string> whitelist; whitelist.push_back("example.com"); whitelist.push_back("com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://example.com/"))); @@ -371,7 +386,7 @@ std::vector<std::string> whitelist; whitelist.push_back(".com"); whitelist.push_back("example.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://example.com/"))); @@ -386,7 +401,7 @@ std::vector<std::string> whitelist; whitelist.push_back("example.com"); whitelist.push_back(".com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(wm_->IsURLWhitelisted(GURL("http://a.google.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://example.com/"))); @@ -403,7 +418,7 @@ std::vector<std::string> whitelist; whitelist.push_back("com"); whitelist.push_back(".example.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://a.example.com/"))); } @@ -413,14 +428,14 @@ std::vector<std::string> whitelist; whitelist.push_back("example.com"); whitelist.push_back(".example.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://a.example.com/"))); whitelist = std::vector<std::string>(); whitelist.push_back(".example.com"); whitelist.push_back("example.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://a.example.com/"))); } @@ -432,7 +447,7 @@ whitelist.push_back(".example.com"); whitelist.push_back("example.com"); whitelist.push_back("a.example.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://a.example.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://b.example.com/"))); @@ -444,7 +459,7 @@ whitelist.push_back("example.com"); whitelist.push_back(".example.com"); whitelist.push_back("b.example.com"); - wm_->SetWhitelistOnUIThread(std::move(whitelist)); + SetWhitelist(std::move(whitelist), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://a.example.com/"))); EXPECT_TRUE(wm_->IsURLWhitelisted(GURL("http://b.example.com/")));
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index acf471f..ac97018 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc
@@ -197,6 +197,8 @@ const viz::LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) {} +void HardwareRenderer::OnBeginFramePausedChanged(bool paused) {} + // static ChildFrameQueue HardwareRenderer::WaitAndPruneFrameQueue( ChildFrameQueue* child_frames_ptr) {
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index 3424e728..0474da6 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h
@@ -57,6 +57,7 @@ const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) override; + void OnBeginFramePausedChanged(bool paused) override; void ReturnChildFrame(std::unique_ptr<ChildFrame> child_frame); void ReturnResourcesToCompositor(
diff --git a/android_webview/browser/surfaces_instance.cc b/android_webview/browser/surfaces_instance.cc index a376fa9..626812ab 100644 --- a/android_webview/browser/surfaces_instance.cc +++ b/android_webview/browser/surfaces_instance.cc
@@ -221,4 +221,6 @@ CHECK(resources.empty()); } +void SurfacesInstance::OnBeginFramePausedChanged(bool paused) {} + } // namespace android_webview
diff --git a/android_webview/browser/surfaces_instance.h b/android_webview/browser/surfaces_instance.h index 738e896..4587a8a4 100644 --- a/android_webview/browser/surfaces_instance.h +++ b/android_webview/browser/surfaces_instance.h
@@ -73,6 +73,7 @@ void OnBeginFrame(const cc::BeginFrameArgs& args) override; void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) override; + void OnBeginFramePausedChanged(bool paused) override; void ReclaimResources( const std::vector<cc::ReturnedResource>& resources) override;
diff --git a/android_webview/common/crash_reporter/crash_keys.cc b/android_webview/common/crash_reporter/crash_keys.cc index f3549c5..7453366e 100644 --- a/android_webview/common/crash_reporter/crash_keys.cc +++ b/android_webview/common/crash_reporter/crash_keys.cc
@@ -32,11 +32,6 @@ const char kZeroEncodeDetails[] = "zero-encode-details"; -// TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. -// TODO(sunnyps): Remove after fixing https://crbug.com/622080 -const char kBeginMainFrameHangCompositorState[] = - "begin-main-frame-hang-compositor-state"; - size_t RegisterWebViewCrashKeys() { base::debug::CrashKey fixed_keys[] = { {"AW_WHITELISTED_DEBUG_KEY", kSmallSize}, @@ -134,10 +129,6 @@ // Temporary for https://crbug.com/685996. {"user-cloud-policy-manager-connect-trace", kMediumSize}, - - // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. - // TODO(sunnyps): Remove after fixing https://crbug.com/622080 - {kBeginMainFrameHangCompositorState, kSmallSize}, }; // This dynamic set of keys is used for sets of key value pairs when gathering
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java index 9325b7a..6a5c5cc 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
@@ -68,6 +68,7 @@ import org.chromium.net.NetworkChangeNotifier; import java.io.File; +import java.util.List; import java.util.Queue; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentLinkedQueue; @@ -576,6 +577,12 @@ AwContentsStatics.shutdownSafeBrowsing(); } + // TODO(ntfschr): add @Override once next android SDK rolls + public void setSafeBrowsingWhitelist( + List<String> urls, ValueCallback<Boolean> callback) { + AwContentsStatics.setSafeBrowsingWhitelist(urls, callback); + } + }; } }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java index 16c5d07..38a45cd8 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
@@ -13,6 +13,7 @@ import org.chromium.base.annotations.JNINamespace; import java.lang.reflect.Method; +import java.util.List; /** * Implementations of various static methods, and also a home for static @@ -107,8 +108,23 @@ setSafeBrowsingEnabledByManifest(enable); } - public static void setSafeBrowsingWhiteList(String[] urls) { - nativeSetSafeBrowsingWhiteList(urls); + @CalledByNative + private static void safeBrowsingWhitelistAssigned( + ValueCallback<Boolean> callback, boolean success) { + if (callback == null) return; + callback.onReceiveValue(success); + } + + public static void setSafeBrowsingWhitelist( + List<String> urls, ValueCallback<Boolean> callback) { + String[] urlArray = urls.toArray(new String[urls.size()]); + if (callback == null) { + callback = new ValueCallback<Boolean>() { + @Override + public void onReceiveValue(Boolean b) {} + }; + } + nativeSetSafeBrowsingWhitelist(urlArray, callback); } @SuppressWarnings("unchecked") @@ -173,7 +189,8 @@ AwContentsIoThreadClient ioThreadClient, AwBrowserContext browserContext); private static native boolean nativeGetSafeBrowsingEnabledByManifest(); private static native void nativeSetSafeBrowsingEnabledByManifest(boolean enable); - private static native void nativeSetSafeBrowsingWhiteList(String[] urls); + private static native void nativeSetSafeBrowsingWhitelist( + String[] urls, ValueCallback<Boolean> callback); private static native void nativeSetCheckClearTextPermitted(boolean permitted); private static native String nativeFindAddress(String addr); }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java index cd1f1b2..ddcb85d 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java
@@ -44,6 +44,7 @@ import org.chromium.content_public.browser.WebContents; import org.chromium.net.test.EmbeddedTestServer; +import java.util.ArrayList; import java.util.Arrays; import java.util.concurrent.Callable; @@ -261,6 +262,15 @@ } } + private static class WhitelistHelper extends CallbackHelper implements ValueCallback<Boolean> { + public boolean success; + + public void onReceiveValue(Boolean success) { + this.success = success; + notifyCalled(); + } + } + @Override public void setUp() throws Exception { super.setUp(); @@ -446,8 +456,9 @@ @Override public void run() { String host = Uri.parse(responseUrl).getHost(); - String[] s = new String[] {host}; - AwContentsStatics.setSafeBrowsingWhiteList(s); + ArrayList<String> s = new ArrayList<String>(); + s.add(host); + AwContentsStatics.setSafeBrowsingWhitelist(s, null); } }); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), responseUrl); @@ -457,6 +468,35 @@ @SmallTest @Feature({"AndroidWebView"}) @CommandLineFlags.Add(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT) + public void testCallbackCalledOnSafeBrowsingBadWhitelistRule() throws Throwable { + verifyWhiteListRule("http://www.google.com", false); + } + + @SmallTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT) + public void testCallbackCalledOnSafeBrowsingGoodWhitelistRule() throws Throwable { + verifyWhiteListRule("www.google.com", true); + } + + private void verifyWhiteListRule(final String rule, boolean expected) throws Throwable { + final WhitelistHelper helper = new WhitelistHelper(); + final int count = helper.getCallCount(); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + ArrayList<String> s = new ArrayList<String>(); + s.add(rule); + AwContentsStatics.setSafeBrowsingWhitelist(s, helper); + } + }); + helper.waitForCallback(count); + assertEquals(expected, helper.success); + } + + @SmallTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add(AwSwitches.WEBVIEW_ENABLE_SAFEBROWSING_SUPPORT) public void testSafeBrowsingShowsInterstitialForMainFrame() throws Throwable { loadGreenPage(); loadPathAndWaitForInterstitial(MALWARE_HTML_PATH);
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 614d4981..8b0c498 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -129,6 +129,8 @@ "drag_drop/drag_drop_tracker.h", "drag_drop/drag_image_view.cc", "drag_drop/drag_image_view.h", + "fast_ink/fast_ink_view.cc", + "fast_ink/fast_ink_view.h", "first_run/desktop_cleaner.cc", "first_run/desktop_cleaner.h", "first_run/first_run_helper.cc", @@ -538,8 +540,6 @@ "system/tray/tray_event_filter.h", "system/tray/tray_image_item.cc", "system/tray/tray_image_item.h", - "system/tray/tray_info_label.cc", - "system/tray/tray_info_label.h", "system/tray/tray_item_more.cc", "system/tray/tray_item_more.h", "system/tray/tray_item_view.cc", @@ -1247,7 +1247,6 @@ "system/tray/system_tray_unittest.cc", "system/tray/tray_details_view_unittest.cc", "system/tray/tray_event_filter_unittest.cc", - "system/tray/tray_info_label_unittest.cc", "system/tray/tri_view_unittest.cc", "system/tray_tracing_unittest.cc", "system/update/tray_update_unittest.cc",
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 538e52ed..76c08e06 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -892,9 +892,6 @@ <message name="IDS_ASH_STATUS_TRAY_NO_MOBILE_NETWORKS" desc="The message to display in the network list when no mobile networks are available."> No mobile network available </message> - <message name="IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH" desc="The message to display in the network list when Tether is enabled but Bluetooth is disabled."> - Turn on Bluetooth to discover nearby devices - </message> <message name="IDS_ASH_STATUS_TRAY_VPN_DISCONNECTED" desc="The label used in system tray bubble to display vpn is disconnected."> VPN disconnected </message>
diff --git a/ash/fast_ink/DEPS b/ash/fast_ink/DEPS new file mode 100644 index 0000000..57b8ea9 --- /dev/null +++ b/ash/fast_ink/DEPS
@@ -0,0 +1,5 @@ +include_rules = [ + "+cc", + "+components/viz/common/gpu", + "+gpu/command_buffer/client", +]
diff --git a/ash/fast_ink/fast_ink_view.cc b/ash/fast_ink/fast_ink_view.cc new file mode 100644 index 0000000..f37832b7 --- /dev/null +++ b/ash/fast_ink/fast_ink_view.cc
@@ -0,0 +1,381 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/fast_ink/fast_ink_view.h" + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <GLES2/gl2extchromium.h> + +#include "ash/public/cpp/shell_window_ids.h" +#include "ash/shell.h" +#include "base/threading/thread_task_runner_handle.h" +#include "cc/output/compositor_frame.h" +#include "cc/output/layer_tree_frame_sink.h" +#include "cc/output/layer_tree_frame_sink_client.h" +#include "cc/quads/texture_draw_quad.h" +#include "components/viz/common/gpu/context_provider.h" +#include "gpu/command_buffer/client/gles2_interface.h" +#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" +#include "ui/aura/env.h" +#include "ui/aura/window.h" +#include "ui/base/layout.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/gpu_memory_buffer.h" +#include "ui/views/widget/widget.h" + +namespace ash { + +class FastInkLayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient { + public: + FastInkLayerTreeFrameSinkHolder( + FastInkView* view, + std::unique_ptr<cc::LayerTreeFrameSink> frame_sink) + : view_(view), frame_sink_(std::move(frame_sink)) { + frame_sink_->BindToClient(this); + } + ~FastInkLayerTreeFrameSinkHolder() override { + frame_sink_->DetachFromClient(); + } + + cc::LayerTreeFrameSink* frame_sink() { return frame_sink_.get(); } + + // Called before fast ink view is destroyed. + void OnFastInkViewDestroying() { view_ = nullptr; } + + // Overridden from cc::LayerTreeFrameSinkClient: + void SetBeginFrameSource(cc::BeginFrameSource* source) override {} + void ReclaimResources( + const std::vector<cc::ReturnedResource>& resources) override { + if (view_) + view_->ReclaimResources(resources); + } + void SetTreeActivationCallback(const base::Closure& callback) override {} + void DidReceiveCompositorFrameAck() override { + if (view_) + view_->DidReceiveCompositorFrameAck(); + } + void DidLoseLayerTreeFrameSink() override {} + void OnDraw(const gfx::Transform& transform, + const gfx::Rect& viewport, + bool resourceless_software_draw) override {} + void SetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override {} + void SetExternalTilePriorityConstraints( + const gfx::Rect& viewport_rect, + const gfx::Transform& transform) override {} + + private: + FastInkView* view_; + std::unique_ptr<cc::LayerTreeFrameSink> frame_sink_; + + DISALLOW_COPY_AND_ASSIGN(FastInkLayerTreeFrameSinkHolder); +}; + +// This struct contains the resources associated with a fast ink frame. +struct FastInkResource { + FastInkResource() {} + ~FastInkResource() { + if (context_provider) { + gpu::gles2::GLES2Interface* gles2 = context_provider->ContextGL(); + if (texture) + gles2->DeleteTextures(1, &texture); + if (image) + gles2->DestroyImageCHROMIUM(image); + } + } + scoped_refptr<viz::ContextProvider> context_provider; + uint32_t texture = 0; + uint32_t image = 0; + gpu::Mailbox mailbox; +}; + +// FastInkView +FastInkView::FastInkView(aura::Window* root_window) : weak_ptr_factory_(this) { + widget_.reset(new views::Widget); + views::Widget::InitParams params; + params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; + params.name = "FastInkOverlay"; + params.accept_events = false; + params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; + params.parent = + Shell::GetContainer(root_window, kShellWindowId_OverlayContainer); + params.layer_type = ui::LAYER_SOLID_COLOR; + + widget_->Init(params); + widget_->Show(); + widget_->SetContentsView(this); + widget_->SetBounds(root_window->GetBoundsInScreen()); + set_owned_by_client(); + + scale_factor_ = ui::GetScaleFactorForNativeView(widget_->GetNativeView()); + + frame_sink_holder_ = base::MakeUnique<FastInkLayerTreeFrameSinkHolder>( + this, widget_->GetNativeView()->CreateLayerTreeFrameSink()); +} + +FastInkView::~FastInkView() { + frame_sink_holder_->OnFastInkViewDestroying(); +} + +void FastInkView::DidReceiveCompositorFrameAck() { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&FastInkView::OnDidDrawSurface, + weak_ptr_factory_.GetWeakPtr())); +} + +void FastInkView::ReclaimResources( + const std::vector<cc::ReturnedResource>& resources) { + DCHECK_EQ(resources.size(), 1u); + + auto it = resources_.find(resources.front().id); + DCHECK(it != resources_.end()); + std::unique_ptr<FastInkResource> resource = std::move(it->second); + resources_.erase(it); + + gpu::gles2::GLES2Interface* gles2 = resource->context_provider->ContextGL(); + if (resources.front().sync_token.HasData()) + gles2->WaitSyncTokenCHROMIUM(resources.front().sync_token.GetConstData()); + + if (!resources.front().lost) + returned_resources_.push_back(std::move(resource)); +} + +void FastInkView::UpdateDamageRect(const gfx::Rect& rect) { + buffer_damage_rect_.Union(rect); +} + +void FastInkView::RequestRedraw() { + if (pending_update_buffer_) + return; + + pending_update_buffer_ = true; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(&FastInkView::UpdateBuffer, weak_ptr_factory_.GetWeakPtr())); +} + +void FastInkView::UpdateBuffer() { + TRACE_EVENT1("ui", "FastInkView::UpdateBuffer", "damage", + buffer_damage_rect_.ToString()); + + DCHECK(pending_update_buffer_); + pending_update_buffer_ = false; + + gfx::Rect screen_bounds = widget_->GetNativeView()->GetBoundsInScreen(); + gfx::Rect update_rect = buffer_damage_rect_; + buffer_damage_rect_ = gfx::Rect(); + + // Create and map a single GPU memory buffer. The fast ink will be + // written into this buffer without any buffering. The result is that we + // might be modifying the buffer while it's being displayed. This provides + // minimal latency but potential tearing. Note that we have to draw into + // a temporary surface and copy it into GPU memory buffer to avoid flicker. + if (!gpu_memory_buffer_) { + TRACE_EVENT0("ui", "FastInkView::UpdateBuffer::Create"); + + gpu_memory_buffer_ = + aura::Env::GetInstance() + ->context_factory() + ->GetGpuMemoryBufferManager() + ->CreateGpuMemoryBuffer( + gfx::ScaleToCeiledSize(screen_bounds.size(), scale_factor_), + SK_B32_SHIFT ? gfx::BufferFormat::RGBA_8888 + : gfx::BufferFormat::BGRA_8888, + gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, + gpu::kNullSurfaceHandle); + if (!gpu_memory_buffer_) { + LOG(ERROR) << "Failed to allocate GPU memory buffer"; + return; + } + + // Make sure the first update rectangle covers the whole buffer. + update_rect = gfx::Rect(screen_bounds.size()); + } + + // Constrain update rectangle to buffer size and early out if empty. + update_rect.Intersect(gfx::Rect(screen_bounds.size())); + if (update_rect.IsEmpty()) + return; + + // Map buffer for writing. + if (!gpu_memory_buffer_->Map()) { + LOG(ERROR) << "Failed to map GPU memory buffer"; + return; + } + + // Create a temporary canvas for update rectangle. + gfx::Canvas canvas(update_rect.size(), scale_factor_, false); + + { + TRACE_EVENT1("ui", "FastInkView::UpdateBuffer::Paint", "update_rect", + update_rect.ToString()); + + gfx::Vector2d offset = + widget_->GetNativeView()->GetBoundsInRootWindow().OffsetFromOrigin() + + update_rect.OffsetFromOrigin(); + OnRedraw(canvas, offset); + } + + // Convert update rectangle to pixel coordinates. + gfx::Rect pixel_rect = gfx::ScaleToEnclosingRect(update_rect, scale_factor_); + + // Copy result to GPU memory buffer. This is effectively a memcpy and unlike + // drawing to the buffer directly this ensures that the buffer is never in a + // state that would result in flicker. + { + TRACE_EVENT1("ui", "FastInkView::UpdateBuffer::Copy", "pixel_rect", + pixel_rect.ToString()); + + uint8_t* data = static_cast<uint8_t*>(gpu_memory_buffer_->memory(0)); + int stride = gpu_memory_buffer_->stride(0); + canvas.GetBitmap().readPixels( + SkImageInfo::MakeN32Premul(pixel_rect.width(), pixel_rect.height()), + data + pixel_rect.y() * stride + pixel_rect.x() * 4, stride, 0, 0); + } + + // Unmap to flush writes to buffer. + gpu_memory_buffer_->Unmap(); + + // Update surface damage rectangle. + surface_damage_rect_.Union(update_rect); + + needs_update_surface_ = true; + + // Early out if waiting for last surface update to be drawn. + if (pending_draw_surface_) + return; + + UpdateSurface(); +} + +void FastInkView::UpdateSurface() { + TRACE_EVENT1("ui", "FastInkView::UpdateSurface", "damage", + surface_damage_rect_.ToString()); + + DCHECK(needs_update_surface_); + needs_update_surface_ = false; + + std::unique_ptr<FastInkResource> resource; + // Reuse returned resource if available. + if (!returned_resources_.empty()) { + resource = std::move(returned_resources_.back()); + returned_resources_.pop_back(); + } + + // Create new resource if needed. + if (!resource) + resource = base::MakeUnique<FastInkResource>(); + + // Acquire context provider for resource if needed. + // Note: We make no attempts to recover if the context provider is later + // lost. It is expected that this class is short-lived and requiring a + // new instance to be created in lost context situations is acceptable and + // keeps the code simple. + if (!resource->context_provider) { + resource->context_provider = aura::Env::GetInstance() + ->context_factory() + ->SharedMainThreadContextProvider(); + if (!resource->context_provider) { + LOG(ERROR) << "Failed to acquire a context provider"; + return; + } + } + + gpu::gles2::GLES2Interface* gles2 = resource->context_provider->ContextGL(); + + if (resource->texture) { + gles2->ActiveTexture(GL_TEXTURE0); + gles2->BindTexture(GL_TEXTURE_2D, resource->texture); + } else { + gles2->GenTextures(1, &resource->texture); + gles2->ActiveTexture(GL_TEXTURE0); + gles2->BindTexture(GL_TEXTURE_2D, resource->texture); + gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gles2->GenMailboxCHROMIUM(resource->mailbox.name); + gles2->ProduceTextureCHROMIUM(GL_TEXTURE_2D, resource->mailbox.name); + } + + gfx::Size buffer_size = gpu_memory_buffer_->GetSize(); + + if (resource->image) { + gles2->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, resource->image); + } else { + resource->image = gles2->CreateImageCHROMIUM( + gpu_memory_buffer_->AsClientBuffer(), buffer_size.width(), + buffer_size.height(), SK_B32_SHIFT ? GL_RGBA : GL_BGRA_EXT); + if (!resource->image) { + LOG(ERROR) << "Failed to create image"; + return; + } + } + gles2->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, resource->image); + + gpu::SyncToken sync_token; + uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM(); + gles2->OrderingBarrierCHROMIUM(); + gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); + + cc::TransferableResource transferable_resource; + transferable_resource.id = next_resource_id_++; + transferable_resource.format = viz::RGBA_8888; + transferable_resource.filter = GL_LINEAR; + transferable_resource.size = buffer_size; + transferable_resource.mailbox_holder = + gpu::MailboxHolder(resource->mailbox, sync_token, GL_TEXTURE_2D); + transferable_resource.is_overlay_candidate = true; + + gfx::Rect quad_rect(widget_->GetNativeView()->GetBoundsInScreen().size()); + + const int kRenderPassId = 1; + std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); + render_pass->SetNew(kRenderPassId, quad_rect, surface_damage_rect_, + gfx::Transform()); + surface_damage_rect_ = gfx::Rect(); + + cc::SharedQuadState* quad_state = + render_pass->CreateAndAppendSharedQuadState(); + quad_state->quad_layer_rect = quad_rect; + quad_state->visible_quad_layer_rect = quad_rect; + quad_state->opacity = 1.0f; + + cc::CompositorFrame frame; + // TODO(eseckler): FastInkView should use BeginFrames and set the ack + // accordingly. + frame.metadata.begin_frame_ack = + cc::BeginFrameAck::CreateManualAckWithDamage(); + frame.metadata.device_scale_factor = + widget_->GetLayer()->device_scale_factor(); + cc::TextureDrawQuad* texture_quad = + render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); + float vertex_opacity[4] = {1.0, 1.0, 1.0, 1.0}; + gfx::PointF uv_top_left(0.f, 0.f); + gfx::PointF uv_bottom_right(1.f, 1.f); + texture_quad->SetNew(quad_state, quad_rect, gfx::Rect(), quad_rect, + transferable_resource.id, true, uv_top_left, + uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity, + false, false, false); + texture_quad->set_resource_size_in_pixels(transferable_resource.size); + frame.resource_list.push_back(transferable_resource); + frame.render_pass_list.push_back(std::move(render_pass)); + + frame_sink_holder_->frame_sink()->SubmitCompositorFrame(std::move(frame)); + + resources_[transferable_resource.id] = std::move(resource); + + DCHECK(!pending_draw_surface_); + pending_draw_surface_ = true; +} + +void FastInkView::OnDidDrawSurface() { + pending_draw_surface_ = false; + if (needs_update_surface_) + UpdateSurface(); +} + +} // namespace ash
diff --git a/ash/fast_ink/fast_ink_view.h b/ash/fast_ink/fast_ink_view.h new file mode 100644 index 0000000..4a31bb6 --- /dev/null +++ b/ash/fast_ink/fast_ink_view.h
@@ -0,0 +1,86 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_FAST_INK_FAST_INK_VIEW_H_ +#define ASH_FAST_INK_FAST_INK_VIEW_H_ + +#include <memory> +#include <vector> + +#include "base/containers/flat_map.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "ui/views/view.h" + +namespace aura { +class Window; +} + +namespace cc { +struct ReturnedResource; +} + +namespace gfx { +class GpuMemoryBuffer; +} + +namespace views { +class Widget; +} + +namespace ash { +class FastInkLayerTreeFrameSinkHolder; +struct FastInkResource; + +// FastInkView is a view supporting low-latency rendering. +class FastInkView : public views::View { + public: + // Creates a FastInkView filling the bounds of |root_window|. + // If |root_window| is resized (e.g. due to a screen size change), + // a new instance of FastInkView should be created. + explicit FastInkView(aura::Window* root_window); + ~FastInkView() override; + + protected: + // Unions |rect| with the current damage rect. + void UpdateDamageRect(const gfx::Rect& rect); + + void RequestRedraw(); + + // Draw the contents of the view in the provided canvas. + virtual void OnRedraw(gfx::Canvas& canvas, const gfx::Vector2d& offset) = 0; + + private: + friend class FastInkLayerTreeFrameSinkHolder; + + // Call this to indicate that the previous frame has been processed. + void DidReceiveCompositorFrameAck(); + + // Call this to return resources so they can be reused or freed. + void ReclaimResources(const std::vector<cc::ReturnedResource>& resources); + + void UpdateBuffer(); + void UpdateSurface(); + void OnDidDrawSurface(); + + std::unique_ptr<views::Widget> widget_; + float scale_factor_ = 1.0f; + std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; + gfx::Rect buffer_damage_rect_; + bool pending_update_buffer_ = false; + gfx::Rect surface_damage_rect_; + bool needs_update_surface_ = false; + bool pending_draw_surface_ = false; + std::unique_ptr<FastInkLayerTreeFrameSinkHolder> frame_sink_holder_; + int next_resource_id_ = 1; + base::flat_map<int, std::unique_ptr<FastInkResource>> resources_; + std::vector<std::unique_ptr<FastInkResource>> returned_resources_; + base::WeakPtrFactory<FastInkView> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(FastInkView); +}; + +} // namespace ash + +#endif // ASH_FAST_INK_FAST_INK_VIEW_H_
diff --git a/ash/laser/DEPS b/ash/laser/DEPS index c592c5d..61499381 100644 --- a/ash/laser/DEPS +++ b/ash/laser/DEPS
@@ -1,6 +1,4 @@ include_rules = [ "+cc", - "+components/viz/common/gpu", - "+components/viz/common/quads", - "+gpu/command_buffer/client", + "+ash/fast_ink", ]
diff --git a/ash/laser/laser_pointer_view.cc b/ash/laser/laser_pointer_view.cc index b46de05..e26d777 100644 --- a/ash/laser/laser_pointer_view.cc +++ b/ash/laser/laser_pointer_view.cc
@@ -4,43 +4,14 @@ #include "ash/laser/laser_pointer_view.h" -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#include <GLES2/gl2extchromium.h> - -#include <algorithm> -#include <array> -#include <cmath> -#include <memory> - #include "ash/laser/laser_pointer_points.h" #include "ash/laser/laser_segment_utils.h" -#include "ash/public/cpp/shell_window_ids.h" -#include "ash/shell.h" #include "base/containers/adapters.h" -#include "base/memory/ptr_util.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/trace_event/trace_event.h" -#include "cc/output/compositor_frame.h" -#include "cc/output/layer_tree_frame_sink.h" -#include "cc/output/layer_tree_frame_sink_client.h" -#include "cc/quads/texture_draw_quad.h" -#include "cc/resources/transferable_resource.h" -#include "components/viz/common/gpu/context_provider.h" -#include "components/viz/common/quads/resource_format.h" -#include "components/viz/common/quads/texture_mailbox.h" -#include "gpu/command_buffer/client/context_support.h" -#include "gpu/command_buffer/client/gles2_interface.h" -#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkTypes.h" -#include "ui/aura/env.h" #include "ui/aura/window.h" -#include "ui/base/layout.h" #include "ui/events/base_event_utils.h" -#include "ui/events/event.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/gpu_memory_buffer.h" #include "ui/views/widget/widget.h" namespace ash { @@ -185,108 +156,23 @@ DISALLOW_COPY_AND_ASSIGN(LaserSegment); }; -class LaserLayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient { - public: - LaserLayerTreeFrameSinkHolder( - LaserPointerView* view, - std::unique_ptr<cc::LayerTreeFrameSink> frame_sink) - : view_(view), frame_sink_(std::move(frame_sink)) { - frame_sink_->BindToClient(this); - } - ~LaserLayerTreeFrameSinkHolder() override { frame_sink_->DetachFromClient(); } - - cc::LayerTreeFrameSink* frame_sink() { return frame_sink_.get(); } - - // Called before laser pointer view is destroyed. - void OnLaserPointerViewDestroying() { view_ = nullptr; } - - // Overridden from cc::LayerTreeFrameSinkClient: - void SetBeginFrameSource(cc::BeginFrameSource* source) override {} - void ReclaimResources( - const std::vector<cc::ReturnedResource>& resources) override { - if (view_) - view_->ReclaimResources(resources); - } - void SetTreeActivationCallback(const base::Closure& callback) override {} - void DidReceiveCompositorFrameAck() override { - if (view_) - view_->DidReceiveCompositorFrameAck(); - } - void DidLoseLayerTreeFrameSink() override {} - void OnDraw(const gfx::Transform& transform, - const gfx::Rect& viewport, - bool resourceless_software_draw) override {} - void SetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override {} - void SetExternalTilePriorityConstraints( - const gfx::Rect& viewport_rect, - const gfx::Transform& transform) override {} - - private: - LaserPointerView* view_; - std::unique_ptr<cc::LayerTreeFrameSink> frame_sink_; - - DISALLOW_COPY_AND_ASSIGN(LaserLayerTreeFrameSinkHolder); -}; - -// This struct contains the resources associated with a laser pointer frame. -struct LaserResource { - LaserResource() {} - ~LaserResource() { - if (context_provider) { - gpu::gles2::GLES2Interface* gles2 = context_provider->ContextGL(); - if (texture) - gles2->DeleteTextures(1, &texture); - if (image) - gles2->DestroyImageCHROMIUM(image); - } - } - scoped_refptr<viz::ContextProvider> context_provider; - uint32_t texture = 0; - uint32_t image = 0; - gpu::Mailbox mailbox; -}; - // LaserPointerView LaserPointerView::LaserPointerView(base::TimeDelta life_duration, base::TimeDelta presentation_delay, aura::Window* root_window) - : laser_points_(life_duration), + : FastInkView(root_window), + laser_points_(life_duration), predicted_laser_points_(life_duration), - presentation_delay_(presentation_delay), - weak_ptr_factory_(this) { - widget_.reset(new views::Widget); - views::Widget::InitParams params; - params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; - params.name = "LaserOverlay"; - params.accept_events = false; - params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; - params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; - params.parent = - Shell::GetContainer(root_window, kShellWindowId_OverlayContainer); - params.layer_type = ui::LAYER_SOLID_COLOR; - - widget_->Init(params); - widget_->Show(); - widget_->SetContentsView(this); - widget_->SetBounds(root_window->GetBoundsInScreen()); - set_owned_by_client(); - - scale_factor_ = ui::GetScaleFactorForNativeView(widget_->GetNativeView()); - - frame_sink_holder_ = base::MakeUnique<LaserLayerTreeFrameSinkHolder>( - this, widget_->GetNativeView()->CreateLayerTreeFrameSink()); -} + presentation_delay_(presentation_delay) {} LaserPointerView::~LaserPointerView() { - frame_sink_holder_->OnLaserPointerViewDestroying(); } void LaserPointerView::Stop() { - buffer_damage_rect_.Union(GetBoundingBox()); + UpdateDamageRect(GetBoundingBox()); laser_points_.Clear(); predicted_laser_points_.Clear(); - OnPointsUpdated(); + RequestRedraw(); } void LaserPointerView::AddNewPoint(const gfx::PointF& new_point, @@ -301,7 +187,7 @@ .Length()) : 0); - buffer_damage_rect_.Union(GetBoundingBox()); + UpdateDamageRect(GetBoundingBox()); laser_points_.AddPoint(new_point, new_time); // Current time is needed to determine presentation time and the number of @@ -316,7 +202,8 @@ predicted_laser_points_.Clear(); // Normalize all coordinates to screen size. - gfx::Size screen_size = widget_->GetNativeView()->GetBoundsInScreen().size(); + gfx::Size screen_size = + GetWidget()->GetNativeView()->GetBoundsInScreen().size(); gfx::Vector2dF scale(1.0f / screen_size.width(), 1.0f / screen_size.height()); // TODO(reveman): Determine interval based on history when event time stamps @@ -400,43 +287,20 @@ laser_points_.MoveForwardToTime(next_presentation_time); predicted_laser_points_.MoveForwardToTime(next_presentation_time); - buffer_damage_rect_.Union(GetBoundingBox()); - OnPointsUpdated(); + UpdateDamageRect(GetBoundingBox()); + RequestRedraw(); } void LaserPointerView::UpdateTime() { - buffer_damage_rect_.Union(GetBoundingBox()); + UpdateDamageRect(GetBoundingBox()); // Do not add the point but advance the time if the view is in process of // fading away. base::TimeTicks next_presentation_time = ui::EventTimeForNow() + presentation_delay_; laser_points_.MoveForwardToTime(next_presentation_time); predicted_laser_points_.MoveForwardToTime(next_presentation_time); - buffer_damage_rect_.Union(GetBoundingBox()); - OnPointsUpdated(); -} - -void LaserPointerView::DidReceiveCompositorFrameAck() { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&LaserPointerView::OnDidDrawSurface, - weak_ptr_factory_.GetWeakPtr())); -} - -void LaserPointerView::ReclaimResources( - const std::vector<cc::ReturnedResource>& resources) { - DCHECK_EQ(resources.size(), 1u); - - auto it = resources_.find(resources.front().id); - DCHECK(it != resources_.end()); - std::unique_ptr<LaserResource> resource = std::move(it->second); - resources_.erase(it); - - gpu::gles2::GLES2Interface* gles2 = resource->context_provider->ContextGL(); - if (resources.front().sync_token.HasData()) - gles2->WaitSyncTokenCHROMIUM(resources.front().sync_token.GetConstData()); - - if (!resources.front().lost) - returned_resources_.push_back(std::move(resource)); + UpdateDamageRect(GetBoundingBox()); + RequestRedraw(); } gfx::Rect LaserPointerView::GetBoundingBox() { @@ -450,295 +314,70 @@ return bounding_box; } -void LaserPointerView::OnPointsUpdated() { - if (pending_update_buffer_) - return; - - pending_update_buffer_ = true; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&LaserPointerView::UpdateBuffer, - weak_ptr_factory_.GetWeakPtr())); -} - -void LaserPointerView::UpdateBuffer() { - TRACE_EVENT1("ui", "LaserPointerView::UpdateBuffer", "damage", - buffer_damage_rect_.ToString()); - - DCHECK(pending_update_buffer_); - pending_update_buffer_ = false; - - gfx::Rect screen_bounds = widget_->GetNativeView()->GetBoundsInScreen(); - gfx::Rect update_rect = buffer_damage_rect_; - buffer_damage_rect_ = gfx::Rect(); - - // Create and map a single GPU memory buffer. The laser pointer will be - // written into this buffer without any buffering. The result is that we - // might be modifying the buffer while it's being displayed. This provides - // minimal latency but potential tearing. Note that we have to draw into - // a temporary surface and copy it into GPU memory buffer to avoid flicker. - if (!gpu_memory_buffer_) { - TRACE_EVENT0("ui", "LaserPointerView::UpdateBuffer::Create"); - - gpu_memory_buffer_ = - aura::Env::GetInstance() - ->context_factory() - ->GetGpuMemoryBufferManager() - ->CreateGpuMemoryBuffer( - gfx::ScaleToCeiledSize(screen_bounds.size(), scale_factor_), - SK_B32_SHIFT ? gfx::BufferFormat::RGBA_8888 - : gfx::BufferFormat::BGRA_8888, - gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, - gpu::kNullSurfaceHandle); - if (!gpu_memory_buffer_) { - LOG(ERROR) << "Failed to allocate GPU memory buffer"; - return; - } - - // Make sure the first update rectangle covers the whole buffer. - update_rect = gfx::Rect(screen_bounds.size()); - } - - // Constrain update rectangle to buffer size and early out if empty. - update_rect.Intersect(gfx::Rect(screen_bounds.size())); - if (update_rect.IsEmpty()) - return; - - // Map buffer for writing. - if (!gpu_memory_buffer_->Map()) { - LOG(ERROR) << "Failed to map GPU memory buffer"; - return; - } - - // Create a temporary canvas for update rectangle. - gfx::Canvas canvas(update_rect.size(), scale_factor_, false); - +void LaserPointerView::OnRedraw(gfx::Canvas& canvas, + const gfx::Vector2d& offset) { cc::PaintFlags flags; flags.setStyle(cc::PaintFlags::kFill_Style); flags.setAntiAlias(true); - // Compute the offset of the current widget. - gfx::Vector2d widget_offset( - widget_->GetNativeView()->GetBoundsInRootWindow().origin().x(), - widget_->GetNativeView()->GetBoundsInRootWindow().origin().y()); - int num_points = laser_points_.GetNumberOfPoints() + predicted_laser_points_.GetNumberOfPoints(); - if (num_points) { - TRACE_EVENT1("ui", "LaserPointerView::UpdateBuffer::Paint", "update_rect", - update_rect.ToString()); - - LaserPointerPoints::LaserPoint previous_point = laser_points_.GetOldest(); - previous_point.location -= widget_offset + update_rect.OffsetFromOrigin(); - LaserPointerPoints::LaserPoint current_point; - std::vector<gfx::PointF> previous_segment_points; - float previous_radius; - int current_opacity; - - for (int i = 0; i < num_points; ++i) { - if (i < laser_points_.GetNumberOfPoints()) { - current_point = laser_points_.laser_points()[i]; - } else { - current_point = - predicted_laser_points_ - .laser_points()[i - laser_points_.GetNumberOfPoints()]; - } - current_point.location -= widget_offset + update_rect.OffsetFromOrigin(); - - // Set the radius and opacity based on the distance. - float current_radius = LinearInterpolate( - kPointInitialRadius, kPointFinalRadius, current_point.age); - current_opacity = static_cast<int>(LinearInterpolate( - kPointInitialOpacity, kPointFinalOpacity, current_point.age)); - - // If we draw laser_points_ that are within a stroke width of each other, - // the result will be very jagged, unless we are on the last point, then - // we draw regardless. - float distance_threshold = current_radius * 2.0f; - if (DistanceBetweenPoints(previous_point.location, - current_point.location) <= distance_threshold && - i != num_points - 1) { - continue; - } - - LaserSegment current_segment( - previous_segment_points, gfx::PointF(previous_point.location), - gfx::PointF(current_point.location), previous_radius, current_radius, - i == num_points - 1); - - SkPath path = current_segment.path(); - if (i < laser_points_.GetNumberOfPoints()) - flags.setColor(SkColorSetA(kPointColor, current_opacity)); - else - flags.setColor(SkColorSetA(kPredictionPointColor, current_opacity)); - canvas.DrawPath(path, flags); - - previous_segment_points = current_segment.path_points(); - previous_radius = current_radius; - previous_point = current_point; - } - - // Draw the last point as a circle. - flags.setStyle(cc::PaintFlags::kFill_Style); - canvas.DrawCircle(current_point.location, kPointInitialRadius, flags); - } - - // Convert update rectangle to pixel coordinates. - gfx::Rect pixel_rect = gfx::ScaleToEnclosingRect(update_rect, scale_factor_); - - // Copy result to GPU memory buffer. This is effectiely a memcpy and unlike - // drawing to the buffer directly this ensures that the buffer is never in a - // state that would result in flicker. - { - TRACE_EVENT1("ui", "LaserPointerView::UpdateBuffer::Copy", "pixel_rect", - pixel_rect.ToString()); - - uint8_t* data = static_cast<uint8_t*>(gpu_memory_buffer_->memory(0)); - int stride = gpu_memory_buffer_->stride(0); - canvas.GetBitmap().readPixels( - SkImageInfo::MakeN32Premul(pixel_rect.width(), pixel_rect.height()), - data + pixel_rect.y() * stride + pixel_rect.x() * 4, stride, 0, 0); - } - - // Unmap to flush writes to buffer. - gpu_memory_buffer_->Unmap(); - - // Update surface damage rectangle. - surface_damage_rect_.Union(update_rect); - - needs_update_surface_ = true; - - // Early out if waiting for last surface update to be drawn. - if (pending_draw_surface_) + if (!num_points) return; - UpdateSurface(); -} + LaserPointerPoints::LaserPoint previous_point = laser_points_.GetOldest(); + previous_point.location -= offset; + LaserPointerPoints::LaserPoint current_point; + std::vector<gfx::PointF> previous_segment_points; + float previous_radius; + int current_opacity; -void LaserPointerView::UpdateSurface() { - TRACE_EVENT1("ui", "LaserPointerView::UpdateSurface", "damage", - surface_damage_rect_.ToString()); - - DCHECK(needs_update_surface_); - needs_update_surface_ = false; - - std::unique_ptr<LaserResource> resource; - // Reuse returned resource if available. - if (!returned_resources_.empty()) { - resource = std::move(returned_resources_.back()); - returned_resources_.pop_back(); - } - - // Create new resource if needed. - if (!resource) - resource = base::MakeUnique<LaserResource>(); - - // Acquire context provider for resource if needed. - // Note: We make no attempts to recover if the context provider is later - // lost. It is expected that this class is short-lived and requiring a - // new instance to be created in lost context situations is acceptable and - // keeps the code simple. - if (!resource->context_provider) { - resource->context_provider = aura::Env::GetInstance() - ->context_factory() - ->SharedMainThreadContextProvider(); - if (!resource->context_provider) { - LOG(ERROR) << "Failed to acquire a context provider"; - return; + for (int i = 0; i < num_points; ++i) { + if (i < laser_points_.GetNumberOfPoints()) { + current_point = laser_points_.laser_points()[i]; + } else { + current_point = + predicted_laser_points_ + .laser_points()[i - laser_points_.GetNumberOfPoints()]; } - } + current_point.location -= offset; - gpu::gles2::GLES2Interface* gles2 = resource->context_provider->ContextGL(); + // Set the radius and opacity based on the distance. + float current_radius = LinearInterpolate( + kPointInitialRadius, kPointFinalRadius, current_point.age); + current_opacity = static_cast<int>(LinearInterpolate( + kPointInitialOpacity, kPointFinalOpacity, current_point.age)); - if (resource->texture) { - gles2->ActiveTexture(GL_TEXTURE0); - gles2->BindTexture(GL_TEXTURE_2D, resource->texture); - } else { - gles2->GenTextures(1, &resource->texture); - gles2->ActiveTexture(GL_TEXTURE0); - gles2->BindTexture(GL_TEXTURE_2D, resource->texture); - gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gles2->GenMailboxCHROMIUM(resource->mailbox.name); - gles2->ProduceTextureCHROMIUM(GL_TEXTURE_2D, resource->mailbox.name); - } - - gfx::Size buffer_size = gpu_memory_buffer_->GetSize(); - - if (resource->image) { - gles2->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, resource->image); - } else { - resource->image = gles2->CreateImageCHROMIUM( - gpu_memory_buffer_->AsClientBuffer(), buffer_size.width(), - buffer_size.height(), SK_B32_SHIFT ? GL_RGBA : GL_BGRA_EXT); - if (!resource->image) { - LOG(ERROR) << "Failed to create image"; - return; + // If we draw laser_points_ that are within a stroke width of each other, + // the result will be very jagged, unless we are on the last point, then + // we draw regardless. + float distance_threshold = current_radius * 2.0f; + if (DistanceBetweenPoints(previous_point.location, + current_point.location) <= distance_threshold && + i != num_points - 1) { + continue; } + + LaserSegment current_segment( + previous_segment_points, gfx::PointF(previous_point.location), + gfx::PointF(current_point.location), previous_radius, current_radius, + i == num_points - 1); + + SkPath path = current_segment.path(); + if (i < laser_points_.GetNumberOfPoints()) + flags.setColor(SkColorSetA(kPointColor, current_opacity)); + else + flags.setColor(SkColorSetA(kPredictionPointColor, current_opacity)); + canvas.DrawPath(path, flags); + + previous_segment_points = current_segment.path_points(); + previous_radius = current_radius; + previous_point = current_point; } - gles2->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, resource->image); - gpu::SyncToken sync_token; - uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM(); - gles2->OrderingBarrierCHROMIUM(); - gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); - - cc::TransferableResource transferable_resource; - transferable_resource.id = next_resource_id_++; - transferable_resource.format = viz::RGBA_8888; - transferable_resource.filter = GL_LINEAR; - transferable_resource.size = buffer_size; - transferable_resource.mailbox_holder = - gpu::MailboxHolder(resource->mailbox, sync_token, GL_TEXTURE_2D); - transferable_resource.is_overlay_candidate = true; - - gfx::Rect quad_rect(widget_->GetNativeView()->GetBoundsInScreen().size()); - - const int kRenderPassId = 1; - std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); - render_pass->SetNew(kRenderPassId, quad_rect, surface_damage_rect_, - gfx::Transform()); - surface_damage_rect_ = gfx::Rect(); - - cc::SharedQuadState* quad_state = - render_pass->CreateAndAppendSharedQuadState(); - quad_state->quad_layer_rect = quad_rect; - quad_state->visible_quad_layer_rect = quad_rect; - quad_state->opacity = 1.0f; - - cc::CompositorFrame frame; - // TODO(eseckler): LaserPointerView should use BeginFrames and set the ack - // accordingly. - frame.metadata.begin_frame_ack = - cc::BeginFrameAck::CreateManualAckWithDamage(); - frame.metadata.device_scale_factor = - widget_->GetLayer()->device_scale_factor(); - cc::TextureDrawQuad* texture_quad = - render_pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); - float vertex_opacity[4] = {1.0, 1.0, 1.0, 1.0}; - gfx::PointF uv_top_left(0.f, 0.f); - gfx::PointF uv_bottom_right(1.f, 1.f); - texture_quad->SetNew(quad_state, quad_rect, gfx::Rect(), quad_rect, - transferable_resource.id, true, uv_top_left, - uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity, - false, false, false); - texture_quad->set_resource_size_in_pixels(transferable_resource.size); - frame.resource_list.push_back(transferable_resource); - frame.render_pass_list.push_back(std::move(render_pass)); - - frame_sink_holder_->frame_sink()->SubmitCompositorFrame(std::move(frame)); - - resources_[transferable_resource.id] = std::move(resource); - - DCHECK(!pending_draw_surface_); - pending_draw_surface_ = true; -} - -void LaserPointerView::OnDidDrawSurface() { - pending_draw_surface_ = false; - if (needs_update_surface_) - UpdateSurface(); + // Draw the last point as a circle. + flags.setStyle(cc::PaintFlags::kFill_Style); + canvas.DrawCircle(current_point.location, kPointInitialRadius, flags); } } // namespace ash
diff --git a/ash/laser/laser_pointer_view.h b/ash/laser/laser_pointer_view.h index d59889c7..ed832d8 100644 --- a/ash/laser/laser_pointer_view.h +++ b/ash/laser/laser_pointer_view.h
@@ -5,41 +5,20 @@ #ifndef ASH_LASER_LASER_POINTER_VIEW_H_ #define ASH_LASER_LASER_POINTER_VIEW_H_ -#include <memory> -#include <vector> - +#include "ash/fast_ink/fast_ink_view.h" #include "ash/laser/laser_pointer_points.h" -#include "base/containers/flat_map.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" #include "base/time/time.h" -#include "ui/views/view.h" - -namespace aura { -class Window; -} - -namespace cc { -struct ReturnedResource; -} namespace gfx { -class GpuMemoryBuffer; class PointF; } -namespace views { -class Widget; -} - namespace ash { -class LaserLayerTreeFrameSinkHolder; -struct LaserResource; // LaserPointerView displays the palette tool laser pointer. It draws the laser, // which consists of a point where the mouse cursor should be, as well as a // trail of lines to help users track. -class LaserPointerView : public views::View { +class LaserPointerView : public FastInkView { public: LaserPointerView(base::TimeDelta life_duration, base::TimeDelta presentation_delay, @@ -51,38 +30,16 @@ void UpdateTime(); void Stop(); - // Call this to indicate that the previous frame has been processed. - void DidReceiveCompositorFrameAck(); - - // Call this to return resources so they can be reused or freed. - void ReclaimResources(const std::vector<cc::ReturnedResource>& resources); - private: friend class LaserPointerControllerTestApi; gfx::Rect GetBoundingBox(); - void OnPointsUpdated(); - void UpdateBuffer(); - void OnBufferUpdated(); - void UpdateSurface(); - void OnDidDrawSurface(); + + void OnRedraw(gfx::Canvas& canvas, const gfx::Vector2d& offset) override; LaserPointerPoints laser_points_; LaserPointerPoints predicted_laser_points_; - std::unique_ptr<views::Widget> widget_; - float scale_factor_ = 1.0f; const base::TimeDelta presentation_delay_; - std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; - gfx::Rect buffer_damage_rect_; - bool pending_update_buffer_ = false; - gfx::Rect surface_damage_rect_; - bool needs_update_surface_ = false; - bool pending_draw_surface_ = false; - std::unique_ptr<LaserLayerTreeFrameSinkHolder> frame_sink_holder_; - int next_resource_id_ = 1; - base::flat_map<int, std::unique_ptr<LaserResource>> resources_; - std::vector<std::unique_ptr<LaserResource>> returned_resources_; - base::WeakPtrFactory<LaserPointerView> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(LaserPointerView); };
diff --git a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon index 6a155be..c14a7063 100644 --- a/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon +++ b/ash/resources/vector_icons/palette_tray_icon_laser_pointer.1x.icon
@@ -2,42 +2,41 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 20, -PATH_COLOR_ARGB, 0xFF, 0x69, 0x69, 0x69, -MOVE_TO, 14.96f, 8.04f, -R_H_LINE_TO, -4.56f, -R_LINE_TO, 4.56f, -4.8f, -R_CUBIC_TO, 0.3f, -0.23f, 0.5f, -0.59f, 0.5f, -0.99f, -R_CUBIC_TO, 0, -0.68f, -0.55f, -1.24f, -1.22f, -1.24f, -R_CUBIC_TO, -0.25f, 0, -0.48f, 0.08f, -0.68f, 0.21f, -R_CUBIC_TO, 0, 0, -9.48f, 6.42f, -9.48f, 6.42f, -R_LINE_TO, -0.36f, 0.24f, -R_CUBIC_TO, -0.41f, 0.37f, -0.7f, 0.16f, -0.7f, 1.41f, -R_CUBIC_TO, 0, 0.56f, 0.92f, 1.69f, 2, 1.69f, -H_LINE_TO, 9.03f, -R_LINE_TO, -1.18f, 0.69f, -R_CUBIC_TO, -1.17f, 0.68f, -3.52f, 2.04f, -3.52f, 2.04f, -R_CUBIC_TO, 0.42f, -0.25f, 0.9f, -0.41f, 1.42f, -0.41f, -R_CUBIC_TO, 1.52f, 0, 2.75f, 1.25f, 2.75f, 2.79f, -R_CUBIC_TO, 0, 0.76f, -0.3f, 1.45f, -0.79f, 1.96f, -R_LINE_TO, 8.26f, -6.98f, -R_CUBIC_TO, 0.16f, -0.1f, 0.3f, -0.22f, 0.43f, -0.36f, -R_CUBIC_TO, 0.25f, -0.29f, 0.47f, -0.54f, 0.56f, -0.86f, -R_CUBIC_TO, 0.03f, -0.1f, 0.04f, -0.2f, 0.04f, -0.32f, -R_CUBIC_TO, 0, -1.31f, -0.96f, -1.48f, -2.04f, -1.48f, +CANVAS_DIMENSIONS, 16, +NEW_PATH, +PATH_COLOR_ARGB, 0x4D, 0xFF, 0xFF, 0xFF, +MOVE_TO, 12.03f, 6, +H_LINE_TO, 8.19f, +R_LINE_TO, 3.84f, -3.71f, +R_CUBIC_TO, 0.24f, -0.19f, 0.4f, -0.5f, 0.4f, -0.84f, +CUBIC_TO, 12.43f, 0.87f, 11.99f, 0.4f, 11.44f, 0.4f, +R_CUBIC_TO, -0.2f, 0, -0.39f, 0.07f, -0.55f, 0.18f, +LINE_TO, 3.24f, 6.01f, +R_CUBIC_TO, -0.09f, 0.05f, -0.18f, 0.11f, -0.26f, 0.18f, +R_LINE_TO, -0.03f, 0.02f, +R_CUBIC_TO, -0.33f, 0.31f, -0.55f, 0.76f, -0.55f, 1.26f, +R_CUBIC_TO, 0, 0.92f, 0.7f, 1.67f, 1.57f, 1.72f, +R_H_LINE_TO, 2.49f, +R_LINE_TO, -3.02f, 1.93f, +R_CUBIC_TO, 0.34f, -0.21f, 0.72f, -0.35f, 1.14f, -0.35f, +R_CUBIC_TO, 1.23f, 0, 2.22f, 1.06f, 2.22f, 2.36f, +R_CUBIC_TO, 0, 0.64f, -0.24f, 1.23f, -0.64f, 1.65f, +R_LINE_TO, 6.68f, -5.9f, +R_CUBIC_TO, 0.13f, -0.08f, 0.24f, -0.18f, 0.34f, -0.3f, +R_CUBIC_TO, 0.26f, -0.32f, 0.41f, -0.7f, 0.41f, -1.12f, +R_CUBIC_TO, 0, -0.92f, -0.71f, -1.47f, -1.57f, -1.48f, CLOSE, NEW_PATH, -MOVE_TO, 9, 16, -R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3, -R_CUBIC_TO, -0.57f, 0, -1.09f, 0.17f, -1.54f, 0.44f, -R_LINE_TO, -0.18f, 0.11f, -R_CUBIC_TO, -0.01f, 0.01f, -0.03f, 0.02f, -0.04f, 0.03f, -CUBIC_TO, 3.49f, 14.13f, 3, 15.01f, 3, 16, -R_CUBIC_TO, 0, 1.66f, 1.34f, 3, 3, 3, -R_CUBIC_TO, 0.62f, 0, 1.19f, -0.19f, 1.67f, -0.51f, -R_H_LINE_TO, 0, -R_LINE_TO, 0.01f, -0.01f, -R_CUBIC_TO, 0.16f, -0.11f, 0.32f, -0.24f, 0.45f, -0.38f, -CUBIC_TO, 8.67f, 17.56f, 9, 16.82f, 9, 16, +MOVE_TO, 7.2f, 13.03f, +R_CUBIC_TO, 0, -1.33f, -1.07f, -2.4f, -2.4f, -2.4f, +R_CUBIC_TO, -0.45f, 0, -0.87f, 0.13f, -1.24f, 0.35f, +R_LINE_TO, -0.15f, 0.09f, +R_CUBIC_TO, -0.01f, 0.01f, -0.02f, 0.02f, -0.03f, 0.03f, +R_CUBIC_TO, -0.59f, 0.44f, -0.98f, 1.14f, -0.98f, 1.93f, +R_CUBIC_TO, 0, 1.33f, 1.08f, 2.4f, 2.4f, 2.4f, +R_CUBIC_TO, 0.5f, 0, 0.96f, -0.15f, 1.34f, -0.41f, +R_LINE_TO, 0.01f, 0, +R_CUBIC_TO, 0.13f, -0.09f, 0.25f, -0.19f, 0.36f, -0.3f, +R_CUBIC_TO, 0.43f, -0.43f, 0.69f, -1.02f, 0.69f, -1.68f, CLOSE, END
diff --git a/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon b/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon index b9ec73e6..ec89944f 100644 --- a/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon +++ b/ash/resources/vector_icons/palette_tray_icon_magnify.1x.icon
@@ -2,35 +2,35 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 20, -MOVE_TO, 8, 10, -H_LINE_TO, 5.5f, -V_LINE_TO, 8, +CANVAS_DIMENSIONS, 16, +MOVE_TO, 6.4f, 8, +R_H_LINE_TO, -2, +V_LINE_TO, 6.4f, +R_H_LINE_TO, 2, +R_V_LINE_TO, -2, H_LINE_TO, 8, -V_LINE_TO, 5.5f, +R_V_LINE_TO, 2, R_H_LINE_TO, 2, V_LINE_TO, 8, -R_H_LINE_TO, 2.5f, -R_V_LINE_TO, 2, -H_LINE_TO, 10, -R_V_LINE_TO, 2.5f, H_LINE_TO, 8, -V_LINE_TO, 10, +R_V_LINE_TO, 2, +H_LINE_TO, 6.4f, +V_LINE_TO, 8, CLOSE, -R_MOVE_TO, 8.32f, 7.9f, -R_LINE_TO, 1.65f, -1.8f, -R_LINE_TO, -3.29f, -3.01f, -R_CUBIC_TO, 0.83f, -1.15f, 1.32f, -2.56f, 1.32f, -4.09f, -R_CUBIC_TO, 0, -3.86f, -3.14f, -7, -7, -7, -CUBIC_TO, 5.14f, 2, 2, 5.14f, 2, 9, -R_CUBIC_TO, 0, 3.86f, 3.14f, 7, 7, 7, -R_CUBIC_TO, 1.45f, 0, 2.81f, -0.45f, 3.93f, -1.21f, -R_LINE_TO, 3.39f, 3.11f, +R_MOVE_TO, 6.65f, 6.32f, +R_LINE_TO, 1.32f, -1.44f, +R_LINE_TO, -2.63f, -2.41f, +R_CUBIC_TO, 0.67f, -0.92f, 1.06f, -2.05f, 1.06f, -3.27f, +R_CUBIC_TO, 0, -3.09f, -2.51f, -5.6f, -5.6f, -5.6f, +R_CUBIC_TO, -3.09f, 0, -5.6f, 2.51f, -5.6f, 5.6f, +R_CUBIC_TO, 0, 3.09f, 2.51f, 5.6f, 5.6f, 5.6f, +R_CUBIC_TO, 1.16f, 0, 2.25f, -0.36f, 3.14f, -0.97f, +R_LINE_TO, 2.71f, 2.49f, CLOSE, -MOVE_TO, 9, 4, -CUBIC_TO, 6.24f, 4, 4, 6.24f, 4, 9, -R_CUBIC_TO, 0, 2.76f, 2.24f, 5, 5, 5, -R_CUBIC_TO, 2.76f, 0, 5, -2.24f, 5, -5, -R_CUBIC_TO, 0, -2.76f, -2.24f, -5, -5, -5, +MOVE_TO, 7.2f, 3.2f, +R_CUBIC_TO, -2.21f, 0, -4, 1.79f, -4, 4, +R_CUBIC_TO, 0, 2.21f, 1.79f, 4, 4, 4, +R_CUBIC_TO, 2.2f, 0, 4, -1.79f, 4, -4, +R_CUBIC_TO, 0, -2.21f, -1.8f, -4, -4, -4, CLOSE, END
diff --git a/ash/resources/vector_icons/palette_tray_icon_magnify.icon b/ash/resources/vector_icons/palette_tray_icon_magnify.icon index 53f1c380..317e26f 100644 --- a/ash/resources/vector_icons/palette_tray_icon_magnify.icon +++ b/ash/resources/vector_icons/palette_tray_icon_magnify.icon
@@ -2,35 +2,35 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 40, -MOVE_TO, 16, 20, -R_H_LINE_TO, -5, -R_V_LINE_TO, -4, -R_H_LINE_TO, 5, -R_V_LINE_TO, -5, -R_H_LINE_TO, 4, -R_V_LINE_TO, 5, -R_H_LINE_TO, 5, -R_V_LINE_TO, 4, -R_H_LINE_TO, -5, -R_V_LINE_TO, 5, +CANVAS_DIMENSIONS, 32, +MOVE_TO, 12.8f, 16, R_H_LINE_TO, -4, -R_V_LINE_TO, -5, +R_V_LINE_TO, -3.2f, +R_H_LINE_TO, 4, +R_V_LINE_TO, -4, +H_LINE_TO, 16, +R_V_LINE_TO, 4, +R_H_LINE_TO, 4, +V_LINE_TO, 16, +R_H_LINE_TO, -4, +R_V_LINE_TO, 4, +R_H_LINE_TO, -3.2f, +R_V_LINE_TO, -4, CLOSE, -R_MOVE_TO, 16.63f, 15.8f, -LINE_TO, 35.93f, 32.2f, -R_LINE_TO, -6.57f, -6.02f, -R_CUBIC_TO, 1.66f, -2.3f, 2.64f, -5.13f, 2.64f, -8.18f, -R_CUBIC_TO, 0, -7.72f, -6.28f, -14, -14, -14, -R_CUBIC_TO, -7.72f, 0, -14, 6.28f, -14, 14, -R_CUBIC_TO, 0, 7.72f, 6.28f, 14, 14, 14, -R_CUBIC_TO, 2.91f, 0, 5.61f, -0.89f, 7.86f, -2.42f, -R_LINE_TO, 6.78f, 6.22f, +R_MOVE_TO, 13.31f, 12.64f, +R_LINE_TO, 2.64f, -2.88f, +R_LINE_TO, -5.26f, -4.82f, +R_CUBIC_TO, 1.33f, -1.84f, 2.11f, -4.1f, 2.11f, -6.54f, +R_CUBIC_TO, 0, -6.17f, -5.03f, -11.2f, -11.2f, -11.2f, +CUBIC_TO, 8.22f, 3.2f, 3.2f, 8.23f, 3.2f, 14.4f, +R_CUBIC_TO, 0, 6.18f, 5.02f, 11.2f, 11.2f, 11.2f, +R_CUBIC_TO, 2.33f, 0, 4.49f, -0.71f, 6.28f, -1.93f, +R_LINE_TO, 5.42f, 4.97f, CLOSE, -MOVE_TO, 18, 8, -CUBIC_TO, 12.48f, 8, 8, 12.49f, 8, 18, -R_CUBIC_TO, 0, 5.51f, 4.49f, 10, 10, 10, -R_CUBIC_TO, 5.51f, 0, 10, -4.49f, 10, -10, -R_CUBIC_TO, 0, -5.51f, -4.49f, -10, -10, -10, +MOVE_TO, 14.4f, 6.4f, +R_CUBIC_TO, -4.41f, 0, -8, 3.59f, -8, 8, +R_CUBIC_TO, 0, 4.41f, 3.59f, 8, 8, 8, +R_CUBIC_TO, 4.41f, 0, 8, -3.59f, 8, -8, +R_CUBIC_TO, 0, -4.41f, -3.59f, -8, -8, -8, CLOSE, END
diff --git a/ash/system/bluetooth/tray_bluetooth.cc b/ash/system/bluetooth/tray_bluetooth.cc index 86984aac..3a49c989 100644 --- a/ash/system/bluetooth/tray_bluetooth.cc +++ b/ash/system/bluetooth/tray_bluetooth.cc
@@ -20,7 +20,6 @@ #include "ash/system/tray/system_tray_notifier.h" #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_details_view.h" -#include "ash/system/tray/tray_info_label.h" #include "ash/system/tray/tray_item_more.h" #include "ash/system/tray/tray_popup_item_style.h" #include "ash/system/tray/tray_popup_utils.h" @@ -315,8 +314,8 @@ // Show user Bluetooth state if there is no bluetooth devices in list. if (device_map_.size() == 0 && bluetooth_available && bluetooth_enabled) { - scroll_content()->AddChildView(new TrayInfoLabel( - nullptr /* delegate */, IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING)); + scroll_content()->AddChildView( + new InfoLabel(IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING)); } // Focus the device which was focused before the device-list update.
diff --git a/ash/system/network/network_icon.cc b/ash/system/network/network_icon.cc index b1ce16d..b19b3a0 100644 --- a/ash/system/network/network_icon.cc +++ b/ash/system/network/network_icon.cc
@@ -876,15 +876,10 @@ static int s_uninitialized_msg(0); NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); - // TODO(lesliewatkins): Only return this message when Tether is uninitialized - // due to no Bluetooth (dependent on codereview.chromium.org/2969493002/). - if (handler->GetTechnologyState(NetworkTypePattern::Tether()) == + if (handler->GetTechnologyState(NetworkTypePattern::Mobile()) == NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) { - s_uninitialized_msg = IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH; - s_uninitialized_state_time = base::Time::Now(); - return s_uninitialized_msg; - } else if (handler->GetTechnologyState(NetworkTypePattern::Mobile()) == - NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) { + // TODO (lesliewatkins): Add a more descriptive message (e.g. "Enable + // Bluetooth") for Tether technology type. s_uninitialized_msg = IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR; s_uninitialized_state_time = base::Time::Now(); return s_uninitialized_msg;
diff --git a/ash/system/network/network_list.cc b/ash/system/network/network_list.cc index 40dd9a09..9ed47151 100644 --- a/ash/system/network/network_list.cc +++ b/ash/system/network/network_list.cc
@@ -23,7 +23,6 @@ #include "ash/system/tray/system_tray_controller.h" #include "ash/system/tray/system_tray_delegate.h" #include "ash/system/tray/tray_constants.h" -#include "ash/system/tray/tray_info_label.h" #include "ash/system/tray/tray_popup_item_style.h" #include "ash/system/tray/tray_popup_utils.h" #include "ash/system/tray/tri_view.h" @@ -631,8 +630,8 @@ void NetworkListView::UpdateInfoLabel(int message_id, int insertion_index, - TrayInfoLabel** info_label_ptr) { - TrayInfoLabel* info_label = *info_label_ptr; + InfoLabel** info_label_ptr) { + InfoLabel* info_label = *info_label_ptr; if (!message_id) { if (info_label) { needs_relayout_ = true; @@ -642,23 +641,13 @@ return; } if (!info_label) - info_label = new TrayInfoLabel(this /* delegate */, message_id); + info_label = new InfoLabel(message_id); else - info_label->Update(message_id); - + info_label->SetMessage(message_id); PlaceViewAtIndex(info_label, insertion_index); *info_label_ptr = info_label; } -void NetworkListView::OnLabelClicked(int message_id) { - if (message_id == IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH) - Shell::Get()->system_tray_controller()->ShowBluetoothSettings(); -} - -bool NetworkListView::IsLabelClickable(int message_id) const { - return message_id == IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH; -} - int NetworkListView::UpdateSectionHeaderRow(NetworkTypePattern pattern, bool enabled, int child_index,
diff --git a/ash/system/network/network_list.h b/ash/system/network/network_list.h index 09b18a4..7fcd2d4 100644 --- a/ash/system/network/network_list.h +++ b/ash/system/network/network_list.h
@@ -14,7 +14,6 @@ #include "ash/system/network/network_icon_animation_observer.h" #include "ash/system/network/network_info.h" #include "ash/system/network/network_state_list_detailed_view.h" -#include "ash/system/tray/tray_info_label.h" #include "base/macros.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_type_pattern.h" @@ -33,8 +32,7 @@ // A list of available networks of a given type. This class is used for all // network types except VPNs. For VPNs, see the |VPNList| class. class NetworkListView : public NetworkStateListDetailedView, - public network_icon::AnimationObserver, - public TrayInfoLabel::Delegate { + public network_icon::AnimationObserver { public: class SectionHeaderRowView; @@ -106,7 +104,7 @@ // and is only modified if the info label is created or destroyed. void UpdateInfoLabel(int message_id, int insertion_index, - TrayInfoLabel** info_label_ptr); + InfoLabel** info_label_ptr); // Creates a cellular/tether/Wi-Fi header row |view| and adds it to // |scroll_content()| if necessary and reorders the |scroll_content()| placing @@ -118,10 +116,6 @@ SectionHeaderRowView** view, views::Separator** separator_view); - // TrayInfoLabel::Delegate: - void OnLabelClicked(int message_id) override; - bool IsLabelClickable(int message_id) const override; - // network_icon::AnimationObserver: void NetworkIconChanged() override; @@ -131,8 +125,8 @@ bool needs_relayout_; - TrayInfoLabel* no_wifi_networks_view_; - TrayInfoLabel* no_mobile_networks_view_; + InfoLabel* no_wifi_networks_view_; + InfoLabel* no_mobile_networks_view_; SectionHeaderRowView* mobile_header_view_; SectionHeaderRowView* wifi_header_view_; views::Separator* mobile_separator_view_;
diff --git a/ash/system/tray/tray_details_view.cc b/ash/system/tray/tray_details_view.cc index 3f154af..f4507f0 100644 --- a/ash/system/tray/tray_details_view.cc +++ b/ash/system/tray/tray_details_view.cc
@@ -237,6 +237,35 @@ } // namespace +//////////////////////////////////////////////////////////////////////////////// +// TrayDetailsView::InfoLabel: + +TrayDetailsView::InfoLabel::InfoLabel(int message_id) + : label_(TrayPopupUtils::CreateDefaultLabel()) { + SetLayoutManager(new views::FillLayout); + + TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::SYSTEM_INFO); + style.SetupLabel(label_); + + TriView* tri_view = TrayPopupUtils::CreateMultiTargetRowView(); + tri_view->SetInsets(gfx::Insets(0, + kMenuExtraMarginFromLeftEdge + + kTrayPopupPaddingHorizontal - + kTrayPopupLabelHorizontalPadding, + 0, kTrayPopupPaddingHorizontal)); + tri_view->SetContainerVisible(TriView::Container::START, false); + tri_view->SetContainerVisible(TriView::Container::END, false); + tri_view->AddView(TriView::Container::CENTER, label_); + AddChildView(tri_view); + + SetMessage(message_id); +} + +TrayDetailsView::InfoLabel::~InfoLabel() {} + +void TrayDetailsView::InfoLabel::SetMessage(int message_id) { + label_->SetText(l10n_util::GetStringUTF16(message_id)); +} //////////////////////////////////////////////////////////////////////////////// // TrayDetailsView:
diff --git a/ash/system/tray/tray_details_view.h b/ash/system/tray/tray_details_view.h index 764892d..e7f3162 100644 --- a/ash/system/tray/tray_details_view.h +++ b/ash/system/tray/tray_details_view.h
@@ -22,6 +22,7 @@ namespace views { class BoxLayout; class CustomButton; +class Label; class ProgressBar; class ScrollView; } // namespace views @@ -51,6 +52,22 @@ SystemTrayItem* owner() { return owner_; } protected: + // A view containing only a label, which is to be inserted as a non-targetable + // row within a system menu detailed view (e.g., the "Scanning for devices..." + // message that can appear at the top of the Bluetooth detailed view). + class InfoLabel : public View { + public: + explicit InfoLabel(int message_id); + ~InfoLabel() override; + + void SetMessage(int message_id); + + private: + views::Label* const label_; + + DISALLOW_COPY_AND_ASSIGN(InfoLabel); + }; + // views::View: void Layout() override; int GetHeightForWidth(int width) const override;
diff --git a/ash/system/tray/tray_info_label.cc b/ash/system/tray/tray_info_label.cc deleted file mode 100644 index bd71a769..0000000 --- a/ash/system/tray/tray_info_label.cc +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/system/tray/tray_info_label.h" - -#include "ash/system/tray/tray_popup_item_style.h" -#include "ash/system/tray/tray_popup_utils.h" -#include "ui/accessibility/ax_node_data.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/views/layout/fill_layout.h" - -namespace ash { - -TrayInfoLabel::TrayInfoLabel(TrayInfoLabel::Delegate* delegate, int message_id) - : ActionableView(nullptr /* owner */, TrayPopupInkDropStyle::FILL_BOUNDS), - label_(TrayPopupUtils::CreateDefaultLabel()), - message_id_(message_id), - delegate_(delegate) { - SetLayoutManager(new views::FillLayout); - - TriView* tri_view = TrayPopupUtils::CreateMultiTargetRowView(); - tri_view->SetInsets(gfx::Insets(0, - kMenuExtraMarginFromLeftEdge + - kTrayPopupPaddingHorizontal - - kTrayPopupLabelHorizontalPadding, - 0, kTrayPopupPaddingHorizontal)); - tri_view->SetContainerVisible(TriView::Container::START, false); - tri_view->SetContainerVisible(TriView::Container::END, false); - tri_view->AddView(TriView::Container::CENTER, label_); - - AddChildView(tri_view); - - Update(message_id); -} - -void TrayInfoLabel::Update(int message_id) { - message_id_ = message_id; - - TrayPopupItemStyle::FontStyle font_style; - - if (IsClickable()) { - SetInkDropMode(InkDropHostView::InkDropMode::ON); - font_style = TrayPopupItemStyle::FontStyle::CLICKABLE_SYSTEM_INFO; - } else { - SetInkDropMode(InkDropHostView::InkDropMode::OFF); - font_style = TrayPopupItemStyle::FontStyle::SYSTEM_INFO; - } - - const TrayPopupItemStyle style(font_style); - style.SetupLabel(label_); - - label_->SetText(l10n_util::GetStringUTF16(message_id)); -} - -bool TrayInfoLabel::PerformAction(const ui::Event& event) { - if (IsClickable()) { - delegate_->OnLabelClicked(message_id_); - return true; - } - return false; -} - -void TrayInfoLabel::GetAccessibleNodeData(ui::AXNodeData* node_data) { - if (IsClickable()) - node_data->role = ui::AX_ROLE_BUTTON; - else - node_data->role = ui::AX_ROLE_LABEL_TEXT; -} - -bool TrayInfoLabel::IsClickable() { - if (delegate_) - return delegate_->IsLabelClickable(message_id_); - return false; -} - -} // namespace ash
diff --git a/ash/system/tray/tray_info_label.h b/ash/system/tray/tray_info_label.h deleted file mode 100644 index 2267e94..0000000 --- a/ash/system/tray/tray_info_label.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_SYSTEM_TRAY_TRAY_INFO_LABEL_H_ -#define ASH_SYSTEM_TRAY_TRAY_INFO_LABEL_H_ - -#include "ash/system/tray/actionable_view.h" -#include "ui/views/controls/label.h" - -namespace ash { - -// A view containing only a label, which is to be inserted as a -// row within a system menu detailed view (e.g., the "Scanning for devices..." -// message that can appear at the top of the Bluetooth detailed view). -// TrayInfoLabel can be clickable; this property is configured by its delegate. -class TrayInfoLabel : public ActionableView { - public: - // A delegate for determining whether or not a TrayInfoLabel is clickable, and - // handling actions when it is clicked. - class Delegate { - public: - virtual ~Delegate() {} - virtual void OnLabelClicked(int message_id) = 0; - virtual bool IsLabelClickable(int message_id) const = 0; - }; - - // |delegate| may be null, which results in a TrayInfoLabel which cannot be - // clicked. - TrayInfoLabel(Delegate* delegate, int message_id); - ~TrayInfoLabel() override{}; - - // Updates the TrayInfoLabel to display the message associated with - // |message_id|. This may update text styling if the delegate indicates that - // the TrayInfoLabel should be clickable. - void Update(int message_id); - - // ActionableView: - bool PerformAction(const ui::Event& event) override; - void GetAccessibleNodeData(ui::AXNodeData* node_data) override; - - private: - friend class TrayInfoLabelTest; - - bool IsClickable(); - - views::Label* const label_; - int message_id_; - - Delegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(TrayInfoLabel); -}; - -} // namespace ash - -#endif // ASH_SYSTEM_TRAY_TRAY_INFO_LABEL_H_
diff --git a/ash/system/tray/tray_info_label_unittest.cc b/ash/system/tray/tray_info_label_unittest.cc deleted file mode 100644 index 2564044..0000000 --- a/ash/system/tray/tray_info_label_unittest.cc +++ /dev/null
@@ -1,136 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/system/tray/tray_info_label.h" - -#include "ash/strings/grit/ash_strings.h" -#include "ash/test/ash_test_base.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/accessibility/ax_node_data.h" - -namespace ash { - -namespace { - -class TestClickEvent : public ui::Event { - public: - TestClickEvent() : ui::Event(ui::ET_MOUSE_PRESSED, base::TimeTicks(), 0) {} -}; - -class TestDelegate : public TrayInfoLabel::Delegate { - public: - TestDelegate() {} - - const std::vector<int>& clicked_message_ids() { return clicked_message_ids_; } - - void AddClickableMessageId(int message_id) { - clickable_message_ids_.insert(message_id); - } - - // TrayInfoLabel::Delegate: - void OnLabelClicked(int message_id) override { - clicked_message_ids_.push_back(message_id); - } - - bool IsLabelClickable(int message_id) const override { - return clickable_message_ids_.find(message_id) != - clickable_message_ids_.end(); - } - - private: - std::unordered_set<int> clickable_message_ids_; - std::vector<int> clicked_message_ids_; -}; - -} // namespace - -class TrayInfoLabelTest : public AshTestBase { - public: - void TearDown() override { - AshTestBase::TearDown(); - label_.reset(); - delegate_.reset(); - } - - void CreateLabel(bool use_delegate, int message_id) { - if (use_delegate) - delegate_ = base::MakeUnique<TestDelegate>(); - - label_ = base::MakeUnique<TrayInfoLabel>(delegate_.get(), message_id); - } - - void ClickOnLabel(bool expect_click_was_handled) { - bool click_was_handled = label_->PerformAction(TestClickEvent()); - EXPECT_EQ(expect_click_was_handled, click_was_handled); - } - - void VerifyClickability(bool expected_clickable) { - EXPECT_EQ(expected_clickable, label_->IsClickable()); - - ui::AXNodeData node_data; - label_->GetAccessibleNodeData(&node_data); - - if (expected_clickable) - EXPECT_EQ(ui::AX_ROLE_BUTTON, node_data.role); - else - EXPECT_EQ(ui::AX_ROLE_LABEL_TEXT, node_data.role); - } - - void VerifyClicks(const std::vector<int>& expected_clicked_message_ids) { - if (!delegate_) { - EXPECT_TRUE(expected_clicked_message_ids.empty()); - return; - } - - EXPECT_EQ(expected_clicked_message_ids, delegate_->clicked_message_ids()); - } - - void VerifyNoClicks() { VerifyClicks(std::vector<int>()); } - - protected: - std::unique_ptr<TrayInfoLabel> label_; - std::unique_ptr<TestDelegate> delegate_; -}; - -TEST_F(TrayInfoLabelTest, NoDelegate) { - CreateLabel(false /* use_delegate */, IDS_ASH_STATUS_TRAY_BLUETOOTH_ENABLED); - VerifyClickability(false /* expected_clickable */); - - label_->Update(IDS_ASH_STATUS_TRAY_BLUETOOTH_DISABLED); - VerifyClickability(false /* expected_clickable */); - - label_->Update(IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING); - VerifyClickability(false /* expected_clickable */); -} - -TEST_F(TrayInfoLabelTest, PerformAction) { - const int kClickableMessageId1 = IDS_ASH_STATUS_TRAY_BLUETOOTH_ENABLED; - const int kClickableMessageId2 = IDS_ASH_STATUS_TRAY_BLUETOOTH_DISABLED; - const int kNonClickableMessageId = IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING; - - CreateLabel(true /* use_delegate */, kClickableMessageId1); - delegate_->AddClickableMessageId(kClickableMessageId1); - delegate_->AddClickableMessageId(kClickableMessageId2); - VerifyNoClicks(); - - VerifyClickability(true /* expected_clickable */); - ClickOnLabel(true /* expect_click_was_handled */); - VerifyClicks(std::vector<int>{kClickableMessageId1}); - - ClickOnLabel(true /* expect_click_was_handled */); - VerifyClicks(std::vector<int>{kClickableMessageId1, kClickableMessageId1}); - - label_->Update(kNonClickableMessageId); - VerifyClickability(false /* expected_clickable */); - ClickOnLabel(false /* expect_click_was_handled */); - VerifyClicks(std::vector<int>{kClickableMessageId1, kClickableMessageId1}); - - label_->Update(kClickableMessageId2); - VerifyClickability(true /* expected_clickable */); - ClickOnLabel(true /* expect_click_was_handled */); - VerifyClicks(std::vector<int>{kClickableMessageId1, kClickableMessageId1, - kClickableMessageId2}); -} - -} // namespace ash
diff --git a/ash/system/tray/tray_popup_item_style.cc b/ash/system/tray/tray_popup_item_style.cc index 97947db9..f803785 100644 --- a/ash/system/tray/tray_popup_item_style.cc +++ b/ash/system/tray/tray_popup_item_style.cc
@@ -89,13 +89,6 @@ label->SetFontList(base_font_list.Derive(1, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL)); break; - case FontStyle::CLICKABLE_SYSTEM_INFO: - label->SetFontList(base_font_list.Derive(1, gfx::Font::NORMAL, - gfx::Font::Weight::NORMAL)); - label->SetEnabledColor(label->GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_ProminentButtonColor)); - label->SetAutoColorReadabilityEnabled(false); - break; case FontStyle::BUTTON: label->SetFontList(base_font_list.Derive(0, gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM));
diff --git a/ash/system/tray/tray_popup_item_style.h b/ash/system/tray/tray_popup_item_style.h index 1a75dc9..36c017e 100644 --- a/ash/system/tray/tray_popup_item_style.h +++ b/ash/system/tray/tray_popup_item_style.h
@@ -44,8 +44,6 @@ // System information text (e.g. date/time, battery status, "Scanning for // devices..." seen in the Bluetooth detailed view, etc). SYSTEM_INFO, - // System information text within a clickable row. - CLICKABLE_SYSTEM_INFO, // Child buttons within rows that have a visible border (e.g. Cast's // "Stop", etc). BUTTON,
diff --git a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java index 24f85d66..2e74589 100644 --- a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java +++ b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
@@ -672,6 +672,17 @@ } /** + * @param activity The {@link Activity} to check. + * @return Whether or not {@code activity} is currently in Android N+ multi-window mode. + */ + public static boolean isInMultiWindowMode(Activity activity) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + return false; + } + return activity.isInMultiWindowMode(); + } + + /** * Null-safe equivalent of {@code a.equals(b)}. * * @see Objects#equals(Object, Object)
diff --git a/base/memory/discardable_shared_memory.cc b/base/memory/discardable_shared_memory.cc index 89d67af8..910bee22 100644 --- a/base/memory/discardable_shared_memory.cc +++ b/base/memory/discardable_shared_memory.cc
@@ -99,6 +99,39 @@ return bits::Align(size, base::GetPageSize()); } +// LockPages/UnlockPages are platform-native discardable page management +// helper functions. Both expect |offset| to be specified relative to the +// base address at which |memory| is mapped, and that |offset| and |length| +// are page-aligned by the caller. + +// Returns SUCCESS on platforms which do not support discardable pages. +DiscardableSharedMemory::LockResult LockPages(const SharedMemory& memory, + size_t offset, + size_t length) { +#if defined(OS_ANDROID) + SharedMemoryHandle handle = memory.handle(); + if (handle.IsValid()) { + int pin_result = ashmem_pin_region(handle.GetHandle(), offset, length); + if (pin_result == ASHMEM_WAS_PURGED) + return DiscardableSharedMemory::PURGED; + if (pin_result < 0) + return DiscardableSharedMemory::FAILED; + } +#endif + return DiscardableSharedMemory::SUCCESS; +} + +// UnlockPages() is a no-op on platforms not supporting discardable pages. +void UnlockPages(const SharedMemory& memory, size_t offset, size_t length) { +#if defined(OS_ANDROID) + SharedMemoryHandle handle = memory.handle(); + if (handle.IsValid()) { + int unpin_result = ashmem_unpin_region(handle.GetHandle(), offset, length); + DCHECK_EQ(0, unpin_result); + } +#endif +} + } // namespace DiscardableSharedMemory::DiscardableSharedMemory() @@ -221,19 +254,9 @@ if (!length) return PURGED; -// Pin pages if supported. -#if defined(OS_ANDROID) - SharedMemoryHandle handle = shared_memory_.handle(); - if (handle.IsValid()) { - if (ashmem_pin_region(handle.GetHandle(), - AlignToPageSize(sizeof(SharedState)) + offset, - length)) { - return PURGED; - } - } -#endif - - return SUCCESS; + // Ensure that the platform won't discard the required pages. + return LockPages(shared_memory_, + AlignToPageSize(sizeof(SharedState)) + offset, length); } void DiscardableSharedMemory::Unlock(size_t offset, size_t length) { @@ -243,23 +266,16 @@ // Calls to this function must be synchronized properly. DFAKE_SCOPED_LOCK(thread_collision_warner_); - // Zero for length means "everything onward". + // Passing zero for |length| means "everything onward". Note that |length| may + // still be zero after this calculation, e.g. if |mapped_size_| is zero. if (!length) length = AlignToPageSize(mapped_size_) - offset; DCHECK(shared_memory_.memory()); -// Unpin pages if supported. -#if defined(OS_ANDROID) - SharedMemoryHandle handle = shared_memory_.handle(); - if (handle.IsValid()) { - if (ashmem_unpin_region(handle.GetHandle(), - AlignToPageSize(sizeof(SharedState)) + offset, - length)) { - DPLOG(ERROR) << "ashmem_unpin_region() failed"; - } - } -#endif + // Allow the pages to be discarded by the platform, if supported. + UnlockPages(shared_memory_, AlignToPageSize(sizeof(SharedState)) + offset, + length); size_t start = offset / base::GetPageSize(); size_t end = start + length / base::GetPageSize();
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index d7712d53..8257d04 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -1633,8 +1633,7 @@ template("package_resources_helper") { _resource_packaged_apk_path = invoker.resource_packaged_apk_path _package_resources_target = target_name - _post_process = defined(invoker.post_process_package_resources_script) && - defined(invoker.post_process_package_resources_args) + _post_process = defined(invoker.post_process_package_resources_script) if (_post_process) { _package_resources_target = "${_package_resources_target}__intermediate" _post_processed_resource_packaged_apk_path = _resource_packaged_apk_path @@ -1752,7 +1751,6 @@ rebase_path(_post_processed_resource_packaged_apk_path, root_build_dir), ] - args += invoker.post_process_package_resources_args inputs = [ _resource_packaged_apk_path, ] @@ -1773,10 +1771,9 @@ "aapt_locale_whitelist", "alternative_android_sdk_jar", "android_aapt_path", - "png_to_webp", "exclude_xxxhdpi", "extensions_to_not_compress", - "post_process_package_resources_args", + "png_to_webp", "post_process_package_resources_script", "xxxhdpi_whitelist", ]) @@ -1827,10 +1824,9 @@ "aapt_locale_whitelist", "alternative_android_sdk_jar", "android_aapt_path", - "png_to_webp", "exclude_xxxhdpi", "extensions_to_not_compress", - "post_process_package_resources_args", + "png_to_webp", "post_process_package_resources_script", "xxxhdpi_whitelist", ])
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 5930a86..954716a2 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -2265,12 +2265,11 @@ "alternative_android_sdk_jar", "android_aapt_path", "app_as_shared_lib", - "png_to_webp", "deps", "exclude_xxxhdpi", "extensions_to_not_compress", "language_splits", - "post_process_package_resources_args", + "png_to_webp", "post_process_package_resources_script", "public_deps", "secondary_native_libs",
diff --git a/cc/ipc/compositor_frame_sink.mojom b/cc/ipc/compositor_frame_sink.mojom index 41cc741..d8c2c7c 100644 --- a/cc/ipc/compositor_frame_sink.mojom +++ b/cc/ipc/compositor_frame_sink.mojom
@@ -53,6 +53,9 @@ // Notification for the client to generate a CompositorFrame. OnBeginFrame(BeginFrameArgs args); + // Inform the client that OnBeginFrame may not be called for some time. + OnBeginFramePausedChanged(bool paused); + // Returns resources sent to SubmitCompositorFrame to be reused or freed. ReclaimResources(array<ReturnedResource> resources); };
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index c709a8c9..bc9b168 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc
@@ -1292,7 +1292,6 @@ GrBackendTexture backend_texture( resource->size.width(), resource->size.height(), ToGrPixelConfig(resource->format), texture_info); - GrBackendTextureDesc desc; sk_image_ = SkImage::MakeFromTexture( resource_provider->compositor_context_provider_->GrContext(), backend_texture, kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType,
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index 604fd1c..0bc83f0a 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc
@@ -7,12 +7,10 @@ #include <algorithm> #include "base/auto_reset.h" -#include "base/debug/crash_logging.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/profiler/scoped_tracker.h" #include "base/single_thread_task_runner.h" -#include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "cc/base/devtools_instrumentation.h" @@ -27,11 +25,6 @@ // for message latency and kernel scheduling variability. const base::TimeDelta kDeadlineFudgeFactor = base::TimeDelta::FromMicroseconds(1000); - -// TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. -// TODO(sunnyps): Remove after fixing https://crbug.com/622080 -const char kBeginMainFrameHangCompositorState[] = - "begin-main-frame-hang-compositor-state"; } // namespace Scheduler::Scheduler( @@ -271,10 +264,6 @@ bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); - // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. - // TODO(sunnyps): Remove after fixing https://crbug.com/622080 - debug_begin_frame_received_at_ = Now(); - if (!state_machine_.BeginFrameNeeded()) { TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped", TRACE_EVENT_SCOPE_THREAD); @@ -695,29 +684,10 @@ break; } } - - // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. - // TODO(sunnyps): Remove after fixing https://crbug.com/622080 - if (action != SchedulerStateMachine::ACTION_NONE) { - debug_actions_.SaveToBuffer(action); - } } while (action != SchedulerStateMachine::ACTION_NONE); ScheduleBeginImplFrameDeadlineIfNeeded(); SetupNextBeginFrameIfNeeded(); - - // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. - // TODO(sunnyps): Remove after fixing https://crbug.com/622080 - std::string state_dump = state_machine_.CrashKeyValueForBeginMainFrameHang(); - base::StringAppendF( - &state_dump, ",%f,%d,%d,%d", - (Now() - debug_begin_frame_received_at_).InMillisecondsF(), - skipped_last_frame_to_reduce_latency_, - skipped_last_frame_missed_exceeded_deadline_, stopped_); - for (auto it = debug_actions_.Begin(); it; ++it) - base::StringAppendF(&state_dump, ",%d", **it); - - base::debug::SetCrashKeyValue(kBeginMainFrameHangCompositorState, state_dump); } std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index 97ba607b..aa1aad6a 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h
@@ -12,7 +12,6 @@ #include "base/cancelable_callback.h" #include "base/macros.h" #include "base/time/time.h" -#include "cc/base/ring_buffer.h" #include "cc/cc_export.h" #include "cc/output/begin_frame_args.h" #include "cc/scheduler/begin_frame_source.h" @@ -199,11 +198,6 @@ SchedulerStateMachine::Action inside_action_ = SchedulerStateMachine::ACTION_NONE; - // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. - // TODO(sunnyps): Remove after fixing https://crbug.com/622080 - base::TimeTicks debug_begin_frame_received_at_; - RingBuffer<SchedulerStateMachine::Action, 10> debug_actions_; - bool stopped_ = false; private:
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc index 96695c6..b73cce2 100644 --- a/cc/scheduler/scheduler_state_machine.cc +++ b/cc/scheduler/scheduler_state_machine.cc
@@ -6,7 +6,6 @@ #include "base/format_macros.h" #include "base/logging.h" -#include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "base/values.h" @@ -237,18 +236,6 @@ state->EndDictionary(); } -// TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. -// TODO(sunnyps): Remove after fixing https://crbug.com/622080 -std::string SchedulerStateMachine::CrashKeyValueForBeginMainFrameHang() const { - return base::StringPrintf( - "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", begin_impl_frame_state_, - begin_main_frame_state_, layer_tree_frame_sink_state_, - pending_submit_frames_, visible_, has_pending_tree_, - pending_tree_is_ready_for_activation_, active_tree_needs_first_draw_, - begin_frame_source_paused_, needs_redraw_, needs_prepare_tiles_, - needs_one_begin_impl_frame_); -} - bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { // Normally when |visible_| is false or |begin_frame_source_paused_| is true, // pending activations will be forced and draws will be aborted. However,
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index c9af02c..052ad8f 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h
@@ -132,10 +132,6 @@ std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; void AsValueInto(base::trace_event::TracedValue* dict) const; - // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. - // TODO(sunnyps): Remove after fixing https://crbug.com/622080 - std::string CrashKeyValueForBeginMainFrameHang() const; - Action NextAction() const; void WillSendBeginMainFrame(); void WillNotifyBeginMainFrameNotSent();
diff --git a/cc/test/fake_compositor_frame_sink_support_client.cc b/cc/test/fake_compositor_frame_sink_support_client.cc index e6b7452f..b67025f0 100644 --- a/cc/test/fake_compositor_frame_sink_support_client.cc +++ b/cc/test/fake_compositor_frame_sink_support_client.cc
@@ -33,4 +33,7 @@ last_damage_rect_ = damage_rect; } +void FakeCompositorFrameSinkSupportClient::OnBeginFramePausedChanged( + bool paused) {} + }; // namespace cc
diff --git a/cc/test/fake_compositor_frame_sink_support_client.h b/cc/test/fake_compositor_frame_sink_support_client.h index 86078de..9fcd9b09 100644 --- a/cc/test/fake_compositor_frame_sink_support_client.h +++ b/cc/test/fake_compositor_frame_sink_support_client.h
@@ -25,6 +25,7 @@ const std::vector<ReturnedResource>& resources) override; void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) override; + void OnBeginFramePausedChanged(bool paused) override; const gfx::Rect& last_damage_rect() const { return last_damage_rect_; } const viz::LocalSurfaceId& last_local_surface_id() const {
diff --git a/cc/test/mock_compositor_frame_sink_support_client.h b/cc/test/mock_compositor_frame_sink_support_client.h index d9712fb0..377069a 100644 --- a/cc/test/mock_compositor_frame_sink_support_client.h +++ b/cc/test/mock_compositor_frame_sink_support_client.h
@@ -24,6 +24,7 @@ MOCK_METHOD1(ReclaimResources, void(const std::vector<ReturnedResource>&)); MOCK_METHOD2(WillDrawSurface, void(const viz::LocalSurfaceId&, const gfx::Rect&)); + MOCK_METHOD1(OnBeginFramePausedChanged, void(bool paused)); }; } // namespace test
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 9256bbe0..277ee1a 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -1646,17 +1646,29 @@ if (!scroll_element_id) return; - auto& scrollbar_ids = element_id_to_scrollbar_layer_ids_[scroll_element_id]; - if (scrollbar_layer->orientation() == HORIZONTAL) { - DCHECK_EQ(scrollbar_ids.horizontal, Layer::INVALID_ID) - << "Existing scrollbar should have been unregistered."; - scrollbar_ids.horizontal = scrollbar_layer->id(); - } else { - DCHECK_EQ(scrollbar_ids.vertical, Layer::INVALID_ID) - << "Existing scrollbar should have been unregistered."; - scrollbar_ids.vertical = scrollbar_layer->id(); + auto* scrollbar_ids = &element_id_to_scrollbar_layer_ids_[scroll_element_id]; + int* scrollbar_layer_id = scrollbar_layer->orientation() == HORIZONTAL + ? &scrollbar_ids->horizontal + : &scrollbar_ids->vertical; + + // We used to DCHECK this was not the case but this can occur on Android: as + // the visual viewport supplies scrollbars for the outer viewport, if the + // outer viewport is changed, we race between updating the visual viewport + // scrollbars and registering new scrollbars on the old outer viewport. It'd + // be nice if we could fix this to be cleaner but its harmless to just + // unregister here. + if (*scrollbar_layer_id != Layer::INVALID_ID) { + UnregisterScrollbar(scrollbar_layer); + + // The scrollbar_ids could have been erased above so get it again. + scrollbar_ids = &element_id_to_scrollbar_layer_ids_[scroll_element_id]; + scrollbar_layer_id = scrollbar_layer->orientation() == HORIZONTAL + ? &scrollbar_ids->horizontal + : &scrollbar_ids->vertical; } + *scrollbar_layer_id = scrollbar_layer->id(); + if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar() && scrollbar_layer->GetScrollbarAnimator() != LayerTreeSettings::NO_ANIMATOR) {
diff --git a/chrome/android/java/res/layout/date_divided_adapter_header_view_holder.xml b/chrome/android/java/res/layout/date_divided_adapter_header_view_holder.xml new file mode 100644 index 0000000..d0bddb7 --- /dev/null +++ b/chrome/android/java/res/layout/date_divided_adapter_header_view_holder.xml
@@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/history_clear_browsing_data_header.xml b/chrome/android/java/res/layout/history_clear_browsing_data_header.xml new file mode 100644 index 0000000..207c6ce --- /dev/null +++ b/chrome/android/java/res/layout/history_clear_browsing_data_header.xml
@@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="8dp" + android:background="@null" > + + <FrameLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/list_item_single" > + <!-- TODO(twellington): change start/end padding back to 16dp and remove duplicate + FrameLayout when list item background is removed. --> + <Button + android:id="@+id/clear_browsing_data_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="top" + style="@style/ButtonCompatBorderless" + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:paddingStart="17dp" + android:paddingEnd="17dp" + android:gravity="center_vertical|start" + android:text="@string/open_clear_browsing_data_dialog_button" + android:textAllCaps="true" + android:textColor="@color/blue_when_enabled" + android:textSize="14sp" /> + </FrameLayout> +</FrameLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/history_header.xml b/chrome/android/java/res/layout/history_header.xml deleted file mode 100644 index 68e401d..0000000 --- a/chrome/android/java/res/layout/history_header.xml +++ /dev/null
@@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2016 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_marginBottom="8dp" > - - <LinearLayout - android:id="@+id/privacy_disclaimers" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:layout_marginTop="8dp" - android:visibility="gone" - android:layout_marginBottom="16dp" > - - <org.chromium.ui.widget.TextViewWithClickableSpans - android:id="@+id/signed_in_not_synced" - style="@style/PrivacyDisclaimerText" /> - - <org.chromium.ui.widget.TextViewWithClickableSpans - android:id="@+id/signed_in_synced" - style="@style/PrivacyDisclaimerText" /> - - <org.chromium.ui.widget.TextViewWithClickableSpans - android:id="@+id/other_forms_of_browsing_history" - style="@style/PrivacyDisclaimerText" /> - - </LinearLayout> - - <FrameLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@drawable/list_item_single" > - - <!-- TODO(twellington): change start/end padding back to 16dp - when new assets with correct built in padding - are available. --> - <Button - android:id="@+id/clear_browsing_data_button" - android:layout_width="match_parent" - android:layout_height="wrap_content" - style="@style/ButtonCompatBorderless" - android:paddingTop="16dp" - android:paddingBottom="16dp" - android:paddingStart="17dp" - android:paddingEnd="17dp" - android:gravity="center_vertical|start" - android:text="@string/open_clear_browsing_data_dialog_button" - android:textAllCaps="true" - android:textColor="@color/blue_when_enabled" - android:textSize="14sp" /> - - </FrameLayout> -</LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml b/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml new file mode 100644 index 0000000..cad7fbd --- /dev/null +++ b/chrome/android/java/res/layout/history_privacy_disclaimer_header.xml
@@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:paddingBottom="16dp" > + + <org.chromium.ui.widget.TextViewWithClickableSpans + android:id="@+id/signed_in_not_synced" + style="@style/PrivacyDisclaimerText" /> + + <org.chromium.ui.widget.TextViewWithClickableSpans + android:id="@+id/signed_in_synced" + style="@style/PrivacyDisclaimerText" /> + + <org.chromium.ui.widget.TextViewWithClickableSpans + android:id="@+id/other_forms_of_browsing_history" + style="@style/PrivacyDisclaimerText" /> + + <Space + android:id="@+id/privacy_disclaimer_bottom_space" + android:layout_width="match_parent" + android:layout_height="8dp" /> +</LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/selectable_list_layout.xml b/chrome/android/java/res/layout/selectable_list_layout.xml index de9117d..95f3b91d 100644 --- a/chrome/android/java/res/layout/selectable_list_layout.xml +++ b/chrome/android/java/res/layout/selectable_list_layout.xml
@@ -21,6 +21,8 @@ android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" + android:paddingTop="8dp" + android:clipToPadding="false" android:visibility="gone" /> <TextView
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java index 0e6ce56..d4bdf5f7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java
@@ -9,6 +9,7 @@ import android.support.v7.widget.RecyclerView.ViewHolder; import android.text.TextUtils; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; import org.chromium.base.ContextUtils; @@ -167,6 +168,7 @@ private int mFilter = DownloadFilter.FILTER_ALL; private String mSearchQuery = EMPTY_QUERY; private SpaceDisplay mSpaceDisplay; + private HeaderItem mSpaceDisplayHeaderItem; private boolean mIsSearching; private boolean mShouldShowStorageInfoHeader; @@ -191,6 +193,8 @@ mBackendProvider = provider; mUiConfig = uiConfig; + generateHeaderItems(); + DownloadItemSelectionDelegate selectionDelegate = (DownloadItemSelectionDelegate) mBackendProvider.getSelectionDelegate(); selectionDelegate.initialize(this); @@ -364,26 +368,30 @@ } @Override + protected void bindViewHolderForHeaderItem(ViewHolder viewHolder, HeaderItem headerItem) { + super.bindViewHolderForHeaderItem(viewHolder, headerItem); + mSpaceDisplay.onChanged(); + } + + @Override protected ItemGroup createGroup(long timeStamp) { return new DownloadItemGroup(timeStamp); } - @Override - protected BasicViewHolder createHeader(ViewGroup parent) { - if (mSpaceDisplay == null) { - mSpaceDisplay = new SpaceDisplay(parent, this); - registerAdapterDataObserver(mSpaceDisplay); - if (mUiConfig != null) { - MarginResizer.createAndAttach(mSpaceDisplay.getView(), mUiConfig, - parent.getResources().getDimensionPixelSize( - R.dimen.list_item_default_margin), - SelectableListLayout.getDefaultListItemLateralShadowSizePx( - parent.getResources())); - } + /** + * Initialize space display view in storage info header and generate header item for it. + */ + void generateHeaderItems() { + mSpaceDisplay = new SpaceDisplay(null, this); + View view = mSpaceDisplay.getView(); + registerAdapterDataObserver(mSpaceDisplay); + if (mUiConfig != null) { + MarginResizer.createAndAttach(view, mUiConfig, + view.getResources().getDimensionPixelSize(R.dimen.list_item_default_margin), + SelectableListLayout.getDefaultListItemLateralShadowSizePx( + view.getResources())); } - - mSpaceDisplay.onChanged(); - return new BasicViewHolder(mSpaceDisplay.getView()); + mSpaceDisplayHeaderItem = new HeaderItem(0, view); } /** Called when a new DownloadItem has been created by the native DownloadManager. */ @@ -598,7 +606,7 @@ clear(false); if (!filteredTimedItems.isEmpty() && !mIsSearching && mShouldShowStorageInfoHeader) { - addHeader(); + setHeaders(mSpaceDisplayHeaderItem); } loadItems(filteredTimedItems);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerToolbar.java index bb1dc62..544b076 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerToolbar.java
@@ -24,6 +24,7 @@ public class DownloadManagerToolbar extends SelectableListToolbar<DownloadHistoryItemWrapper> implements DownloadUiObserver { private Spinner mSpinner; + private DownloadManagerUi mManager; public DownloadManagerToolbar(Context context, AttributeSet attrs) { super(context, attrs); @@ -31,6 +32,13 @@ } /** + * @param manager The {@link DownloadManagerUi} associated with this toolbar. + */ + public void setManager(DownloadManagerUi manager) { + mManager = manager; + } + + /** * Initializes the spinner for the download filter. * @param adapter The adapter associated with the spinner. */ @@ -96,6 +104,12 @@ } @Override + protected void showNormalView() { + super.showNormalView(); + mManager.updateInfoButtonVisibility(); + } + + @Override public void showSearchView() { super.showSearchView(); mSpinner.setVisibility(GONE);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java index 417417a..061b7099 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
@@ -9,6 +9,7 @@ import android.content.Intent; import android.os.AsyncTask; import android.support.graphics.drawable.VectorDrawableCompat; +import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar.OnMenuItemClickListener; import android.view.LayoutInflater; @@ -200,6 +201,13 @@ // Prevent every progress update from causing a transition animation. mRecyclerView.getItemAnimator().setChangeDuration(0); + mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + updateInfoButtonVisibility(); + } + }); + mFilterAdapter = new FilterAdapter(); mFilterAdapter.initialize(this); addObserver(mFilterAdapter); @@ -207,6 +215,7 @@ mToolbar = (DownloadManagerToolbar) mSelectableListLayout.initializeToolbar( R.layout.download_manager_toolbar, mBackendProvider.getSelectionDelegate(), 0, null, R.id.normal_menu_group, R.id.selection_mode_menu_group, null, this, true); + mToolbar.setManager(this); mToolbar.initializeFilterSpinner(mFilterAdapter); mToolbar.initializeSearchView(this, R.string.download_manager_search, R.id.search_menu_id); mToolbar.setInfoMenuItem(R.id.info_menu_id); @@ -454,6 +463,23 @@ mSnackbarManager.dismissSnackbars(mUndoDeletionSnackbarController); } + /** + * @return True if info menu item should be shown on download toolbar, false otherwise. + */ + boolean shouldShowInfoButton() { + return mHistoryAdapter.getItemCount() > 0 && !mToolbar.isSearching(); + } + + /** + * Update info button visibility based on whether info header is visible on download page. + */ + void updateInfoButtonVisibility() { + LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager(); + boolean infoHeaderIsVisible = layoutManager.findFirstVisibleItemPosition() == 0; + mToolbar.updateInfoMenuItem(infoHeaderIsVisible && shouldShowInfoButton(), + mHistoryAdapter.shouldShowStorageInfoHeader()); + } + @VisibleForTesting public SnackbarManager getSnackbarManagerForTesting() { return mSnackbarManager;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java index c7bee88..1e599c1f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java
@@ -15,6 +15,7 @@ import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ObserverList; import org.chromium.base.VisibleForTesting; @@ -114,7 +115,7 @@ SpaceDisplay(final ViewGroup parent, DownloadHistoryAdapter historyAdapter) { mHistoryAdapter = historyAdapter; - mView = (ViewGroup) LayoutInflater.from(parent.getContext()) + mView = LayoutInflater.from(ContextUtils.getApplicationContext()) .inflate(R.layout.download_manager_ui_space_widget, parent, false); mSpaceUsedByDownloadsTextView = (TextView) mView.findViewById(R.id.size_downloaded); mSpaceUsedByOtherAppsTextView = (TextView) mView.findViewById(R.id.size_other_apps);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java index 005e639..66eef39e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
@@ -14,7 +14,7 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; -import android.widget.FrameLayout; +import android.widget.Space; import android.widget.TextView; import org.chromium.base.VisibleForTesting; @@ -53,22 +53,24 @@ private final ArrayList<HistoryItemView> mItemViews; private RecyclerView mRecyclerView; - private ViewGroup mPrivacyDisclaimers; private TextView mSignedInNotSyncedTextView; private TextView mSignedInSyncedTextView; private TextView mOtherFormsOfBrowsingHistoryTextView; + private Space mPrivacyDisclaimerBottomSpace; private Button mClearBrowsingDataButton; - private FrameLayout mClearBrowsingDataButtonContainer; + private HeaderItem mPrivacyDisclaimerHeaderItem; + private HeaderItem mClearBrowsingDataButtonHeaderItem; private boolean mHasOtherFormsOfBrowsingData; private boolean mHasSyncedData; - private boolean mIsHeaderInflated; private boolean mIsDestroyed; private boolean mIsInitialized; private boolean mIsLoadingItems; private boolean mIsSearching; private boolean mHasMorePotentialItems; private boolean mClearOnNextQueryComplete; + private boolean mPrivacyDisclaimersVisible; + private boolean mClearBrowsingDataButtonVisible; private long mNextQueryEndTime; private String mQueryText = EMPTY_QUERY; private int mDefaultTextMargin; @@ -194,6 +196,7 @@ for (HistoryItemView itemView : mItemViews) { itemView.onSignInStateChange(); } + initialize(); updateClearBrowsingDataButtonVisibility(); setPrivacyDisclaimerVisibility(); } @@ -252,7 +255,7 @@ boolean wasInitialized = mIsInitialized; if (!mIsInitialized) { - if (items.size() > 0 && !mIsSearching) addHeader(); + if (items.size() > 0 && !mIsSearching) setHeaders(); mIsInitialized = true; } @@ -298,28 +301,34 @@ } @Override - protected BasicViewHolder createHeader(ViewGroup parent) { - ViewGroup v = (ViewGroup) LayoutInflater.from(parent.getContext()).inflate( - R.layout.history_header, parent, false); - Resources resources = v.getResources(); - mIsHeaderInflated = true; + protected BasicViewHolder createFooter(ViewGroup parent) { + return new BasicViewHolder( + LayoutInflater.from(parent.getContext()) + .inflate(R.layout.indeterminate_progress_view, parent, false)); + } - mClearBrowsingDataButton = (Button) v.findViewById(R.id.clear_browsing_data_button); - mClearBrowsingDataButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mHistoryManager.openClearBrowsingDataPreference(); - } - }); - mClearBrowsingDataButtonContainer = (FrameLayout) mClearBrowsingDataButton.getParent(); - MarginResizer.createAndAttach(mClearBrowsingDataButtonContainer, + @Override + protected DateViewHolder createDateViewHolder(ViewGroup parent) { + DateViewHolder viewHolder = super.createDateViewHolder(parent); + MarginResizer.createAndAttach(viewHolder.itemView, mHistoryManager.getSelectableListLayout().getUiConfig(), - SelectableListLayout.getDefaultListItemLateralMarginPx(resources), 0); - updateClearBrowsingDataButtonVisibility(); + getDefaultTextMargin(parent.getResources()), + SelectableListLayout.getDefaultListItemLateralShadowSizePx(parent.getResources())); + return viewHolder; + } - mPrivacyDisclaimers = (ViewGroup) v.findViewById(R.id.privacy_disclaimers); + /** + * Initialize clear browsing data and privacy disclaimer header views and generate header + * items for them. + */ + void generateHeaderItems() { + ViewGroup privacyDisclaimers = + (ViewGroup) View.inflate(mHistoryManager.getSelectableListLayout().getContext(), + R.layout.history_privacy_disclaimer_header, null); + Resources resources = privacyDisclaimers.getResources(); - mSignedInNotSyncedTextView = (TextView) v.findViewById(R.id.signed_in_not_synced); + mSignedInNotSyncedTextView = + (TextView) privacyDisclaimers.findViewById(R.id.signed_in_not_synced); setPrivacyDisclaimerText(mSignedInNotSyncedTextView, R.string.android_history_no_synced_results, LEARN_MORE_LINK); MarginResizer.createAndAttach(mSignedInNotSyncedTextView, @@ -327,7 +336,7 @@ getDefaultTextMargin(resources), SelectableListLayout.getDefaultListItemLateralShadowSizePx(resources)); - mSignedInSyncedTextView = (TextView) v.findViewById(R.id.signed_in_synced); + mSignedInSyncedTextView = (TextView) privacyDisclaimers.findViewById(R.id.signed_in_synced); setPrivacyDisclaimerText(mSignedInSyncedTextView, R.string.android_history_has_synced_results, LEARN_MORE_LINK); MarginResizer.createAndAttach(mSignedInSyncedTextView, @@ -335,8 +344,8 @@ getDefaultTextMargin(resources), SelectableListLayout.getDefaultListItemLateralShadowSizePx(resources)); - mOtherFormsOfBrowsingHistoryTextView = (TextView) v.findViewById( - R.id.other_forms_of_browsing_history); + mOtherFormsOfBrowsingHistoryTextView = + (TextView) privacyDisclaimers.findViewById(R.id.other_forms_of_browsing_history); boolean flagEnabled = ChromeFeatureList.isEnabled(ChromeFeatureList.TABS_IN_CBD); int disclaimerTextId = flagEnabled ? R.string.android_history_other_forms_of_history_new : R.string.android_history_other_forms_of_history; @@ -348,25 +357,39 @@ getDefaultTextMargin(resources), SelectableListLayout.getDefaultListItemLateralShadowSizePx(resources)); - setPrivacyDisclaimerVisibility(); + mPrivacyDisclaimerBottomSpace = + (Space) privacyDisclaimers.findViewById(R.id.privacy_disclaimer_bottom_space); - return new BasicViewHolder(v); - } + ViewGroup clearBrowsingDataButtonContainer = + (ViewGroup) View.inflate(mHistoryManager.getSelectableListLayout().getContext(), + R.layout.history_clear_browsing_data_header, null); - @Override - protected BasicViewHolder createFooter(ViewGroup parent) { - return new BasicViewHolder(LayoutInflater.from(parent.getContext()).inflate( - R.layout.indeterminate_progress_view, parent, false)); - } - - @Override - protected DateViewHolder createDateViewHolder(ViewGroup parent) { - DateViewHolder viewHolder = super.createDateViewHolder(parent); - MarginResizer.createAndAttach(viewHolder.itemView, + mClearBrowsingDataButton = (Button) clearBrowsingDataButtonContainer.findViewById( + R.id.clear_browsing_data_button); + mClearBrowsingDataButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mHistoryManager.openClearBrowsingDataPreference(); + } + }); + MarginResizer.createAndAttach(clearBrowsingDataButtonContainer, mHistoryManager.getSelectableListLayout().getUiConfig(), - getDefaultTextMargin(parent.getResources()), - SelectableListLayout.getDefaultListItemLateralShadowSizePx(parent.getResources())); - return viewHolder; + SelectableListLayout.getDefaultListItemLateralMarginPx(resources), 0); + + mPrivacyDisclaimerHeaderItem = new HeaderItem(0, privacyDisclaimers); + mClearBrowsingDataButtonHeaderItem = new HeaderItem(1, clearBrowsingDataButtonContainer); + updateClearBrowsingDataButtonVisibility(); + setPrivacyDisclaimerVisibility(); + } + + /** + * Pass header items to {@link #setHeaders(HeaderItem...)} as parameters. + */ + private void setHeaders() { + ArrayList<HeaderItem> args = new ArrayList<>(); + if (mPrivacyDisclaimersVisible) args.add(mPrivacyDisclaimerHeaderItem); + if (mClearBrowsingDataButtonVisible) args.add(mClearBrowsingDataButtonHeaderItem); + setHeaders(args.toArray(new HeaderItem[args.size()])); } private void setPrivacyDisclaimerText(TextView view, int stringId, final String url) { @@ -396,26 +419,29 @@ * Set visibility for privacy disclaimer layout and views. */ void setPrivacyDisclaimerVisibility() { - if (!mIsHeaderInflated) return; - - boolean show = hasPrivacyDisclaimers() && mHistoryManager.shouldShowInfoHeaderIfAvailable(); boolean isSignedIn = ChromeSigninController.get().isSignedIn(); + boolean shouldShowPrivacyDisclaimers = + hasPrivacyDisclaimers() && mHistoryManager.shouldShowInfoHeaderIfAvailable(); mSignedInNotSyncedTextView.setVisibility( !mHasSyncedData && isSignedIn ? View.VISIBLE : View.GONE); mSignedInSyncedTextView.setVisibility(mHasSyncedData ? View.VISIBLE : View.GONE); mOtherFormsOfBrowsingHistoryTextView.setVisibility( mHasOtherFormsOfBrowsingData ? View.VISIBLE : View.GONE); - mPrivacyDisclaimers.setVisibility(show ? View.VISIBLE : View.GONE); + // Prevent from refreshing the recycler view if header visibility is not changed. + if (mPrivacyDisclaimersVisible == shouldShowPrivacyDisclaimers) return; + mPrivacyDisclaimersVisible = shouldShowPrivacyDisclaimers; + if (mIsInitialized) setHeaders(); } private void updateClearBrowsingDataButtonVisibility() { // If the history header is not showing (e.g. when there is no browsing history), // mClearBrowsingDataButton will be null. if (mClearBrowsingDataButton == null) return; - - mClearBrowsingDataButtonContainer.setVisibility( - !PrefServiceBridge.getInstance().canDeleteBrowsingHistory() ? View.GONE : - View.VISIBLE); + boolean shouldShowButton = PrefServiceBridge.getInstance().canDeleteBrowsingHistory(); + if (mClearBrowsingDataButtonVisible == shouldShowButton) return; + mClearBrowsingDataButtonVisible = shouldShowButton; + mPrivacyDisclaimerBottomSpace.setVisibility(shouldShowButton ? View.GONE : View.VISIBLE); + if (mIsInitialized) setHeaders(); } private int getDefaultTextMargin(Resources resources) { @@ -441,12 +467,27 @@ } @VisibleForTesting - ViewGroup getPrivacyDisclaimersForTests() { - return mPrivacyDisclaimers; + ItemGroup getFirstGroupForTests() { + return getGroupAt(0).first; + } + + @VisibleForTesting + void setClearBrowsingDataButtonVisibilityForTest(boolean isVisible) { + if (mClearBrowsingDataButton == null) return; + if (mClearBrowsingDataButtonVisible == isVisible) return; + mClearBrowsingDataButtonVisible = isVisible; + if (mIsInitialized) setHeaders(); } @VisibleForTesting public ArrayList<HistoryItemView> getItemViewsForTests() { return mItemViews; } + + @VisibleForTesting + void generateHeaderItemsForTest() { + mPrivacyDisclaimerHeaderItem = new HeaderItem(0, null); + mClearBrowsingDataButtonHeaderItem = new HeaderItem(1, null); + mClearBrowsingDataButtonVisible = true; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java index 67d71ce..0371c324 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -134,17 +134,23 @@ mLargeIconBridge.createCache(maxSize); // 7. Initialize the adapter to load items. + mHistoryAdapter.generateHeaderItems(); mHistoryAdapter.initialize(); - // 8. Add scroll listener to page in more items when necessary. + // 8. Add scroll listener to show/hide info button on scroll and page in more items + // when necessary. mRecyclerView.addOnScrollListener(new OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - if (!mHistoryAdapter.canLoadMoreItems()) return; - - // Load more items if the scroll position is close to the bottom of the list. LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); + // Show info button if available if first visible position is close to info header; + // otherwise hide info button. + mToolbar.updateInfoMenuItem(infoHeaderIsVisible() && shouldShowInfoButton(), + shouldShowInfoHeaderIfAvailable()); + + if (!mHistoryAdapter.canLoadMoreItems()) return; + // Load more items if the scroll position is close to the bottom of the list. if (layoutManager.findLastVisibleItemPosition() > (mHistoryAdapter.getItemCount() - 25)) { mHistoryAdapter.loadMoreItems(); @@ -414,7 +420,8 @@ * @return True if info menu item should be shown on history toolbar, false otherwise. */ boolean shouldShowInfoButton() { - return mHistoryAdapter.hasPrivacyDisclaimers(); + return mHistoryAdapter.hasPrivacyDisclaimers() && mHistoryAdapter.getItemCount() > 0 + && !mToolbar.isSearching(); } /** @@ -425,6 +432,14 @@ return mShouldShowInfoHeader; } + /** + * @return True if info header is visible on history page. + */ + boolean infoHeaderIsVisible() { + LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager(); + return (layoutManager.findFirstVisibleItemPosition() == 0); + } + @Override public void onSignedIn() { mToolbar.onSignInStateChange();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerToolbar.java index 0f99ce6..b1f1050 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManagerToolbar.java
@@ -44,8 +44,8 @@ @Override protected void showNormalView() { super.showNormalView(); - updateInfoMenuItem( - mManager.shouldShowInfoButton(), mManager.shouldShowInfoHeaderIfAvailable()); + updateInfoMenuItem(mManager.infoHeaderIsVisible() && mManager.shouldShowInfoButton(), + mManager.shouldShowInfoHeaderIfAvailable()); } @Override @@ -77,9 +77,7 @@ @Override protected void onDataChanged(int numItems) { super.onDataChanged(numItems); - getMenu() - .findItem(R.id.info_menu_id) - .setVisible(mManager.shouldShowInfoButton() && !mIsSearching && numItems > 0); + getMenu().findItem(R.id.info_menu_id).setVisible(mManager.shouldShowInfoButton()); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/JourneyLogger.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/JourneyLogger.java index c865c01..fda3186 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/JourneyLogger.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/JourneyLogger.java
@@ -36,12 +36,16 @@ /** * Sets the number of suggestions shown for the specified section. * - * @param section The section for which to log. - * @param number The number of suggestions. + * @param section The section for which to log. + * @param number The number of suggestions. + * @param hasCompleteSuggestion Whether the section has at least one + * complete suggestion. */ - public void setNumberOfSuggestionsShown(int section, int number) { + public void setNumberOfSuggestionsShown( + int section, int number, boolean hasCompleteSuggestion) { assert section < Section.MAX; - nativeSetNumberOfSuggestionsShown(mJourneyLoggerAndroid, section, number); + nativeSetNumberOfSuggestionsShown( + mJourneyLoggerAndroid, section, number, hasCompleteSuggestion); } /** @@ -174,17 +178,10 @@ } } - /** - * Records the fact that the user had an initial form of payment. - */ - public void setUserHadInitialFormOfPayment() { - nativeSetUserHadInitialFormOfPayment(mJourneyLoggerAndroid); - } - private native long nativeInitJourneyLoggerAndroid(boolean isIncognito, String url); private native void nativeDestroy(long nativeJourneyLoggerAndroid); - private native void nativeSetNumberOfSuggestionsShown( - long nativeJourneyLoggerAndroid, int section, int number); + private native void nativeSetNumberOfSuggestionsShown(long nativeJourneyLoggerAndroid, + int section, int number, boolean hasCompleteSuggestion); private native void nativeIncrementSelectionChanges( long nativeJourneyLoggerAndroid, int section); private native void nativeIncrementSelectionEdits(long nativeJourneyLoggerAndroid, int section); @@ -201,5 +198,4 @@ private native void nativeSetCompleted(long nativeJourneyLoggerAndroid); private native void nativeSetAborted(long nativeJourneyLoggerAndroid, int reason); private native void nativeSetNotShown(long nativeJourneyLoggerAndroid, int reason); - private native void nativeSetUserHadInitialFormOfPayment(long nativeJourneyLoggerAndroid); } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index 007d652..95aef18 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -527,8 +527,8 @@ if (mRequestPayerName || mRequestPayerPhone || mRequestPayerEmail) { mContactEditor = new ContactEditor(mRequestPayerName, mRequestPayerPhone, mRequestPayerEmail); - mContactSection = new ContactDetailsSection( - activity, Collections.unmodifiableList(profiles), mContactEditor); + mContactSection = new ContactDetailsSection(activity, + Collections.unmodifiableList(profiles), mContactEditor, mJourneyLogger); } setIsAnyPaymentRequestShowing(true); @@ -590,14 +590,11 @@ } } - // Log the number of suggested shipping addresses. - mJourneyLogger.setNumberOfSuggestionsShown(Section.SHIPPING_ADDRESS, addresses.size()); - // Automatically select the first address if one is complete and if the merchant does // not require a shipping address to calculate shipping costs. + boolean hasCompleteShippingAddress = !addresses.isEmpty() && addresses.get(0).isComplete(); int firstCompleteAddressIndex = SectionInformation.NO_SELECTION; - if (mUiShippingOptions.getSelectedItem() != null && !addresses.isEmpty() - && addresses.get(0).isComplete()) { + if (mUiShippingOptions.getSelectedItem() != null && hasCompleteShippingAddress) { firstCompleteAddressIndex = 0; // The initial label for the selected shipping address should not include the @@ -605,6 +602,11 @@ addresses.get(firstCompleteAddressIndex).setShippingAddressLabelWithoutCountry(); } + // Log the number of suggested shipping addresses and whether at least one of them is + // complete. + mJourneyLogger.setNumberOfSuggestionsShown( + Section.SHIPPING_ADDRESS, addresses.size(), hasCompleteShippingAddress); + mShippingAddressesSection = new SectionInformation( PaymentRequestUI.TYPE_SHIPPING_ADDRESSES, firstCompleteAddressIndex, addresses); } @@ -1085,8 +1087,6 @@ } else if (optionType == PaymentRequestUI.TYPE_PAYMENT_METHODS) { assert option instanceof PaymentInstrument; if (option instanceof AutofillPaymentInstrument) { - // Log the change of credit card. - mJourneyLogger.incrementSelectionChanges(Section.CREDIT_CARDS); AutofillPaymentInstrument card = (AutofillPaymentInstrument) option; if (!card.isComplete()) { @@ -1094,6 +1094,8 @@ return PaymentRequestUI.SELECTION_RESULT_EDITOR_LAUNCH; } } + // Log the change of payment method. + mJourneyLogger.incrementSelectionChanges(Section.PAYMENT_METHOD); updateOrderSummary((PaymentInstrument) option); mPaymentMethodsSection.setSelectedItem(option); @@ -1147,7 +1149,7 @@ } else if (optionType == PaymentRequestUI.TYPE_PAYMENT_METHODS) { editCard(null); // Log the add of credit card. - mJourneyLogger.incrementSelectionAdds(Section.CREDIT_CARDS); + mJourneyLogger.incrementSelectionAdds(Section.PAYMENT_METHOD); return PaymentRequestUI.SELECTION_RESULT_EDITOR_LAUNCH; } @@ -1238,7 +1240,7 @@ private void editCard(final AutofillPaymentInstrument toEdit) { if (toEdit != null) { // Log the edit of a credit card. - mJourneyLogger.incrementSelectionEdits(Section.CREDIT_CARDS); + mJourneyLogger.incrementSelectionEdits(Section.PAYMENT_METHOD); } mCardEditor.edit(toEdit, new Callback<AutofillPaymentInstrument>() { @Override @@ -1550,17 +1552,6 @@ Collections.sort(mPendingInstruments, PAYMENT_INSTRUMENT_COMPARATOR); - // Log the number of suggested credit cards. - int numberOfAutofillInstruments = 0; - for (int i = 0; i < mPendingInstruments.size(); i++) { - if (mPendingInstruments.get(i).isAutofillInstrument()) numberOfAutofillInstruments++; - } - mJourneyLogger.setNumberOfSuggestionsShown( - Section.CREDIT_CARDS, numberOfAutofillInstruments); - - // Record whether the user had a form of payment initially. - if (!mPendingInstruments.isEmpty()) mJourneyLogger.setUserHadInitialFormOfPayment(); - // Possibly pre-select the first instrument on the list. int selection = !mPendingInstruments.isEmpty() && mPendingInstruments.get(0).canPreselect() ? 0 @@ -1582,6 +1573,12 @@ } } + // Record the number suggested payment methods and whether at least one of them was + // complete. + mJourneyLogger.setNumberOfSuggestionsShown(Section.PAYMENT_METHOD, + mPendingInstruments.size(), + !mPendingInstruments.isEmpty() && mPendingInstruments.get(0).isComplete()); + mPendingInstruments.clear(); updateInstrumentModifiedTotals();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java index 8bc00617..e9800f0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java
@@ -11,7 +11,9 @@ import org.chromium.chrome.browser.payments.AutofillAddress; import org.chromium.chrome.browser.payments.AutofillContact; import org.chromium.chrome.browser.payments.ContactEditor; +import org.chromium.chrome.browser.payments.JourneyLogger; import org.chromium.chrome.browser.payments.PaymentRequestImpl; +import org.chromium.chrome.browser.payments.Section; import java.util.ArrayList; import java.util.Collection; @@ -35,10 +37,11 @@ * * @param context Context * @param unmodifiableProfiles The list of profiles to build from. - * @param mContactEditor The Contact Editor associated with this flow. + * @param contactEditor The Contact Editor associated with this flow. + * @param journeyLogger The JourneyLogger for the current Payment Request. */ public ContactDetailsSection(Context context, Collection<AutofillProfile> unmodifiableProfiles, - ContactEditor contactEditor) { + ContactEditor contactEditor, JourneyLogger journeyLogger) { // Initially no items are selected, but they are updated later in the constructor. super(PaymentRequestUI.TYPE_CONTACT_DETAILS, null); @@ -48,7 +51,7 @@ mProfiles = new ArrayList<AutofillProfile>(unmodifiableProfiles); // Refresh the contact section items and selection. - createContactListFromAutofillProfiles(); + createContactListFromAutofillProfiles(journeyLogger); } /** @@ -88,7 +91,7 @@ } /** Recomputes the list of displayed contacts and possibly updates the selection. */ - private void createContactListFromAutofillProfiles() { + private void createContactListFromAutofillProfiles(JourneyLogger journeyLogger) { List<AutofillContact> contacts = new ArrayList<>(); List<AutofillContact> uniqueContacts = new ArrayList<>(); @@ -143,6 +146,13 @@ firstCompleteContactIndex = 0; } + // TODO(crbug.com/746062): Remove this once a journeyLogger is passed in tests. + if (journeyLogger != null) { + // Log the number of suggested contact info. + journeyLogger.setNumberOfSuggestionsShown(Section.CONTACT_INFO, uniqueContacts.size(), + firstCompleteContactIndex != SectionInformation.NO_SELECTION); + } + updateItemsWithCollection(firstCompleteContactIndex, uniqueContacts); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentOption.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentOption.java index 76088fa..04c19c2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentOption.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentOption.java
@@ -14,7 +14,9 @@ * method. */ public class PaymentOption implements Completable { - protected boolean mIsComplete; + // By default a payment option is complete. It is up to the subclass to update this value if the + // payment option is not complete. + protected boolean mIsComplete = true; protected boolean mIsEditable; protected String mEditMessage; protected String mEditTitle;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index 8edc302..639245a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -56,6 +56,8 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.webapps.WebappActivity; +import org.chromium.content_public.browser.ScreenOrientationDelegate; +import org.chromium.content_public.browser.ScreenOrientationDelegateManager; import org.chromium.ui.UiUtils; import java.lang.annotation.Retention; @@ -68,8 +70,9 @@ * Manages interactions with the VR Shell. */ @JNINamespace("vr_shell") -public class VrShellDelegate implements ApplicationStatus.ActivityStateListener, - View.OnSystemUiVisibilityChangeListener { +public class VrShellDelegate + implements ApplicationStatus.ActivityStateListener, View.OnSystemUiVisibilityChangeListener, + ScreenOrientationDelegate { private static final String TAG = "VrShellDelegate"; // Pseudo-random number to avoid request id collisions. @@ -783,6 +786,7 @@ // Lock orientation to landscape after enter VR. mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + ScreenOrientationDelegateManager.setOrientationDelegate(this); addVrViews(); boolean webVrMode = mRequestedWebVr || tentativeWebVrMode && !mAutopresentWebVr; @@ -944,6 +948,20 @@ } } + @Override + public boolean canUnlockOrientation(Activity activity, int defaultOrientation) { + if (mActivity == activity && mRestoreOrientation != null) { + mRestoreOrientation = defaultOrientation; + return false; + } + return true; + } + + @Override + public boolean canLockOrientation() { + return false; + } + private boolean isWindowModeCorrectForVr() { int flags = mActivity.getWindow().getDecorView().getSystemUiVisibility(); int orientation = mActivity.getResources().getConfiguration().orientation; @@ -957,11 +975,13 @@ mRestoreOrientation = mActivity.getRequestedOrientation(); } mActivity.setRequestedOrientation(requestedOrientation); + ScreenOrientationDelegateManager.setOrientationDelegate(this); setupVrModeWindowFlags(); } private void restoreWindowMode() { if (mRestoreOrientation != null) mActivity.setRequestedOrientation(mRestoreOrientation); + ScreenOrientationDelegateManager.setOrientationDelegate(null); mRestoreOrientation = null; clearVrModeWindowFlags(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java index 7cf149e..9e94bb31 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java
@@ -106,6 +106,41 @@ } /** + * Contains information of a single header that this adapter uses to manage headers. + */ + public static class HeaderItem extends TimedItem { + private final long mStableId; + private final View mView; + + /** + * Initialize stable id and view associated with this HeaderItem. + * @param position Position of this HeaderItem in the header group. + * @param view View associated with this HeaderItem. + */ + public HeaderItem(int position, View view) { + mStableId = getTimestamp() - position; + mView = view; + } + + @Override + public long getTimestamp() { + return Long.MAX_VALUE; + } + + @Override + public long getStableId() { + return mStableId; + } + + /** + * @return The View associated with this HeaderItem. + */ + public View getView() { + return mView; + } + } + + /** * A {@link RecyclerView.ViewHolder} that displays a date header. */ public static class DateViewHolder extends RecyclerView.ViewHolder { @@ -193,6 +228,10 @@ mItems.remove(item); } + public void removeAllItems() { + mItems.clear(); + } + /** Records the position of all the TimedItems in this group, relative to the full list. */ public void setPosition(int index) { assert mIndex == 0 || mIndex == TimedItem.INVALID_POSITION; @@ -225,15 +264,18 @@ * @return The size of this group. */ public int size() { - if (mIsListHeader || mIsListFooter) return 1; + if (mIsListHeader) return mItems.size(); + if (mIsListFooter) return 1; // Plus 1 to account for the date header. return mItems.size() + 1; } public TimedItem getItemAt(int index) { - // 0 is allocated to the date header. The list header has no items. - if (index <= 0 || mIsListHeader || mIsListFooter) return null; + // 0 is allocated to the date header. Return item if list header has + // header items, otherwise return null. + if (mIsListHeader) return mItems.get(index); + if (index <= 0 || mIsListFooter) return null; sortIfNeeded(); return mItems.get(index - 1); @@ -305,12 +347,15 @@ protected abstract ViewHolder createViewHolder(ViewGroup parent); /** - * Creates a {@link BasicViewHolder} in the given view parent for the header. + * Creates a {@link BasicViewHolder} in the given view parent for the header. The default + * implementation will create an empty FrameLayout container as the view holder. * @see #onCreateViewHolder(ViewGroup, int) */ - @Nullable protected BasicViewHolder createHeader(ViewGroup parent) { - return null; + // Create an empty layout as a container for the header view. + View v = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.date_divided_adapter_header_view_holder, parent, false); + return new BasicViewHolder(v); } /** @@ -363,6 +408,18 @@ SubsectionHeaderViewHolder holder, TimedItem timedItem) {} /** + * Binds the {@link BasicViewHolder} with the given {@link HeaderItem}. + * @see #onBindViewHolder(ViewHolder, int) + */ + protected void bindViewHolderForHeaderItem(ViewHolder viewHolder, HeaderItem headerItem) { + BasicViewHolder basicViewHolder = (BasicViewHolder) viewHolder; + View v = headerItem.getView(); + ((ViewGroup) basicViewHolder.itemView).removeAllViews(); + if (v.getParent() != null) ((ViewGroup) v.getParent()).removeView(v); + ((ViewGroup) basicViewHolder.itemView).addView(v); + } + + /** * Gets the resource id of the view showing the date header. * Contract for subclasses: this view should be a {@link TextView}. */ @@ -420,17 +477,40 @@ } /** - * Adds a header as the first group in this adapter. + * Add a list of headers as the first group in this adapter. If headerItems has no items, + * the header group will not be created. Otherwise, header items will be added as child items + * to the header group. Note that any previously added header items will be removed. + * {@link #bindViewHolderForHeaderItem(ViewHolder, HeaderItem)} will bind the HeaderItem views + * to the given ViewHolder. Sub-classes may override #bindViewHolderForHeaderItem and + * (@link #createHeader(ViewGroup)} if custom behavior is needed. + * + * @param headerItems Zero or more header items to be add to the header item group. */ - public void addHeader() { - assert mSize == 0; + public void setHeaders(HeaderItem... headerItems) { + if (headerItems == null || headerItems.length == 0) { + removeHeader(); + return; + } - ItemGroup header = new ItemGroup(Long.MAX_VALUE); - header.mIsListHeader = true; + ItemGroup header; + if (mHasListHeader) { + header = mGroups.first(); + mSize -= header.size(); + header.removeAllItems(); + } else { + header = new ItemGroup(Long.MAX_VALUE); + header.mIsListHeader = true; + mGroups.add(header); + } - mGroups.add(header); - mSize++; + for (HeaderItem item : headerItems) { + header.addItem(item); + mSize++; + } mHasListHeader = true; + + setGroupPositions(); + notifyDataSetChanged(); } /** @@ -439,8 +519,8 @@ public void removeHeader() { if (!mHasListHeader) return; + mSize -= mGroups.first().size(); mGroups.remove(mGroups.first()); - mSize--; mHasListHeader = false; setGroupPositions(); @@ -510,7 +590,8 @@ public Pair<Date, TimedItem> getItemAt(int position) { Pair<ItemGroup, Integer> pair = getGroupAt(position); ItemGroup group = pair.first; - return new Pair<>(group.mDate, group.getItemAt(pair.second)); + return new Pair<>(group.mDate, + group.mIsListHeader ? group.getItemAt(position) : group.getItemAt(pair.second)); } @Override @@ -556,6 +637,8 @@ bindViewHolderForSubsectionHeader((SubsectionHeaderViewHolder) holder, pair.second); } else if (!(holder instanceof BasicViewHolder)) { bindViewHolderForTimedItem(holder, pair.second); + } else if (pair.second instanceof HeaderItem) { + bindViewHolderForHeaderItem(holder, (HeaderItem) pair.second); } } @@ -569,7 +652,7 @@ */ protected Pair<ItemGroup, Integer> getGroupAt(int position) { // TODO(ianwen): Optimize the performance if the number of groups becomes too large. - if (mHasListHeader && position == 0) { + if (mHasListHeader && position < mGroups.first().size()) { assert mGroups.first().mIsListHeader; return new Pair<>(mGroups.first(), TYPE_HEADER); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java index 2e157e6b..ca3bb07 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/OSKOverscrollTest.java
@@ -94,7 +94,7 @@ private int getViewportHeight(WebContents webContents) { try { String jsonText = JavaScriptUtils.executeJavaScriptAndWaitForResult( - webContents, "window.innerHeight"); + webContents, "window.visualViewport.height"); MoreAsserts.assertNotEqual(jsonText.trim().toLowerCase(Locale.US), "null"); return Integer.parseInt(jsonText); } catch (Exception ex) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java index b80b6ac..5045064 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java
@@ -722,7 +722,7 @@ } })); ApplicationTestUtils.assertWaitForPageScaleFactorMatch( - mActivityTestRule.getActivity(), 0.5f, false); + mActivityTestRule.getActivity(), 0.5f); // Long press the center of the page, which should bring up the context menu. final TestTabObserver observer = new TestTabObserver();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java index a624e56..830ab81 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapterTest.java
@@ -90,7 +90,7 @@ editor.putBoolean(PREF_SHOW_STORAGE_INFO_HEADER, true).apply(); } - private void initializeAdapter(boolean showOffTheRecord) throws Exception { + private void initializeAdapter(boolean showOffTheRecord, boolean hasHeader) throws Exception { mObserver = new Observer(); mAdapter = new DownloadHistoryAdapter(showOffTheRecord, null); mAdapter.registerAdapterDataObserver(mObserver); @@ -106,14 +106,17 @@ } }); mDownloadDelegate.addCallback.waitForCallback(0); - mObserver.onChangedCallback.waitForCallback(callCount, 1); + // If header should be added, onChanged() will be called twice because both setHeaders() + // and loadMoreItems() will call notifyDataSetChanged(). Otherwise, setHeaders() will not + // be called and onChanged() will only be called once. + mObserver.onChangedCallback.waitForCallback(callCount, hasHeader ? 2 : 1); } /** Nothing downloaded, nothing shown. */ @Test @SmallTest public void testInitialize_Empty() throws Exception { - initializeAdapter(false); + initializeAdapter(false, false); Assert.assertEquals(0, mAdapter.getItemCount()); Assert.assertEquals(0, mAdapter.getTotalDownloadSize()); @@ -133,7 +136,7 @@ public void testInitialize_SingleItem() throws Exception { DownloadItem item = StubbedProvider.createDownloadItem(0, "19840116 12:00"); mDownloadDelegate.regularItems.add(item); - initializeAdapter(false); + initializeAdapter(false, true); checkAdapterContents(HEADER, null, item); Assert.assertEquals(1, mAdapter.getTotalDownloadSize()); } @@ -146,7 +149,7 @@ DownloadItem item1 = StubbedProvider.createDownloadItem(1, "19840116 12:01"); mDownloadDelegate.regularItems.add(item0); mDownloadDelegate.regularItems.add(item1); - initializeAdapter(false); + initializeAdapter(false, true); checkAdapterContents(HEADER, null, item1, item0); Assert.assertEquals(11, mAdapter.getTotalDownloadSize()); } @@ -159,7 +162,7 @@ DownloadItem item1 = StubbedProvider.createDownloadItem(1, "19840117 12:00"); mDownloadDelegate.regularItems.add(item0); mDownloadDelegate.regularItems.add(item1); - initializeAdapter(false); + initializeAdapter(false, true); checkAdapterContents(HEADER, null, item1, null, item0); Assert.assertEquals(11, mAdapter.getTotalDownloadSize()); } @@ -172,7 +175,7 @@ editor.putBoolean(PREF_SHOW_STORAGE_INFO_HEADER, false).apply(); DownloadItem item = StubbedProvider.createDownloadItem(0, "19840116 12:00"); mDownloadDelegate.regularItems.add(item); - initializeAdapter(false); + initializeAdapter(false, false); checkAdapterContents(null, item); Assert.assertEquals(1, mAdapter.getTotalDownloadSize()); } @@ -185,7 +188,7 @@ DownloadItem item1 = StubbedProvider.createDownloadItem(1, "19840116 12:01"); mDownloadDelegate.regularItems.add(item0); mDownloadDelegate.regularItems.add(item1); - initializeAdapter(false); + initializeAdapter(false, true); checkAdapterContents(HEADER, null, item1, item0); Assert.assertEquals(11, mAdapter.getTotalDownloadSize()); @@ -216,7 +219,7 @@ DownloadItem item1 = StubbedProvider.createDownloadItem(1, "19840116 12:01"); mDownloadDelegate.regularItems.add(item0); mDownloadDelegate.offTheRecordItems.add(item1); - initializeAdapter(false); + initializeAdapter(false, true); checkAdapterContents(HEADER, null, item0); Assert.assertEquals(1, mAdapter.getTotalDownloadSize()); } @@ -229,7 +232,7 @@ DownloadItem item1 = StubbedProvider.createDownloadItem(1, "19840116 12:00"); mDownloadDelegate.regularItems.add(item0); mDownloadDelegate.offTheRecordItems.add(item1); - initializeAdapter(true); + initializeAdapter(true, true); checkAdapterContents(HEADER, null, item0, item1); Assert.assertEquals(11, mAdapter.getTotalDownloadSize()); } @@ -244,7 +247,7 @@ mDownloadDelegate.regularItems.add(item0); mDownloadDelegate.offTheRecordItems.add(item1); mOfflineDelegate.items.add(item2); - initializeAdapter(true); + initializeAdapter(true, true); checkAdapterContents(HEADER, null, item2, null, item0, item1); Assert.assertEquals(100011, mAdapter.getTotalDownloadSize()); } @@ -254,7 +257,7 @@ @SmallTest public void testUpdate_UpdateItems() throws Exception { // Start with an empty Adapter. - initializeAdapter(false); + initializeAdapter(false, false); Assert.assertEquals(0, mAdapter.getItemCount()); Assert.assertEquals(0, mAdapter.getTotalDownloadSize()); @@ -267,7 +270,7 @@ Assert.assertEquals(1, mAdapter.getTotalDownloadSize()); // Add a second item with a different date. - Assert.assertEquals(2, mObserver.onChangedCallback.getCallCount()); + Assert.assertEquals(3, mObserver.onChangedCallback.getCallCount()); DownloadItem item1 = StubbedProvider.createDownloadItem(1, "19840117 12:00"); mAdapter.onDownloadItemCreated(item1); mObserver.onChangedCallback.waitForCallback(2); @@ -323,26 +326,28 @@ mDownloadDelegate.regularItems.add(regularItem); mDownloadDelegate.offTheRecordItems.add(offTheRecordItem); mOfflineDelegate.items.add(offlineItem); - initializeAdapter(true); + initializeAdapter(true, true); checkAdapterContents(HEADER, null, offlineItem, null, regularItem, offTheRecordItem); Assert.assertEquals(100011, mAdapter.getTotalDownloadSize()); - // Remove an item from the date bucket with two items. - Assert.assertEquals(1, mObserver.onChangedCallback.getCallCount()); + // Remove an item from the date bucket with two items. Wait for two callbacks as + // notifyDataSetChanged() is called once when setHeaders() is called and once when items + // are loaded. + Assert.assertEquals(2, mObserver.onChangedCallback.getCallCount()); mAdapter.onDownloadItemRemoved(offTheRecordItem.getId(), true); mObserver.onChangedCallback.waitForCallback(1); checkAdapterContents(HEADER, null, offlineItem, null, regularItem); Assert.assertEquals(100001, mAdapter.getTotalDownloadSize()); // Remove an item from the second bucket, which removes the bucket entirely. - Assert.assertEquals(2, mObserver.onChangedCallback.getCallCount()); + Assert.assertEquals(4, mObserver.onChangedCallback.getCallCount()); mOfflineDelegate.observer.onItemDeleted(offlineItem.getGuid()); mObserver.onChangedCallback.waitForCallback(2); checkAdapterContents(HEADER, null, regularItem); Assert.assertEquals(1, mAdapter.getTotalDownloadSize()); // Remove the last item in the list. - Assert.assertEquals(3, mObserver.onChangedCallback.getCallCount()); + Assert.assertEquals(6, mObserver.onChangedCallback.getCallCount()); mAdapter.onDownloadItemRemoved(regularItem.getId(), false); mObserver.onChangedCallback.waitForCallback(3); Assert.assertEquals(0, mAdapter.getItemCount()); @@ -367,7 +372,7 @@ mDownloadDelegate.offTheRecordItems.add(item4); mDownloadDelegate.regularItems.add(item5); mOfflineDelegate.items.add(item6); - initializeAdapter(true); + initializeAdapter(true, true); checkAdapterContents( HEADER, null, item5, item4, item6, null, item3, item2, null, item1, item0); Assert.assertEquals(1666, mAdapter.getTotalDownloadSize()); @@ -401,7 +406,7 @@ mOfflineDelegate.items.add(item0); mOfflineDelegate.items.add(item1); mOfflineDelegate.items.add(item2); - initializeAdapter(false); + initializeAdapter(false, true); checkAdapterContents(HEADER, null, item2, null, item1, item0); Assert.assertEquals(111000, mAdapter.getTotalDownloadSize()); @@ -427,7 +432,7 @@ public void testInProgress_FilePathMapAccurate() throws Exception { Set<DownloadHistoryItemWrapper> toDelete; - initializeAdapter(false); + initializeAdapter(false, false); Assert.assertEquals(0, mAdapter.getItemCount()); Assert.assertEquals(0, mAdapter.getTotalDownloadSize()); @@ -486,7 +491,7 @@ mDownloadDelegate.offTheRecordItems.add(item4); mDownloadDelegate.regularItems.add(item5); mOfflineDelegate.items.add(item6); - initializeAdapter(true); + initializeAdapter(true, true); checkAdapterContents( HEADER, null, item5, item4, item6, null, item3, item2, null, item1, item0); @@ -540,7 +545,7 @@ mDownloadDelegate.offTheRecordItems.add(item4); mDownloadDelegate.regularItems.add(item5); mOfflineDelegate.items.add(item6); - initializeAdapter(true); + initializeAdapter(true, true); checkAdapterContents( HEADER, null, item5, item4, item6, null, item3, item2, null, item1, item0); @@ -586,7 +591,7 @@ mDownloadDelegate.offTheRecordItems.add(item4); mDownloadDelegate.regularItems.add(item5); mOfflineDelegate.items.add(item6); - initializeAdapter(true); + initializeAdapter(true, true); checkAdapterContents( HEADER, null, item5, item4, item6, null, item3, item2, null, item1, item0);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java index 2071f3fb..e0a19ea 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java
@@ -34,6 +34,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; +import org.chromium.chrome.browser.widget.DateDividedAdapter; import org.chromium.chrome.browser.widget.TintedImageButton; import org.chromium.chrome.browser.widget.selection.SelectableItemView; import org.chromium.chrome.browser.widget.selection.SelectableItemViewHolder; @@ -442,11 +443,10 @@ // Not signed in ChromeSigninController signinController = ChromeSigninController.get(); signinController.setSignedInAccountName(null); - assertEquals(false, infoMenuItem.isVisible()); - assertEquals(View.GONE, mAdapter.getSignedInNotSyncedViewForTests().getVisibility()); - assertEquals(View.GONE, mAdapter.getSignedInSyncedViewForTests().getVisibility()); - assertEquals( - View.GONE, mAdapter.getOtherFormsOfBrowsingHistoryViewForTests().getVisibility()); + assertFalse(infoMenuItem.isVisible()); + DateDividedAdapter.ItemGroup headerGroup = mAdapter.getFirstGroupForTests(); + assertTrue(mAdapter.hasListHeader()); + assertEquals(1, headerGroup.size()); // Signed in but not synced and history has items signinController.setSignedInAccountName("test@gmail.com"); @@ -457,22 +457,100 @@ toolbar.onSignInStateChange(); } }); - assertEquals(true, infoMenuItem.isVisible()); + assertTrue(infoMenuItem.isVisible()); // Signed in, synced, has other forms and has items // Privacy disclaimers should be shown by default setHasOtherFormsOfBrowsingData(true, true); - assertEquals(true, infoMenuItem.isVisible()); - assertEquals(View.VISIBLE, mAdapter.getPrivacyDisclaimersForTests().getVisibility()); + assertTrue(infoMenuItem.isVisible()); + headerGroup = mAdapter.getFirstGroupForTests(); + assertTrue(mAdapter.hasListHeader()); + assertEquals(2, headerGroup.size()); - // Toggle Info Menu Item + // Toggle Info Menu Item to off ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { mHistoryManager.onMenuItemClick(infoMenuItem); } }); - assertEquals(View.GONE, mAdapter.getPrivacyDisclaimersForTests().getVisibility()); + headerGroup = mAdapter.getFirstGroupForTests(); + assertTrue(mAdapter.hasListHeader()); + assertEquals(1, headerGroup.size()); + + // Toggle Info Menu Item to on + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + mHistoryManager.onMenuItemClick(infoMenuItem); + } + }); + headerGroup = mAdapter.getFirstGroupForTests(); + assertTrue(mAdapter.hasListHeader()); + assertEquals(2, headerGroup.size()); + + signinController.setSignedInAccountName(null); + } + + @SmallTest + public void testInfoHeaderInSearchMode() throws Exception { + final HistoryManagerToolbar toolbar = mHistoryManager.getToolbarForTests(); + final MenuItem infoMenuItem = toolbar.getItemById(R.id.info_menu_id); + + // Sign in + int callCount = mTestObserver.onSelectionCallback.getCallCount(); + ChromeSigninController signinController = ChromeSigninController.get(); + signinController.setSignedInAccountName("test@gmail.com"); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + toolbar.onSignInStateChange(); + mAdapter.onSignInStateChange(); + } + }); + mTestObserver.onChangedCallback.waitForCallback(callCount, 1); + DateDividedAdapter.ItemGroup firstGroup = mAdapter.getFirstGroupForTests(); + assertTrue(infoMenuItem.isVisible()); + assertTrue(mAdapter.hasListHeader()); + assertEquals(2, firstGroup.size()); + + // Enter search mode + callCount = mTestObserver.onSelectionCallback.getCallCount(); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + toolbar.getMenu().performIdentifierAction(R.id.search_menu_id, 0); + } + }); + + mTestObserver.onSelectionCallback.waitForCallback(callCount, 1); + firstGroup = mAdapter.getFirstGroupForTests(); + assertFalse(infoMenuItem.isVisible()); + // The first group should be the history item group from SetUp() + assertFalse(mAdapter.hasListHeader()); + assertEquals(3, firstGroup.size()); + + signinController.setSignedInAccountName(null); + } + + @SmallTest + public void testInvisibleHeader() throws Exception { + assertTrue(mAdapter.hasListHeader()); + + // Not sign in and set clear browsing data button to invisible + ChromeSigninController signinController = ChromeSigninController.get(); + signinController.setSignedInAccountName(null); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + mAdapter.setClearBrowsingDataButtonVisibilityForTest(false); + mAdapter.setPrivacyDisclaimerVisibility(); + } + }); + + DateDividedAdapter.ItemGroup firstGroup = mAdapter.getFirstGroupForTests(); + assertFalse(mAdapter.hasListHeader()); + assertEquals(3, firstGroup.size()); } @SmallTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java index 78d54128..a547d4f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/history/HistoryAdapterTest.java
@@ -36,6 +36,7 @@ public void setUp() throws Exception { mHistoryProvider = new StubbedHistoryProvider(); mAdapter = new HistoryAdapter(new SelectionDelegate<HistoryItem>(), null, mHistoryProvider); + mAdapter.generateHeaderItemsForTest(); } private void initializeAdapter() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsSectionUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsSectionUnitTest.java index f687ff1..18ab3521 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsSectionUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsSectionUnitTest.java
@@ -42,7 +42,7 @@ mContactEditor = new ContactEditor(requestPayerName, requestPayerPhone, requestPayerEmail); mContactDetailsSection = new ContactDetailsSection( InstrumentationRegistry.getInstrumentation().getTargetContext(), autofillProfiles, - mContactEditor); + mContactEditor, null); } /** Tests the creation of the contact list, with most complete first. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java index 5302797a..93a23ee 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
@@ -55,7 +55,7 @@ // The user has a shipping address and a credit card associated with that address on disk. String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", - "US", "650-253-0000", "", "en-US")); + "US", "650-253-0000", "jondoe@email.com", "en-US")); mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, CardType.UNKNOWN, mBillingAddressId, "" /* serverId */)); @@ -235,53 +235,61 @@ } /** - * Expect that the number of credit card suggestions was logged properly. + * Expect that the number of payment method suggestions was logged properly. */ @Test @MediumTest @Feature({"Payments"}) - public void testNumberOfSuggestionsShown_CreditCards_Completed() + public void testNumberOfSuggestionsShown_PaymentMethod_Completed() throws InterruptedException, ExecutionException, TimeoutException { + // Add two credit cards. createTestData(); - // Complete a Payment Request with a credit card. - mPaymentRequestTestRule.triggerUIAndWait("ccBuy", mPaymentRequestTestRule.getReadyToPay()); + // Add a complete payment app. + mPaymentRequestTestRule.installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); + + // Complete a Payment Request with the payment app. + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyToPay()); mPaymentRequestTestRule.clickAndWait( - R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput()); - mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait( - R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask()); - mPaymentRequestTestRule.clickCardUnmaskButtonAndWait( - DialogInterface.BUTTON_POSITIVE, mPaymentRequestTestRule.getDismissed()); + R.id.button_primary, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains( + new String[] {"https://bobpay.com", "\"transaction\"", "1337"}); // Make sure the right number of suggestions were logged. Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSuggestionsShown.CreditCards.Completed", 2)); + "PaymentRequest.NumberOfSuggestionsShown.PaymentMethod.Completed", 3)); // Make sure no adds, edits or changes were logged. Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSelectionAdds.CreditCards.Completed", 0)); + "PaymentRequest.NumberOfSelectionAdds.PaymentMethod.Completed", 0)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSelectionChanges.CreditCards.Completed", 0)); + "PaymentRequest.NumberOfSelectionChanges.PaymentMethod.Completed", 0)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSelectionEdits.CreditCards.Completed", 0)); + "PaymentRequest.NumberOfSelectionEdits.PaymentMethod.Completed", 0)); } /** - * Expect that the number of credit card suggestions was logged properly. + * Expect that the number of payment method suggestions was logged properly. */ @Test @MediumTest @Feature({"Payments"}) - public void testNumberOfSuggestionsShown_CreditCards_AbortedByUser() + public void testNumberOfSuggestionsShown_PaymentMethod_AbortedByUser() throws InterruptedException, ExecutionException, TimeoutException { + // Add two credit cards. createTestData(); + // Add a complete payment app. + mPaymentRequestTestRule.installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); + // Cancel the payment request. - mPaymentRequestTestRule.triggerUIAndWait("ccBuy", mPaymentRequestTestRule.getReadyToPay()); + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyToPay()); mPaymentRequestTestRule.clickAndWait( R.id.close_button, mPaymentRequestTestRule.getDismissed()); @@ -291,27 +299,55 @@ // Make sure the right number of suggestions were logged. Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSuggestionsShown.CreditCards.UserAborted", 2)); + "PaymentRequest.NumberOfSuggestionsShown.PaymentMethod.UserAborted", 3)); // Make sure no adds, edits or changes were logged. Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSelectionAdds.CreditCards.UserAborted", 0)); + "PaymentRequest.NumberOfSelectionAdds.PaymentMethod.UserAborted", 0)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSelectionChanges.CreditCards.UserAborted", 0)); + "PaymentRequest.NumberOfSelectionChanges.PaymentMethod.UserAborted", 0)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSelectionEdits.CreditCards.UserAborted", 0)); + "PaymentRequest.NumberOfSelectionEdits.PaymentMethod.UserAborted", 0)); } /** - * Expect that the NumberOfSelectionAdds histogram gets logged properly for credit cards. + * Expect that an incomplete payment app is not suggested to the user. */ @Test @MediumTest @Feature({"Payments"}) - public void testNumberOfSelectionAdds_CreditCards_Completed() + public void testNumberOfSuggestionsShown_PaymentMethod_InvalidPaymentApp() + throws InterruptedException, ExecutionException, TimeoutException { + // Add two credit cards. + createTestData(); + + // Add an incomplete payment app. + mPaymentRequestTestRule.installPaymentApp(NO_INSTRUMENTS, IMMEDIATE_RESPONSE); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyToPay()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + + Thread.sleep(200); + + // Make sure only the two credit card suggestions were logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSuggestionsShown.PaymentMethod.UserAborted", 2)); + } + + /** + * Expect that the NumberOfSelectionAdds histogram gets logged properly for payment methods. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testNumberOfSelectionAdds_PaymentMethod_Completed() throws InterruptedException, ExecutionException, TimeoutException { createTestData(); @@ -342,15 +378,630 @@ // Make sure the add was logged. Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSelectionAdds.CreditCards.Completed", 1)); + "PaymentRequest.NumberOfSelectionAdds.PaymentMethod.Completed", 1)); // Make sure no edits or changes were logged. Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSelectionChanges.CreditCards.Completed", 0)); + "PaymentRequest.NumberOfSelectionChanges.PaymentMethod.Completed", 0)); Assert.assertEquals(1, RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.NumberOfSelectionEdits.CreditCards.Completed", 0)); + "PaymentRequest.NumberOfSelectionEdits.PaymentMethod.Completed", 0)); + } + + /** + * Expect that the number of contact info suggestions was logged properly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testNumberOfSuggestionsShown_ContactInfo_Completed() + throws InterruptedException, ExecutionException, TimeoutException { + createTestData(); + + // Complete a Payment Request with a credit card. + mPaymentRequestTestRule.triggerUIAndWait( + "contactInfoBuy", mPaymentRequestTestRule.getReadyToPay()); + mPaymentRequestTestRule.clickAndWait( + R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput()); + mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait( + R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask()); + mPaymentRequestTestRule.clickCardUnmaskButtonAndWait( + DialogInterface.BUTTON_POSITIVE, mPaymentRequestTestRule.getDismissed()); + + // Make sure the right number of suggestions were logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSuggestionsShown.ContactInfo.Completed", 2)); + + // Make sure no adds, edits or changes were logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionAdds.ContactInfo.Completed", 0)); + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionChanges.ContactInfo.Completed", 0)); + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionEdits.ContactInfo.Completed", 0)); + } + + /** + * Expect that the number of contact info suggestions was logged properly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testNumberOfSuggestionsShown_ContactInfo_AbortedByUser() + throws InterruptedException, ExecutionException, TimeoutException { + createTestData(); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait( + "contactInfoBuy", mPaymentRequestTestRule.getReadyToPay()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + + // Wait for the histograms to be logged. + Thread.sleep(200); + + // Make sure the right number of suggestions were logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSuggestionsShown.ContactInfo.UserAborted", 2)); + + // Make sure no adds, edits or changes were logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionAdds.ContactInfo.UserAborted", 0)); + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionChanges.ContactInfo.UserAborted", 0)); + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionEdits.ContactInfo.UserAborted", 0)); + } + + /** + * Expect that the NumberOfSelectionEdits histogram gets logged properly for contact info. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testNumberOfSelectionEdits_ContactInfo_Completed() + throws InterruptedException, ExecutionException, TimeoutException { + createTestData(); + + // Complete a Payment Request with a credit card. + mPaymentRequestTestRule.triggerUIAndWait( + "contactInfoBuy", mPaymentRequestTestRule.getReadyToPay()); + mPaymentRequestTestRule.clickInContactInfoAndWait( + R.id.payments_section, mPaymentRequestTestRule.getReadyForInput()); + + // Select the incomplete contact info and edit it. + mPaymentRequestTestRule.clickOnContactInfoSuggestionOptionAndWait( + 1, mPaymentRequestTestRule.getReadyToEdit()); + mPaymentRequestTestRule.setTextInEditorAndWait( + new String[] {"In Complete", "514-123-1234", "test@email.com"}, + mPaymentRequestTestRule.getEditorTextUpdate()); + mPaymentRequestTestRule.clickInEditorAndWait( + R.id.payments_edit_done_button, mPaymentRequestTestRule.getReadyToPay()); + mPaymentRequestTestRule.clickAndWait( + R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput()); + mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait( + R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask()); + mPaymentRequestTestRule.clickCardUnmaskButtonAndWait( + DialogInterface.BUTTON_POSITIVE, mPaymentRequestTestRule.getDismissed()); + + // Make sure the edit was logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionEdits.ContactInfo.Completed", 1)); + + // Since the edit was not for the default selection a change should be logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionChanges.ContactInfo.Completed", 1)); + + // Make sure no add was logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionAdds.ContactInfo.Completed", 0)); + } + + /** + * Expect that the NumberOfSelectionAdds histogram gets logged properly for contact info. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testNumberOfSelectionAdds_ContactInfo_Completed() + throws InterruptedException, ExecutionException, TimeoutException { + createTestData(); + + // Complete a Payment Request with a credit card. + mPaymentRequestTestRule.triggerUIAndWait( + "contactInfoBuy", mPaymentRequestTestRule.getReadyToPay()); + mPaymentRequestTestRule.clickInContactInfoAndWait( + R.id.payments_section, mPaymentRequestTestRule.getReadyForInput()); + + // Add a new shipping address. + mPaymentRequestTestRule.clickInContactInfoAndWait( + R.id.payments_add_option_button, mPaymentRequestTestRule.getReadyToEdit()); + mPaymentRequestTestRule.setTextInEditorAndWait( + new String[] {"Alice", "020-253-0000", "test@email.com"}, + mPaymentRequestTestRule.getEditorTextUpdate()); + mPaymentRequestTestRule.clickInEditorAndWait( + R.id.payments_edit_done_button, mPaymentRequestTestRule.getReadyToPay()); + + // Complete the transaction. + mPaymentRequestTestRule.clickAndWait( + R.id.button_primary, mPaymentRequestTestRule.getReadyForUnmaskInput()); + mPaymentRequestTestRule.setTextInCardUnmaskDialogAndWait( + R.id.card_unmask_input, "123", mPaymentRequestTestRule.getReadyToUnmask()); + mPaymentRequestTestRule.clickCardUnmaskButtonAndWait( + DialogInterface.BUTTON_POSITIVE, mPaymentRequestTestRule.getDismissed()); + + // Make sure the add was logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionAdds.ContactInfo.Completed", 1)); + + // Make sure no edits or changes were logged. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionChanges.ContactInfo.Completed", 0)); + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.NumberOfSelectionEdits.ContactInfo.Completed", 0)); + } + + /** + * Expect that the metric that records whether the user had complete suggestions for the + * requested information is logged correctly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserHadCompleteSuggestions_ShippingAndPayment() + throws InterruptedException, ExecutionException, TimeoutException { + // Add two addresses and two cards. + createTestData(); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait("ccBuy", mPaymentRequestTestRule.getReadyToPay()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the metric that records whether the user had complete suggestions for the + * requested information is logged correctly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserDidNotHaveCompleteSuggestions_ShippingAndPayment_IncompleteShipping() + throws InterruptedException, ExecutionException, TimeoutException { + // Add a card and an incomplete address (no region). + AutofillTestHelper mHelper = new AutofillTestHelper(); + String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", + true, "Jon Doe", "Google", "340 Main St", /*region=*/"", "Los Angeles", "", "90291", + "", "US", "650-253-0000", "", "en-US")); + mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, + CardType.UNKNOWN, mBillingAddressId, "" /* serverId */)); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait( + "ccBuy", mPaymentRequestTestRule.getReadyForInput()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the metric that records whether the user had complete suggestions for the + * requested information is logged correctly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserDidNotHaveCompleteSuggestions_ShippingAndPayment_IncompleteCard() + throws InterruptedException, ExecutionException, TimeoutException { + // Add an incomplete card (no exp date) and an complete address. + AutofillTestHelper mHelper = new AutofillTestHelper(); + String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", + true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", + "US", "650-253-0000", "", "en-US")); + mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", + /*number=*/"", "1111", "10", "2021", "visa", R.drawable.visa_card, CardType.UNKNOWN, + mBillingAddressId, "" /* serverId */)); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait( + "ccBuy", mPaymentRequestTestRule.getReadyForInput()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the metric that records whether the user had complete suggestions for the + * requested information is logged correctly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserDidNotHaveCompleteSuggestions_ShippingAndPayment_UnsupportedCard() + throws InterruptedException, ExecutionException, TimeoutException { + // Add an unsupported card (mastercard) and an complete address. + AutofillTestHelper mHelper = new AutofillTestHelper(); + String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", + true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", + "US", "650-253-0000", "", "en-US")); + mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", + "5187654321098765", "8765", "10", "2021", "mastercard", R.drawable.visa_card, + CardType.UNKNOWN, mBillingAddressId, "" /* serverId */)); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait( + "ccBuy", mPaymentRequestTestRule.getReadyForInput()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the metric that records whether the user had complete suggestions for the + * requested information is logged correctly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserDidNotHaveCompleteSuggestions_ShippingAndPayment_OnlyPaymentApp() + throws InterruptedException, ExecutionException, TimeoutException { + // Add a complete address and a working payment app. + AutofillTestHelper mHelper = new AutofillTestHelper(); + mHelper.setProfile(new AutofillProfile("", "https://example.com", true, "Jon Doe", "Google", + "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", + "en-US")); + mPaymentRequestTestRule.installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait( + "ccBuy", mPaymentRequestTestRule.getReadyForInput()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the metric that records whether the user had complete suggestions for the + * requested information is logged correctly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserDidNotHaveCompleteSuggestions_PaymentApp_NoInstruments() + throws InterruptedException, ExecutionException, TimeoutException { + // Add an address and a payment app without instruments on file. + AutofillTestHelper mHelper = new AutofillTestHelper(); + mHelper.setProfile(new AutofillProfile("", "https://example.com", true, "Jon Doe", "Google", + "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", + "en-US")); + mPaymentRequestTestRule.installPaymentApp(NO_INSTRUMENTS, IMMEDIATE_RESPONSE); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyForInput()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the metric that records whether the user had complete suggestions for the + * requested information is logged correctly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserHadCompleteSuggestions_PaymentApp_HasValidPaymentApp() + throws InterruptedException, ExecutionException, TimeoutException { + // Add an address and a payment app on file. + AutofillTestHelper mHelper = new AutofillTestHelper(); + mHelper.setProfile(new AutofillProfile("", "https://example.com", true, "Jon Doe", "Google", + "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", + "en-US")); + mPaymentRequestTestRule.installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyForInput()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the metric that records whether the user had complete suggestions for the + * requested information is logged correctly. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserHadCompleteSuggestions_ShippingAndPaymentApp_HasInvalidShipping() + throws InterruptedException, ExecutionException, TimeoutException { + // Add a card and an incomplete address (no region). + AutofillTestHelper mHelper = new AutofillTestHelper(); + String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", + true, "Jon Doe", "Google", "340 Main St", /*region=*/"", "Los Angeles", "", "90291", + "", "US", "650-253-0000", "", "en-US")); + mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, + CardType.UNKNOWN, mBillingAddressId, "" /* serverId */)); + + // Cancel the payment request. + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyForInput()); + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the UserHadCompleteSuggestions histogram gets logged properly when the user has + * at least one credit card on file. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserHadCompleteSuggestions_AcceptsCardsAndApps_UserHasOnlyCard() + throws InterruptedException, ExecutionException, TimeoutException { + // Add an address and a credit card on file. + AutofillTestHelper mHelper = new AutofillTestHelper(); + String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", + true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", + "US", "650-253-0000", "", "en-US")); + mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, + CardType.UNKNOWN, mBillingAddressId, "" /* serverId */)); + + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyToPay()); + + // The user cancels the Payment Request (trigger the logs). + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the UserHadCompleteSuggestions histogram gets logged properly when the user has + * at least one payment app on file. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserHadCompleteSuggestions_AcceptsCardsAndApps_UserHasOnlyPaymentApp() + throws InterruptedException, ExecutionException, TimeoutException { + // Add an address and a payment app on file. + AutofillTestHelper mHelper = new AutofillTestHelper(); + mHelper.setProfile(new AutofillProfile("", "https://example.com", true, "Jon Doe", "Google", + "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", + "en-US")); + mPaymentRequestTestRule.installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); + + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyToPay()); + + // The user cancels the Payment Request (trigger the logs). + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the UserHadCompleteSuggestions histogram gets logged properly when the user has + * at both a card and a payment app on file. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserHadCompleteSuggestions_AcceptsCardsAndApps_UserHasCardAndPaymentApp() + throws InterruptedException, ExecutionException, TimeoutException { + // Add an address, a credit card and a payment app on file. + AutofillTestHelper mHelper = new AutofillTestHelper(); + String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", + true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", + "US", "650-253-0000", "", "en-US")); + mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", + "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, + CardType.UNKNOWN, mBillingAddressId, "" /* serverId */)); + mPaymentRequestTestRule.installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); + + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyToPay()); + + // The user cancels the Payment Request (trigger the logs). + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion")); + } + + /** + * Expect that the UserDidNotHaveInitialFormOfPayment histogram gets logged properly when the + * user has no form of payment on file. + */ + @Test + @MediumTest + @Feature({"Payments"}) + public void testUserDidNotHaveCompleteSuggestions_AcceptsCardsAndApps_NoCardOrPaymentApp() + throws InterruptedException, ExecutionException, TimeoutException { + // Add an address on file. + new AutofillTestHelper().setProfile(new AutofillProfile("", "https://example.com", true, + "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", + "650-253-0000", "", "en-US")); + + mPaymentRequestTestRule.triggerUIAndWait( + "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyForInput()); + + // The user cancels the Payment Request (trigger the logs). + mPaymentRequestTestRule.clickAndWait( + R.id.close_button, mPaymentRequestTestRule.getDismissed()); + mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); + + // Make sure the metric was logged correctly. + Assert.assertEquals(1, + RecordHistogram.getHistogramValueCountForTesting( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + + "EffectOnCompletion", + CompletionStatus.USER_ABORTED)); + + // Make sure the opposite metric has no logs. + Assert.assertEquals(0, + RecordHistogram.getHistogramTotalCountForTesting( + "PaymentRequest.UserHadCompleteSuggestions.EffectOnCompletion")); } /** @@ -475,231 +1126,4 @@ RecordHistogram.getHistogramValueCountForTesting( "PaymentRequest.NumberOfSuggestionsShown.ShippingAddress.Completed", 2)); } - - /** - * Expect that the UserHadInitialFormOfPayment histogram gets logged properly when the user has - * at least one credit card on file. - */ - @Test - @MediumTest - @Feature({"Payments"}) - public void testUserHadInitialFormOfPayment_AcceptsCardsAndApps_UserHasOnlyCard() - throws InterruptedException, ExecutionException, TimeoutException { - // Add an address and a credit card on file. - AutofillTestHelper mHelper = new AutofillTestHelper(); - String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", - true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", - "US", "650-253-0000", "", "en-US")); - mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, - CardType.UNKNOWN, mBillingAddressId, "" /* serverId */)); - - mPaymentRequestTestRule.triggerUIAndWait( - "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyToPay()); - - // The user cancels the Payment Request (trigger the logs). - mPaymentRequestTestRule.clickAndWait( - R.id.close_button, mPaymentRequestTestRule.getDismissed()); - - mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - - // Make sure that the fact that the user had a form of payment was recorded. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion")); - } - - /** - * Expect that the UserHadInitialFormOfPayment histogram gets logged properly when the user has - * at least one payment app on file. - */ - @Test - @MediumTest - @Feature({"Payments"}) - public void testUserHadInitialFormOfPayment_AcceptsCardsAndApps_UserHasOnlyPaymentApp() - throws InterruptedException, ExecutionException, TimeoutException { - // Add an address and a payment app on file. - AutofillTestHelper mHelper = new AutofillTestHelper(); - mHelper.setProfile(new AutofillProfile("", "https://example.com", true, "Jon Doe", "Google", - "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", - "en-US")); - mPaymentRequestTestRule.installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); - - mPaymentRequestTestRule.triggerUIAndWait( - "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyToPay()); - - // The user cancels the Payment Request (trigger the logs). - mPaymentRequestTestRule.clickAndWait( - R.id.close_button, mPaymentRequestTestRule.getDismissed()); - - mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - - // Make sure that the fact that the user had a form of payment was recorded. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion")); - } - - /** - * Expect that the UserHadInitialFormOfPayment histogram gets logged properly when the user has - * at both a card and a payment app on file. - */ - @Test - @MediumTest - @Feature({"Payments"}) - public void testUserHadInitialFormOfPayment_AcceptsCardsAndApps_UserHasCardAndPaymentApp() - throws InterruptedException, ExecutionException, TimeoutException { - // Add an address, a credit card and a payment app on file. - AutofillTestHelper mHelper = new AutofillTestHelper(); - String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", - true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", - "US", "650-253-0000", "", "en-US")); - mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "4111111111111111", "1111", "12", "2050", "visa", R.drawable.visa_card, - CardType.UNKNOWN, mBillingAddressId, "" /* serverId */)); - mPaymentRequestTestRule.installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); - - mPaymentRequestTestRule.triggerUIAndWait( - "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyToPay()); - - // The user cancels the Payment Request (trigger the logs). - mPaymentRequestTestRule.clickAndWait( - R.id.close_button, mPaymentRequestTestRule.getDismissed()); - - mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - - // Make sure that the fact that the user had a form of payment was recorded. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion")); - } - - /** - * Expect that the UserDidNotHaveInitialFormOfPayment histogram gets logged properly when the - * user has no form of payment on file. - */ - @Test - @MediumTest - @Feature({"Payments"}) - public void testUserHadInitialFormOfPayment_AcceptsCardsAndApps_UserHasNoCardOrPaymentApp() - throws InterruptedException, ExecutionException, TimeoutException { - // Add an address on file. - new AutofillTestHelper().setProfile(new AutofillProfile("", "https://example.com", true, - "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", - "650-253-0000", "", "en-US")); - - mPaymentRequestTestRule.triggerUIAndWait( - "cardsAndBobPayBuy", mPaymentRequestTestRule.getReadyForInput()); - - // The user cancels the Payment Request (trigger the logs). - mPaymentRequestTestRule.clickAndWait( - R.id.close_button, mPaymentRequestTestRule.getDismissed()); - - mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - - // Make sure that the fact that the user had no form of payment was recorded. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion")); - } - - /** - * Expect that the UserDidNotHaveInitialFormOfPayment histogram gets logged properly when the - * user has a payment app but the merchant only accepts credit cards. - */ - @Test - @MediumTest - @Feature({"Payments"}) - public void testUserHadInitialFormOfPayment_AcceptsCards_UserHasOnlyApp() - throws InterruptedException, ExecutionException, TimeoutException { - // Add an address and a payment app on file. - AutofillTestHelper mHelper = new AutofillTestHelper(); - mHelper.setProfile(new AutofillProfile("", "https://example.com", true, "Jon Doe", "Google", - "340 Main St", "CA", "Los Angeles", "", "90291", "", "US", "650-253-0000", "", - "en-US")); - mPaymentRequestTestRule.installPaymentApp(HAVE_INSTRUMENTS, IMMEDIATE_RESPONSE); - - mPaymentRequestTestRule.triggerUIAndWait( - "ccBuy", mPaymentRequestTestRule.getReadyForInput()); - - // The user cancels the Payment Request (trigger the logs). - mPaymentRequestTestRule.clickAndWait( - R.id.close_button, mPaymentRequestTestRule.getDismissed()); - - mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - - // Make sure that the fact that the user had no form of payment was recorded. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion")); - } - - /** - * Expect that the UserDidNotHaveInitialFormOfPayment histogram gets logged properly when the - * user has a payment app but the merchant only accepts credit cards. - */ - @Test - @MediumTest - @Feature({"Payments"}) - public void testUserHadInitialFormOfPayment_AcceptsCards_UserHasOnlyUnsupportedNetwork() - throws InterruptedException, ExecutionException, TimeoutException { - // Add an address and a card from an unsupported network on file. - AutofillTestHelper mHelper = new AutofillTestHelper(); - String mBillingAddressId = mHelper.setProfile(new AutofillProfile("", "https://example.com", - true, "Jon Doe", "Google", "340 Main St", "CA", "Los Angeles", "", "90291", "", - "US", "650-253-0000", "", "en-US")); - mHelper.setCreditCard(new CreditCard("", "https://example.com", true, true, "Jon Doe", - "378282246310005", "1111", "12", "2050", "amex", R.drawable.visa_card, - CardType.UNKNOWN, mBillingAddressId, "" /* serverId */)); - - mPaymentRequestTestRule.triggerUIAndWait( - "ccBuy", mPaymentRequestTestRule.getReadyForInput()); - - // The user cancels the Payment Request (trigger the logs). - mPaymentRequestTestRule.clickAndWait( - R.id.close_button, mPaymentRequestTestRule.getDismissed()); - - mPaymentRequestTestRule.expectResultContains(new String[] {"Request cancelled"}); - - // Make sure that the fact that the user had no form of payment was recorded. - Assert.assertEquals(1, - RecordHistogram.getHistogramValueCountForTesting( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion", - CompletionStatus.USER_ABORTED)); - - // Make sure the opposite metric has no logs. - Assert.assertEquals(0, - RecordHistogram.getHistogramTotalCountForTesting( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion")); - } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestCommon.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestCommon.java index e5e31b5..b08fee77 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestCommon.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestCommon.java
@@ -473,6 +473,23 @@ helper.waitForCallback(callCount); } + protected void clickOnContactInfoSuggestionOptionAndWait( + final int suggestionIndex, CallbackHelper helper) + throws ExecutionException, TimeoutException, InterruptedException { + Assert.assertTrue(suggestionIndex < getNumberOfContactDetailSuggestions()); + + int callCount = helper.getCallCount(); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + ((OptionSection) mUI.getContactDetailsSectionForTest()) + .getOptionLabelsForTest(suggestionIndex) + .performClick(); + } + }); + helper.waitForCallback(callCount); + } + protected void clickOnPaymentMethodSuggestionEditIconAndWait( final int suggestionIndex, CallbackHelper helper) throws ExecutionException, TimeoutException, InterruptedException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java index d3bf11a..b4fb4e04 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java
@@ -216,7 +216,7 @@ return mTestCommon.getContactDetailsButtonState(); } - /** Returns the label corresponding to the payment instrument at the specified |index|. */ + /** Returns the label corresponding to the payment instrument at the specified |index|. */ protected String getPaymentInstrumentLabel(final int index) throws ExecutionException { return mTestCommon.getPaymentInstrumentLabel(index); } @@ -226,33 +226,33 @@ return mTestCommon.getSelectedPaymentInstrumentLabel(); } - /** Returns the total amount in order summary section. */ + /** Returns the total amount in order summary section. */ protected String getOrderSummaryTotal() throws ExecutionException { return mTestCommon.getOrderSummaryTotal(); } /** - * Returns the label corresponding to the contact detail suggestion at the specified - * |suggestionIndex|. + * Returns the label corresponding to the contact detail suggestion at the specified + * |suggestionIndex|. */ protected String getContactDetailsSuggestionLabel(final int suggestionIndex) throws ExecutionException { return mTestCommon.getContactDetailsSuggestionLabel(suggestionIndex); } - /** Returns the number of payment instruments. */ + /** Returns the number of payment instruments. */ protected int getNumberOfPaymentInstruments() throws ExecutionException { return mTestCommon.getNumberOfPaymentInstruments(); } - /** Returns the number of contact detail suggestions. */ + /** Returns the number of contact detail suggestions. */ protected int getNumberOfContactDetailSuggestions() throws ExecutionException { return mTestCommon.getNumberOfContactDetailSuggestions(); } /** - * Returns the label corresponding to the shipping address suggestion at the specified - * |suggestionIndex|. + * Returns the label corresponding to the shipping address suggestion at the specified + * |suggestionIndex|. */ protected String getShippingAddressSuggestionLabel(final int suggestionIndex) throws ExecutionException { @@ -260,21 +260,21 @@ } /** - * Returns the summary text of the shipping address section. + * Returns the summary text of the shipping address section. */ protected String getShippingAddressSummaryLabel() throws ExecutionException { return mTestCommon.getShippingAddressSummary(); } /** - * Returns the summary text of the shipping option section. + * Returns the summary text of the shipping option section. */ protected String getShippingOptionSummaryLabel() throws ExecutionException { return mTestCommon.getShippingOptionSummary(); } /** - * Returns the cost text of the shipping option section on the bottom sheet. + * Returns the cost text of the shipping option section on the bottom sheet. */ protected String getShippingOptionCostSummaryLabelOnBottomSheet() throws ExecutionException { return mTestCommon.getShippingOptionCostSummaryOnBottomSheet(); @@ -286,8 +286,8 @@ } /** - * Clicks on the label corresponding to the shipping address suggestion at the specified - * |suggestionIndex|. + * Clicks on the label corresponding to the shipping address suggestion at the specified + * |suggestionIndex|. * @throws InterruptedException */ protected void clickOnShippingAddressSuggestionOptionAndWait( @@ -297,8 +297,8 @@ } /** - * Clicks on the label corresponding to the payment method suggestion at the specified - * |suggestionIndex|. + * Clicks on the label corresponding to the payment method suggestion at the specified + * |suggestionIndex|. * @throws InterruptedException */ protected void clickOnPaymentMethodSuggestionOptionAndWait( @@ -308,8 +308,19 @@ } /** - * Clicks on the edit icon corresponding to the payment method suggestion at the specified - * |suggestionIndex|. + * Clicks on the label corresponding to the contact info suggestion at the specified + * |suggestionIndex|. + * @throws InterruptedException + */ + protected void clickOnContactInfoSuggestionOptionAndWait( + final int suggestionIndex, CallbackHelper helper) + throws ExecutionException, TimeoutException, InterruptedException { + mTestCommon.clickOnContactInfoSuggestionOptionAndWait(suggestionIndex, helper); + } + + /** + * Clicks on the edit icon corresponding to the payment method suggestion at the specified + * |suggestionIndex|. */ protected void clickOnPaymentMethodSuggestionEditIconAndWait( final int suggestionIndex, CallbackHelper helper) @@ -318,7 +329,7 @@ } /** - * Returns the number of shipping address suggestions. + * Returns the number of shipping address suggestions. */ protected int getNumberOfShippingAddressSuggestions() throws ExecutionException { return mTestCommon.getNumberOfShippingAddressSuggestions(); @@ -407,17 +418,17 @@ mTestCommon.expectResultContains(contents); } - /** Will fail if the OptionRow at |index| is not selected in Contact Details.*/ + /** Will fail if the OptionRow at |index| is not selected in Contact Details.*/ protected void expectContactDetailsRowIsSelected(final int index) { mTestCommon.expectContactDetailsRowIsSelected(index); } - /** Will fail if the OptionRow at |index| is not selected in Shipping Address section.*/ + /** Will fail if the OptionRow at |index| is not selected in Shipping Address section.*/ protected void expectShippingAddressRowIsSelected(final int index) { mTestCommon.expectShippingAddressRowIsSelected(index); } - /** Will fail if the OptionRow at |index| is not selected in PaymentMethod section.*/ + /** Will fail if the OptionRow at |index| is not selected in PaymentMethod section.*/ protected void expectPaymentMethodRowIsSelected(final int index) { mTestCommon.expectPaymentMethodRowIsSelected(index); }
diff --git a/chrome/app/chrome_crash_reporter_client_win.cc b/chrome/app/chrome_crash_reporter_client_win.cc index 857a0c54..7e196905 100644 --- a/chrome/app/chrome_crash_reporter_client_win.cc +++ b/chrome/app/chrome_crash_reporter_client_win.cc
@@ -74,11 +74,6 @@ constexpr size_t kPrinterInfoCount = 4; constexpr char kPrinterInfo[] = "prn-info-%" PRIuS; -// TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. -// TODO(sunnyps): Remove after fixing https://crbug.com/622080 -constexpr char kBeginMainFrameHangCompositorState[] = - "begin-main-frame-hang-compositor-state"; - using namespace crash_keys; int snprintf(char* buffer, @@ -189,10 +184,6 @@ // Temporary for https://crbug.com/685996. {"user-cloud-policy-manager-connect-trace", kMediumSize}, - // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. - // TODO(sunnyps): Remove after fixing https://crbug.com/622080 - {kBeginMainFrameHangCompositorState, kSmallSize}, - // TODO(asvitkine): Remove after fixing https://crbug.com/736675 {"bad_histogram", kMediumSize}, };
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 2af0516..5036d11 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1468,7 +1468,7 @@ Cancelling update... </message> <message name="IDS_REMORA_CONFIRM_MESSAGE" desc="Remora confirm message on the first OOBE screen"> - Chromebox for Meetings device is ready to be set up. + Your Hangouts Meet hardware is ready to be set up. </message> <message name="IDS_WELCOME_SCREEN_GREETING" desc="Greeting message on the OOBE welcome screen"> Welcome! @@ -3647,6 +3647,9 @@ <message name="IDS_RESET_SCREEN_ROLLBACK_OPTION" desc="Checkbox label for rollback option of powerwash process. Is shown on reset screen."> Also return to the previously installed version of <ph name="IDS_SHORT_PRODUCT_NAME">$1<ex>Chrome</ex></ph>. </message> + <message name="IDS_RESET_SCREEN_TPM_FIRMWARE_UPDATE_OPTION" desc="Checkbox label for the TPM firmware update option of the powerwash process, shown on the device reset screen."> + Update firmware for added security. + </message> <message name="IDS_RESET_SCREEN_POWERWASH" desc="Powerwash button text"> Powerwash </message> @@ -5461,7 +5464,7 @@ Offline </message> - <!-- Strings for the "Chromebox for meeting" OOBE UI. --> + <!-- Strings for the "Hangouts Meet" OOBE UI. --> <message name="IDS_ENTERPRISE_DEVICE_REQUISITION_PROMPT_CANCEL" desc="Cancel button text in the device requisition poup."> Cancel </message> @@ -5472,30 +5475,30 @@ Use this device requisition when enrolling the device for enterprise management: </message> <message name="IDS_ENTERPRISE_DEVICE_REQUISITION_REMORA_PROMPT_TEXT" desc="Prompt shown in the device requisition remora prompt popup."> - Are you sure you want to set up this device as a Chromebox for Meetings device? + Are you sure you want to set up this device to run Hangouts Meet? </message> <message name="IDS_ENTERPRISE_DEVICE_REQUISITION_SHARK_PROMPT_TEXT" desc="Prompt shown in the device requisition shark prompt popup."> Are you sure you want to set up this device as a "Shark"? </message> - <message name="IDS_PAIRING_CONTROLLER_WELCOME" desc="Message shown on 'Chromebox for meetings' controller in the beginning of the setup process."> - Welcome to Chromebox for meetings + <message name="IDS_PAIRING_CONTROLLER_WELCOME" desc="Message shown on 'Hangouts Meet' controller in the beginning of the setup process."> + Welcome to Hangouts Meet </message> - <message name="IDS_PAIRING_CONTROLLER_SEARCHING" desc="Message shown on 'Chromebox for meetings' controller when it is searching for host devices."> + <message name="IDS_PAIRING_CONTROLLER_SEARCHING" desc="Message shown on 'Hangouts Meet' controller when it is searching for host devices."> Searching for nearby Chromeboxes... </message> - <message name="IDS_PAIRING_NEED_HELP" desc="Text on the button launching help article about the 'Chromebox for meetings' setup process."> + <message name="IDS_PAIRING_NEED_HELP" desc="Text on the button launching help article about the 'Hangouts Meet' setup process."> Need help? </message> - <message name="IDS_PAIRING_CONTROLLER_TROUBLE_CONNECTING" desc="Title of the the dialog giving an advice on how to improve a connection between a host and a controller during the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_TROUBLE_CONNECTING" desc="Title of the the dialog giving an advice on how to improve a connection between a host and a controller during the 'Hangouts Meet' setup process."> Trouble connecting? </message> - <message name="IDS_PAIRING_CONTROLLER_CONNECTING_ADVICE" desc="Text in the dialog giving an advice on how to improve a connection between a host and a controller during the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_CONNECTING_ADVICE" desc="Text in the dialog giving an advice on how to improve a connection between a host and a controller during the 'Hangouts Meet' setup process."> Please make sure that your Hotrod device is turned on and connected to a TV. </message> - <message name="IDS_PAIRING_CONTROLLER_ADVICE_GOT_IT" desc="Text on the confirmation button of the dialog giving an advice on how to improve a connection between a host and a controller during the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_ADVICE_GOT_IT" desc="Text on the confirmation button of the dialog giving an advice on how to improve a connection between a host and a controller during the 'Hangouts Meet' setup process."> OK, got it </message> - <message name="IDS_PAIRING_CONTROLLER_SELECT_TITLE" desc="Title of the list of nearby 'Chromebox for meeting' devices, that is shown on a controller device during a setup process."> + <message name="IDS_PAIRING_CONTROLLER_SELECT_TITLE" desc="Title of the list of nearby 'Hangouts Meet' devices, that is shown on a controller device during a setup process."> Select a Chromebox to connect to </message> <message name="IDS_PAIRING_CONTROLLER_CONNECT" desc="Text on the button initiating a connection to the choosen device. After a user pressed the button, text changes to 'Connecting...'."> @@ -5504,10 +5507,10 @@ <message name="IDS_PAIRING_CONTROLLER_CONNECTING" desc="Text on the button initiating a connection to the choosen device, after a user pressed it. The initial text is 'Connect'."> Connecting... </message> - <message name="IDS_PAIRING_CONTROLLER_CONFIRMATION_TITLE" desc="Title of the page showing the confirmation code on a controller's screen during the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_CONFIRMATION_TITLE" desc="Title of the page showing the confirmation code on a controller's screen during the 'Hangouts Meet' setup process."> Pair with Chromebox </message> - <message name="IDS_PAIRING_CONTROLLER_CONFIRMATION_QUESTION" desc="Text that is shown near 6-digit confirmation code on a controller's screen during the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_CONFIRMATION_QUESTION" desc="Text that is shown near 6-digit confirmation code on a controller's screen during the 'Hangouts Meet' setup process."> Does this code appear on your Chromebox screen? </message> <message name="IDS_PAIRING_CONTROLLER_REJECT_CODE" desc="Text on a button which the user presses to report that they don't see a confirmation code."> @@ -5516,70 +5519,70 @@ <message name="IDS_PAIRING_CONTROLLER_ACCEPT_CODE" desc="Text on a button which the user presses to report that they see a correct confirmation code."> Yes, I see it </message> - <message name="IDS_PAIRING_CONTROLLER_UPDATE_TITLE" desc="Title of the controller's update page of the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_UPDATE_TITLE" desc="Title of the controller's update page of the 'Hangouts Meet' setup process."> Updating Chromebox </message> - <message name="IDS_PAIRING_CONTROLLER_UPDATE_TEXT" desc="Text on the controller's update page of the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_UPDATE_TEXT" desc="Text on the controller's update page of the 'Hangouts Meet' setup process."> In order to bring you the latest features, your Chromebox needs to update. </message> - <message name="IDS_PAIRING_CONTROLLER_CONNECTION_LOST_TITLE" desc="Title of the controller page which says that connection with host was lost during the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_CONNECTION_LOST_TITLE" desc="Title of the controller page which says that connection with host was lost during the 'Hangouts Meet' setup process."> Connection to Chromebox lost </message> - <message name="IDS_PAIRING_CONTROLLER_CONNECTION_LOST_TEXT" desc="Text on the controller page which says that connection with host was lost during the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_CONNECTION_LOST_TEXT" desc="Text on the controller page which says that connection with host was lost during the 'Hangouts Meet' setup process."> Lost connection to your Chromebox. Please move closer, or check your device while we try to reconnect. </message> <message name="IDS_PAIRING_CONTROLLER_HOST_NETWORK_ERROR_TITLE" desc="Title of the controller page which says that the host device's network is not set up successfully."> Failed to set up your Chromebox's network </message> - <message name="IDS_PAIRING_CONTROLLER_ENROLL_TITLE" desc="Title of the enroll page of the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_ENROLL_TITLE" desc="Title of the enroll page of the 'Hangouts Meet' setup process."> Enroll in your organization </message> - <message name="IDS_PAIRING_CONTROLLER_ENROLL_TEXT_1" desc="First paragraph of text shown on the controller's enroll page of the 'Chromebox for meeting' setup process. Second paragraph is: 'This will only happen once, and your credentials will not be stored.'"> - Chromebox for meetings needs to know what domain it belongs to. This will require you to sign in to your account. + <message name="IDS_PAIRING_CONTROLLER_ENROLL_TEXT_1" desc="First paragraph of text shown on the controller's enroll page of the 'Hangouts Meet' setup process. Second paragraph is: 'This will only happen once, and your credentials will not be stored.'"> + Hangouts Meet needs to know what domain it belongs to. This will require you to sign in to your account. </message> - <message name="IDS_PAIRING_CONTROLLER_ENROLL_TEXT_2" desc="Second paragraph of text shown on the controller's enroll page of the 'Chromebox for meeting' setup process. First paragraph is: 'Chromebox for meetings needs to know what domain it belongs to. This will require you to sign in to your account.'"> + <message name="IDS_PAIRING_CONTROLLER_ENROLL_TEXT_2" desc="Second paragraph of text shown on the controller's enroll page of the 'Hangouts Meet' setup process. First paragraph is: 'Hangouts Meet needs to know what domain it belongs to. This will require you to sign in to your account.'"> This will only happen once, and your credentials will not be stored. </message> - <message name="IDS_PAIRING_CONTROLLER_CONTINUE" desc="Text on buttons leading to the next step of the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_CONTINUE" desc="Text on buttons leading to the next step of the 'Hangouts Meet' setup process."> Continue </message> - <message name="IDS_PAIRING_CONTROLLER_ENROLLMENT_IN_PROGRESS" desc="Message shown on enroll screens of the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_ENROLLMENT_IN_PROGRESS" desc="Message shown on enroll screens of the 'Hangouts Meet' setup process."> Enrolling in <ph name="BEGIN_BOLD"><strong></ph><ph name="DOMAIN_NAME">$1<ex>example.com</ex></ph><ph name="END_BOLD"></strong></ph>... </message> - <message name="IDS_PAIRING_ENROLLMENT_ERROR_TITLE" desc="Title of the page shown when enrollment attempt is failed during the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_ENROLLMENT_ERROR_TITLE" desc="Title of the page shown when enrollment attempt is failed during the 'Hangouts Meet' setup process."> Unable to enroll </message> - <message name="IDS_PAIRING_CONTROLLER_ENROLLMENT_ERROR_HOST_RESTARTS" desc="Text on the controller's page shown when enrollment attempt is failed during the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_CONTROLLER_ENROLLMENT_ERROR_HOST_RESTARTS" desc="Text on the controller's page shown when enrollment attempt is failed during the 'Hangouts Meet' setup process."> Please wait while your Chromebox restarts... </message> - <message name="IDS_PAIRING_CONTROLLER_SUCCESS_TITLE" desc="Title of the final controller's page shown when the 'Chromebox for meeting' setup process is finished."> + <message name="IDS_PAIRING_CONTROLLER_SUCCESS_TITLE" desc="Title of the final controller's page shown when the 'Hangouts Meet' setup process is finished."> Success! </message> - <message name="IDS_PAIRING_CONTROLLER_SUCCESS_TEXT" desc="Text on the final controller's page shown when the 'Chromebox for meeting' setup process is finished."> + <message name="IDS_PAIRING_CONTROLLER_SUCCESS_TEXT" desc="Text on the final controller's page shown when the 'Hangouts Meet' setup process is finished."> <ph name="DEVICE_NAME">$1<ex>Chromebox-01</ex></ph> will now appear in the Admin Console </message> - <message name="IDS_PAIRING_CONTROLLER_CONTINUE_TO_HANGOUTS" desc="Text on the button, shown on the final controller's page, displayed when the 'Chromebox for meeting' setup process is finished."> - Continue to Hangouts + <message name="IDS_PAIRING_CONTROLLER_CONTINUE_TO_HANGOUTS" desc="Text on the button, shown on the final controller's page, displayed when the 'Hangouts Meet' setup process is finished."> + Continue to Hangouts Meet </message> - <message name="IDS_PAIRING_HOST_WELCOME_TITLE" desc="Title of the host's welcome page of the 'Chromebox for meeting' setup process."> - Welcome to Chromebox for meetings! + <message name="IDS_PAIRING_HOST_WELCOME_TITLE" desc="Title of the host's welcome page of the 'Hangouts Meet' setup process."> + Welcome to Hangouts Meet! </message> - <message name="IDS_PAIRING_HOST_WELCOME_TEXT" desc="Text on the host's welcome page of the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_HOST_WELCOME_TEXT" desc="Text on the host's welcome page of the 'Hangouts Meet' setup process."> Turn on your touch controller to set me up </message> - <message name="IDS_PAIRING_HOST_UPDATING_TITLE" desc="Title of the host's update page of the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_HOST_UPDATING_TITLE" desc="Title of the host's update page of the 'Hangouts Meet' setup process."> Updating Chromebox... </message> - <message name="IDS_PAIRING_HOST_UPDATING_TEXT" desc="Update progress shown on the host's update page of the 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_HOST_UPDATING_TEXT" desc="Update progress shown on the host's update page of the 'Hangouts Meet' setup process."> <ph name="DOWNLOADED_AMOUNT_MB">$1<ex>13.7</ex></ph> MB / <ph name="TOTAL_AMOUNT_MB">$2<ex>23</ex></ph> MB downloaded </message> - <message name="IDS_PAIRING_HOST_DONE_TITLE" desc="Title of the final host's page shown when the 'Chromebox for meeting' setup process is finished."> + <message name="IDS_PAIRING_HOST_DONE_TITLE" desc="Title of the final host's page shown when the 'Hangouts Meet' setup process is finished."> Congratulations </message> - <message name="IDS_PAIRING_HOST_DONE_TEXT" desc="Title of the final host's page shown when the 'Chromebox for meeting' setup process is finished."> - You're all set to continue on to Hangouts + <message name="IDS_PAIRING_HOST_DONE_TEXT" desc="Title of the final host's page shown when the 'Hangouts Meet' setup process is finished."> + You're all set to continue on to Hangouts Meet </message> - <message name="IDS_PAIRING_HOST_ERROR_NEED_RESTART_TEXT" desc="Text on the host's error page shown when the bootstrapping attampt or 'Chromebox for meeting' setup process is failed."> + <message name="IDS_PAIRING_HOST_ERROR_NEED_RESTART_TEXT" desc="Text on the host's error page shown when the bootstrapping attampt or 'Hangouts Meet' setup process is failed."> Please restart the device and try again later. </message> @@ -5602,10 +5605,10 @@ <message name="IDS_SLAVE_ENROLLMENT_ERROR_TITLE" desc="Title of the page shown when enrollment attempt is failed during the bootstrapping process."> Unable to enroll </message> - <message name="IDS_PAIRING_HOST_INITIALIZATION_ERROR_TITLE" desc="Title of the host's initialization error page during the bootstrapping process or 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_HOST_INITIALIZATION_ERROR_TITLE" desc="Title of the host's initialization error page during the bootstrapping process or 'Hangouts Meet' setup process."> Could not initialize the connection </message> - <message name="IDS_PAIRING_HOST_CONNECTION_ERROR_TITLE" desc="Title of the host's connection error page during the bootstrapping process or 'Chromebox for meeting' setup process."> + <message name="IDS_PAIRING_HOST_CONNECTION_ERROR_TITLE" desc="Title of the host's connection error page during the bootstrapping process or 'Hangouts Meet' setup process."> Connection was lost </message>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 451f7e2..14cdaba2 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -3874,6 +3874,9 @@ <message name="IDS_EXTENSION_PROMPT_WARNING_DISPLAY_SOURCE" desc="Permission string for access to Display Source API."> Send audio and video to displays on the local network </message> + <message name="IDS_EXTENSION_PROMPT_WARNING_NEW_TAB_PAGE_OVERRIDE" desc="Permission string for extensions that override the new tab page."> + Replace the page you see when opening a new tab + </message> </if> <!-- Extension/App error messages -->
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 352ae62..e997adb 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -907,7 +907,6 @@ "password_manager/password_store_win.cc", "password_manager/password_store_win.h", "payments/ssl_validity_checker.cc", - "payments/ssl_validity_checker.h", "performance_monitor/performance_monitor.cc", "performance_monitor/performance_monitor.h", "performance_monitor/process_metrics_history.cc", @@ -993,7 +992,6 @@ "predictors/loading_predictor.cc", "predictors/loading_predictor.h", "predictors/loading_predictor_android.cc", - "predictors/loading_predictor_android.h", "predictors/loading_predictor_config.cc", "predictors/loading_predictor_config.h", "predictors/loading_predictor_factory.cc", @@ -2591,7 +2589,6 @@ if (is_android) { sources += [ "after_startup_task_utils_android.cc", - "after_startup_task_utils_android.h", "android/accessibility/font_size_prefs_android.cc", "android/accessibility/font_size_prefs_android.h", "android/activity_type_ids.cc", @@ -2938,13 +2935,11 @@ "autofill/android/personal_data_manager_android.cc", "autofill/android/personal_data_manager_android.h", "autofill/android/phone_number_util_android.cc", - "autofill/android/phone_number_util_android.h", "chrome_browser_field_trials_mobile.cc", "chrome_browser_field_trials_mobile.h", "dom_distiller/dom_distiller_service_factory_android.cc", "dom_distiller/dom_distiller_service_factory_android.h", "dom_distiller/tab_utils_android.cc", - "dom_distiller/tab_utils_android.h", "download/download_request_infobar_delegate_android.cc", "download/download_request_infobar_delegate_android.h", "engagement/site_engagement_service_android.cc", @@ -2968,7 +2963,6 @@ "media/android/cdm/media_drm_storage_factory.cc", "media/android/cdm/media_drm_storage_factory.h", "media/android/remote/record_cast_action.cc", - "media/android/remote/record_cast_action.h", "media/android/remote/remote_media_player_bridge.cc", "media/android/remote/remote_media_player_bridge.h", "media/android/remote/remote_media_player_manager.cc", @@ -3015,8 +3009,6 @@ "password_manager/save_password_infobar_delegate_android.h", "password_manager/update_password_infobar_delegate_android.cc", "password_manager/update_password_infobar_delegate_android.h", - "payments/android/chrome_payments_jni_registrar.cc", - "payments/android/chrome_payments_jni_registrar.h", "payments/android/journey_logger_android.cc", "payments/android/journey_logger_android.h", "payments/android/payment_manifest_web_data_service_android.cc", @@ -3049,7 +3041,6 @@ "signin/oauth2_token_service_delegate_android.cc", "signin/oauth2_token_service_delegate_android.h", "ssl/security_state_model_android.cc", - "ssl/security_state_model_android.h", "sync/glue/synced_tab_delegate_android.cc", "sync/glue/synced_tab_delegate_android.h", "sync/glue/synced_window_delegate_android.cc", @@ -3059,7 +3050,6 @@ "sync/profile_sync_service_android.cc", "sync/profile_sync_service_android.h", "sync/sessions/sync_sessions_metrics_android.cc", - "sync/sessions/sync_sessions_metrics_android.h", ] deps += [ ":client_discourse_context_proto",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 6ecd981..b280ee16 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1860,9 +1860,6 @@ flag_descriptions::kSettingsWindowDescription, kOsDesktop, ENABLE_DISABLE_VALUE_TYPE(switches::kEnableSettingsWindow, switches::kDisableSettingsWindow)}, - {"inert-visual-viewport", flag_descriptions::kInertVisualViewportName, - flag_descriptions::kInertVisualViewportDescription, kOsAll, - SINGLE_VALUE_TYPE(switches::kInertVisualViewport)}, {"distance-field-text", flag_descriptions::kDistanceFieldTextName, flag_descriptions::kDistanceFieldTextDescription, kOsAll, ENABLE_DISABLE_VALUE_TYPE(switches::kEnableDistanceFieldText,
diff --git a/chrome/browser/after_startup_task_utils_android.cc b/chrome/browser/after_startup_task_utils_android.cc index a914f36..8f239f9 100644 --- a/chrome/browser/after_startup_task_utils_android.cc +++ b/chrome/browser/after_startup_task_utils_android.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/after_startup_task_utils_android.h" - #include "chrome/browser/after_startup_task_utils.h" #include "jni/AfterStartupTaskUtils_jni.h" @@ -23,7 +21,3 @@ static void SetStartupComplete(JNIEnv* env, const JavaParamRef<jclass>& obj) { android::AfterStartupTaskUtilsJNI::SetBrowserStartupIsComplete(); } - -bool RegisterAfterStartupTaskUtilsJNI(JNIEnv* env) { - return RegisterNativesImpl(env); -}
diff --git a/chrome/browser/after_startup_task_utils_android.h b/chrome/browser/after_startup_task_utils_android.h deleted file mode 100644 index b06033a..0000000 --- a/chrome/browser/after_startup_task_utils_android.h +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_AFTER_STARTUP_TASK_UTILS_ANDROID_H_ -#define CHROME_BROWSER_AFTER_STARTUP_TASK_UTILS_ANDROID_H_ - -#include <jni.h> - -bool RegisterAfterStartupTaskUtilsJNI(JNIEnv* env); - -#endif // CHROME_BROWSER_AFTER_STARTUP_TASK_UTILS_ANDROID_H_
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc index 204a64a..ffdaad52 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.cc +++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -616,11 +616,6 @@ Java_PersonalDataManager_personalDataChanged(env, java_obj); } -// static -bool PersonalDataManagerAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - void PersonalDataManagerAndroid::RecordAndLogProfileUse( JNIEnv* env, const JavaParamRef<jobject>& unused_obj,
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.h b/chrome/browser/autofill/android/personal_data_manager_android.h index f88843a..136d325a 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.h +++ b/chrome/browser/autofill/android/personal_data_manager_android.h
@@ -27,9 +27,6 @@ : public PersonalDataManagerObserver, public base::SupportsWeakPtr<PersonalDataManagerAndroid> { public: - // Registers the JNI bindings for this class. - static bool Register(JNIEnv* env); - PersonalDataManagerAndroid(JNIEnv* env, jobject obj); // Returns true if personal data manager has loaded the initial data.
diff --git a/chrome/browser/autofill/android/phone_number_util_android.cc b/chrome/browser/autofill/android/phone_number_util_android.cc index 29d4f0e..9cca2278 100644 --- a/chrome/browser/autofill/android/phone_number_util_android.cc +++ b/chrome/browser/autofill/android/phone_number_util_android.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/autofill/android/phone_number_util_android.h" - #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "chrome/browser/browser_process.h" @@ -118,8 +116,3 @@ } } // namespace autofill - -// static -bool RegisterPhoneNumberUtil(JNIEnv* env) { - return autofill::RegisterNativesImpl(env); -}
diff --git a/chrome/browser/autofill/android/phone_number_util_android.h b/chrome/browser/autofill/android/phone_number_util_android.h deleted file mode 100644 index 17c85c6..0000000 --- a/chrome/browser/autofill/android/phone_number_util_android.h +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_AUTOFILL_ANDROID_PHONE_NUMBER_UTIL_ANDROID_H_ -#define CHROME_BROWSER_AUTOFILL_ANDROID_PHONE_NUMBER_UTIL_ANDROID_H_ - -#include <jni.h> - -bool RegisterPhoneNumberUtil(JNIEnv* env); - -#endif // CHROME_BROWSER_AUTOFILL_ANDROID_PHONE_NUMBER_UTIL_ANDROID_H_
diff --git a/chrome/browser/browsing_data/autofill_counter_browsertest.cc b/chrome/browser/browsing_data/autofill_counter_browsertest.cc index 9b2abb3..db5cf374 100644 --- a/chrome/browser/browsing_data/autofill_counter_browsertest.cc +++ b/chrome/browser/browsing_data/autofill_counter_browsertest.cc
@@ -18,6 +18,7 @@ #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/credit_card.h" +#include "components/autofill/core/browser/test_autofill_clock.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/browsing_data/core/browsing_data_utils.h" #include "components/browsing_data/core/pref_names.h" @@ -180,10 +181,10 @@ num_suggestions_ = autofill_result->Value(); num_credit_cards_ = autofill_result->num_credit_cards(); num_addresses_ = autofill_result->num_addresses(); - } - if (run_loop_ && finished_) - run_loop_->Quit(); + if (run_loop_) + run_loop_->Quit(); + } } private: @@ -343,29 +344,23 @@ // Tests that the counting respects time ranges. IN_PROC_BROWSER_TEST_F(AutofillCounterTest, TimeRanges) { - // This test makes time comparisons that are precise to a microsecond, but the - // database uses the time_t format which is only precise to a second. - // Make sure we use timestamps rounded to a second. - base::Time time1 = base::Time::FromTimeT(base::Time::Now().ToTimeT()); - + autofill::TestAutofillClock test_clock; + const base::Time kTime1 = base::Time::FromDoubleT(25); + test_clock.SetNow(kTime1); AddAutocompleteSuggestion("email", "example@example.com"); AddCreditCard("0000-0000-0000-0000", "1", "2015", "1"); AddAddress("John", "Doe", "Main Street 12345"); WaitForDBThread(); - // Skip at least a second has passed and add another batch. - base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); - base::Time time2 = base::Time::FromTimeT(base::Time::Now().ToTimeT()); - + const base::Time kTime2 = kTime1 + base::TimeDelta::FromSeconds(10); + test_clock.SetNow(kTime2); AddCreditCard("0123-4567-8910-1112", "10", "2015", "1"); AddAddress("Jane", "Smith", "Main Street 12346"); AddAddress("John", "Smith", "Side Street 47"); WaitForDBThread(); - // Skip at least a second has passed and add another batch. - base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); - base::Time time3 = base::Time::FromTimeT(base::Time::Now().ToTimeT()); - + const base::Time kTime3 = kTime2 + base::TimeDelta::FromSeconds(10); + test_clock.SetNow(kTime3); AddAutocompleteSuggestion("tel", "+987654321"); AddCreditCard("1211-1098-7654-3210", "10", "2030", "1"); WaitForDBThread(); @@ -378,12 +373,10 @@ const browsing_data::BrowsingDataCounter::ResultInt expected_num_credit_cards; const browsing_data::BrowsingDataCounter::ResultInt expected_num_addresses; - } test_cases[] = { - { base::Time(), 2, 3, 3}, - { time1, 2, 3, 3}, - { time2, 1, 2, 2}, - { time3, 1, 1, 0} - }; + } test_cases[] = {{base::Time(), 2, 3, 3}, + {kTime1, 2, 3, 3}, + {kTime2, 1, 2, 2}, + {kTime3, 1, 1, 0}}; Profile* profile = browser()->profile(); browsing_data::AutofillCounter counter(GetWebDataService(), nullptr);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 2a6c4cb..5453757 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2935,11 +2935,9 @@ if (!frame_interfaces_.get() && !frame_interfaces_parameterized_.get()) InitFrameInterfaces(); - if (frame_interfaces_parameterized_->CanBindInterface(interface_name)) { - frame_interfaces_parameterized_->BindInterface( - interface_name, std::move(interface_pipe), render_frame_host); - } else if (frame_interfaces_->CanBindInterface(interface_name)) { - frame_interfaces_->BindInterface(interface_name, std::move(interface_pipe)); + if (!frame_interfaces_parameterized_->TryBindInterface( + interface_name, &interface_pipe, render_frame_host)) { + frame_interfaces_->TryBindInterface(interface_name, &interface_pipe); } } @@ -2963,11 +2961,8 @@ const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe) { - if (source_info.identity.name() == content::mojom::kGpuServiceName && - gpu_binder_registry_.CanBindInterface(interface_name)) { - gpu_binder_registry_.BindInterface(interface_name, - std::move(*interface_pipe)); - } + if (source_info.identity.name() == content::mojom::kGpuServiceName) + gpu_binder_registry_.TryBindInterface(interface_name, interface_pipe); } void ChromeContentBrowserClient::RegisterInProcessServices(
diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc index 0e46ddf8..eefe7c92 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc +++ b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
@@ -295,8 +295,9 @@ // attribute prompt screen. Verifies the attribute prompt screen is displayed. // Verifies that the data the user enters into the attribute prompt screen is // received by the enrollment helper. +// Crashes on ChromeOS: http://crbug.com/746723. IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentTest, - TestAttributePromptPageGetsLoaded) { + DISABLED_TestAttributePromptPageGetsLoaded) { ShowEnrollmentScreen(); ExpectAttributePromptUpdate(); SubmitEnrollmentCredentials(); @@ -347,8 +348,9 @@ // Directory domain join screen. Verifies the domain join screen is displayed. // Submits Active Directory different incorrect credentials. Verifies that the // correct error is displayed. +// Crashes on ChromeOS: http://crbug.com/746723. IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentTest, - TestActiveDirectoryEnrollment_UIErrors) { + DISABLED_TestActiveDirectoryEnrollment_UIErrors) { ShowEnrollmentScreen(); SetupActiveDirectoryJoin(); SubmitEnrollmentCredentials();
diff --git a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc index d733496..dec93df 100644 --- a/chrome/browser/devtools/device/usb/android_usb_browsertest.cc +++ b/chrome/browser/devtools/device/usb/android_usb_browsertest.cc
@@ -138,7 +138,10 @@ return device_; } - void Close() override { device_ = nullptr; } + void Close() override { + device_->set_open(false); + device_ = nullptr; + } void SetConfiguration(int configuration_value, const ResultCallback& callback) override { @@ -422,12 +425,21 @@ } void Open(const OpenCallback& callback) override { + // While most operating systems allow multiple applications to open a + // device simultaneously so that they may claim separate interfaces DevTools + // will always be trying to claim the same interface and so multiple + // connections are more likely to cause problems. https://crbug.com/725320 + EXPECT_FALSE(open_); + open_ = true; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(callback, make_scoped_refptr(new MockUsbDeviceHandle<T>(this)))); } + void set_open(bool open) { open_ = open; } + + bool open_ = false; std::set<int> claimed_interfaces_; protected:
diff --git a/chrome/browser/devtools/device/usb/android_usb_device.cc b/chrome/browser/devtools/device/usb/android_usb_device.cc index 841daf1f..c8acbd1 100644 --- a/chrome/browser/devtools/device/usb/android_usb_device.cc +++ b/chrome/browser/devtools/device/usb/android_usb_device.cc
@@ -64,6 +64,11 @@ base::LazyInstance<std::vector<AndroidUsbDevice*>>::Leaky g_devices = LAZY_INSTANCE_INITIALIZER; +// Stores the GUIDs of devices that are currently opened so that they are not +// re-probed. +base::LazyInstance<std::vector<std::string>>::Leaky g_open_devices = + LAZY_INSTANCE_INITIALIZER; + bool IsAndroidInterface(const UsbInterfaceDescriptor& interface) { if (interface.alternate_setting != 0 || interface.interface_class != kAdbClass || @@ -133,6 +138,7 @@ void CloseDevice(scoped_refptr<UsbDeviceHandle> usb_device, bool release_successful) { + base::Erase(g_open_devices.Get(), usb_device->GetDevice()->guid()); usb_device->Close(); } @@ -187,6 +193,7 @@ } void OnDeviceOpened(AndroidUsbDevices* devices, + const std::string& device_guid, crypto::RSAPrivateKey* rsa_key, int inbound_address, int outbound_address, @@ -195,6 +202,7 @@ const base::Closure& barrier, scoped_refptr<UsbDeviceHandle> usb_handle) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (usb_handle.get()) { usb_handle->ClaimInterface( interface_number, @@ -202,6 +210,7 @@ usb_handle, inbound_address, outbound_address, zero_mask, interface_number, barrier)); } else { + base::Erase(g_open_devices.Get(), device_guid); barrier.Run(); } } @@ -243,8 +252,15 @@ return; } - device->Open(base::Bind(&OnDeviceOpened, devices, rsa_key, inbound_address, - outbound_address, zero_mask, + if (base::ContainsValue(g_open_devices.Get(), device->guid())) { + // |device| is already open, do not make parallel attempts to connect to it. + barrier.Run(); + return; + } + + g_open_devices.Get().push_back(device->guid()); + device->Open(base::Bind(&OnDeviceOpened, devices, device->guid(), rsa_key, + inbound_address, outbound_address, zero_mask, interface.interface_number, barrier)); } @@ -459,9 +475,8 @@ void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status, scoped_refptr<net::IOBuffer> buffer, size_t result) { - if (status != UsbTransferStatus::COMPLETED) { + if (status != UsbTransferStatus::COMPLETED) return; - } task_runner_->PostTask( FROM_HERE, base::BindOnce(&AndroidUsbDevice::ProcessOutgoing, this));
diff --git a/chrome/browser/dom_distiller/dom_distiller_service_factory_android.cc b/chrome/browser/dom_distiller/dom_distiller_service_factory_android.cc index b2ea21f40..e036237a 100644 --- a/chrome/browser/dom_distiller/dom_distiller_service_factory_android.cc +++ b/chrome/browser/dom_distiller/dom_distiller_service_factory_android.cc
@@ -29,10 +29,6 @@ return ScopedJavaLocalRef<jobject>(service_android->java_ref_); } -bool DomDistillerServiceFactoryAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - ScopedJavaLocalRef<jobject> GetForProfile( JNIEnv* env, const JavaParamRef<jclass>& clazz,
diff --git a/chrome/browser/dom_distiller/dom_distiller_service_factory_android.h b/chrome/browser/dom_distiller/dom_distiller_service_factory_android.h index 86f0356..8f4ed08 100644 --- a/chrome/browser/dom_distiller/dom_distiller_service_factory_android.h +++ b/chrome/browser/dom_distiller/dom_distiller_service_factory_android.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_DOM_DISTILLER_DOM_DISTILLER_SERVICE_FACTORY_ANDROID_H_ #define CHROME_BROWSER_DOM_DISTILLER_DOM_DISTILLER_SERVICE_FACTORY_ANDROID_H_ -#include <jni.h> #include "base/android/scoped_java_ref.h" namespace dom_distiller { @@ -17,8 +16,6 @@ public: static base::android::ScopedJavaLocalRef<jobject> GetForProfile(JNIEnv* env, jclass clazz, jobject j_profile); - - static bool Register(JNIEnv* env); }; } // namespace android
diff --git a/chrome/browser/dom_distiller/tab_utils_android.cc b/chrome/browser/dom_distiller/tab_utils_android.cc index df6a1ff..4f75a9d 100644 --- a/chrome/browser/dom_distiller/tab_utils_android.cc +++ b/chrome/browser/dom_distiller/tab_utils_android.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/dom_distiller/tab_utils_android.h" - #include <string> #include "base/android/jni_string.h" @@ -76,7 +74,3 @@ } } // namespace android - -bool RegisterDomDistillerTabUtils(JNIEnv* env) { - return android::RegisterNativesImpl(env); -}
diff --git a/chrome/browser/dom_distiller/tab_utils_android.h b/chrome/browser/dom_distiller/tab_utils_android.h deleted file mode 100644 index cdd98eb..0000000 --- a/chrome/browser/dom_distiller/tab_utils_android.h +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_DOM_DISTILLER_TAB_UTILS_ANDROID_H_ -#define CHROME_BROWSER_DOM_DISTILLER_TAB_UTILS_ANDROID_H_ - -#include <jni.h> - -// Register JNI methods. -bool RegisterDomDistillerTabUtils(JNIEnv* env); - -#endif // CHROME_BROWSER_DOM_DISTILLER_TAB_UTILS_ANDROID_H_
diff --git a/chrome/browser/engagement/site_engagement_service_android.cc b/chrome/browser/engagement/site_engagement_service_android.cc index 02ead89..3a70b48 100644 --- a/chrome/browser/engagement/site_engagement_service_android.cc +++ b/chrome/browser/engagement/site_engagement_service_android.cc
@@ -15,11 +15,6 @@ using base::android::JavaParamRef; // static -bool SiteEngagementServiceAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -// static const base::android::ScopedJavaGlobalRef<jobject>& SiteEngagementServiceAndroid::GetOrCreate(JNIEnv* env, SiteEngagementService* service) {
diff --git a/chrome/browser/engagement/site_engagement_service_android.h b/chrome/browser/engagement/site_engagement_service_android.h index d3a7186..77ac067 100644 --- a/chrome/browser/engagement/site_engagement_service_android.h +++ b/chrome/browser/engagement/site_engagement_service_android.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_ANDROID_H_ #define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_ANDROID_H_ -#include <jni.h> - #include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "chrome/browser/engagement/site_engagement_service.h" @@ -20,8 +18,6 @@ // This class may only be used on the UI thread. class SiteEngagementServiceAndroid { public: - static bool Register(JNIEnv* env); - // Returns the Java-side SiteEngagementService object corresponding to // |service|. static const base::android::ScopedJavaGlobalRef<jobject>& GetOrCreate(
diff --git a/chrome/browser/extensions/api/messaging/extension_message_port.cc b/chrome/browser/extensions/api/messaging/extension_message_port.cc index a53fc70..7252e2f 100644 --- a/chrome/browser/extensions/api/messaging/extension_message_port.cc +++ b/chrome/browser/extensions/api/messaging/extension_message_port.cc
@@ -6,7 +6,6 @@ #include "base/memory/ptr_util.h" #include "base/scoped_observer.h" -#include "chrome/browser/profiles/profile.h" #include "content/public/browser/interstitial_page.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h"
diff --git a/chrome/browser/extensions/api/messaging/message_property_provider.cc b/chrome/browser/extensions/api/messaging/message_property_provider.cc index abf18ab..a98f99c 100644 --- a/chrome/browser/extensions/api/messaging/message_property_provider.cc +++ b/chrome/browser/extensions/api/messaging/message_property_provider.cc
@@ -11,8 +11,9 @@ #include "base/strings/string_piece.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" -#include "chrome/browser/profiles/profile.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" #include "crypto/ec_private_key.h" #include "extensions/common/api/runtime.h" #include "net/base/completion_callback.h" @@ -27,16 +28,20 @@ MessagePropertyProvider::MessagePropertyProvider() {} -void MessagePropertyProvider::GetChannelID(Profile* profile, - const GURL& source_url, const ChannelIDCallback& reply) { +void MessagePropertyProvider::GetChannelID( + content::BrowserContext* browser_context, + const GURL& source_url, + const ChannelIDCallback& reply) { if (!source_url.is_valid()) { // This isn't a real URL, so there's no sense in looking for a channel ID // for it. Dispatch with an empty tls channel ID. reply.Run(std::string()); return; } + scoped_refptr<net::URLRequestContextGetter> request_context_getter( - profile->GetRequestContext()); + content::BrowserContext::GetDefaultStoragePartition(browser_context) + ->GetURLRequestContext()); content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, base::BindOnce(&MessagePropertyProvider::GetChannelIDOnIOThread,
diff --git a/chrome/browser/extensions/api/messaging/message_property_provider.h b/chrome/browser/extensions/api/messaging/message_property_provider.h index 06a91b1..576b172 100644 --- a/chrome/browser/extensions/api/messaging/message_property_provider.h +++ b/chrome/browser/extensions/api/messaging/message_property_provider.h
@@ -11,12 +11,15 @@ #include "base/macros.h" class GURL; -class Profile; namespace base { class TaskRunner; } +namespace content { +class BrowserContext; +} + namespace net { class URLRequestContextGetter; } @@ -33,7 +36,7 @@ // Gets the DER-encoded public key of the domain-bound cert, // aka TLS channel ID, for the given URL. // Runs |reply| on the current message loop. - void GetChannelID(Profile* profile, + void GetChannelID(content::BrowserContext* browser_context, const GURL& source_url, const ChannelIDCallback& reply);
diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc index 801f3b6..9be1a4a32 100644 --- a/chrome/browser/extensions/api/messaging/message_service.cc +++ b/chrome/browser/extensions/api/messaging/message_service.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/tab_contents/tab_util.h" #include "components/guest_view/common/guest_view_constants.h" #include "components/prefs/pref_service.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -469,14 +470,14 @@ content::RenderFrameHost::FromID(source_process_id, source_routing_id); if (!source) return; - Profile* profile = - Profile::FromBrowserContext(source->GetProcess()->GetBrowserContext()); + content::BrowserContext* browser_context = + source->GetProcess()->GetBrowserContext(); WebContents* contents = NULL; std::unique_ptr<MessagePort> receiver; PortId receiver_port_id(source_port_id.context_id, source_port_id.port_number, false); - if (!ExtensionTabUtil::GetTabById(tab_id, profile, true, NULL, NULL, + if (!ExtensionTabUtil::GetTabById(tab_id, browser_context, true, NULL, NULL, &contents, NULL) || contents->GetController().NeedsReload()) { // The tab isn't loaded yet. Don't attempt to connect. @@ -505,8 +506,9 @@ if (!extension_id.empty()) { // Source extension == target extension so the extension must exist, or // where did the IPC come from? - extension = ExtensionRegistry::Get(profile)->enabled_extensions().GetByID( - extension_id); + extension = ExtensionRegistry::Get(browser_context) + ->enabled_extensions() + .GetByID(extension_id); DCHECK(extension); } @@ -882,7 +884,7 @@ // Capture this reference before params is invalidated by base::Passed(). const GURL& source_url = params->source_url; property_provider_.GetChannelID( - Profile::FromBrowserContext(context), source_url, + context, source_url, base::Bind(&MessageService::GotChannelID, weak_factory_.GetWeakPtr(), base::Passed(¶ms))); return;
diff --git a/chrome/browser/extensions/extension_loading_browsertest.cc b/chrome/browser/extensions/extension_loading_browsertest.cc index 095be6cd6..12c2c1b 100644 --- a/chrome/browser/extensions/extension_loading_browsertest.cc +++ b/chrome/browser/extensions/extension_loading_browsertest.cc
@@ -21,6 +21,7 @@ #include "content/public/test/browser_test_utils.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/process_manager.h" +#include "extensions/common/permissions/permissions_data.h" #include "extensions/test/extension_test_message_listener.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gmock/include/gmock/gmock.h" @@ -43,7 +44,7 @@ ASSERT_TRUE(embedded_test_server()->Start()); TestExtensionDir extension_dir; - const char manifest_template[] = + const char kManifestTemplate[] = "{" " 'name': 'Overrides New Tab'," " 'version': '%d'," @@ -58,7 +59,7 @@ " }" "}"; extension_dir.WriteManifestWithSingleQuotes( - base::StringPrintf(manifest_template, 1)); + base::StringPrintf(kManifestTemplate, 1)); extension_dir.WriteFile(FILE_PATH_LITERAL("event.js"), ""); extension_dir.WriteFile(FILE_PATH_LITERAL("newtab.html"), "<h1>Overridden New Tab Page</h1>"); @@ -81,7 +82,7 @@ // Increase the extension's version. extension_dir.WriteManifestWithSingleQuotes( - base::StringPrintf(manifest_template, 2)); + base::StringPrintf(kManifestTemplate, 2)); // Upgrade the extension. new_tab_extension = UpdateExtension( @@ -101,6 +102,67 @@ EXPECT_TRUE(registry->enabled_extensions().Contains(new_tab_extension->id())); } +IN_PROC_BROWSER_TEST_F(ExtensionLoadingTest, + UpgradeAddingNewTabPagePermissionNoPrompt) { + embedded_test_server()->ServeFilesFromDirectory( + base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); + ASSERT_TRUE(embedded_test_server()->Start()); + + TestExtensionDir extension_dir; + const char kManifestTemplate[] = + "{" + " 'name': 'Overrides New Tab'," + " 'version': '%d'," + " 'description': 'Will override New Tab soon'," + " %s" // Placeholder for future NTP url override block. + " 'manifest_version': 2" + "}"; + extension_dir.WriteManifestWithSingleQuotes( + base::StringPrintf(kManifestTemplate, 1, "")); + extension_dir.WriteFile(FILE_PATH_LITERAL("event.js"), ""); + extension_dir.WriteFile(FILE_PATH_LITERAL("newtab.html"), + "<h1>Overridden New Tab Page</h1>"); + + const Extension* new_tab_extension = + InstallExtension(extension_dir.Pack(), 1 /*new install*/); + ASSERT_TRUE(new_tab_extension); + + EXPECT_FALSE(new_tab_extension->permissions_data()->HasAPIPermission( + APIPermission::kNewTabPageOverride)); + + // Navigate that tab to a non-extension URL to swap out the extension's + // renderer. + const GURL test_link_from_ntp = + embedded_test_server()->GetURL("/README.chromium"); + EXPECT_THAT(test_link_from_ntp.spec(), testing::EndsWith("/README.chromium")) + << "Check that the test server started."; + NavigateInRenderer(browser()->tab_strip_model()->GetActiveWebContents(), + test_link_from_ntp); + + // Increase the extension's version and add the NTP url override which will + // add the kNewTabPageOverride permission. + const char ntp_override_string[] = + " 'chrome_url_overrides': {" + " 'newtab': 'newtab.html'" + " },"; + extension_dir.WriteManifestWithSingleQuotes( + base::StringPrintf(kManifestTemplate, 2, ntp_override_string)); + + // Upgrade the extension, ensure that the upgrade 'worked' in the sense that + // the extension is still present and not disabled and that it now has the + // new API permission. + // TODO(robertshield): Update this once most of the population is on M62+ + // and adding NTP permissions implies a permission upgrade. + new_tab_extension = UpdateExtension( + new_tab_extension->id(), extension_dir.Pack(), 0 /*expected upgrade*/); + ASSERT_NE(nullptr, new_tab_extension); + + EXPECT_TRUE(new_tab_extension->permissions_data()->HasAPIPermission( + APIPermission::kNewTabPageOverride)); + EXPECT_THAT(new_tab_extension->version()->components(), + testing::ElementsAre(2)); +} + // Tests the behavior described in http://crbug.com/532088. IN_PROC_BROWSER_TEST_F(ExtensionLoadingTest, KeepAliveWithDevToolsOpenOnReload) {
diff --git a/chrome/browser/extensions/permission_message_combinations_unittest.cc b/chrome/browser/extensions/permission_message_combinations_unittest.cc index 0adaffc..f2f3d009 100644 --- a/chrome/browser/extensions/permission_message_combinations_unittest.cc +++ b/chrome/browser/extensions/permission_message_combinations_unittest.cc
@@ -1187,6 +1187,19 @@ CheckManifestProducesPermissions("Modify data you copy and paste")); } +TEST_F(PermissionMessageCombinationsUnittest, NewTabPagePermissionMessages) { + const char kManifest[] = + "{" + " 'chrome_url_overrides': {" + " 'newtab': 'newtab.html'" + " }" + "}"; + + CreateAndInstall(kManifest); + ASSERT_TRUE(CheckManifestProducesPermissions( + "Replace the page you see when opening a new tab")); +} + // TODO(sashab): Add a test that checks that messages are generated correctly // for withheld permissions, when an app is granted the 'all sites' permission.
diff --git a/chrome/browser/history/android/sqlite_cursor.cc b/chrome/browser/history/android/sqlite_cursor.cc index 8bf9cc0..abcb6ac9 100644 --- a/chrome/browser/history/android/sqlite_cursor.cc +++ b/chrome/browser/history/android/sqlite_cursor.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/history/android/sqlite_cursor.h" -#include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/bind.h" @@ -57,10 +56,6 @@ return Java_SQLiteCursor_create(env, reinterpret_cast<intptr_t>(cursor)); } -bool SQLiteCursor::RegisterSqliteCursor(JNIEnv* env) { - return RegisterNativesImpl(env); -} - jint SQLiteCursor::GetCount(JNIEnv* env, const JavaParamRef<jobject>& obj) { // Moves to maxium possible position so we will reach the last row, then finds // out the total number of rows.
diff --git a/chrome/browser/history/android/sqlite_cursor.h b/chrome/browser/history/android/sqlite_cursor.h index bdc60926..946db7e 100644 --- a/chrome/browser/history/android/sqlite_cursor.h +++ b/chrome/browser/history/android/sqlite_cursor.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_ #define CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_ -#include <jni.h> - #include <memory> #include <vector> @@ -76,8 +74,6 @@ history::AndroidStatement* statement, AndroidHistoryProviderService* service); - static bool RegisterSqliteCursor(JNIEnv* env); - // JNI methods ----------------------------------------------------------- // Returns the result row count.
diff --git a/chrome/browser/invalidation/invalidation_service_factory_android.cc b/chrome/browser/invalidation/invalidation_service_factory_android.cc index da5e0d6..7baf090 100644 --- a/chrome/browser/invalidation/invalidation_service_factory_android.cc +++ b/chrome/browser/invalidation/invalidation_service_factory_android.cc
@@ -47,8 +47,4 @@ return InvalidationServiceFactoryAndroid::GetForTest(); } -bool InvalidationServiceFactoryAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - } // namespace invalidation
diff --git a/chrome/browser/invalidation/invalidation_service_factory_android.h b/chrome/browser/invalidation/invalidation_service_factory_android.h index da375a54..c2f2fbe 100644 --- a/chrome/browser/invalidation/invalidation_service_factory_android.h +++ b/chrome/browser/invalidation/invalidation_service_factory_android.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_INVALIDATION_INVALIDATION_SERVICE_FACTORY_ANDROID_H_ #define CHROME_BROWSER_INVALIDATION_INVALIDATION_SERVICE_FACTORY_ANDROID_H_ -#include <jni.h> #include "base/android/scoped_java_ref.h" namespace invalidation { @@ -18,8 +17,6 @@ const base::android::JavaRef<jobject>& j_profile); static base::android::ScopedJavaLocalRef<jobject> GetForTest(); - - static bool Register(JNIEnv* env); }; } // namespace invalidation
diff --git a/chrome/browser/media/android/cdm/media_drm_credential_manager.cc b/chrome/browser/media/android/cdm/media_drm_credential_manager.cc index b5c369c1..070fef28 100644 --- a/chrome/browser/media/android/cdm/media_drm_credential_manager.cc +++ b/chrome/browser/media/android/cdm/media_drm_credential_manager.cc
@@ -110,8 +110,3 @@ media_drm_bridge_->ResetDeviceCredentials(reset_credentials_cb); } - -// static -bool MediaDrmCredentialManager::RegisterMediaDrmCredentialManager(JNIEnv* env) { - return RegisterNativesImpl(env); -}
diff --git a/chrome/browser/media/android/cdm/media_drm_credential_manager.h b/chrome/browser/media/android/cdm/media_drm_credential_manager.h index 1283556..2c1b5c5 100644 --- a/chrome/browser/media/android/cdm/media_drm_credential_manager.h +++ b/chrome/browser/media/android/cdm/media_drm_credential_manager.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_MEDIA_ANDROID_CDM_MEDIA_DRM_CREDENTIAL_MANAGER_H_ #define CHROME_BROWSER_MEDIA_ANDROID_CDM_MEDIA_DRM_CREDENTIAL_MANAGER_H_ -#include <jni.h> #include <string> #include "base/callback.h" @@ -39,8 +38,6 @@ // |reset_credentials_cb|. void ResetCredentials(const ResetCredentialsCB& reset_credentials_cb); - static bool RegisterMediaDrmCredentialManager(JNIEnv* env); - private: friend struct base::DefaultSingletonTraits<MediaDrmCredentialManager>; typedef media::MediaDrmBridge::SecurityLevel SecurityLevel;
diff --git a/chrome/browser/media/android/remote/record_cast_action.cc b/chrome/browser/media/android/remote/record_cast_action.cc index b25a5e47..3d05a15e 100644 --- a/chrome/browser/media/android/remote/record_cast_action.cc +++ b/chrome/browser/media/android/remote/record_cast_action.cc
@@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/media/android/remote/record_cast_action.h" - -#include <jni.h> - #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "jni/RecordCastAction_jni.h" @@ -102,9 +98,4 @@ percent_remaining, 101); } -// Register native methods -bool RegisterRecordCastAction(JNIEnv* env) { - return RegisterNativesImpl(env); -} - } // namespace remote_media
diff --git a/chrome/browser/media/android/remote/record_cast_action.h b/chrome/browser/media/android/remote/record_cast_action.h deleted file mode 100644 index 1f52d9c..0000000 --- a/chrome/browser/media/android/remote/record_cast_action.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_MEDIA_ANDROID_REMOTE_RECORD_CAST_ACTION_H_ -#define CHROME_BROWSER_MEDIA_ANDROID_REMOTE_RECORD_CAST_ACTION_H_ - -#include <jni.h> - -namespace remote_media { - -// Registers the native methods through jni -bool RegisterRecordCastAction(JNIEnv* env); - -} // namespace remote_media - -#endif // CHROME_BROWSER_MEDIA_ANDROID_REMOTE_RECORD_CAST_ACTION_H_
diff --git a/chrome/browser/media/android/remote/remote_media_player_bridge.cc b/chrome/browser/media/android/remote/remote_media_player_bridge.cc index 6c3e609..2b151b5e 100644 --- a/chrome/browser/media/android/remote/remote_media_player_bridge.cc +++ b/chrome/browser/media/android/remote/remote_media_player_bridge.cc
@@ -8,7 +8,6 @@ #include "base/android/jni_android.h" #include "base/android/jni_string.h" -#include "chrome/browser/media/android/remote/record_cast_action.h" #include "chrome/browser/media/android/remote/remote_media_player_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" @@ -259,12 +258,6 @@ static_cast<blink::WebRemotePlaybackAvailability>(availability)); } -// static -bool RemoteMediaPlayerBridge::RegisterRemoteMediaPlayerBridge(JNIEnv* env) { - bool ret = RegisterNativesImpl(env); - return ret; -} - void RemoteMediaPlayerBridge::RequestRemotePlayback() { DCHECK_CURRENTLY_ON(BrowserThread::UI); MediaPlayerAndroid* local_player = GetLocalPlayer();
diff --git a/chrome/browser/media/android/remote/remote_media_player_bridge.h b/chrome/browser/media/android/remote/remote_media_player_bridge.h index 5840e34..a30e59a 100644 --- a/chrome/browser/media/android/remote/remote_media_player_bridge.h +++ b/chrome/browser/media/android/remote/remote_media_player_bridge.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_MEDIA_ANDROID_REMOTE_REMOTE_MEDIA_PLAYER_BRIDGE_H_ #define CHROME_BROWSER_MEDIA_ANDROID_REMOTE_REMOTE_MEDIA_PLAYER_BRIDGE_H_ -#include <jni.h> #include <vector> #include "base/macros.h" @@ -29,8 +28,6 @@ RemoteMediaPlayerManager* manager); ~RemoteMediaPlayerBridge() override; - static bool RegisterRemoteMediaPlayerBridge(JNIEnv* env); - // Initialize this object. virtual void Initialize();
diff --git a/chrome/browser/media/android/router/media_router_android_bridge.cc b/chrome/browser/media/android/router/media_router_android_bridge.cc index 4c57cde..0f4416a 100644 --- a/chrome/browser/media/android/router/media_router_android_bridge.cc +++ b/chrome/browser/media/android/router/media_router_android_bridge.cc
@@ -26,12 +26,6 @@ MediaRouterAndroidBridge::~MediaRouterAndroidBridge() = default; -// static -bool MediaRouterAndroidBridge::Register(JNIEnv* env) { - bool ret = RegisterNativesImpl(env); - return ret; -} - void MediaRouterAndroidBridge::CreateRoute(const MediaSource::Id& source_id, const MediaSink::Id& sink_id, const std::string& presentation_id,
diff --git a/chrome/browser/media/android/router/media_router_android_bridge.h b/chrome/browser/media/android/router/media_router_android_bridge.h index cab095e0..eb76fe0 100644 --- a/chrome/browser/media/android/router/media_router_android_bridge.h +++ b/chrome/browser/media/android/router/media_router_android_bridge.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_MEDIA_ANDROID_ROUTER_MEDIA_ROUTER_ANDROID_BRIDGE_H_ #define CHROME_BROWSER_MEDIA_ANDROID_ROUTER_MEDIA_ROUTER_ANDROID_BRIDGE_H_ -#include <jni.h> - #include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "chrome/common/media_router/media_route.h" @@ -24,8 +22,6 @@ explicit MediaRouterAndroidBridge(MediaRouterAndroid* router); ~MediaRouterAndroidBridge(); - static bool Register(JNIEnv* env); - // Implement the corresponding calls for the MediaRouterAndroid class. // Virtual so could be overridden by tests. virtual void CreateRoute(const MediaSource::Id& source_id,
diff --git a/chrome/browser/media/android/router/media_router_dialog_controller_android.cc b/chrome/browser/media/android/router/media_router_dialog_controller_android.cc index 59db7ee..108dd48 100644 --- a/chrome/browser/media/android/router/media_router_dialog_controller_android.cc +++ b/chrome/browser/media/android/router/media_router_dialog_controller_android.cc
@@ -136,11 +136,6 @@ env, reinterpret_cast<jlong>(this))); } -// static -bool MediaRouterDialogControllerAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - MediaRouterDialogControllerAndroid::~MediaRouterDialogControllerAndroid() { }
diff --git a/chrome/browser/media/android/router/media_router_dialog_controller_android.h b/chrome/browser/media/android/router/media_router_dialog_controller_android.h index b8efb59..ccde216 100644 --- a/chrome/browser/media/android/router/media_router_dialog_controller_android.h +++ b/chrome/browser/media/android/router/media_router_dialog_controller_android.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_MEDIA_ANDROID_ROUTER_MEDIA_ROUTER_DIALOG_CONTROLLER_ANDROID_H_ #define CHROME_BROWSER_MEDIA_ANDROID_ROUTER_MEDIA_ROUTER_DIALOG_CONTROLLER_ANDROID_H_ -#include <jni.h> - #include <memory> #include "base/android/scoped_java_ref.h" @@ -23,8 +21,6 @@ public: ~MediaRouterDialogControllerAndroid() override; - static bool Register(JNIEnv* env); - static MediaRouterDialogControllerAndroid* GetOrCreateForWebContents( content::WebContents* web_contents);
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc index ecf15830..007f2269 100644 --- a/chrome/browser/metrics/ukm_browsertest.cc +++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -145,4 +145,37 @@ ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting(nullptr); } +// Make sure that UKM is disabled when metrics consent is revoked. +IN_PROC_BROWSER_TEST_F(UkmBrowserTest, MetricsConsentCheck) { + // Enable metrics recording and update MetricsServicesManager. + bool metrics_enabled = true; + ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting( + &metrics_enabled); + g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions(true); + + Profile* profile = ProfileManager::GetActiveUserProfile(); + std::unique_ptr<ProfileSyncServiceHarness> harness = + EnableSyncForProfile(profile); + + Browser* sync_browser = CreateBrowser(profile); + EXPECT_TRUE(ukm_enabled()); + uint64_t original_client_id = client_id(); + + metrics_enabled = false; + g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions(true); + + EXPECT_FALSE(ukm_enabled()); + + metrics_enabled = true; + g_browser_process->GetMetricsServicesManager()->UpdateUploadPermissions(true); + + EXPECT_TRUE(ukm_enabled()); + // Client ID should have been reset. + EXPECT_NE(original_client_id, client_id()); + + harness->service()->RequestStop(browser_sync::ProfileSyncService::CLEAR_DATA); + CloseBrowserSynchronously(sync_browser); + ChromeMetricsServiceAccessor::SetMetricsAndCrashReportingForTesting(nullptr); +} + } // namespace metrics
diff --git a/chrome/browser/net/spdyproxy/data_reduction_promo_infobar_delegate_android.cc b/chrome/browser/net/spdyproxy/data_reduction_promo_infobar_delegate_android.cc index 6f31964..5215e7a 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_promo_infobar_delegate_android.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_promo_infobar_delegate_android.cc
@@ -34,11 +34,6 @@ } // static -bool DataReductionPromoInfoBarDelegateAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -// static void DataReductionPromoInfoBarDelegateAndroid::Launch( JNIEnv* env, const JavaRef<jobject>& jweb_contents) {
diff --git a/chrome/browser/net/spdyproxy/data_reduction_promo_infobar_delegate_android.h b/chrome/browser/net/spdyproxy/data_reduction_promo_infobar_delegate_android.h index 66b1a86..9bccfdb 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_promo_infobar_delegate_android.h +++ b/chrome/browser/net/spdyproxy/data_reduction_promo_infobar_delegate_android.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/android/jni_android.h" #include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "base/strings/string16.h" @@ -31,8 +30,6 @@ DataReductionPromoInfoBarDelegateAndroid(); ~DataReductionPromoInfoBarDelegateAndroid() override; - static bool Register(JNIEnv* env); - static void Launch(JNIEnv* env, const base::android::JavaRef<jobject>& jweb_contents);
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc index 7346476..0e472d9 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
@@ -9,7 +9,6 @@ #include <map> #include <string> -#include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/strings/string_piece.h" #include "base/values.h" @@ -169,11 +168,6 @@ data_reduction_proxy::params::AreLitePagesEnabledViaFlags()); } -// static -bool DataReductionProxySettingsAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - ScopedJavaLocalRef<jlongArray> DataReductionProxySettingsAndroid::GetDailyContentLengths( JNIEnv* env, const char* pref_name) {
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h index 58969da2..9cd519a2d 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h
@@ -5,12 +5,9 @@ #ifndef CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_ANDROID_H_ #define CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_ANDROID_H_ -#include <jni.h> - #include <memory> #include <vector> -#include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/android/jni_weak_ref.h" #include "base/android/scoped_java_ref.h" @@ -123,9 +120,6 @@ std::unique_ptr<std::vector<data_reduction_proxy::DataUsageBucket>> data_usage); - // Registers the native methods to be call from Java. - static bool Register(JNIEnv* env); - JavaObjectWeakGlobalRef j_settings_obj_; base::android::ScopedJavaGlobalRef<jobject> j_query_result_obj_; int num_day_for_query_;
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc index 35c8eca..ab0983dd 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc
@@ -88,7 +88,6 @@ // DataReductionProxySettingsTest implementation: void SetUp() override { env_ = base::android::AttachCurrentThread(); - DataReductionProxySettingsAndroid::Register(env_); DataReductionProxySettingsTestBase::SetUp(); ResetSettingsAndroid(); }
diff --git a/chrome/browser/notifications/notification_platform_bridge_android.cc b/chrome/browser/notifications/notification_platform_bridge_android.cc index 7e928f2..138f94b 100644 --- a/chrome/browser/notifications/notification_platform_bridge_android.cc +++ b/chrome/browser/notifications/notification_platform_bridge_android.cc
@@ -328,12 +328,6 @@ } // static -bool NotificationPlatformBridgeAndroid::RegisterNotificationPlatformBridge( - JNIEnv* env) { - return RegisterNativesImpl(env); -} - -// static void NotificationPlatformBridgeAndroid::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterBooleanPref(prefs::kNotificationsVibrateEnabled, true);
diff --git a/chrome/browser/notifications/notification_platform_bridge_android.h b/chrome/browser/notifications/notification_platform_bridge_android.h index 9b2af9a..e0d5640 100644 --- a/chrome/browser/notifications/notification_platform_bridge_android.h +++ b/chrome/browser/notifications/notification_platform_bridge_android.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_PLATFORM_BRIDGE_ANDROID_H_ #define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_PLATFORM_BRIDGE_ANDROID_H_ -#include <jni.h> #include <stdint.h> #include <map> #include <set> @@ -76,8 +75,6 @@ const GetDisplayedNotificationsCallback& callback) const override; void SetReadyCallback(NotificationBridgeReadyCallback callback) override; - static bool RegisterNotificationPlatformBridge(JNIEnv* env); - static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); private:
diff --git a/chrome/browser/password_manager/account_chooser_dialog_android.cc b/chrome/browser/password_manager/account_chooser_dialog_android.cc index 4384ef0..082f4c27 100644 --- a/chrome/browser/password_manager/account_chooser_dialog_android.cc +++ b/chrome/browser/password_manager/account_chooser_dialog_android.cc
@@ -237,7 +237,3 @@ action); } } - -bool RegisterAccountChooserDialogAndroid(JNIEnv* env) { - return RegisterNativesImpl(env); -}
diff --git a/chrome/browser/password_manager/account_chooser_dialog_android.h b/chrome/browser/password_manager/account_chooser_dialog_android.h index 328a20b..a9afa7e 100644 --- a/chrome/browser/password_manager/account_chooser_dialog_android.h +++ b/chrome/browser/password_manager/account_chooser_dialog_android.h
@@ -69,7 +69,4 @@ DISALLOW_COPY_AND_ASSIGN(AccountChooserDialogAndroid); }; -// Native JNI methods -bool RegisterAccountChooserDialogAndroid(JNIEnv* env); - #endif // CHROME_BROWSER_PASSWORD_MANAGER_ACCOUNT_CHOOSER_DIALOG_ANDROID_H_
diff --git a/chrome/browser/password_manager/auto_signin_first_run_dialog_android.cc b/chrome/browser/password_manager/auto_signin_first_run_dialog_android.cc index 7f26816..5f019ee 100644 --- a/chrome/browser/password_manager/auto_signin_first_run_dialog_android.cc +++ b/chrome/browser/password_manager/auto_signin_first_run_dialog_android.cc
@@ -115,7 +115,3 @@ JNIEnv* env = AttachCurrentThread(); Java_AutoSigninFirstRunDialog_dismissDialog(env, dialog_jobject_); } - -bool RegisterAutoSigninFirstRunDialogAndroid(JNIEnv* env) { - return RegisterNativesImpl(env); -}
diff --git a/chrome/browser/password_manager/auto_signin_first_run_dialog_android.h b/chrome/browser/password_manager/auto_signin_first_run_dialog_android.h index 8650687..d5201a6 100644 --- a/chrome/browser/password_manager/auto_signin_first_run_dialog_android.h +++ b/chrome/browser/password_manager/auto_signin_first_run_dialog_android.h
@@ -53,7 +53,4 @@ DISALLOW_COPY_AND_ASSIGN(AutoSigninFirstRunDialogAndroid); }; -// Native JNI methods -bool RegisterAutoSigninFirstRunDialogAndroid(JNIEnv* env); - #endif // CHROME_BROWSER_PASSWORD_MANAGER_AUTO_SIGNIN_FIRST_RUN_DIALOG_ANDROID_H_
diff --git a/chrome/browser/payments/android/chrome_payments_jni_registrar.cc b/chrome/browser/payments/android/chrome_payments_jni_registrar.cc deleted file mode 100644 index 293945b..0000000 --- a/chrome/browser/payments/android/chrome_payments_jni_registrar.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/payments/android/chrome_payments_jni_registrar.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_registrar.h" -#include "base/macros.h" -#include "chrome/browser/payments/android/journey_logger_android.h" -#include "chrome/browser/payments/android/payment_manifest_web_data_service_android.h" -#include "chrome/browser/payments/android/ssl_validity_checker_android.h" - -namespace payments { -namespace android { - -static base::android::RegistrationMethod kChromePaymentsRegisteredMethods[] = { - {"JourneyLogger", JourneyLoggerAndroid::Register}, - {"SslValidityChecker", RegisterSslValidityChecker}, - {"PaymentManifestWebDataService", - PaymentManifestWebDataServiceAndroid::Register}, -}; - -bool RegisterChromePayments(JNIEnv* env) { - return base::android::RegisterNativeMethods( - env, kChromePaymentsRegisteredMethods, - arraysize(kChromePaymentsRegisteredMethods)); -} - -} // namespace android -} // namespace payments
diff --git a/chrome/browser/payments/android/chrome_payments_jni_registrar.h b/chrome/browser/payments/android/chrome_payments_jni_registrar.h deleted file mode 100644 index 92d3fa1..0000000 --- a/chrome/browser/payments/android/chrome_payments_jni_registrar.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PAYMENTS_ANDROID_CHROME_PAYMENTS_JNI_REGISTRAR_H_ -#define CHROME_BROWSER_PAYMENTS_ANDROID_CHROME_PAYMENTS_JNI_REGISTRAR_H_ - -#include <jni.h> - -namespace payments { -namespace android { - -// Register all JNI bindings necessary for the chrome payments classes. -bool RegisterChromePayments(JNIEnv* env); - -} // namespace android -} // namespace payments - -#endif // CHROME_BROWSER_PAYMENTS_ANDROID_CHROME_PAYMENTS_JNI_REGISTRAR_H_
diff --git a/chrome/browser/payments/android/journey_logger_android.cc b/chrome/browser/payments/android/journey_logger_android.cc index 6f3540b..55fbc28 100644 --- a/chrome/browser/payments/android/journey_logger_android.cc +++ b/chrome/browser/payments/android/journey_logger_android.cc
@@ -17,11 +17,6 @@ } // namespace -// static -bool JourneyLoggerAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - JourneyLoggerAndroid::JourneyLoggerAndroid(bool is_incognito, const std::string& url) : journey_logger_(is_incognito, @@ -39,11 +34,13 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller, jint jsection, - jint jnumber) { + jint jnumber, + jboolean jhas_complete_suggestion) { DCHECK_GE(jsection, 0); DCHECK_LT(jsection, JourneyLogger::Section::SECTION_MAX); journey_logger_.SetNumberOfSuggestionsShown( - static_cast<JourneyLogger::Section>(jsection), jnumber); + static_cast<JourneyLogger::Section>(jsection), jnumber, + jhas_complete_suggestion); } void JourneyLoggerAndroid::IncrementSelectionChanges( @@ -145,12 +142,6 @@ static_cast<JourneyLogger::NotShownReason>(jreason)); } -void JourneyLoggerAndroid::SetUserHadInitialFormOfPayment( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& jcaller) { - journey_logger_.SetUserHadInitialFormOfPayment(); -} - static jlong InitJourneyLoggerAndroid( JNIEnv* env, const JavaParamRef<jobject>& jcaller,
diff --git a/chrome/browser/payments/android/journey_logger_android.h b/chrome/browser/payments/android/journey_logger_android.h index 95afb75..c67871d7 100644 --- a/chrome/browser/payments/android/journey_logger_android.h +++ b/chrome/browser/payments/android/journey_logger_android.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_PAYMENTS_ANDROID_JOURNEY_LOGGER_ANDROID_H_ #define CHROME_BROWSER_PAYMENTS_ANDROID_JOURNEY_LOGGER_ANDROID_H_ -#include <jni.h> - #include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "components/payments/core/journey_logger.h" @@ -16,9 +14,6 @@ // Forwarding calls to payments::JourneyLogger. class JourneyLoggerAndroid { public: - // Registers the JNI bindings for this class. - static bool Register(JNIEnv* env); - JourneyLoggerAndroid(bool is_incognito, const std::string& url); ~JourneyLoggerAndroid(); @@ -30,7 +25,8 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller, jint jsection, - jint jnumber); + jint jnumber, + jboolean jhas_complete_suggestion); void IncrementSelectionChanges( JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller, @@ -71,9 +67,6 @@ void SetNotShown(JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller, jint jreason); - void SetUserHadInitialFormOfPayment( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& jcaller); private: JourneyLogger journey_logger_;
diff --git a/chrome/browser/payments/android/payment_manifest_web_data_service_android.cc b/chrome/browser/payments/android/payment_manifest_web_data_service_android.cc index 0938af0..b7be3ab 100644 --- a/chrome/browser/payments/android/payment_manifest_web_data_service_android.cc +++ b/chrome/browser/payments/android/payment_manifest_web_data_service_android.cc
@@ -6,7 +6,6 @@ #include <string> -#include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/logging.h" @@ -20,11 +19,6 @@ namespace payments { -// static -bool PaymentManifestWebDataServiceAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - PaymentManifestWebDataServiceAndroid::PaymentManifestWebDataServiceAndroid( JNIEnv* env, jobject obj)
diff --git a/chrome/browser/payments/android/payment_manifest_web_data_service_android.h b/chrome/browser/payments/android/payment_manifest_web_data_service_android.h index 0033c0e..bdf4a45f 100644 --- a/chrome/browser/payments/android/payment_manifest_web_data_service_android.h +++ b/chrome/browser/payments/android/payment_manifest_web_data_service_android.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_PAYMENTS_ANDROID_PAYMENT_MANIFEST_WEB_DATA_SERVICE_ANDROID_H_ #define CHROME_BROWSER_PAYMENTS_ANDROID_PAYMENT_MANIFEST_WEB_DATA_SERVICE_ANDROID_H_ -#include <jni.h> #include <map> #include <memory> #include <vector> @@ -25,9 +24,6 @@ // therefore a single instance of this wrapper. class PaymentManifestWebDataServiceAndroid : public WebDataServiceConsumer { public: - // Registers the JNI bindings for this class. - static bool Register(JNIEnv* env); - PaymentManifestWebDataServiceAndroid(JNIEnv* env, jobject obj); ~PaymentManifestWebDataServiceAndroid() override;
diff --git a/chrome/browser/payments/android/ssl_validity_checker_android.cc b/chrome/browser/payments/android/ssl_validity_checker_android.cc index 1d7658d..b6fdce2e 100644 --- a/chrome/browser/payments/android/ssl_validity_checker_android.cc +++ b/chrome/browser/payments/android/ssl_validity_checker_android.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/payments/android/ssl_validity_checker_android.h" - #include "base/android/scoped_java_ref.h" #include "chrome/browser/payments/ssl_validity_checker.h" #include "content/public/browser/web_contents.h" @@ -20,8 +18,4 @@ content::WebContents::FromJavaWebContents(jweb_contents)); } -bool RegisterSslValidityChecker(JNIEnv* env) { - return RegisterNativesImpl(env); -} - } // namespace payments
diff --git a/chrome/browser/payments/android/ssl_validity_checker_android.h b/chrome/browser/payments/android/ssl_validity_checker_android.h deleted file mode 100644 index c6d1bb85c..0000000 --- a/chrome/browser/payments/android/ssl_validity_checker_android.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PAYMENTS_ANDROID_SSL_VALIDITY_CHECKER_ANDROID_H_ -#define CHROME_BROWSER_PAYMENTS_ANDROID_SSL_VALIDITY_CHECKER_ANDROID_H_ - -#include <jni.h> - -namespace payments { - -bool RegisterSslValidityChecker(JNIEnv* env); - -} // namespace payments - -#endif // CHROME_BROWSER_PAYMENTS_ANDROID_SSL_VALIDITY_CHECKER_ANDROID_H_
diff --git a/chrome/browser/permissions/permission_dialog_delegate.cc b/chrome/browser/permissions/permission_dialog_delegate.cc index ff6fbc9..a9b4a0e 100644 --- a/chrome/browser/permissions/permission_dialog_delegate.cc +++ b/chrome/browser/permissions/permission_dialog_delegate.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/feature_list.h" @@ -120,11 +119,6 @@ return has_user_gesture; } -// static -bool PermissionDialogDelegate::RegisterPermissionDialogDelegate(JNIEnv* env) { - return RegisterNativesImpl(env); -} - void PermissionDialogDelegate::CreateJavaDelegate(JNIEnv* env) { base::android::ScopedJavaLocalRef<jstring> primaryButtonText = ConvertUTF16ToJavaString(env,
diff --git a/chrome/browser/permissions/permission_dialog_delegate.h b/chrome/browser/permissions/permission_dialog_delegate.h index 12358bb9..e68a238 100644 --- a/chrome/browser/permissions/permission_dialog_delegate.h +++ b/chrome/browser/permissions/permission_dialog_delegate.h
@@ -65,7 +65,6 @@ static bool ShouldShowDialog(bool has_user_gesture); // JNI methods. - static bool RegisterPermissionDialogDelegate(JNIEnv* env); void Accept(JNIEnv* env, const JavaParamRef<jobject>& obj, jboolean persist); void Cancel(JNIEnv* env, const JavaParamRef<jobject>& obj, jboolean persist); void Dismissed(JNIEnv* env, const JavaParamRef<jobject>& obj);
diff --git a/chrome/browser/permissions/permission_update_infobar_delegate_android.cc b/chrome/browser/permissions/permission_update_infobar_delegate_android.cc index f72bb1a..81ae8ad 100644 --- a/chrome/browser/permissions/permission_update_infobar_delegate_android.cc +++ b/chrome/browser/permissions/permission_update_infobar_delegate_android.cc
@@ -120,12 +120,6 @@ return false; } -// static -bool PermissionUpdateInfoBarDelegate::RegisterPermissionUpdateInfoBarDelegate( - JNIEnv* env) { - return RegisterNativesImpl(env); -} - void PermissionUpdateInfoBarDelegate::OnPermissionResult( JNIEnv* env, const JavaParamRef<jobject>& obj,
diff --git a/chrome/browser/permissions/permission_update_infobar_delegate_android.h b/chrome/browser/permissions/permission_update_infobar_delegate_android.h index 15a5105..877aa1c 100644 --- a/chrome/browser/permissions/permission_update_infobar_delegate_android.h +++ b/chrome/browser/permissions/permission_update_infobar_delegate_android.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_PERMISSIONS_PERMISSION_UPDATE_INFOBAR_DELEGATE_ANDROID_H_ #define CHROME_BROWSER_PERMISSIONS_PERMISSION_UPDATE_INFOBAR_DELEGATE_ANDROID_H_ -#include <jni.h> #include <string> #include <vector> @@ -61,8 +60,6 @@ content::WebContents* web_contents, const std::vector<ContentSettingsType>& content_settings_types); - static bool RegisterPermissionUpdateInfoBarDelegate(JNIEnv* env); - void OnPermissionResult(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jboolean all_permissions_granted);
diff --git a/chrome/browser/predictors/loading_predictor_android.cc b/chrome/browser/predictors/loading_predictor_android.cc index 83347d1f..bc3a2e04b 100644 --- a/chrome/browser/predictors/loading_predictor_android.cc +++ b/chrome/browser/predictors/loading_predictor_android.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/predictors/loading_predictor_android.h" - #include "base/android/jni_android.h" #include "base/android/jni_string.h" @@ -66,8 +64,4 @@ return true; } -bool RegisterLoadingPredictor(JNIEnv* env) { - return RegisterNativesImpl(env); -} - } // namespace predictors
diff --git a/chrome/browser/predictors/loading_predictor_android.h b/chrome/browser/predictors/loading_predictor_android.h deleted file mode 100644 index af165aa..0000000 --- a/chrome/browser/predictors/loading_predictor_android.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_ANDROID_H_ -#define CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_ANDROID_H_ - -#include <jni.h> - -namespace predictors { - -bool RegisterLoadingPredictor(JNIEnv* env); - -} // namespace predictors - -#endif // CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_ANDROID_H_
diff --git a/chrome/browser/prerender/external_prerender_handler_android.cc b/chrome/browser/prerender/external_prerender_handler_android.cc index bf9e0d3f..1a9f17ff9 100644 --- a/chrome/browser/prerender/external_prerender_handler_android.cc +++ b/chrome/browser/prerender/external_prerender_handler_android.cc
@@ -159,9 +159,4 @@ return reinterpret_cast<intptr_t>(external_handler); } -bool ExternalPrerenderHandlerAndroid::RegisterExternalPrerenderHandlerAndroid( - JNIEnv* env) { - return RegisterNativesImpl(env); -} - } // namespace prerender
diff --git a/chrome/browser/prerender/external_prerender_handler_android.h b/chrome/browser/prerender/external_prerender_handler_android.h index d11a2bb..4f076286 100644 --- a/chrome/browser/prerender/external_prerender_handler_android.h +++ b/chrome/browser/prerender/external_prerender_handler_android.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_PRERENDER_EXTERNAL_PRERENDER_HANDLER_ANDROID_H_ #define CHROME_BROWSER_PRERENDER_EXTERNAL_PRERENDER_HANDLER_ANDROID_H_ -#include <jni.h> - #include <memory> #include "base/android/scoped_java_ref.h" @@ -60,8 +58,6 @@ GURL url, content::WebContents* web_contents); - static bool RegisterExternalPrerenderHandlerAndroid(JNIEnv* env); - private: virtual ~ExternalPrerenderHandlerAndroid(); std::unique_ptr<prerender::PrerenderHandle> prerender_handle_;
diff --git a/chrome/browser/profiles/profile_android.cc b/chrome/browser/profiles/profile_android.cc index ddcba395..9202fab9 100644 --- a/chrome/browser/profiles/profile_android.cc +++ b/chrome/browser/profiles/profile_android.cc
@@ -46,11 +46,6 @@ } // static -bool ProfileAndroid::RegisterProfileAndroid(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -// static ScopedJavaLocalRef<jobject> ProfileAndroid::GetLastUsedProfile(JNIEnv* env, jclass clazz) { Profile* profile = ProfileManager::GetLastUsedProfile();
diff --git a/chrome/browser/profiles/profile_android.h b/chrome/browser/profiles/profile_android.h index 8f881869..ca3030f 100644 --- a/chrome/browser/profiles/profile_android.h +++ b/chrome/browser/profiles/profile_android.h
@@ -19,7 +19,6 @@ public: static ProfileAndroid* FromProfile(Profile* profile); static Profile* FromProfileAndroid(jobject obj); - static bool RegisterProfileAndroid(JNIEnv* env); static base::android::ScopedJavaLocalRef<jobject> GetLastUsedProfile( JNIEnv* env,
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.html b/chrome/browser/resources/settings/internet_page/internet_detail_page.html index 10c310d6..9bc0a37 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.html
@@ -287,8 +287,7 @@ <tether-connection-dialog id="tetherDialog" network-properties="[[networkProperties]]" - on-tether-connect="onTetherConnect_" - on-close="onTetherDialogClose_"> + on-tether-connect="onTetherConnect_"> </tether-connection-dialog> </template> <script src="internet_detail_page.js"></script>
diff --git a/chrome/browser/resources/settings/internet_page/internet_detail_page.js b/chrome/browser/resources/settings/internet_page/internet_detail_page.js index 8be3b0c1..8ca817f 100644 --- a/chrome/browser/resources/settings/internet_page/internet_detail_page.js +++ b/chrome/browser/resources/settings/internet_page/internet_detail_page.js
@@ -146,12 +146,6 @@ shouldShowConfigureWhenNetworkLoaded_: false, /** - * Whether the previous route was also the network detail page. - * @private {boolean} - */ - wasPreviousRouteNetworkDetailPage_: false, - - /** * settings.RouteObserverBehavior * @param {!settings.Route} route * @param {!settings.Route} oldRoute @@ -177,15 +171,15 @@ console.error('No guid specified for page:' + route); this.close_(); } + // Set basic networkProperties until they are loaded. this.networkPropertiesReceived_ = false; + this.shouldShowConfigureWhenNetworkLoaded_ = + queryParams.get('showConfigure') == 'true'; + var type = /** @type {!chrome.networkingPrivate.NetworkType} */ ( queryParams.get('type')) || CrOnc.Type.WI_FI; - this.shouldShowConfigureWhenNetworkLoaded_ = - queryParams.get('showConfigure') == 'true'; - this.wasPreviousRouteNetworkDetailPage_ = - oldRoute == settings.routes.NETWORK_DETAIL; var name = queryParams.get('name') || type; this.networkProperties = { GUID: this.guid, @@ -244,6 +238,9 @@ if (this.shouldShowConfigureWhenNetworkLoaded_ && this.networkProperties.Tether) { + // Set |this.shouldShowConfigureWhenNetworkLoaded_| back to false to + // ensure that the Tether dialog is only shown once. + this.shouldShowConfigureWhenNetworkLoaded_ = false; this.showTetherDialog_(); } }, @@ -561,6 +558,11 @@ /** @private */ onConnectTap_: function() { + if (CrOnc.shouldShowTetherDialogBeforeConnection(this.networkProperties)) { + this.showTetherDialog_(); + return; + } + this.fire('network-connect', {networkProperties: this.networkProperties}); }, @@ -574,17 +576,6 @@ }, /** @private */ - onTetherDialogClose_: function() { - // The tether dialog is opened by specifying "showConfigure=true" - // in the query params. This may lead to the previous route also - // being the detail page, in which case we should navigate back to - // the previous route here so that when the user navigates back - // they will navigate to the previous non-detail page. - if (this.wasPreviousRouteNetworkDetailPage_) - settings.navigateToPreviousRoute(); - }, - - /** @private */ onDisconnectTap_: function() { this.networkingPrivate.startDisconnect(this.guid); },
diff --git a/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html b/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html index 1424885a..637c6b04 100644 --- a/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html +++ b/chrome/browser/resources/settings/internet_page/tether_connection_dialog.html
@@ -65,8 +65,7 @@ padding-left: 16px; } </style> - <dialog is="cr-dialog" id="dialog" on-cancel="onDialogCanceled_" - close-text="$i18n{close}" on-closed="onDialogCanceled_"> + <dialog is="cr-dialog" id="dialog" close-text="$i18n{close}"> <div class="title" slot="title">$i18n{tetherConnectionDialogTitle}</div> <div class="body" slot="body"> <span id="availability-title">
diff --git a/chrome/browser/search_engines/template_url_service_android.cc b/chrome/browser/search_engines/template_url_service_android.cc index 0fd162fb..e052ebd3 100644 --- a/chrome/browser/search_engines/template_url_service_android.cc +++ b/chrome/browser/search_engines/template_url_service_android.cc
@@ -382,8 +382,3 @@ new TemplateUrlServiceAndroid(env, obj); return reinterpret_cast<intptr_t>(template_url_service_android); } - -// static -bool TemplateUrlServiceAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -}
diff --git a/chrome/browser/search_engines/template_url_service_android.h b/chrome/browser/search_engines/template_url_service_android.h index 14a353b..3bdedcb 100644 --- a/chrome/browser/search_engines/template_url_service_android.h +++ b/chrome/browser/search_engines/template_url_service_android.h
@@ -99,8 +99,6 @@ const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jstring>& jkeyword); - static bool Register(JNIEnv* env); - private: ~TemplateUrlServiceAndroid() override;
diff --git a/chrome/browser/signin/oauth2_token_service_delegate_android.cc b/chrome/browser/signin/oauth2_token_service_delegate_android.cc index 36d8b0b0..48dc99b5 100644 --- a/chrome/browser/signin/oauth2_token_service_delegate_android.cc +++ b/chrome/browser/signin/oauth2_token_service_delegate_android.cc
@@ -558,8 +558,3 @@ : GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); heap_callback->Run(err, token, base::Time()); } - -// static -bool OAuth2TokenServiceDelegateAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -}
diff --git a/chrome/browser/signin/oauth2_token_service_delegate_android.h b/chrome/browser/signin/oauth2_token_service_delegate_android.h index 658fff9..c2714786 100644 --- a/chrome/browser/signin/oauth2_token_service_delegate_android.h +++ b/chrome/browser/signin/oauth2_token_service_delegate_android.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_DELEGATE_ANDROID_H_ #define CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_DELEGATE_ANDROID_H_ -#include <jni.h> - #include <map> #include <memory> #include <string> @@ -35,10 +33,6 @@ AccountTrackerService* account_tracker_service); ~OAuth2TokenServiceDelegateAndroid() override; - // Registers the OAuth2TokenServiceDelegateAndroid's native methods through - // JNI. - static bool Register(JNIEnv* env); - // Creates a new instance of the OAuth2TokenServiceDelegateAndroid. static OAuth2TokenServiceDelegateAndroid* Create();
diff --git a/chrome/browser/speech/tts_android.cc b/chrome/browser/speech/tts_android.cc index 35ca0b2d..33055bd2 100644 --- a/chrome/browser/speech/tts_android.cc +++ b/chrome/browser/speech/tts_android.cc
@@ -143,8 +143,3 @@ TtsPlatformImplAndroid, base::LeakySingletonTraits<TtsPlatformImplAndroid>>::get(); } - -// static -bool TtsPlatformImplAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -}
diff --git a/chrome/browser/speech/tts_android.h b/chrome/browser/speech/tts_android.h index 6095c0f..13329b0 100644 --- a/chrome/browser/speech/tts_android.h +++ b/chrome/browser/speech/tts_android.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_SPEECH_TTS_ANDROID_H_ #define CHROME_BROWSER_SPEECH_TTS_ANDROID_H_ -#include "base/android/jni_android.h" #include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "chrome/browser/speech/tts_platform.h" @@ -40,7 +39,6 @@ // Static functions. static TtsPlatformImplAndroid* GetInstance(); - static bool Register(JNIEnv* env); private: friend struct base::DefaultSingletonTraits<TtsPlatformImplAndroid>;
diff --git a/chrome/browser/ssl/security_state_model_android.cc b/chrome/browser/ssl/security_state_model_android.cc index 5f1c178..3d06aae 100644 --- a/chrome/browser/ssl/security_state_model_android.cc +++ b/chrome/browser/ssl/security_state_model_android.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ssl/security_state_model_android.h" - #include "base/logging.h" #include "chrome/browser/ssl/security_state_tab_helper.h" #include "components/security_state/core/security_state.h" @@ -13,11 +11,6 @@ using base::android::JavaParamRef; // static -bool RegisterSecurityStateModelAndroid(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -// static jint GetSecurityLevelForWebContents( JNIEnv* env, const JavaParamRef<jclass>& jcaller,
diff --git a/chrome/browser/ssl/security_state_model_android.h b/chrome/browser/ssl/security_state_model_android.h deleted file mode 100644 index 1a7f526a0..0000000 --- a/chrome/browser/ssl/security_state_model_android.h +++ /dev/null
@@ -1,12 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_SSL_SECURITY_STATE_MODEL_ANDROID_H_ -#define CHROME_BROWSER_SSL_SECURITY_STATE_MODEL_ANDROID_H_ - -#include "base/android/jni_android.h" - -bool RegisterSecurityStateModelAndroid(JNIEnv* env); - -#endif // CHROME_BROWSER_SSL_SECURITY_STATE_MODEL_ANDROID_H_
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc b/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc index c2309c2..d616359 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service_android.cc
@@ -22,10 +22,6 @@ using base::android::RunCallbackAndroid; using base::android::ScopedJavaGlobalRef; -bool RegisterChildAccountService(JNIEnv* env) { - return RegisterNativesImpl(env); -} - void ListenForChildStatusReceived(JNIEnv* env, const JavaParamRef<jclass>& jcaller, const JavaParamRef<jobject>& callback) {
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service_android.h b/chrome/browser/supervised_user/child_accounts/child_account_service_android.h index 78b2f04..6eddc3a 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service_android.h +++ b/chrome/browser/supervised_user/child_accounts/child_account_service_android.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_SUPERVISED_USER_CHILD_ACCOUNTS_CHILD_ACCOUNT_SERVICE_ANDROID_H_ #define CHROME_BROWSER_SUPERVISED_USER_CHILD_ACCOUNTS_CHILD_ACCOUNT_SERVICE_ANDROID_H_ -#include <jni.h> - #include <string> #include "base/callback_forward.h" @@ -15,9 +13,6 @@ class WebContents; } -// Register native methods. -bool RegisterChildAccountService(JNIEnv* env); - void ReauthenticateChildAccount(content::WebContents* web_contents, const std::string& email, const base::Callback<void(bool)>& callback);
diff --git a/chrome/browser/supervised_user/supervised_user_content_provider_android.cc b/chrome/browser/supervised_user/supervised_user_content_provider_android.cc index 96b74994..3b37136 100644 --- a/chrome/browser/supervised_user/supervised_user_content_provider_android.cc +++ b/chrome/browser/supervised_user/supervised_user_content_provider_android.cc
@@ -149,7 +149,3 @@ Java_SupervisedUserInsertReply_onInsertRequestSendComplete( AttachCurrentThread(), insert_reply_jobj, sent_ok); } - -bool SupervisedUserContentProvider::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -}
diff --git a/chrome/browser/supervised_user/supervised_user_content_provider_android.h b/chrome/browser/supervised_user/supervised_user_content_provider_android.h index bcdbf4c..f18e153 100644 --- a/chrome/browser/supervised_user/supervised_user_content_provider_android.h +++ b/chrome/browser/supervised_user/supervised_user_content_provider_android.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_CONTENT_PROVIDER_ANDROID_H_ #define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_CONTENT_PROVIDER_ANDROID_H_ -#include <jni.h> #include <memory> #include "base/android/scoped_java_ref.h" #include "base/macros.h" @@ -36,8 +35,6 @@ void SetFilterForTesting(JNIEnv* env, jobject caller); - static bool Register(JNIEnv* env); - private: class UrlFilterObserver : public SupervisedUserServiceObserver { public:
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc index 61be6202..9dcc6a8 100644 --- a/chrome/browser/sync/profile_sync_service_android.cc +++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -10,7 +10,6 @@ #include <string> #include <vector> -#include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/bind.h" @@ -503,11 +502,6 @@ AttachCurrentThread())); } -// static -bool ProfileSyncServiceAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - static jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) { ProfileSyncServiceAndroid* profile_sync_service_android = new ProfileSyncServiceAndroid(env, obj);
diff --git a/chrome/browser/sync/profile_sync_service_android.h b/chrome/browser/sync/profile_sync_service_android.h index 03e03e6..e7ba99e 100644 --- a/chrome/browser/sync/profile_sync_service_android.h +++ b/chrome/browser/sync/profile_sync_service_android.h
@@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_ANDROID_H_ #define CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_ANDROID_H_ -#include <jni.h> - #include <map> #include <memory> @@ -190,9 +188,6 @@ static ProfileSyncServiceAndroid* GetProfileSyncServiceAndroid(); - // Registers the ProfileSyncServiceAndroid's native methods through JNI. - static bool Register(JNIEnv* env); - private: // Returns whether sync is allowed by Android. bool IsSyncAllowedByAndroid() const;
diff --git a/chrome/browser/sync/sessions/sync_sessions_metrics_android.cc b/chrome/browser/sync/sessions/sync_sessions_metrics_android.cc index b0d65ac..116cf62 100644 --- a/chrome/browser/sync/sessions/sync_sessions_metrics_android.cc +++ b/chrome/browser/sync/sessions/sync_sessions_metrics_android.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/sync/sessions/sync_sessions_metrics_android.h" - #include <string> #include "base/metrics/field_trial.h" @@ -16,11 +14,6 @@ #include "jni/SyncSessionsMetrics_jni.h" // static -bool SyncSessionsMetricsAndroid::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -// static void RecordYoungestForeignTabAgeOnNTP( JNIEnv* env, const base::android::JavaParamRef<jclass>& jcaller) {
diff --git a/chrome/browser/sync/sessions/sync_sessions_metrics_android.h b/chrome/browser/sync/sessions/sync_sessions_metrics_android.h deleted file mode 100644 index 9bd8664..0000000 --- a/chrome/browser/sync/sessions/sync_sessions_metrics_android.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSIONS_METRICS_ANDROID_H_ -#define CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSIONS_METRICS_ANDROID_H_ - -#include <jni.h> - -// Android JNI bridge, java class name is SyncSessionsMetrics. -class SyncSessionsMetricsAndroid { - public: - static bool Register(JNIEnv* env); -}; - -#endif // CHROME_BROWSER_SYNC_SESSIONS_SYNC_SESSIONS_METRICS_ANDROID_H_
diff --git a/chrome/browser/ui/android/infobars/instant_apps_infobar.h b/chrome/browser/ui/android/infobars/instant_apps_infobar.h index bd7ecfb..4c9dc88 100644 --- a/chrome/browser/ui/android/infobars/instant_apps_infobar.h +++ b/chrome/browser/ui/android/infobars/instant_apps_infobar.h
@@ -27,7 +27,4 @@ DISALLOW_COPY_AND_ASSIGN(InstantAppsInfoBar); }; -// Register native methods. -bool RegisterInstantAppInfoBar(JNIEnv* env); - #endif // CHROME_BROWSER_UI_ANDROID_INFOBARS_INSTANT_APPS_INFOBAR_H_
diff --git a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc index b7fdae6..ab8048b 100644 --- a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
@@ -222,7 +222,7 @@ // Expect the appropriate number of suggestions shown to be logged. histogram_tester.ExpectUniqueSample( - "PaymentRequest.NumberOfSuggestionsShown.CreditCards.Completed", 1, 1); + "PaymentRequest.NumberOfSuggestionsShown.PaymentMethod.Completed", 1, 1); histogram_tester.ExpectUniqueSample( "PaymentRequest.NumberOfSuggestionsShown.ShippingAddress.Completed", 2, 1); @@ -252,7 +252,8 @@ // Expect the appropriate number of suggestions shown to be logged. histogram_tester.ExpectUniqueSample( - "PaymentRequest.NumberOfSuggestionsShown.CreditCards.UserAborted", 1, 1); + "PaymentRequest.NumberOfSuggestionsShown.PaymentMethod.UserAborted", 1, + 1); histogram_tester.ExpectUniqueSample( "PaymentRequest.NumberOfSuggestionsShown.ShippingAddress.UserAborted", 2, 1); @@ -295,7 +296,7 @@ // Expect the appropriate number of suggestions shown to be logged. histogram_tester.ExpectUniqueSample( - "PaymentRequest.NumberOfSuggestionsShown.CreditCards.Completed", 1, 1); + "PaymentRequest.NumberOfSuggestionsShown.PaymentMethod.Completed", 1, 1); histogram_tester.ExpectUniqueSample( "PaymentRequest.NumberOfSuggestionsShown.ContactInfo.Completed", 2, 1); @@ -326,7 +327,8 @@ // Expect the appropriate number of suggestions shown to be logged. histogram_tester.ExpectUniqueSample( - "PaymentRequest.NumberOfSuggestionsShown.CreditCards.UserAborted", 1, 1); + "PaymentRequest.NumberOfSuggestionsShown.PaymentMethod.UserAborted", 1, + 1); histogram_tester.ExpectUniqueSample( "PaymentRequest.NumberOfSuggestionsShown.ContactInfo.UserAborted", 2, 1); @@ -371,7 +373,7 @@ // Expect the appropriate number of suggestions shown to be logged. histogram_tester.ExpectUniqueSample( - "PaymentRequest.NumberOfSuggestionsShown.CreditCards.Completed", 1, 1); + "PaymentRequest.NumberOfSuggestionsShown.PaymentMethod.Completed", 1, 1); histogram_tester.ExpectUniqueSample( "PaymentRequest.NumberOfSuggestionsShown.ShippingAddress.Completed", 2, 1); @@ -404,7 +406,8 @@ // Expect the appropriate number of suggestions shown to be logged. histogram_tester.ExpectUniqueSample( - "PaymentRequest.NumberOfSuggestionsShown.CreditCards.UserAborted", 1, 1); + "PaymentRequest.NumberOfSuggestionsShown.PaymentMethod.UserAborted", 1, + 1); histogram_tester.ExpectUniqueSample( "PaymentRequest.NumberOfSuggestionsShown.ShippingAddress.UserAborted", 2, 1); @@ -458,21 +461,21 @@ histogram_tester.ExpectTotalCount( "PaymentRequest.UserHadInitialFormOfPayment", 0); histogram_tester.ExpectTotalCount( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment", 0); + "PaymentRequest.UserHadSuggestionsForEverything", 0); } -class PaymentRequestInitialFormOfPaymentTest +class PaymentRequestCompleteSuggestionsForEverythingTest : public PaymentRequestBrowserTestBase { protected: - PaymentRequestInitialFormOfPaymentTest() + PaymentRequestCompleteSuggestionsForEverythingTest() : PaymentRequestBrowserTestBase("/payment_request_email_test.html") {} private: - DISALLOW_COPY_AND_ASSIGN(PaymentRequestInitialFormOfPaymentTest); + DISALLOW_COPY_AND_ASSIGN(PaymentRequestCompleteSuggestionsForEverythingTest); }; -IN_PROC_BROWSER_TEST_F(PaymentRequestInitialFormOfPaymentTest, - UserHadInitialFormOfPayment) { +IN_PROC_BROWSER_TEST_F(PaymentRequestCompleteSuggestionsForEverythingTest, + UserHadCompleteSuggestionsForEverything) { base::HistogramTester histogram_tester; // Add an address and a credit card on file. @@ -490,17 +493,22 @@ // The fact that the user had a form of payment on file should be recorded. histogram_tester.ExpectUniqueSample( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion", + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + "EffectOnCompletion", JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); histogram_tester.ExpectTotalCount( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion", + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + "EffectOnCompletion", 0); } -IN_PROC_BROWSER_TEST_F(PaymentRequestInitialFormOfPaymentTest, - UserDidNotHaveInitialFormOfPayment_NoCard) { +IN_PROC_BROWSER_TEST_F(PaymentRequestCompleteSuggestionsForEverythingTest, + UserDidNotHaveCompleteSuggestionsForEverything_NoCard) { base::HistogramTester histogram_tester; + // Add an address. + AddAutofillProfile(autofill::test::GetFullProfile()); + // Show a Payment Request. The user has no form of payment on file. InvokePaymentRequestUI(); @@ -509,15 +517,18 @@ // The fact that the user had no form of payment on file should be recorded. histogram_tester.ExpectUniqueSample( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion", + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + "EffectOnCompletion", JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); histogram_tester.ExpectTotalCount( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion", 0); + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + "EffectOnCompletion", + 0); } IN_PROC_BROWSER_TEST_F( - PaymentRequestInitialFormOfPaymentTest, - UserDidNotHaveInitialFormOfPayment_CardNetworkNotSupported) { + PaymentRequestCompleteSuggestionsForEverythingTest, + UserDidNotHaveCompleteSuggestionsForEverything_CardNetworkNotSupported) { base::HistogramTester histogram_tester; // Add an address and an AMEX credit card on file. AMEX is not supported by @@ -536,10 +547,13 @@ // The fact that the user had no form of payment on file should be recorded. histogram_tester.ExpectUniqueSample( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion", + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + "EffectOnCompletion", JourneyLogger::COMPLETION_STATUS_USER_ABORTED, 1); histogram_tester.ExpectTotalCount( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion", 0); + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + "EffectOnCompletion", + 0); } } // namespace payments
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc index 4a382e2..effec5c 100644 --- a/chrome/common/crash_keys.cc +++ b/chrome/common/crash_keys.cc
@@ -89,11 +89,6 @@ const char kUserCloudPolicyManagerConnectTrace[] = "user-cloud-policy-manager-connect-trace"; -// TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. -// TODO(sunnyps): Remove after fixing https://crbug.com/622080 -const char kBeginMainFrameHangCompositorState[] = - "begin-main-frame-hang-compositor-state"; - size_t RegisterChromeCrashKeys() { // The following keys may be chunked by the underlying crash logging system, // but ultimately constitute a single key-value pair. @@ -228,10 +223,6 @@ // Temporary for https://crbug.com/685996. {kUserCloudPolicyManagerConnectTrace, kMediumSize}, - // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. - // TODO(sunnyps): Remove after fixing https://crbug.com/622080 - {kBeginMainFrameHangCompositorState, crash_keys::kSmallSize}, - // TODO(asvitkine): Remove after fixing https://crbug.com/736675 {"bad_histogram", kMediumSize}, };
diff --git a/chrome/common/crash_keys.h b/chrome/common/crash_keys.h index 52b9b69d..687146e 100644 --- a/chrome/common/crash_keys.h +++ b/chrome/common/crash_keys.h
@@ -150,10 +150,6 @@ // browser crash due to an attempt to connect twice. https://crbug.com/685996. extern const char kUserCloudPolicyManagerConnectTrace[]; -// TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. -// TODO(sunnyps): Remove after fixing https://crbug.com/622080 -extern const char kBeginMainFrameHangCompositorState[]; - } // namespace crash_keys #endif // CHROME_COMMON_CRASH_KEYS_H_
diff --git a/chrome/common/extensions/chrome_manifest_url_handlers.cc b/chrome/common/extensions/chrome_manifest_url_handlers.cc index cb6a0e9..59238d8 100644 --- a/chrome/common/extensions/chrome_manifest_url_handlers.cc +++ b/chrome/common/extensions/chrome_manifest_url_handlers.cc
@@ -142,8 +142,16 @@ *error = base::ASCIIToUTF16(errors::kMultipleOverrides); return false; } + + // If this is an NTP override extension, add the NTP override permission. + if (url_overrides->chrome_url_overrides_.count(chrome::kChromeUINewTabHost)) { + PermissionsParser::AddAPIPermission(extension, + APIPermission::kNewTabPageOverride); + } + extension->SetManifestData(keys::kChromeURLOverrides, std::move(url_overrides)); + return true; }
diff --git a/chrome/common/extensions/permissions/chrome_permission_message_provider.cc b/chrome/common/extensions/permissions/chrome_permission_message_provider.cc index d0afe3b..50175df3 100644 --- a/chrome/common/extensions/permissions/chrome_permission_message_provider.cc +++ b/chrome/common/extensions/permissions/chrome_permission_message_provider.cc
@@ -195,6 +195,12 @@ DropPermissionParameter(id, &new_ids); } + // For M62, we added a new permission ID for new tab page overrides. Consider + // the addition of this permission to not result in a privilege increase for + // the time being. + // TODO(robertshield): Remove this once most of the population is on M62+ + new_ids.erase(APIPermission::kNewTabPageOverride); + // If all the IDs were already there, it's not a privilege increase. if (old_ids.Includes(new_ids)) return false;
diff --git a/chrome/common/extensions/permissions/chrome_permission_message_rules.cc b/chrome/common/extensions/permissions/chrome_permission_message_rules.cc index 285668db..94cbbc68 100644 --- a/chrome/common/extensions/permissions/chrome_permission_message_rules.cc +++ b/chrome/common/extensions/permissions/chrome_permission_message_rules.cc
@@ -378,6 +378,12 @@ {APIPermission::kHostReadOnly}, {}}, + // New tab page permission is fairly highly used so rank it quite highly. + // Nothing should subsume it. + {IDS_EXTENSION_PROMPT_WARNING_NEW_TAB_PAGE_OVERRIDE, + {APIPermission::kNewTabPageOverride}, + {}}, + // History-related permission messages. // History already allows reading favicons, tab access and accessing the // list of most frequently visited sites.
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index bb13e36..9ebd9c542 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -319,25 +319,36 @@ }; #if defined(OS_WIN) +// Binds |module_event_sink| to the provided |interface_ptr_info|. This function +// is used to do the binding on the IO thread. +void BindModuleEventSink(mojom::ModuleEventSinkPtr* module_event_sink, + mojom::ModuleEventSinkPtrInfo interface_ptr_info) { + DCHECK(!module_event_sink->is_bound()); + + module_event_sink->Bind(std::move(interface_ptr_info)); +} + // Dispatches a module |event| to the provided |module_event_sink| interface. -// It is expected that this only be called from the IO thread. This is only -// safe because the underlying |module_event_sink| object is never deleted, -// being owned by the leaked ChromeContentRendererClient object. If this ever -// changes then a WeakPtr mechanism would have to be used. -void HandleModuleEventOnIOThread(mojom::ModuleEventSinkPtr* module_event_sink, - const ModuleWatcher::ModuleEvent& event) { +// It is expected that this only be called from the IO thread. This is only safe +// because the underlying |module_event_sink| object is never deleted, being +// owned by the leaked ChromeContentRendererClient object. If this ever changes +// then a WeakPtr mechanism would have to be used. +void HandleModuleEventOnIOThread( + const mojom::ModuleEventSinkPtr& module_event_sink, + const ModuleWatcher::ModuleEvent& event) { + DCHECK(module_event_sink.is_bound()); + // Simply send the module load address. The browser can validate this and look // up the module details on its own. - (*module_event_sink) - ->OnModuleEvent(event.event_type, - reinterpret_cast<uintptr_t>(event.module_load_address)); + module_event_sink->OnModuleEvent( + event.event_type, reinterpret_cast<uintptr_t>(event.module_load_address)); } // Receives notifications from the ModuleWatcher on any thread. Bounces these // over to the provided |io_task_runner| where they are subsequently dispatched // to the |module_event_sink| interface. void OnModuleEvent(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - mojom::ModuleEventSinkPtr* module_event_sink, + const mojom::ModuleEventSinkPtr& module_event_sink, const ModuleWatcher::ModuleEvent& event) { // The Mojo interface can only be used from a single thread. Bounce tasks // over to it. It is safe to pass an unretained pointer to @@ -345,7 +356,7 @@ // a leaked singleton in the process. io_task_runner->PostTask( FROM_HERE, base::Bind(&HandleModuleEventOnIOThread, - base::Unretained(module_event_sink), event)); + base::ConstRef(module_event_sink), event)); } #endif @@ -371,8 +382,7 @@ #endif } -ChromeContentRendererClient::~ChromeContentRendererClient() { -} +ChromeContentRendererClient::~ChromeContentRendererClient() = default; void ChromeContentRendererClient::RenderThreadStarted() { RenderThread* thread = RenderThread::Get(); @@ -389,16 +399,20 @@ thread->GetConnector()->BindInterface(content::mojom::kBrowserServiceName, &module_event_sink_); - // Rebind the ModuleEventSink so that it can be accessed on the IO thread. - module_event_sink_.Bind(module_event_sink_.PassInterface(), - thread->GetIOTaskRunner()); + // Rebind the ModuleEventSink to the IO task runner. + // The use of base::Unretained() is safe here because |module_event_sink_| + // is never deleted and is only used on the IO task runner. + thread->GetIOTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&BindModuleEventSink, + base::Unretained(&module_event_sink_), + module_event_sink_.PassInterface())); // It is safe to pass an unretained pointer to |module_event_sink_|, as it // is owned by the process singleton ChromeContentRendererClient, which is // leaked. module_watcher_ = ModuleWatcher::Create( - base::Bind(&OnModuleEvent, thread->GetIOTaskRunner(), - base::Unretained(&module_event_sink_))); + base::BindRepeating(&OnModuleEvent, thread->GetIOTaskRunner(), + base::ConstRef(module_event_sink_))); } #endif
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java index f2a2e966..66ea342 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestBase.java
@@ -50,13 +50,4 @@ protected void waitForFullLoad(final ChromeActivity activity, final String expectedTitle) { mTestCommon.waitForFullLoad(activity, expectedTitle); } - - /** - * Approximates when a ChromeActivity is fully ready and loaded, which is hard to gauge - * because Android's Activity transition animations are not monitorable. - */ - protected void waitForFullLoad(final ChromeActivity activity, final String expectedTitle, - boolean waitLongerForLoad) { - mTestCommon.waitForFullLoad(activity, expectedTitle, waitLongerForLoad); - } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestCommon.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestCommon.java index 576777e..f38a7e8 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestCommon.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestCommon.java
@@ -8,17 +8,26 @@ import android.content.Context; import android.text.TextUtils; +import org.chromium.base.Log; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.test.util.CallbackHelper; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelSelector; import org.chromium.chrome.test.util.ApplicationTestUtils; import org.chromium.chrome.test.util.browser.tabmodel.document.MockStorageDelegate; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + // TODO(yolandyan): move this class to its test rule once JUnit4 migration is over final class MultiActivityTestCommon { + private static final String TAG = "MultiActivityTest"; + private final MultiActivityTestCommonCallback mCallback; MockStorageDelegate mStorageDelegate; Context mContext; @@ -45,12 +54,8 @@ } void waitForFullLoad(final ChromeActivity activity, final String expectedTitle) { - waitForFullLoad(activity, expectedTitle, false); - } - - void waitForFullLoad( - final ChromeActivity activity, final String expectedTitle, boolean waitLongerForLoad) { - ApplicationTestUtils.assertWaitForPageScaleFactorMatch(activity, 0.5f, waitLongerForLoad); + waitForTabCreation(activity); + ApplicationTestUtils.assertWaitForPageScaleFactorMatch(activity, 0.5f); final Tab tab = activity.getActivityTab(); assert tab != null; @@ -64,5 +69,23 @@ }); } + private void waitForTabCreation(final ChromeActivity activity) { + final CountDownLatch latch = new CountDownLatch(1); + activity.getTabModelSelector().addObserver(new TabModelSelectorObserver() { + public void onChange() {} + public void onNewTabCreated(Tab tab) { + latch.countDown(); + } + public void onTabModelSelected(TabModel newModel, TabModel oldModel) {} + public void onTabStateInitialized() {} + + }); + try { + latch.await(CallbackHelper.WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Log.w(TAG, "CountDownLatch interrupted. The test may fail."); + } + } + public interface MultiActivityTestCommonCallback { Instrumentation getInstrumentation(); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestRule.java index 98440c5..d5800e4 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/MultiActivityTestRule.java
@@ -36,11 +36,6 @@ mTestCommon.waitForFullLoad(activity, expectedTitle); } - public void waitForFullLoad( - final ChromeActivity activity, final String expectedTitle, boolean waitLongerForLoad) { - mTestCommon.waitForFullLoad(activity, expectedTitle, waitLongerForLoad); - } - @Override public Statement apply(final Statement base, Description desc) { return new Statement() {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationTestUtils.java index b7402e37..3422eaa 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ApplicationTestUtils.java
@@ -192,23 +192,14 @@ } /** - * See {@link #assertWaitForPageScaleFactorMatch(ChromeActivity,float,long)}. - */ - public static void assertWaitForPageScaleFactorMatch( - final ChromeActivity activity, final float expectedScale) { - assertWaitForPageScaleFactorMatch(activity, expectedScale, false); - } - - /** * Waits till the ContentViewCore receives the expected page scale factor * from the compositor and asserts that this happens. * * Proper use of this function requires waiting for a page scale factor that isn't 1.0f because * the default seems to be 1.0f. */ - public static void assertWaitForPageScaleFactorMatch(final ChromeActivity activity, - final float expectedScale, boolean waitLongerForLoad) { - long waitTimeInMs = waitLongerForLoad ? 10000 : CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL; + public static void assertWaitForPageScaleFactorMatch( + final ChromeActivity activity, final float expectedScale) { CriteriaHelper.pollInstrumentationThread(new Criteria() { @Override public boolean isSatisfied() { @@ -219,6 +210,6 @@ return Math.abs(activity.getCurrentContentViewCore().getScale() - expectedScale) < FLOAT_EPSILON; } - }, waitTimeInMs, CriteriaHelper.DEFAULT_POLLING_INTERVAL); + }, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL, CriteriaHelper.DEFAULT_POLLING_INTERVAL); } }
diff --git a/chromecast/crash/cast_crash_keys.cc b/chromecast/crash/cast_crash_keys.cc index f9ad50b7..48dab21 100644 --- a/chromecast/crash/cast_crash_keys.cc +++ b/chromecast/crash/cast_crash_keys.cc
@@ -14,11 +14,6 @@ const char kCurrentApp[] = "current_app"; const char kPreviousApp[] = "previous_app"; -// TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. -// TODO(sunnyps): Remove after fixing https://crbug.com/622080 -const char kBeginMainFrameHangCompositorState[] = - "begin-main-frame-hang-compositor-state"; - size_t RegisterCastCrashKeys() { const base::debug::CrashKey fixed_keys[] = { {kLastApp, ::crash_keys::kSmallSize}, @@ -96,10 +91,6 @@ // Temporary for https://crbug.com/685996. {"user-cloud-policy-manager-connect-trace", ::crash_keys::kMediumSize}, - - // TEMPORARY: Compositor state for debugging BeginMainFrame renderer hang. - // TODO(sunnyps): Remove after fixing https://crbug.com/622080 - {kBeginMainFrameHangCompositorState, ::crash_keys::kSmallSize}, }; return base::debug::InitCrashKeys(fixed_keys, arraysize(fixed_keys),
diff --git a/components/feature_engagement_tracker/public/event_constants.cc b/components/feature_engagement_tracker/public/event_constants.cc index 3ada90e..1638095 100644 --- a/components/feature_engagement_tracker/public/event_constants.cc +++ b/components/feature_engagement_tracker/public/event_constants.cc
@@ -25,9 +25,7 @@ const char kChromeOpened[] = "chrome_opened"; const char kIncognitoTabOpened[] = "incognito_tab_opened"; const char kClearedBrowsingData[] = "cleared_browsing_data"; -const char kAddedItemToReadingList[] = "added_item_to_reading_list"; const char kViewedReadingList[] = "viewed_reading_list"; -const char kOpenedReadingListItem[] = "opened_reading_list_item"; #endif // defined(OS_IOS) } // namespace events
diff --git a/components/feature_engagement_tracker/public/event_constants.h b/components/feature_engagement_tracker/public/event_constants.h index d932c7e..fbe217c 100644 --- a/components/feature_engagement_tracker/public/event_constants.h +++ b/components/feature_engagement_tracker/public/event_constants.h
@@ -55,15 +55,9 @@ // The user has cleared their browsing data. extern const char kClearedBrowsingData[]; -// The user has added an item to their reading list. -extern const char kAddedItemToReadingList[]; - // The user has viewed their reading list. extern const char kViewedReadingList[]; -// The user has opened an item in their reading list. -extern const char kOpenedReadingListItem[]; - #endif // defined(OS_IOS) } // namespace events
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn index 2775981..319d951 100644 --- a/components/metrics/BUILD.gn +++ b/components/metrics/BUILD.gn
@@ -31,6 +31,8 @@ "environment_recorder.h", "execution_phase.cc", "execution_phase.h", + "field_trials_provider.cc", + "field_trials_provider.h", "file_metrics_provider.cc", "file_metrics_provider.h", "histogram_encoder.cc", @@ -346,6 +348,7 @@ "data_use_tracker_unittest.cc", "drive_metrics_provider_unittest.cc", "environment_recorder_unittest.cc", + "field_trials_provider_unittest.cc", "file_metrics_provider_unittest.cc", "histogram_encoder_unittest.cc", "machine_id_provider_win_unittest.cc",
diff --git a/components/metrics/field_trials_provider.cc b/components/metrics/field_trials_provider.cc new file mode 100644 index 0000000..90e13e62 --- /dev/null +++ b/components/metrics/field_trials_provider.cc
@@ -0,0 +1,58 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/metrics/field_trials_provider.h" + +#include "components/metrics/proto/system_profile.pb.h" +#include "components/variations/active_field_trials.h" +#include "components/variations/synthetic_trial_registry.h" + +namespace variations { + +namespace { + +void WriteFieldTrials(const std::vector<ActiveGroupId>& field_trial_ids, + metrics::SystemProfileProto* system_profile) { + for (const ActiveGroupId& id : field_trial_ids) { + metrics::SystemProfileProto::FieldTrial* field_trial = + system_profile->add_field_trial(); + field_trial->set_name_id(id.name); + field_trial->set_group_id(id.group); + } +} + +} // namespace + +FieldTrialsProvider::FieldTrialsProvider(SyntheticTrialRegistry* registry) + : registry_(registry) {} +FieldTrialsProvider::~FieldTrialsProvider() = default; + +void FieldTrialsProvider::GetFieldTrialIds( + std::vector<ActiveGroupId>* field_trial_ids) const { + // We use the default field trial suffixing (no suffix). + variations::GetFieldTrialActiveGroupIds(base::StringPiece(), field_trial_ids); +} + +void FieldTrialsProvider::OnDidCreateMetricsLog() { + creation_times_.push_back(base::TimeTicks::Now()); +} + +void FieldTrialsProvider::ProvideSystemProfileMetrics( + metrics::SystemProfileProto* system_profile_proto) { + base::TimeTicks creation_time; + // Should always be true, but don't crash even if there is a bug. + if (!creation_times_.empty()) { + creation_time = creation_times_.back(); + creation_times_.pop_back(); + } + std::vector<ActiveGroupId> synthetic_trials; + registry_->GetSyntheticFieldTrialsOlderThan(creation_time, &synthetic_trials); + + std::vector<ActiveGroupId> field_trial_ids; + GetFieldTrialIds(&field_trial_ids); + WriteFieldTrials(field_trial_ids, system_profile_proto); + WriteFieldTrials(synthetic_trials, system_profile_proto); +} + +} // namespace variations
diff --git a/components/metrics/field_trials_provider.h b/components/metrics/field_trials_provider.h new file mode 100644 index 0000000..6242a20d --- /dev/null +++ b/components/metrics/field_trials_provider.h
@@ -0,0 +1,50 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_METRICS_FIELD_TRIALS_PROVIDER_H_ +#define COMPONENTS_METRICS_FIELD_TRIALS_PROVIDER_H_ + +#include <vector> + +#include "base/time/time.h" +#include "components/metrics/metrics_provider.h" + +// TODO(crbug/507665): Once MetricsProvider/SystemProfileProto are moved into +// //services/metrics, then //components/variations can depend on them, and +// this should be moved there. +namespace variations { + +class SyntheticTrialRegistry; +struct ActiveGroupId; + +class FieldTrialsProvider : public metrics::MetricsProvider { + public: + // |registry| must outlive this metrics provider. + FieldTrialsProvider(SyntheticTrialRegistry* registry); + ~FieldTrialsProvider() override; + + // metrics::MetricsProvider: + void OnDidCreateMetricsLog() override; + void ProvideSystemProfileMetrics( + metrics::SystemProfileProto* system_profile_proto) override; + + private: + // Overrideable for testing. + virtual void GetFieldTrialIds( + std::vector<ActiveGroupId>* field_trial_ids) const; + + SyntheticTrialRegistry* registry_; + + // A stack of log creation times. + // While the initial metrics log exists, there will be two logs open. + // Use a stack so that we use the right creation time for the first ongoing + // log. + // TODO(crbug/746098): Simplify InitialMetricsLog logic so this is not + // necessary. + std::vector<base::TimeTicks> creation_times_; +}; + +} // namespace variations + +#endif // COMPONENTS_METRICS_FIELD_TRIALS_PROVIDER_H_
diff --git a/components/metrics/field_trials_provider_unittest.cc b/components/metrics/field_trials_provider_unittest.cc new file mode 100644 index 0000000..25c31c5d8 --- /dev/null +++ b/components/metrics/field_trials_provider_unittest.cc
@@ -0,0 +1,103 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/metrics/field_trials_provider.h" + +#include "components/metrics/proto/system_profile.pb.h" +#include "components/variations/active_field_trials.h" +#include "components/variations/synthetic_trial_registry.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace variations { + +namespace { + +const ActiveGroupId kFieldTrialIds[] = {{37, 43}, {13, 47}, {23, 17}}; +const ActiveGroupId kSyntheticTrials[] = {{55, 15}, {66, 16}}; + +class TestProvider : public FieldTrialsProvider { + public: + TestProvider(SyntheticTrialRegistry* registry) + : FieldTrialsProvider(registry) {} + ~TestProvider() override {} + + void GetFieldTrialIds( + std::vector<ActiveGroupId>* field_trial_ids) const override { + ASSERT_TRUE(field_trial_ids->empty()); + for (const ActiveGroupId& id : kFieldTrialIds) { + field_trial_ids->push_back(id); + } + } +}; + +// Check that the values in |system_values| correspond to the test data +// defined at the top of this file. +void CheckSystemProfile(const metrics::SystemProfileProto& system_profile) { + ASSERT_EQ(arraysize(kFieldTrialIds) + arraysize(kSyntheticTrials), + static_cast<size_t>(system_profile.field_trial_size())); + for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { + const metrics::SystemProfileProto::FieldTrial& field_trial = + system_profile.field_trial(i); + EXPECT_EQ(kFieldTrialIds[i].name, field_trial.name_id()); + EXPECT_EQ(kFieldTrialIds[i].group, field_trial.group_id()); + } + // Verify the right data is present for the synthetic trials. + for (size_t i = 0; i < arraysize(kSyntheticTrials); ++i) { + const metrics::SystemProfileProto::FieldTrial& field_trial = + system_profile.field_trial(i + arraysize(kFieldTrialIds)); + EXPECT_EQ(kSyntheticTrials[i].name, field_trial.name_id()); + EXPECT_EQ(kSyntheticTrials[i].group, field_trial.group_id()); + } +} + +} // namespace + +class FieldTrialsProviderTest : public ::testing::Test { + public: + FieldTrialsProviderTest() {} + ~FieldTrialsProviderTest() override {} + + protected: + // Register trials which should get recorded. + void RegisterExpectedSyntheticTrials() { + for (const ActiveGroupId& id : kSyntheticTrials) { + registry_.RegisterSyntheticFieldTrial( + SyntheticTrialGroup(id.name, id.group)); + } + } + // Register trial which shouldn't get recorded. + void RegisterExtraSyntheticTrial() { + registry_.RegisterSyntheticFieldTrial(SyntheticTrialGroup(100, 1000)); + } + + // Waits until base::TimeTicks::Now() no longer equals |value|. This should + // take between 1-15ms per the documented resolution of base::TimeTicks. + void WaitUntilTimeChanges(const base::TimeTicks& value) { + while (base::TimeTicks::Now() == value) { + base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); + } + } + + SyntheticTrialRegistry registry_; +}; + +TEST_F(FieldTrialsProviderTest, ProvideSyntheticTrials) { + TestProvider provider(®istry_); + + RegisterExpectedSyntheticTrials(); + // Make sure these trials are older than the log. + WaitUntilTimeChanges(base::TimeTicks::Now()); + + provider.OnDidCreateMetricsLog(); + // Make sure that the log is older than the trials that should be excluded. + WaitUntilTimeChanges(base::TimeTicks::Now()); + + RegisterExtraSyntheticTrial(); + + metrics::SystemProfileProto proto; + provider.ProvideSystemProfileMetrics(&proto); + CheckSystemProfile(proto); +} + +} // namespace variations
diff --git a/components/metrics/metrics_log.cc b/components/metrics/metrics_log.cc index 2a3cb56..5169ea84 100644 --- a/components/metrics/metrics_log.cc +++ b/components/metrics/metrics_log.cc
@@ -32,7 +32,6 @@ #include "components/metrics/proto/user_action_event.pb.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" -#include "components/variations/active_field_trials.h" #if defined(OS_ANDROID) #include "base/android/build_info.h" @@ -43,7 +42,6 @@ #endif using base::SampleCountIterator; -typedef variations::ActiveGroupId ActiveGroupId; namespace metrics { @@ -82,17 +80,6 @@ return id.size() < 16; } -void WriteFieldTrials(const std::vector<ActiveGroupId>& field_trial_ids, - SystemProfileProto* system_profile) { - for (std::vector<ActiveGroupId>::const_iterator it = - field_trial_ids.begin(); it != field_trial_ids.end(); ++it) { - SystemProfileProto::FieldTrial* field_trial = - system_profile->add_field_trial(); - field_trial->set_name_id(it->name); - field_trial->set_group_id(it->group); - } -} - // Round a timestamp measured in seconds since epoch to one with a granularity // of an hour. This can be used before uploaded potentially sensitive // timestamps. @@ -247,12 +234,6 @@ metrics_providers[i]->ProvideGeneralMetrics(uma_proto()); } -void MetricsLog::GetFieldTrialIds( - std::vector<ActiveGroupId>* field_trial_ids) const { - // We use the default field trial suffixing (no suffix). - variations::GetFieldTrialActiveGroupIds(base::StringPiece(), field_trial_ids); -} - bool MetricsLog::HasEnvironment() const { return uma_proto()->system_profile().has_uma_enabled_date(); } @@ -305,7 +286,6 @@ std::string MetricsLog::RecordEnvironment( const std::vector<std::unique_ptr<MetricsProvider>>& metrics_providers, - const std::vector<variations::ActiveGroupId>& synthetic_trials, int64_t install_date, int64_t metrics_reporting_enabled_date) { DCHECK(!HasEnvironment()); @@ -333,11 +313,6 @@ cpu->set_signature(cpu_info.signature()); cpu->set_num_cores(base::SysInfo::NumberOfProcessors()); - std::vector<ActiveGroupId> field_trial_ids; - GetFieldTrialIds(&field_trial_ids); - WriteFieldTrials(field_trial_ids, system_profile); - WriteFieldTrials(synthetic_trials, system_profile); - for (size_t i = 0; i < metrics_providers.size(); ++i) metrics_providers[i]->ProvideSystemProfileMetrics(system_profile);
diff --git a/components/metrics/metrics_log.h b/components/metrics/metrics_log.h index 688a624..27e9033 100644 --- a/components/metrics/metrics_log.h +++ b/components/metrics/metrics_log.h
@@ -25,10 +25,6 @@ class HistogramSamples; } -namespace variations { -struct ActiveGroupId; -} - namespace metrics { namespace internal { @@ -102,7 +98,6 @@ // current environment is returned serialized as a string. std::string RecordEnvironment( const std::vector<std::unique_ptr<MetricsProvider>>& metrics_providers, - const std::vector<variations::ActiveGroupId>& synthetic_trials, int64_t install_date, int64_t metrics_reporting_enabled_date); @@ -156,11 +151,6 @@ protected: // Exposed for the sake of mocking/accessing in test code. - // Fills |field_trial_ids| with the list of initialized field trials name and - // group ids. - virtual void GetFieldTrialIds( - std::vector<variations::ActiveGroupId>* field_trial_ids) const; - ChromeUserMetricsExtension* uma_proto() { return &uma_proto_; } // Exposed to allow subclass to access to export the uma_proto. Can be used
diff --git a/components/metrics/metrics_log_unittest.cc b/components/metrics/metrics_log_unittest.cc index 8a1c6bc..cb48cc09 100644 --- a/components/metrics/metrics_log_unittest.cc +++ b/components/metrics/metrics_log_unittest.cc
@@ -46,15 +46,6 @@ const int64_t kEnabledDate = 1373001211; const int64_t kEnabledDateExpected = 1373000400; // Computed from kEnabledDate. const int kSessionId = 127; -const variations::ActiveGroupId kFieldTrialIds[] = { - {37, 43}, - {13, 47}, - {23, 17} -}; -const variations::ActiveGroupId kSyntheticTrials[] = { - {55, 15}, - {66, 16} -}; class TestMetricsLog : public MetricsLog { public: @@ -88,15 +79,6 @@ base::Int64ToString(kEnabledDate)); } - void GetFieldTrialIds( - std::vector<variations::ActiveGroupId>* field_trial_ids) const override { - ASSERT_TRUE(field_trial_ids->empty()); - - for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { - field_trial_ids->push_back(kFieldTrialIds[i]); - } - } - // Weak pointer to the PrefsService used by this log. TestingPrefServiceSimple* prefs_; @@ -121,22 +103,6 @@ EXPECT_EQ(kInstallDateExpected, system_profile.install_date()); EXPECT_EQ(kEnabledDateExpected, system_profile.uma_enabled_date()); - ASSERT_EQ(arraysize(kFieldTrialIds) + arraysize(kSyntheticTrials), - static_cast<size_t>(system_profile.field_trial_size())); - for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { - const SystemProfileProto::FieldTrial& field_trial = - system_profile.field_trial(i); - EXPECT_EQ(kFieldTrialIds[i].name, field_trial.name_id()); - EXPECT_EQ(kFieldTrialIds[i].group, field_trial.group_id()); - } - // Verify the right data is present for the synthetic trials. - for (size_t i = 0; i < arraysize(kSyntheticTrials); ++i) { - const SystemProfileProto::FieldTrial& field_trial = - system_profile.field_trial(i + arraysize(kFieldTrialIds)); - EXPECT_EQ(kSyntheticTrials[i].name, field_trial.name_id()); - EXPECT_EQ(kSyntheticTrials[i].group, field_trial.group_id()); - } - EXPECT_EQ(TestMetricsServiceClient::kBrandForTesting, system_profile.brand_code()); @@ -289,13 +255,8 @@ TestMetricsLog log( kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); - std::vector<variations::ActiveGroupId> synthetic_trials; - // Add two synthetic trials. - synthetic_trials.push_back(kSyntheticTrials[0]); - synthetic_trials.push_back(kSyntheticTrials[1]); - log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - synthetic_trials, kInstallDate, kEnabledDate); + kInstallDate, kEnabledDate); // Check that the system profile on the log has the correct values set. CheckSystemProfile(log.system_profile()); @@ -311,17 +272,15 @@ TestMetricsLog log_unknown(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); - std::vector<variations::ActiveGroupId> synthetic_trials; - log_unknown.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - synthetic_trials, kInstallDate, kEnabledDate); + kInstallDate, kEnabledDate); EXPECT_FALSE(log_unknown.system_profile().has_uma_default_state()); client.set_enable_default(EnableMetricsDefault::OPT_IN); TestMetricsLog log_opt_in(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); log_opt_in.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - synthetic_trials, kInstallDate, kEnabledDate); + kInstallDate, kEnabledDate); EXPECT_TRUE(log_opt_in.system_profile().has_uma_default_state()); EXPECT_EQ(SystemProfileProto_UmaDefaultState_OPT_IN, log_opt_in.system_profile().uma_default_state()); @@ -330,7 +289,7 @@ TestMetricsLog log_opt_out(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); log_opt_out.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - synthetic_trials, kInstallDate, kEnabledDate); + kInstallDate, kEnabledDate); EXPECT_TRUE(log_opt_out.system_profile().has_uma_default_state()); EXPECT_EQ(SystemProfileProto_UmaDefaultState_OPT_OUT, log_opt_out.system_profile().uma_default_state()); @@ -339,7 +298,7 @@ TestMetricsLog log_managed(kClientId, kSessionId, MetricsLog::ONGOING_LOG, &client, &prefs_); log_managed.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - synthetic_trials, kInstallDate, kEnabledDate); + kInstallDate, kEnabledDate); EXPECT_TRUE(log_managed.system_profile().has_uma_default_state()); EXPECT_EQ(SystemProfileProto_UmaDefaultState_POLICY_FORCED_ENABLED, log_managed.system_profile().uma_default_state()); @@ -355,9 +314,7 @@ TestMetricsProvider* test_provider = new TestMetricsProvider(); std::vector<std::unique_ptr<MetricsProvider>> metrics_providers; metrics_providers.push_back(base::WrapUnique<MetricsProvider>(test_provider)); - log.RecordEnvironment(metrics_providers, - std::vector<variations::ActiveGroupId>(), kInstallDate, - kEnabledDate); + log.RecordEnvironment(metrics_providers, kInstallDate, kEnabledDate); log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(), base::TimeDelta()); @@ -374,9 +331,7 @@ TestMetricsProvider* test_provider = new TestMetricsProvider(); std::vector<std::unique_ptr<MetricsProvider>> metrics_providers; metrics_providers.push_back(base::WrapUnique<MetricsProvider>(test_provider)); - log.RecordEnvironment(metrics_providers, - std::vector<variations::ActiveGroupId>(), kInstallDate, - kEnabledDate); + log.RecordEnvironment(metrics_providers, kInstallDate, kEnabledDate); log.RecordStabilityMetrics(metrics_providers, base::TimeDelta(), base::TimeDelta());
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc index 4e9fa9e..ef1d389 100644 --- a/components/metrics/metrics_service.cc +++ b/components/metrics/metrics_service.cc
@@ -145,6 +145,7 @@ #include "base/tracked_objects.h" #include "build/build_config.h" #include "components/metrics/environment_recorder.h" +#include "components/metrics/field_trials_provider.h" #include "components/metrics/metrics_log.h" #include "components/metrics/metrics_log_manager.h" #include "components/metrics/metrics_log_uploader.h" @@ -231,8 +232,11 @@ if (install_date == 0) local_state_->SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT()); - RegisterMetricsProvider(std::unique_ptr<metrics::MetricsProvider>( - new StabilityMetricsProvider(local_state_))); + RegisterMetricsProvider( + base::MakeUnique<StabilityMetricsProvider>(local_state_)); + + RegisterMetricsProvider(base::MakeUnique<variations::FieldTrialsProvider>( + &synthetic_trial_registry_)); } MetricsService::~MetricsService() { @@ -863,12 +867,8 @@ void MetricsService::RecordCurrentEnvironment(MetricsLog* log) { DCHECK(client_); - std::vector<variations::ActiveGroupId> synthetic_trials; - synthetic_trial_registry_.GetSyntheticFieldTrialsOlderThan( - log->creation_time(), &synthetic_trials); std::string serialized_environment = log->RecordEnvironment( - metrics_providers_, synthetic_trials, GetInstallDate(), - GetMetricsReportingEnabledDate()); + metrics_providers_, GetInstallDate(), GetMetricsReportingEnabledDate()); client_->OnEnvironmentUpdate(&serialized_environment); }
diff --git a/components/metrics/metrics_service_unittest.cc b/components/metrics/metrics_service_unittest.cc index 790c81b7..6c1497326 100644 --- a/components/metrics/metrics_service_unittest.cc +++ b/components/metrics/metrics_service_unittest.cc
@@ -191,8 +191,7 @@ // saved from a previous session. TestMetricsServiceClient client; TestMetricsLog log("client", 1, &client, GetLocalState()); - log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - std::vector<variations::ActiveGroupId>(), 0, 0); + log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), 0, 0); // Record stability build time and version from previous session, so that // stability metrics (including exited cleanly flag) won't be cleared. @@ -262,8 +261,7 @@ // saved from a previous session. TestMetricsServiceClient client; TestMetricsLog log("client", 1, &client, GetLocalState()); - log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), - std::vector<variations::ActiveGroupId>(), 0, 0); + log.RecordEnvironment(std::vector<std::unique_ptr<MetricsProvider>>(), 0, 0); // Record stability build time and version from previous session, so that // stability metrics (including exited cleanly flag) won't be cleared.
diff --git a/components/omnibox/bug-triage.md b/components/omnibox/bug-triage.md index daff8d4..2581801a 100644 --- a/components/omnibox/bug-triage.md +++ b/components/omnibox/bug-triage.md
@@ -138,10 +138,13 @@ | Label | Description | | --- | --- | -| Performance-Browser | Bugs that affect performance. | +| Hotlist-OmniboxFocus | Bugs about focus, including not having focus when it should, focussing on the wrong end of the URL, etc. (Note: label does not appear in the Hotlist completion dropdown.) | +| Hotlist-OmniboxKeyboardShortcuts | Bugs related to handling of keyboard shortcuts, including both incorrectly handling real omnibox shortcuts and preventing other Chrome shortcuts from working when focus is in the omnibox. (Note: label does not appear in the Hotlist completion dropdown.) | +| Hotlist-OmniboxRanking | Bugs related to which suggestions are considered matches against the input and how relevance scores are assigned. (Note: label does not appear in the Hotlist completion dropdown.) | | Hotlist-CodeHealth | Bugs about the making the code base easy to work with such as quality of comments. Refactoring efforts can also be included when for that purpose. | | Hotlist-Polish | Bugs about how a feature looks and feels: not whether the feature works or not; instead, more of whether it appears the feature was created with attention to detail. Often user-visible edge cases fit in this category. | | Hotlist-Refactoring | Bugs related to restructuring existing code without changing its behavior. | +| Performance-Browser | Bugs that affect performance. | The components that additionally apply to bugs include:
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc index f62ed9b..812127fd4 100644 --- a/components/payments/content/payment_request_state.cc +++ b/components/payments/content/payment_request_state.cc
@@ -279,13 +279,22 @@ // merchant. if (spec_->request_payer_name() || spec_->request_payer_phone() || spec_->request_payer_email()) { + bool has_complete_contact = + contact_profiles_.empty() + ? false + : profile_comparator()->IsContactInfoComplete(contact_profiles_[0]); journey_logger_->SetNumberOfSuggestionsShown( - JourneyLogger::Section::SECTION_CONTACT_INFO, contact_profiles_.size()); + JourneyLogger::Section::SECTION_CONTACT_INFO, contact_profiles_.size(), + has_complete_contact); } if (spec_->request_shipping()) { + bool has_complete_shipping = + shipping_profiles_.empty() + ? false + : profile_comparator()->IsShippingComplete(shipping_profiles_[0]); journey_logger_->SetNumberOfSuggestionsShown( JourneyLogger::Section::SECTION_SHIPPING_ADDRESS, - shipping_profiles_.size()); + shipping_profiles_.size(), has_complete_shipping); } // Create the list of available instruments. A copy of each card will be made @@ -295,12 +304,14 @@ for (autofill::CreditCard* card : cards) AddAutofillPaymentInstrument(/*selected=*/false, *card); - journey_logger_->SetNumberOfSuggestionsShown( - JourneyLogger::Section::SECTION_CREDIT_CARDS, - available_instruments().size()); + bool has_complete_instrument = + available_instruments().empty() + ? false + : available_instruments()[0]->IsCompleteForPayment(); - if (!available_instruments().empty()) - journey_logger_->SetUserHadInitialFormOfPayment(); + journey_logger_->SetNumberOfSuggestionsShown( + JourneyLogger::Section::SECTION_PAYMENT_METHOD, + available_instruments().size(), has_complete_instrument); } void PaymentRequestState::SetDefaultProfileSelections() {
diff --git a/components/payments/core/journey_logger.cc b/components/payments/core/journey_logger.cc index ae2d4b6..33e881e 100644 --- a/components/payments/core/journey_logger.cc +++ b/components/payments/core/journey_logger.cc
@@ -36,8 +36,8 @@ case JourneyLogger::SECTION_CONTACT_INFO: name_suffix = "ContactInfo."; break; - case JourneyLogger::SECTION_CREDIT_CARDS: - name_suffix = "CreditCards."; + case JourneyLogger::SECTION_PAYMENT_METHOD: + name_suffix = "PaymentMethod."; break; default: break; @@ -91,10 +91,13 @@ sections_[section].number_selection_edits_++; } -void JourneyLogger::SetNumberOfSuggestionsShown(Section section, int number) { +void JourneyLogger::SetNumberOfSuggestionsShown(Section section, + int number, + bool has_complete_suggestion) { DCHECK_LT(section, SECTION_MAX); sections_[section].number_suggestions_shown_ = number; sections_[section].is_requested_ = true; + sections_[section].has_complete_suggestion_ = has_complete_suggestion; } void JourneyLogger::SetCanMakePaymentValue(bool value) { @@ -158,10 +161,6 @@ UMA_HISTOGRAM_BOOLEAN("PaymentRequest.CheckoutFunnel.Initiated", true); } -void JourneyLogger::SetUserHadInitialFormOfPayment() { - user_had_initial_form_of_payment_ = true; -} - void JourneyLogger::RecordJourneyStatsHistograms( CompletionStatus completion_status) { DCHECK(!has_recorded_); @@ -212,6 +211,10 @@ // Record whether the user had suggestions for each requested information. bool user_had_all_requested_information = true; + // Record whether the user had at least one complete suggestion for each + // requested section. + bool user_had_complete_suggestions_ = true; + for (int i = 0; i < NUMBER_OF_SECTIONS; ++i) { std::string name_suffix = GetHistogramNameSuffix(i, completion_status); @@ -236,6 +239,9 @@ if (sections_[i].number_suggestions_shown_ == 0) { user_had_all_requested_information = false; + user_had_complete_suggestions_ = false; + } else if (!sections_[i].has_complete_suggestion_) { + user_had_complete_suggestions_ = false; } } } @@ -254,16 +260,16 @@ completion_status, COMPLETION_STATUS_MAX); } - // Recond the metric about completion status based on whether the user - // initally had a form of payment on file. - if (user_had_initial_form_of_payment_) { + // Record metrics about completion based on whether the user had complete + // suggestions for each requested information. + if (user_had_complete_suggestions_) { base::UmaHistogramEnumeration( - "PaymentRequest.UserHadInitialFormOfPayment." + "PaymentRequest.UserHadCompleteSuggestionsForEverything." "EffectOnCompletion", completion_status, COMPLETION_STATUS_MAX); } else { base::UmaHistogramEnumeration( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment." + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." "EffectOnCompletion", completion_status, COMPLETION_STATUS_MAX); }
diff --git a/components/payments/core/journey_logger.h b/components/payments/core/journey_logger.h index 143903fa..f32b062 100644 --- a/components/payments/core/journey_logger.h +++ b/components/payments/core/journey_logger.h
@@ -38,7 +38,7 @@ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: Section enum Section { SECTION_CONTACT_INFO = 0, - SECTION_CREDIT_CARDS = 1, + SECTION_PAYMENT_METHOD = 1, SECTION_SHIPPING_ADDRESS = 2, SECTION_MAX, }; @@ -153,7 +153,9 @@ void IncrementSelectionEdits(Section section); // Sets the number of suggestions shown for the specified section. - void SetNumberOfSuggestionsShown(Section section, int number); + void SetNumberOfSuggestionsShown(Section section, + int number, + bool has_valid_suggestion); // Records the fact that the merchant called CanMakePayment and records it's // return value. @@ -186,10 +188,6 @@ // reason. void SetNotShown(NotShownReason reason); - // Records the fact that the user had a Payment Method on file at the start of - // the Payment Request. - void SetUserHadInitialFormOfPayment(); - private: static const int NUMBER_OF_SECTIONS = 3; @@ -208,13 +206,15 @@ number_selection_changes_(0), number_selection_edits_(0), number_suggestions_shown_(0), - is_requested_(false) {} + is_requested_(false), + has_complete_suggestion_(false) {} int number_selection_adds_; int number_selection_changes_; int number_selection_edits_; int number_suggestions_shown_; bool is_requested_; + bool has_complete_suggestion_; }; // Records the histograms for all the sections that were requested by the @@ -258,7 +258,6 @@ bool was_can_make_payments_used_ = false; bool could_make_payment_ = false; bool was_show_called_ = false; - bool user_had_initial_form_of_payment_ = false; bool is_incognito_; // Accumulates the many events that have happened during the Payment Request.
diff --git a/components/payments/core/journey_logger_unittest.cc b/components/payments/core/journey_logger_unittest.cc index 394960f..af7a83a 100644 --- a/components/payments/core/journey_logger_unittest.cc +++ b/components/payments/core/journey_logger_unittest.cc
@@ -445,7 +445,8 @@ /*requested_phone=*/false, /*requested_name=*/false); // Simulate that the user had suggestions for all the requested sections. - logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 1); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 1, + /*has_complete_suggestion=*/false); // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -477,7 +478,8 @@ /*requested_phone=*/false, /*requested_name=*/false); // Simulate that the user had suggestions for all the requested sections. - logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 1); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 1, + /*has_complete_suggestion=*/false); // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -509,7 +511,8 @@ /*requested_phone=*/false, /*requested_name=*/false); // Simulate that the user had suggestions for all the requested sections. - logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 1); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 1, + /*has_complete_suggestion=*/false); // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -542,7 +545,8 @@ /*requested_phone=*/false, /*requested_name=*/false); // Simulate that the user had suggestions for all the requested sections. - logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 1); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 1, + /*has_complete_suggestion=*/false); // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -574,7 +578,8 @@ /*requested_phone=*/false, /*requested_name=*/false); // Simulate that the user had suggestions for none of the requested sections. - logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 0, + /*has_complete_suggestion=*/false); // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -607,7 +612,8 @@ /*requested_phone=*/false, /*requested_name=*/false); // Simulate that the user had suggestions for none of the requested sections. - logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 0, + /*has_complete_suggestion=*/false); // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -640,7 +646,8 @@ /*requested_phone=*/false, /*requested_name=*/false); // Simulate that the user had suggestions for none of the requested sections. - logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 0, + /*has_complete_suggestion=*/false); // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -674,7 +681,8 @@ /*requested_phone=*/false, /*requested_name=*/false); // Simulate that the user had suggestions for none of the requested sections. - logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 0, + /*has_complete_suggestion=*/false); // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -693,9 +701,11 @@ testing::ContainerEq(base::HistogramTester::CountsMap())); } -// Tests that the UserHadInitialFormOfPayment metric is correctly logged. -TEST(JourneyLoggerTest, - RecordJourneyStatsHistograms_UserHadInitialFormOfPayment) { +// Tests that the completion status metrics based on whether the user had +// suggestions for all the requested sections are logged as correctly. +TEST( + JourneyLoggerTest, + RecordJourneyStatsHistograms_NoCompleteSuggestionsForEverything_OtherAborted) { base::HistogramTester histogram_tester; JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); @@ -705,8 +715,10 @@ /*requested_shipping=*/false, /*requested_email=*/false, /*requested_phone=*/false, /*requested_name=*/false); - // Simulate that the user had an inital form of payment. - logger.SetUserHadInitialFormOfPayment(); + // Simulate that the user had incomplete suggestions for the requested + // sections. + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 2, + /*has_complete_suggestion=*/false); // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -715,25 +727,37 @@ logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); histogram_tester.ExpectBucketCount( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion", + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + "EffectOnCompletion", JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion", - 0); + + EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + "EffectOnCompletion"), + testing::ContainerEq(base::HistogramTester::CountsMap())); } -// Tests that the UserDidNotHaveInitialFormOfPayment metric is correctly logged. -TEST(JourneyLoggerTest, - RecordJourneyStatsHistograms_UserDidNotHaveInitialFormOfPayment) { +// Tests that the completion status metrics based on whether the user had +// suggestions for all the requested sections are logged as correctly. +TEST( + JourneyLoggerTest, + RecordJourneyStatsHistograms_NoCompleteSuggestionsForEverything_SomeComplete_OtherAborted) { base::HistogramTester histogram_tester; JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), /*ukm_recorder=*/nullptr); // The merchant only requests payment information. logger.SetRequestedInformation( - /*requested_shipping=*/false, /*requested_email=*/false, + /*requested_shipping=*/true, /*requested_email=*/false, /*requested_phone=*/false, /*requested_name=*/false); + // Simulate that the user had incomplete suggestions for one of the requested + // sections. + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 2, + /*has_complete_suggestion=*/false); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_SHIPPING_ADDRESS, 1, + /*has_complete_suggestion=*/true); + // Simulate that the Payment Request was shown to the user. logger.SetShowCalled(); @@ -741,35 +765,53 @@ logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); histogram_tester.ExpectBucketCount( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion", + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + "EffectOnCompletion", JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion", 0); + + EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix( + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + "EffectOnCompletion"), + testing::ContainerEq(base::HistogramTester::CountsMap())); } -// Tests that the InitialFormOfPayment metrics are only logged if the Payment -// Request is shown. -TEST(JourneyLoggerTest, - RecordJourneyStatsHistograms_InitialFormOfPayment_NotShown) { +// Tests that the completion status metrics based on whether the user had +// suggestions for all the requested sections are logged as correctly. +TEST( + JourneyLoggerTest, + RecordJourneyStatsHistograms_CompleteSuggestionsForEverything_OtherAborted) { base::HistogramTester histogram_tester; - JourneyLogger logger_with_fop(/*is_incognito=*/false, /*url=*/GURL(""), - /*ukm_recorder=*/nullptr); - JourneyLogger logger_without_fop(/*is_incognito=*/false, /*url=*/GURL(""), - /*ukm_recorder=*/nullptr); + JourneyLogger logger(/*is_incognito=*/false, /*url=*/GURL(""), + /*ukm_recorder=*/nullptr); - // Set that the user had an initial form of payment. - logger_with_fop.SetUserHadInitialFormOfPayment(); + // The merchant only requests payment information. + logger.SetRequestedInformation( + /*requested_shipping=*/true, /*requested_email=*/false, + /*requested_phone=*/false, /*requested_name=*/false); - // Simulate that the the checkouts are aborted. - logger_with_fop.SetAborted(JourneyLogger::ABORT_REASON_OTHER); - logger_without_fop.SetAborted(JourneyLogger::ABORT_REASON_ABORTED_BY_USER); + // Simulate that the user had incomplete suggestions for one of the requested + // sections. + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 2, + /*has_complete_suggestion=*/true); + logger.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_SHIPPING_ADDRESS, 1, + /*has_complete_suggestion=*/true); - // There should be no logs for the two metrics. - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion", - 0); - histogram_tester.ExpectTotalCount( - "PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion", 0); + // Simulate that the Payment Request was shown to the user. + logger.SetShowCalled(); + + // Simulate that the the checkout is aborted. + logger.SetAborted(JourneyLogger::ABORT_REASON_OTHER); + + histogram_tester.ExpectBucketCount( + "PaymentRequest.UserHadCompleteSuggestionsForEverything." + "EffectOnCompletion", + JourneyLogger::COMPLETION_STATUS_OTHER_ABORTED, 1); + + EXPECT_THAT( + histogram_tester.GetTotalCountsForPrefix( + "PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything." + "EffectOnCompletion"), + testing::ContainerEq(base::HistogramTester::CountsMap())); } // Tests that the metrics are logged correctly for two simultaneous Payment @@ -793,8 +835,10 @@ logger1.SetCanMakePaymentValue(true); - logger1.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 1); - logger2.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_CREDIT_CARDS, 0); + logger1.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 1, + /*has_complete_suggestion=*/false); + logger2.SetNumberOfSuggestionsShown(JourneyLogger::SECTION_PAYMENT_METHOD, 0, + /*has_complete_suggestion=*/false); // Simulate that the user completes one checkout and aborts the other. logger1.SetCompleted();
diff --git a/components/test/data/payments/metrics.js b/components/test/data/payments/metrics.js index fc8241b..d40298f 100644 --- a/components/test/data/payments/metrics.js +++ b/components/test/data/payments/metrics.js
@@ -234,10 +234,45 @@ }); request.show() .then(function(resp) { - return resp.complete('success'); + resp.complete('success') + .then(function() { + print(resp.methodName + '<br>' + + JSON.stringify(resp.details, undefined, 2)); + }) + .catch(function(error) { + print(error.message); + }); }) - .then(function() { - print(JSON.stringify(resp, undefined, 2)); + .catch(function(error) { + print(error.message); + }); + } catch (error) { + print(error.message); + } +} + +/** + * Launches the PaymentRequest UI that requests contact information. + */ +function contactInfoBuy() { // eslint-disable-line no-unused-vars + try { + new PaymentRequest( + [{supportedMethods: ['https://bobpay.com', 'amex', 'visa']}], + {total: {label: 'Total', amount: {currency: 'USD', value: '5.00'}}}, + {requestPayerName: true, requestPayerEmail: true, + requestPayerPhone: true}) + .show() + .then(function(resp) { + resp.complete('success') + .then(function() { + print( + resp.payerName + '<br>' + resp.payerEmail + '<br>' + + resp.payerPhone + '<br>' + resp.methodName + '<br>' + + JSON.stringify(resp.details, undefined, 2)); + }) + .catch(function(error) { + print(error); + }); }) .catch(function(error) { print(error);
diff --git a/components/test/data/payments/payment_request_metrics_test.html b/components/test/data/payments/payment_request_metrics_test.html index b8a8b14f..19d8d81 100644 --- a/components/test/data/payments/payment_request_metrics_test.html +++ b/components/test/data/payments/payment_request_metrics_test.html
@@ -15,7 +15,8 @@ <div> <button onclick="androidPayBuy()" id="androidPayBuy">Android Pay Buy Test</button> </div> <div> <button onclick="androidPaySkipUiBuy()" id="androidPaySkipUiBuy">Android Pay Skip UI Buy Test</button> </div> <div> <button onclick="noSupported()" id="noSupported">No Supported Method Test</button> </div> -<div> <button onclick="cardsAndBobPayBuy()" id="cardsAndBobPayBuy">Android Pay Buy Test</button> </div> +<div> <button onclick="cardsAndBobPayBuy()" id="cardsAndBobPayBuy">Bob Pay Buy Test</button> </div> +<div> <button onclick="contactInfoBuy()" id="contactInfoBuy">Contact Info Buy Test</button> </div> <button onclick="abort()" id="abort">Abort</button> <pre id="result"></pre> <script src="util.js"></script>
diff --git a/components/variations/synthetic_trial_registry.h b/components/variations/synthetic_trial_registry.h index b15fff8..db37ade0 100644 --- a/components/variations/synthetic_trial_registry.h +++ b/components/variations/synthetic_trial_registry.h
@@ -12,12 +12,13 @@ namespace metrics { class MetricsServiceAccessor; -class MetricsService; } // namespace metrics namespace variations { struct ActiveGroupId; +class FieldTrialsProvider; +class FieldTrialsProviderTest; class SyntheticTrialRegistry { public: @@ -32,7 +33,8 @@ private: friend metrics::MetricsServiceAccessor; - friend metrics::MetricsService; + friend FieldTrialsProvider; + friend FieldTrialsProviderTest; FRIEND_TEST_ALL_PREFIXES(SyntheticTrialRegistryTest, RegisterSyntheticTrial); FRIEND_TEST_ALL_PREFIXES(SyntheticTrialRegistryTest, RegisterSyntheticMultiGroupFieldTrial);
diff --git a/components/viz/client/client_layer_tree_frame_sink.cc b/components/viz/client/client_layer_tree_frame_sink.cc index 0cfef14..4425d5f 100644 --- a/components/viz/client/client_layer_tree_frame_sink.cc +++ b/components/viz/client/client_layer_tree_frame_sink.cc
@@ -79,6 +79,7 @@ client->SetBeginFrameSource(synthetic_begin_frame_source_.get()); } else { begin_frame_source_ = base::MakeUnique<cc::ExternalBeginFrameSource>(this); + begin_frame_source_->OnSetBeginFrameSourcePaused(begin_frames_paused_); client->SetBeginFrameSource(begin_frame_source_.get()); } @@ -139,6 +140,12 @@ begin_frame_source_->OnBeginFrame(begin_frame_args); } +void ClientLayerTreeFrameSink::OnBeginFramePausedChanged(bool paused) { + begin_frames_paused_ = paused; + if (begin_frame_source_) + begin_frame_source_->OnSetBeginFrameSourcePaused(paused); +} + void ClientLayerTreeFrameSink::ReclaimResources( const std::vector<cc::ReturnedResource>& resources) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/components/viz/client/client_layer_tree_frame_sink.h b/components/viz/client/client_layer_tree_frame_sink.h index 4a709aa..b2893cc 100644 --- a/components/viz/client/client_layer_tree_frame_sink.h +++ b/components/viz/client/client_layer_tree_frame_sink.h
@@ -61,6 +61,7 @@ void DidReceiveCompositorFrameAck( const std::vector<cc::ReturnedResource>& resources) override; void OnBeginFrame(const cc::BeginFrameArgs& begin_frame_args) override; + void OnBeginFramePausedChanged(bool paused) override; void ReclaimResources( const std::vector<cc::ReturnedResource>& resources) override; @@ -70,6 +71,7 @@ static void OnMojoConnectionError(uint32_t custom_reason, const std::string& description); + bool begin_frames_paused_ = false; LocalSurfaceId local_surface_id_; std::unique_ptr<LocalSurfaceIdProvider> local_surface_id_provider_; std::unique_ptr<cc::ExternalBeginFrameSource> begin_frame_source_;
diff --git a/components/viz/host/host_frame_sink_manager_unittests.cc b/components/viz/host/host_frame_sink_manager_unittests.cc index 450d92f..84e28835 100644 --- a/components/viz/host/host_frame_sink_manager_unittests.cc +++ b/components/viz/host/host_frame_sink_manager_unittests.cc
@@ -46,6 +46,7 @@ void DidReceiveCompositorFrameAck( const std::vector<cc::ReturnedResource>& resources) override {} void OnBeginFrame(const cc::BeginFrameArgs& begin_frame_args) override {} + void OnBeginFramePausedChanged(bool paused) override {} void ReclaimResources( const std::vector<cc::ReturnedResource>& resources) override {}
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index bedccb71..c13c567f 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -338,7 +338,10 @@ return last_begin_frame_args_; } -void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {} +void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) { + if (client_) + client_->OnBeginFramePausedChanged(paused); +} void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() { if (!begin_frame_source_)
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_client.h b/components/viz/service/frame_sinks/compositor_frame_sink_support_client.h index fa0f4782..792bd9dcb 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support_client.h +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_client.h
@@ -41,6 +41,9 @@ virtual void WillDrawSurface(const LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) = 0; + // Notification that there may not be OnBeginFrame calls for some time. + virtual void OnBeginFramePausedChanged(bool paused) = 0; + protected: virtual ~CompositorFrameSinkSupportClient() {} };
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc index 868be88..e876d65 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
@@ -75,6 +75,8 @@ void WillDrawSurface(const LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) override {} + void OnBeginFramePausedChanged(bool paused) override {} + void clear_returned_resources() { returned_resources_.clear(); } const std::vector<cc::ReturnedResource>& returned_resources() { return returned_resources_;
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc index 792ef37a..d0e94605 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -162,6 +162,10 @@ // TODO(staraz): Implement this. } +void DirectLayerTreeFrameSink::OnBeginFramePausedChanged(bool paused) { + begin_frame_source_->OnSetBeginFrameSourcePaused(paused); +} + void DirectLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frame) { support_->SetNeedsBeginFrame(needs_begin_frame); }
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h index 602c804..0a1724f 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
@@ -75,6 +75,7 @@ const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) override; + void OnBeginFramePausedChanged(bool paused) override; // ExternalBeginFrameSourceClient implementation: void OnNeedsBeginFrames(bool needs_begin_frame) override;
diff --git a/components/viz/service/frame_sinks/gpu_compositor_frame_sink.cc b/components/viz/service/frame_sinks/gpu_compositor_frame_sink.cc index 4f2e6f6..12e0d5b 100644 --- a/components/viz/service/frame_sinks/gpu_compositor_frame_sink.cc +++ b/components/viz/service/frame_sinks/gpu_compositor_frame_sink.cc
@@ -78,6 +78,11 @@ client_->OnBeginFrame(args); } +void GpuCompositorFrameSink::OnBeginFramePausedChanged(bool paused) { + if (client_) + client_->OnBeginFramePausedChanged(paused); +} + void GpuCompositorFrameSink::ReclaimResources( const std::vector<cc::ReturnedResource>& resources) { if (client_)
diff --git a/components/viz/service/frame_sinks/gpu_compositor_frame_sink.h b/components/viz/service/frame_sinks/gpu_compositor_frame_sink.h index 20b24be..54a4056 100644 --- a/components/viz/service/frame_sinks/gpu_compositor_frame_sink.h +++ b/components/viz/service/frame_sinks/gpu_compositor_frame_sink.h
@@ -50,6 +50,7 @@ void DidReceiveCompositorFrameAck( const std::vector<cc::ReturnedResource>& resources) override; void OnBeginFrame(const cc::BeginFrameArgs& args) override; + void OnBeginFramePausedChanged(bool paused) override; void ReclaimResources( const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const LocalSurfaceId& local_surface_id,
diff --git a/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.cc b/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.cc index 19d3ea1e..610d3f8 100644 --- a/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.cc +++ b/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.cc
@@ -135,6 +135,11 @@ client_->OnBeginFrame(args); } +void GpuRootCompositorFrameSink::OnBeginFramePausedChanged(bool paused) { + if (client_) + client_->OnBeginFramePausedChanged(paused); +} + void GpuRootCompositorFrameSink::ReclaimResources( const std::vector<cc::ReturnedResource>& resources) { if (client_)
diff --git a/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.h b/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.h index dec063e..05ef8d6 100644 --- a/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.h +++ b/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.h
@@ -75,6 +75,7 @@ void DidReceiveCompositorFrameAck( const std::vector<cc::ReturnedResource>& resources) override; void OnBeginFrame(const cc::BeginFrameArgs& args) override; + void OnBeginFramePausedChanged(bool paused) override; void ReclaimResources( const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const LocalSurfaceId& local_surface_id,
diff --git a/components/viz/test/test_layer_tree_frame_sink.cc b/components/viz/test/test_layer_tree_frame_sink.cc index 016cee4..3bd30806 100644 --- a/components/viz/test/test_layer_tree_frame_sink.cc +++ b/components/viz/test/test_layer_tree_frame_sink.cc
@@ -198,6 +198,8 @@ const LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) {} +void TestLayerTreeFrameSink::OnBeginFramePausedChanged(bool paused) {} + void TestLayerTreeFrameSink::DisplayOutputSurfaceLost() { client_->DidLoseLayerTreeFrameSink(); }
diff --git a/components/viz/test/test_layer_tree_frame_sink.h b/components/viz/test/test_layer_tree_frame_sink.h index 40d663d..bf4ba001 100644 --- a/components/viz/test/test_layer_tree_frame_sink.h +++ b/components/viz/test/test_layer_tree_frame_sink.h
@@ -95,6 +95,7 @@ const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) override; + void OnBeginFramePausedChanged(bool paused) override; // DisplayClient implementation. void DisplayOutputSurfaceLost() override;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 6d7e11c..bde20f69 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -4009,11 +4009,8 @@ void RenderFrameHostImpl::GetInterface( const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) { - if (interface_registry_.get() && - interface_registry_->CanBindInterface(interface_name)) { - interface_registry_->BindInterface(interface_name, - std::move(interface_pipe)); - } else { + if (!interface_registry_ || + !interface_registry_->TryBindInterface(interface_name, &interface_pipe)) { GetContentClient()->browser()->BindInterfaceRequestFromFrame( this, interface_name, std::move(interface_pipe)); }
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index e591499..e9a90ca 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -758,6 +758,10 @@ renderer_compositor_frame_sink_->OnBeginFrame(args); } +void RenderWidgetHostViewChildFrame::OnBeginFramePausedChanged(bool paused) { + renderer_compositor_frame_sink_->OnBeginFramePausedChanged(paused); +} + void RenderWidgetHostViewChildFrame::SetNeedsBeginFrames( bool needs_begin_frames) { if (support_)
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h index b0a77cb..297163e0 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.h +++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -179,6 +179,7 @@ const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const viz::LocalSurfaceId& id, const gfx::Rect& damage_rect) override {} + void OnBeginFramePausedChanged(bool paused) override; // Exposed for tests. bool IsChildFrameForTesting() const override;
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 558f242..8c2dd4d 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -352,9 +352,7 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe, service_manager::Connector* connector) override { - if (registry_.CanBindInterface(interface_name)) { - registry_.BindInterface(interface_name, std::move(*interface_pipe)); - } else { + if (!registry_.TryBindInterface(interface_name, interface_pipe)) { GetContentClient()->browser()->BindInterfaceRequest( source_info, interface_name, interface_pipe); }
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index 3cb085d..eb3a2ee83 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -508,6 +508,11 @@ AttemptFrameSubscriberCapture(damage_rect); } +void DelegatedFrameHost::OnBeginFramePausedChanged(bool paused) { + if (renderer_compositor_frame_sink_) + renderer_compositor_frame_sink_->OnBeginFramePausedChanged(paused); +} + void DelegatedFrameHost::OnBeginFrame(const cc::BeginFrameArgs& args) { if (renderer_compositor_frame_sink_) renderer_compositor_frame_sink_->OnBeginFrame(args);
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h index 94262a4..383422e 100644 --- a/content/browser/renderer_host/delegated_frame_host.h +++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -113,6 +113,7 @@ const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const viz::LocalSurfaceId& id, const gfx::Rect& damage_rect) override; + void OnBeginFramePausedChanged(bool paused) override; // Public interface exposed to RenderWidgetHostView.
diff --git a/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc b/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc index 0cd3bf9b..6d49029 100644 --- a/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc +++ b/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc
@@ -125,19 +125,10 @@ int command_id) const { bool editable = rwhv_->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE; bool readable = rwhv_->GetTextInputType() != ui::TEXT_INPUT_TYPE_PASSWORD; - // TODO(wjmaclean): The test for has_selection should be changed to - // - // rwhv_->GetSelectionRange(&selection_range); - // bool has_selection = !selection_range.is_empty(); - // - // like in TouchSelectionControllerClientAura. Unfortunately this fails here - // due to https://crbug.com/723790, which means that the first text - // selected in an oopif subframe when it acquires focus will fail to send - // a FrameHostMsg_SelectionChanged, meaning the TextInputManager won't - // know about the new selection. - bool has_selection = selection_start_.type() != gfx::SelectionBound::EMPTY && - selection_end_.type() != gfx::SelectionBound::EMPTY && - selection_start_ != selection_end_; + + gfx::Range selection_range; + bool has_selection = + rwhv_->GetSelectionRange(&selection_range) && !selection_range.is_empty(); switch (command_id) { case IDS_APP_CUT: return editable && readable && has_selection;
diff --git a/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc b/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc index f3b8a1e..9784025 100644 --- a/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc +++ b/content/browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc
@@ -83,6 +83,7 @@ void DidReceiveCompositorFrameAck( const std::vector<cc::ReturnedResource>& resources) override {} void OnBeginFrame(const cc::BeginFrameArgs& begin_frame_args) override {} + void OnBeginFramePausedChanged(bool paused) override {} void ReclaimResources( const std::vector<cc::ReturnedResource>& resources) override {}
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index edac736..37ecb41 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1099,8 +1099,7 @@ if (!enabled_) return; - if (registry_->CanBindInterface(interface_name)) - registry_->BindInterface(interface_name, std::move(*interface_pipe)); + registry_->TryBindInterface(interface_name, interface_pipe); } base::ThreadChecker thread_checker_; @@ -2539,7 +2538,6 @@ switches::kForceOverlayFullscreenVideo, switches::kFullMemoryCrashReport, switches::kIgnoreAutoplayRestrictionsForTests, - switches::kInertVisualViewport, switches::kIPCConnectionTimeout, switches::kIsolateOrigins, switches::kIsRunningInMash,
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 7218c7f..9f50939 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -428,9 +428,6 @@ atoi(command_line.GetSwitchValueASCII( switches::kAcceleratedCanvas2dMSAASampleCount).c_str()); - prefs.inert_visual_viewport = - command_line.HasSwitch(switches::kInertVisualViewport); - prefs.use_solid_color_scrollbars = false; prefs.history_entry_requires_user_gesture =
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 99c8662..866dd54 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1633,8 +1633,7 @@ return; observing_root_window_ = true; - if (host_) - host_->Send(new ViewMsg_SetBeginFramePaused(host_->GetRoutingID(), false)); + SendBeginFramePaused(); view_.GetWindowAndroid()->AddObserver(this); // When using browser compositor, DelegatedFrameHostAndroid provides the BFS. if (!using_browser_compositor_) @@ -1660,8 +1659,7 @@ is_window_activity_started_ = true; is_window_visible_ = true; observing_root_window_ = false; - if (host_) - host_->Send(new ViewMsg_SetBeginFramePaused(host_->GetRoutingID(), true)); + SendBeginFramePaused(); view_.GetWindowAndroid()->RemoveObserver(this); if (!using_browser_compositor_) SetBeginFrameSource(nullptr); @@ -2245,11 +2243,24 @@ return last_begin_frame_args_; } +void RenderWidgetHostViewAndroid::SendBeginFramePaused() { + bool paused = begin_frame_paused_ || !observing_root_window_; + + if (!using_browser_compositor_) { + if (host_) { + host_->Send( + new ViewMsg_SetBeginFramePaused(host_->GetRoutingID(), paused)); + } + } else if (renderer_compositor_frame_sink_) { + renderer_compositor_frame_sink_->OnBeginFramePausedChanged(paused); + } +} + void RenderWidgetHostViewAndroid::OnBeginFrameSourcePausedChanged(bool paused) { - // The BeginFrameSources we listen to don't use this. For WebView, we signal - // the "paused" state to the RenderWidget when our window attaches/detaches, - // see |StartObservingRootWindow()| and |StopObservingRootWindow()|. - DCHECK(!paused); + if (paused != begin_frame_paused_) { + begin_frame_paused_ = paused; + SendBeginFramePaused(); + } } void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time) {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index b0321f94..19d6b94 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -352,6 +352,7 @@ void AcknowledgeBeginFrame(const cc::BeginFrameAck& ack); void StartObservingRootWindow(); void StopObservingRootWindow(); + void SendBeginFramePaused(); void SendBeginFrame(cc::BeginFrameArgs args); bool Animate(base::TimeTicks frame_time); void RequestDisallowInterceptTouchEvent(); @@ -374,6 +375,7 @@ // The begin frame source being observed. Null if none. cc::BeginFrameSource* begin_frame_source_; cc::BeginFrameArgs last_begin_frame_args_; + bool begin_frame_paused_ = false; // Indicates whether and for what reason a request for begin frames has been // issued. Used to control action dispatch at the next |OnBeginFrame()| call.
diff --git a/content/browser/screen_orientation/screen_orientation_delegate_android.cc b/content/browser/screen_orientation/screen_orientation_delegate_android.cc index ebd1f94..4fc5d57 100644 --- a/content/browser/screen_orientation/screen_orientation_delegate_android.cc +++ b/content/browser/screen_orientation/screen_orientation_delegate_android.cc
@@ -39,8 +39,11 @@ } bool ScreenOrientationDelegateAndroid::ScreenOrientationProviderSupported() { - // Always supported on Android - return true; + // TODO(MLamouri): Consider moving isOrientationLockEnabled to a separate + // function, so reported error messages can differentiate between the device + // never supporting orientation or currently not support orientation. + return Java_ScreenOrientationProvider_isOrientationLockEnabled( + base::android::AttachCurrentThread()); } void ScreenOrientationDelegateAndroid::Unlock(WebContents* web_contents) {
diff --git a/content/browser/service_manager/common_browser_interfaces.cc b/content/browser/service_manager/common_browser_interfaces.cc index 95bdea2..dbe8696e 100644 --- a/content/browser/service_manager/common_browser_interfaces.cc +++ b/content/browser/service_manager/common_browser_interfaces.cc
@@ -63,10 +63,7 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe, service_manager::Connector* connector) override { - if (registry_.CanBindInterface(interface_name)) { - registry_.BindInterface(interface_name, std::move(*interface_pipe), - source_info); - } + registry_.TryBindInterface(interface_name, interface_pipe, source_info); } template <typename Interface>
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 4f1f4130..b6eac88 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -228,6 +228,8 @@ "java/src/org/chromium/content_public/browser/NavigationEntry.java", "java/src/org/chromium/content_public/browser/NavigationHistory.java", "java/src/org/chromium/content_public/browser/RenderFrameHost.java", + "java/src/org/chromium/content_public/browser/ScreenOrientationDelegate.java", + "java/src/org/chromium/content_public/browser/ScreenOrientationDelegateManager.java", "java/src/org/chromium/content_public/browser/SmartClipCallback.java", "java/src/org/chromium/content_public/browser/WebContents.java", "java/src/org/chromium/content_public/browser/WebContentsObserver.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java index 83aa4cd..cb641297 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java +++ b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java
@@ -13,6 +13,7 @@ import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.content_public.browser.ScreenOrientationDelegate; import org.chromium.content_public.common.ScreenOrientationConstants; import org.chromium.content_public.common.ScreenOrientationValues; import org.chromium.ui.base.WindowAndroid; @@ -26,6 +27,7 @@ @JNINamespace("content") public class ScreenOrientationProvider { private static final String TAG = "cr.ScreenOrientation"; + private static ScreenOrientationDelegate sDelegate; private static int getOrientationFromWebScreenOrientations(byte orientation, @Nullable WindowAndroid window, Context context) { @@ -71,6 +73,8 @@ @CalledByNative public static void lockOrientation(@Nullable WindowAndroid window, byte webScreenOrientation) { + if (sDelegate != null && !sDelegate.canLockOrientation()) return; + // WindowAndroid may be null if the tab is being reparented. if (window == null) return; Activity activity = window.getActivity().get(); @@ -119,10 +123,21 @@ } catch (PackageManager.NameNotFoundException e) { // Do nothing, defaultOrientation should be SCREEN_ORIENTATION_UNSPECIFIED. } finally { - activity.setRequestedOrientation(defaultOrientation); + if (sDelegate == null || sDelegate.canUnlockOrientation(activity, defaultOrientation)) { + activity.setRequestedOrientation(defaultOrientation); + } } } + @CalledByNative + static boolean isOrientationLockEnabled() { + return sDelegate == null || sDelegate.canLockOrientation(); + } + + public static void setOrientationDelegate(ScreenOrientationDelegate delegate) { + sDelegate = delegate; + } + private ScreenOrientationProvider() { } }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegate.java b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegate.java new file mode 100644 index 0000000..deb681faa --- /dev/null +++ b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegate.java
@@ -0,0 +1,26 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content_public.browser; + +import android.app.Activity; + +/** + * An interface for ScreenOrientationProvider to notify other components that orientation + * preferences may change. + */ +public interface ScreenOrientationDelegate { + /** + * Notify the delegate that ScreenOrientationProvider consumers would like to unlock orientation + * for an activity. Returns true if ScreenOrientationProvider should unlock orientation, and + * false if the delegate already handled it. + */ + boolean canUnlockOrientation(Activity activity, int defaultOrientation); + + /** + * Allows the delegate to control whether ScreenOrientationProvider clients + * can lock orientation. + */ + boolean canLockOrientation(); +} \ No newline at end of file
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegateManager.java b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegateManager.java new file mode 100644 index 0000000..f536c7b17 --- /dev/null +++ b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegateManager.java
@@ -0,0 +1,21 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content_public.browser; + +import org.chromium.content.browser.ScreenOrientationProvider; + +/** + * An static class used for managing registration of ScreenOrientationDelegates. + */ +public final class ScreenOrientationDelegateManager { + /** + * Sets the current ScreenOrientationDelegate. + */ + public static void setOrientationDelegate(ScreenOrientationDelegate delegate) { + ScreenOrientationProvider.setOrientationDelegate(delegate); + } + + private ScreenOrientationDelegateManager() {} +} \ No newline at end of file
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index 25ddd4c..95656cd4 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -157,7 +157,6 @@ IPC_STRUCT_TRAITS_MEMBER(allow_file_access_from_file_urls) IPC_STRUCT_TRAITS_MEMBER(experimental_webgl_enabled) IPC_STRUCT_TRAITS_MEMBER(pepper_3d_enabled) - IPC_STRUCT_TRAITS_MEMBER(inert_visual_viewport) IPC_STRUCT_TRAITS_MEMBER(record_whole_document) IPC_STRUCT_TRAITS_MEMBER(use_solid_color_scrollbars) IPC_STRUCT_TRAITS_MEMBER(flash_3d_enabled)
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 5ad97d8a..d7101f4 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -593,9 +593,6 @@ const char kIgnoreCertificateErrorsSPKIList[] = "ignore-certificate-errors-spki-list"; -// Makes all APIs reflect the layout viewport. -const char kInertVisualViewport[] = "inert-visual-viewport"; - // Run the GPU process as a thread in the browser process. const char kInProcessGPU[] = "in-process-gpu";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 95137e3..0227769 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -177,7 +177,6 @@ CONTENT_EXPORT extern const char kHistoryEntryRequiresUserGesture[]; CONTENT_EXPORT extern const char kHostResolverRules[]; CONTENT_EXPORT extern const char kIgnoreCertificateErrorsSPKIList[]; -CONTENT_EXPORT extern const char kInertVisualViewport[]; CONTENT_EXPORT extern const char kInProcessGPU[]; CONTENT_EXPORT extern const char kIPCConnectionTimeout[]; CONTENT_EXPORT extern const char kIsolateOrigins[];
diff --git a/content/public/common/simple_connection_filter.cc b/content/public/common/simple_connection_filter.cc index 4131ef5..e6f9b82 100644 --- a/content/public/common/simple_connection_filter.cc +++ b/content/public/common/simple_connection_filter.cc
@@ -17,8 +17,7 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe, service_manager::Connector* connector) { - if (registry_->CanBindInterface(interface_name)) - registry_->BindInterface(interface_name, std::move(*interface_pipe)); + registry_->TryBindInterface(interface_name, interface_pipe); } SimpleConnectionFilterWithSourceInfo::SimpleConnectionFilterWithSourceInfo( @@ -33,9 +32,7 @@ const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe, service_manager::Connector* connector) { - if (registry_->CanBindInterface(interface_name)) - registry_->BindInterface(interface_name, std::move(*interface_pipe), - source_info); + registry_->TryBindInterface(interface_name, interface_pipe, source_info); } } // namespace content
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index 4311aff33..767e91cc 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc
@@ -172,7 +172,6 @@ use_solid_color_scrollbars(false), navigate_on_drag_drop(true), v8_cache_options(V8_CACHE_OPTIONS_DEFAULT), - inert_visual_viewport(false), record_whole_document(false), cookie_enabled(true), pepper_accelerated_video_decode_enabled(false),
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index 643c288..5012952 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h
@@ -192,7 +192,6 @@ bool use_solid_color_scrollbars; bool navigate_on_drag_drop; V8CacheOptions v8_cache_options; - bool inert_visual_viewport; bool record_whole_document; // This flags corresponds to a Page's Settings' setCookieEnabled state. It
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.cc b/content/renderer/android/synchronous_layer_tree_frame_sink.cc index 1291b20..b283839 100644 --- a/content/renderer/android/synchronous_layer_tree_frame_sink.cc +++ b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
@@ -503,4 +503,6 @@ const viz::LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) {} +void SynchronousLayerTreeFrameSink::OnBeginFramePausedChanged(bool paused) {} + } // namespace content
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.h b/content/renderer/android/synchronous_layer_tree_frame_sink.h index 3182fb3..0972157 100644 --- a/content/renderer/android/synchronous_layer_tree_frame_sink.h +++ b/content/renderer/android/synchronous_layer_tree_frame_sink.h
@@ -106,6 +106,7 @@ const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) override; + void OnBeginFramePausedChanged(bool paused) override; private: class SoftwareOutputSurface;
diff --git a/content/renderer/input/frame_input_handler_impl.cc b/content/renderer/input/frame_input_handler_impl.cc index 2974163..009c6de 100644 --- a/content/renderer/input/frame_input_handler_impl.cc +++ b/content/renderer/input/frame_input_handler_impl.cc
@@ -13,6 +13,7 @@ #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" #include "content/renderer/render_widget.h" +#include "third_party/WebKit/public/web/WebInputMethodController.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" namespace content { @@ -255,8 +256,9 @@ if (!render_frame_) return; - const blink::WebRange& range = - render_frame_->GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange(); + const blink::WebRange& range = render_frame_->GetWebFrame() + ->GetInputMethodController() + ->GetSelectionOffsets(); if (range.IsNull()) return; @@ -298,8 +300,9 @@ if (!render_frame_) return; - blink::WebRange range = - render_frame_->GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange(); + blink::WebRange range = render_frame_->GetWebFrame() + ->GetInputMethodController() + ->GetSelectionOffsets(); if (range.IsNull()) return;
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index ba453bd..9002567 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -196,15 +196,15 @@ webkit_preferences.embedded_media_experience_enabled; #endif // defined(OS_ANDROID) + // Enable background optimizations based on field trial for src= content, but + // always enable for MSE content. See http://crbug.com/709302. base::TimeDelta max_keyframe_distance_to_disable_background_video = base::TimeDelta::FromMilliseconds(base::GetFieldTrialParamByFeatureAsInt( media::kBackgroundVideoTrackOptimization, "max_keyframe_distance_ms", - base::TimeDelta::FromSeconds(10).InMilliseconds())); + 0)); base::TimeDelta max_keyframe_distance_to_disable_background_video_mse = - base::TimeDelta::FromMilliseconds(base::GetFieldTrialParamByFeatureAsInt( - media::kBackgroundVideoTrackOptimization, - "max_keyframe_distance_media_source_ms", - base::TimeDelta::FromSeconds(10).InMilliseconds())); + base::TimeDelta::FromSeconds(5); + // When memory pressure based garbage collection is enabled for MSE, the // |enable_instant_source_buffer_gc| flag controls whether the GC is done // immediately on memory pressure notification or during the next SourceBuffer
diff --git a/content/renderer/media/mock_web_rtc_peer_connection_handler_client.cc b/content/renderer/media/mock_web_rtc_peer_connection_handler_client.cc index 8467004..fa2e147 100644 --- a/content/renderer/media/mock_web_rtc_peer_connection_handler_client.cc +++ b/content/renderer/media/mock_web_rtc_peer_connection_handler_client.cc
@@ -34,15 +34,9 @@ void MockWebRTCPeerConnectionHandlerClient::didGenerateICECandidateWorker( const blink::WebRTCICECandidate& candidate) { - if (!candidate.IsNull()) { - candidate_sdp_ = candidate.Candidate().Utf8(); - candidate_mline_index_ = candidate.SdpMLineIndex(); - candidate_mid_ = candidate.SdpMid().Utf8(); - } else { - candidate_sdp_ = ""; - candidate_mline_index_ = -1; - candidate_mid_ = ""; - } + candidate_sdp_ = candidate.Candidate().Utf8(); + candidate_mline_index_ = candidate.SdpMLineIndex(); + candidate_mid_ = candidate.SdpMid().Utf8(); } void MockWebRTCPeerConnectionHandlerClient::didAddRemoteStreamWorker(
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc index 294f0fa7..a517a4b 100644 --- a/content/renderer/media/rtc_peer_connection_handler.cc +++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -1932,13 +1932,6 @@ TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceGatheringChange"); if (new_state == webrtc::PeerConnectionInterface::kIceGatheringComplete) { - // If ICE gathering is completed, generate a NULL ICE candidate, - // to signal end of candidates. - if (!is_closed_) { - blink::WebRTCICECandidate null_candidate; - client_->DidGenerateICECandidate(null_candidate); - } - UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv4LocalCandidates", num_local_candidates_ipv4_);
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 86818c6..32511e9 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1986,7 +1986,7 @@ void RenderFrameImpl::OnAdjustSelectionByCharacterOffset(int start_adjust, int end_adjust) { - WebRange range = GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange(); + WebRange range = frame_->GetInputMethodController()->GetSelectionOffsets(); if (range.IsNull()) return; @@ -2008,7 +2008,7 @@ void RenderFrameImpl::OnCollapseSelection() { const WebRange& range = - GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange(); + frame_->GetInputMethodController()->GetSelectionOffsets(); if (range.IsNull()) return; @@ -6243,7 +6243,7 @@ #endif { WebRange selection = - GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange(); + frame_->GetInputMethodController()->GetSelectionOffsets(); if (selection.IsNull()) return; @@ -6266,9 +6266,8 @@ text = frame_->SelectionAsText().Utf16(); // http://crbug.com/101435 // In some case, frame->selectionAsText() returned text's length is not - // equal to the length returned from - // GetWebWidget()->caretOrSelectionRange(). - // So we have to set the range according to text.length(). + // equal to the length returned from frame_->GetSelectionOffsets(). So we + // have to set the range according to text.length(). range.set_end(range.start() + text.length()); } }
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 1e589a5b..f26cc788 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -890,8 +890,6 @@ settings->SetSupportsMultipleWindows(prefs.supports_multiple_windows); - settings->SetInertVisualViewport(prefs.inert_visual_viewport); - settings->SetMainFrameClipsContent(!prefs.record_whole_document); settings->SetSmartInsertDeleteEnabled(prefs.smart_insert_delete_enabled);
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 5ed6989..1b342c2 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -223,10 +223,8 @@ RenderFrameHost* render_frame_host, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) { - if (frame_interfaces_.CanBindInterface(interface_name)) { - frame_interfaces_.BindInterface(interface_name, std::move(interface_pipe), - render_frame_host); - } + frame_interfaces_.TryBindInterface(interface_name, &interface_pipe, + render_frame_host); } void ShellContentBrowserClient::RegisterInProcessServices(
diff --git a/content/test/data/media/peerconnection-setConfiguration.html b/content/test/data/media/peerconnection-setConfiguration.html index 8a896c1..a24482889 100644 --- a/content/test/data/media/peerconnection-setConfiguration.html +++ b/content/test/data/media/peerconnection-setConfiguration.html
@@ -31,15 +31,13 @@ // Now test successful cases of setConfiguration. Changes should trigger an // ICE restart in the next offer. To do this, first we need to trigger an // initial ICE gathering phase and wait until it completes. - // TODO(deadbeef): Once onicegatheringstatechange is implemented, use that - // instead of a "null" candidate. - gPeerConnection.onicecandidate = iceCandidateCallback1; + gPeerConnection.onicegatheringstatechange = iceGatheringCallback1; createOfferAndSetLocalDescription(); } - function iceCandidateCallback1(candidate) { + function iceGatheringCallback1(candidate) { if (gPeerConnection.iceGatheringState === 'complete') { - gPeerConnection.onicecandidate = iceCandidateCallback2; + gPeerConnection.onicegatheringstatechange = iceGatheringCallback2; // Policy changed. gPeerConnection.setConfiguration( {iceServers:[], iceTransportPolicy:'relay', bundlePolicy:'balanced', @@ -48,9 +46,9 @@ } } - function iceCandidateCallback2(candidate) { + function iceGatheringCallback2(candidate) { if (gPeerConnection.iceGatheringState === 'complete') { - gPeerConnection.onicecandidate = iceCandidateCallback3; + gPeerConnection.onicegatheringstatechange = iceGatheringCallback3; // Servers changed. gPeerConnection.setConfiguration( {iceServers:[{urls:'stun:foo.invalid'}], iceTransportPolicy:'all', @@ -60,7 +58,7 @@ } } - function iceCandidateCallback3(candidate) { + function iceGatheringCallback3(candidate) { // Only wait for 'gathering', since it will take a while for the requests to // 'foo.invalid' to time out. if (gPeerConnection.iceGatheringState === 'gathering') {
diff --git a/content/test/data/media/webrtc_test_common.js b/content/test/data/media/webrtc_test_common.js index 8455e4d..07179eb6 100644 --- a/content/test/data/media/webrtc_test_common.js +++ b/content/test/data/media/webrtc_test_common.js
@@ -117,16 +117,24 @@ * @private */ function connectOnIceCandidate_(caller, callee) { - caller.onicecandidate = function(event) { onIceCandidate_(event, callee); } - callee.onicecandidate = function(event) { onIceCandidate_(event, caller); } + caller.onicecandidate = function(event) { + onIceCandidate_(event, caller, callee); + } + callee.onicecandidate = function(event) { + onIceCandidate_(event, callee, caller); + } } /** * @private */ -function onIceCandidate_(event, target) { +function onIceCandidate_(event, originator, target) { if (event.candidate) { var candidate = new RTCIceCandidate(event.candidate); target.addIceCandidate(candidate); + } else { + // The spec guarantees that the special "null" candidate will be fired + // *after* changing the gathering state to "complete". + assertEquals('complete', originator.iceGatheringState); } }
diff --git a/content/test/fake_renderer_compositor_frame_sink.h b/content/test/fake_renderer_compositor_frame_sink.h index 5e2655b..31e1239 100644 --- a/content/test/fake_renderer_compositor_frame_sink.h +++ b/content/test/fake_renderer_compositor_frame_sink.h
@@ -29,6 +29,7 @@ void DidReceiveCompositorFrameAck( const std::vector<cc::ReturnedResource>& resources) override; void OnBeginFrame(const cc::BeginFrameArgs& args) override {} + void OnBeginFramePausedChanged(bool paused) override {} void ReclaimResources( const std::vector<cc::ReturnedResource>& resources) override;
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py index df3e3ebd..258b9a0 100755 --- a/content/test/gpu/generate_buildbot_json.py +++ b/content/test/gpu/generate_buildbot_json.py
@@ -1057,7 +1057,10 @@ '--test-launcher-batch-limit=400', '--deqp-egl-display-type=angle-gles' ], - 'android_args': ['--enable-xml-result-parsing'] + 'android_args': [ + '--enable-xml-result-parsing', + '--shard-timeout=300' + ], }, 'angle_deqp_gles3_gles_tests': {
diff --git a/docs/fuchsia_sdk_updates.md b/docs/fuchsia_sdk_updates.md new file mode 100644 index 0000000..427d735c --- /dev/null +++ b/docs/fuchsia_sdk_updates.md
@@ -0,0 +1,71 @@ +# Publishing a new Fuchsia SDK, and updating Chrome to use it + +Updating the Fuchsia SDK in Chromium currently involves: +1. Building and testing the latest Fuchsia version. +0. Packaging the SDK from that and uploading to cloud storage. +0. Updating Chromium with DEPS and any other changes to build with the new SDK. + +## Build and test Fuchsia + +For current documentation on Fuchsia setup, visit the [Fuchsia Getting Started Guide](https://fuchsia.googlesource.com/docs/+/HEAD/getting_started.md). + +Perform these steps on your Linux workstation: +1. Check if fuchsia-dashboard.appspot.com looks green. +0. Fetch the latest Fuchsia source. + + $ jiri update + +0. Build Magenta, the sysroot, and Fuchsia. + + $ fbuild + +Now verify that the build is stable: + +1. Either: Boot the build in QEMU - you will probably want to use -k to enable KVM acceleration (see the guide for details of other options to enable networking, graphics, etc). + + $ frun -k + +0. Or (preferably): Boot the build on hardware (see the guide for details of first-time setup). + + $ fboot + +0. Run tests to verify the build. All the tests should pass! If they don't then find out which of the test fixtures is failing and ping #cr-fuchsia on IRC to determine if it's a known issue. + + $ runtests + +## Build and upload the SDK +1. Configure and build a release mode build with sdk config: + + $ ./packages/gn/gen.py --release --goma -m runtime + $ ./packages/gn/build.py --release -j1000 + +0. Package the sysroot and tools. + + $ ./scripts/makesdk.go . + +0. Compute the SHA-1 hash of the tarball, to use as its filename. + + $ sha1sum fuchsia-sdk.tgz + f79f55be4e69ebd90ea84f79d7322525853256c3 + +0. Note that it's possible to un-tar the SDK into place in your Chromium checkout at this point, for testing, and skip to the Build & Test steps below, before doing the actual upload. + +0. (Googlers only) Upload the tarball to the fuchsia-build build, under the SDK path. This will require "create" access to the bucket, which is restricted to Googlers, and you'll need to have authenticated to the gcloud tools with OAuth. + + $ gsutil.py cp fuchsia-sdk.tgz gs://fuchsia-build/fuchsia/sdk/linux64/f79f55be4e69ebd90ea84f79d7322525853256c + +## Update & test Chromium + +1. Update the fuchsia SDK line in top-level DEPS with the new hash. + +0. Fetch the new SDK. + + $ gclient sync + +0. Build & test. + + $ ninja -C out/gnRelease ... <check build-bots for current targets> ... + +0. Make necessary changes to fix build, to include in the roll CL. You may find problems in dependencies of Chromium, in which case you'll need to fix those, get the dependency rolled, and then try again. + +0. Upload the roll CL for review! Remember to run the Fuchsia try-bots over the patch-set before landing it.
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json index b8d286d0..3836829 100644 --- a/extensions/common/api/_permission_features.json +++ b/extensions/common/api/_permission_features.json
@@ -247,16 +247,13 @@ ] }], "fileSystem.directory": { - "channel": "stable", - "extension_types": ["platform_app"] + // Inherit from fileSystem's default_parent. }, "fileSystem.retainEntries": { - "channel": "stable", - "extension_types": ["platform_app"] + // Inherit from fileSystem's default_parent. }, "fileSystem.write": [{ - "channel": "stable", - "extension_types": ["platform_app"] + // Inherit from fileSystem's default_parent. },{ "channel": "stable", "extension_types": ["extension"], @@ -270,8 +267,6 @@ ] }], "fileSystem.requestFileSystem": { - "channel": "stable", - "extension_types": ["platform_app"], "platforms": ["chromeos"] }, "hid": [
diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h index 35e4c20..d7aac84 100644 --- a/extensions/common/permissions/api_permission.h +++ b/extensions/common/permissions/api_permission.h
@@ -246,6 +246,7 @@ kNetworkingCastPrivate, kMediaPerceptionPrivate, kLockScreen, + kNewTabPageOverride, // Last entry: Add new entries above and ensure to update the // "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml // (by running update_extension_permission.py).
diff --git a/extensions/common/permissions/extensions_api_permissions.cc b/extensions/common/permissions/extensions_api_permissions.cc index c180c43..df99686 100644 --- a/extensions/common/permissions/extensions_api_permissions.cc +++ b/extensions/common/permissions/extensions_api_permissions.cc
@@ -31,7 +31,7 @@ ExtensionsAPIPermissions::GetAllPermissions() const { // WARNING: If you are modifying a permission message in this list, be sure to // add the corresponding permission message rule to - // ChromePermissionMessageProvider::GetPermissionMessages as well. + // ChromePermissionMessageRule::GetAllRules as well. APIPermissionInfo::InitInfo permissions_to_register[] = { {APIPermission::kAlarms, "alarms"}, {APIPermission::kAlphaEnabled, "app.window.alpha"}, @@ -84,6 +84,8 @@ {APIPermission::kNetworkingOnc, "networking.onc"}, {APIPermission::kNetworkingPrivate, "networkingPrivate", APIPermissionInfo::kFlagCannotBeOptional}, + {APIPermission::kNewTabPageOverride, "newTabPageOverride", + APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kPower, "power"}, {APIPermission::kPrinterProvider, "printerProvider"}, {APIPermission::kSerial, "serial"},
diff --git a/ios/chrome/browser/ui/reading_list/BUILD.gn b/ios/chrome/browser/ui/reading_list/BUILD.gn index fe103cd..e39825e7 100644 --- a/ios/chrome/browser/ui/reading_list/BUILD.gn +++ b/ios/chrome/browser/ui/reading_list/BUILD.gn
@@ -120,11 +120,13 @@ "//base/test:test_support", "//components/favicon/core", "//components/favicon/core/test:test_support", + "//components/feature_engagement_tracker", "//components/prefs", "//components/reading_list/core", "//components/url_formatter", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/favicon", + "//ios/chrome/browser/feature_engagement_tracker", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui",
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator_unittest.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator_unittest.mm index 722543a..666caeb 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator_unittest.mm
@@ -9,9 +9,13 @@ #include "base/time/default_clock.h" #include "components/favicon/core/large_icon_service.h" #include "components/favicon/core/test/mock_favicon_service.h" +#include "components/feature_engagement_tracker/public/event_constants.h" +#include "components/feature_engagement_tracker/public/feature_constants.h" +#include "components/feature_engagement_tracker/public/feature_engagement_tracker.h" #include "components/reading_list/core/reading_list_entry.h" #include "components/reading_list/core/reading_list_model_impl.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#include "ios/chrome/browser/feature_engagement_tracker/feature_engagement_tracker_factory.h" #include "ios/chrome/browser/reading_list/offline_url_utils.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_controller.h" @@ -22,6 +26,7 @@ #include "ios/web/public/referrer.h" #import "ios/web/public/test/web_test_with_web_state.h" #include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" #import "third_party/ocmock/OCMock/OCMock.h" #import "third_party/ocmock/gtest_support.h" #include "ui/base/page_transition_types.h" @@ -95,6 +100,21 @@ @end +#pragma mark - FeatureEngagementTracker +namespace { + +class FeatureEngagementTrackerStub + : public feature_engagement_tracker::FeatureEngagementTracker { + public: + MOCK_METHOD1(NotifyEvent, void(const std::string&)); + MOCK_METHOD1(ShouldTriggerHelpUI, bool(const base::Feature& feature)); + MOCK_METHOD1(Dismissed, void(const base::Feature& feature)); + MOCK_METHOD0(IsInitialized, bool()); + MOCK_METHOD1(AddOnInitializedCallback, void(OnInitializedCallback callback)); +}; + +} // namespace + #pragma mark - ReadingListCoordinatorTest class ReadingListCoordinatorTest : public web::WebTestWithWebState { @@ -103,6 +123,9 @@ loader_mock_ = [[UrlLoaderStub alloc] init]; TestChromeBrowserState::Builder builder; + builder.AddTestingFactory( + FeatureEngagementTrackerFactory::GetInstance(), + ReadingListCoordinatorTest::BuildFeatureEngagementTrackerStub); browser_state_ = builder.Build(); reading_list_model_.reset(new ReadingListModelImpl( @@ -131,6 +154,8 @@ ReadingListModel* GetReadingListModel() { return reading_list_model_.get(); } UrlLoaderStub* GetLoaderStub() { return loader_mock_; } + ios::ChromeBrowserState* GetBrowserState() { return browser_state_.get(); } + ReadingListCollectionViewController* GetAReadingListCollectionViewController() { return [[ReadingListCollectionViewController alloc] @@ -138,6 +163,11 @@ toolbar:nil]; } + static std::unique_ptr<KeyedService> BuildFeatureEngagementTrackerStub( + web::BrowserState*) { + return base::MakeUnique<FeatureEngagementTrackerStub>(); + } + private: ReadingListCoordinator* coordinator_; ReadingListMediator* mediator_; @@ -229,3 +259,17 @@ EXPECT_EQ(url, loader.url); EXPECT_TRUE(loader.inIncognito); } + +TEST_F(ReadingListCoordinatorTest, SendViewedReadingListEventInStart) { + // Setup. + FeatureEngagementTrackerStub* tracker = + static_cast<FeatureEngagementTrackerStub*>( + FeatureEngagementTrackerFactory::GetForBrowserState( + GetBrowserState())); + + // Actions and Tests. + EXPECT_CALL( + (*tracker), + NotifyEvent(feature_engagement_tracker::events::kViewedReadingList)); + [GetCoordinator() start]; +}
diff --git a/ios/chrome/today_extension/today_metrics_logger.mm b/ios/chrome/today_extension/today_metrics_logger.mm index 55c2ddc..7eb52e32 100644 --- a/ios/chrome/today_extension/today_metrics_logger.mm +++ b/ios/chrome/today_extension/today_metrics_logger.mm
@@ -250,8 +250,7 @@ log_->RecordEnvironment( std::vector<std::unique_ptr<metrics::MetricsProvider>>(), - std::vector<variations::ActiveGroupId>(), [install_date longLongValue], - [enabled_date longLongValue]); + [install_date longLongValue], [enabled_date longLongValue]); return true; }
diff --git a/media/BUILD.gn b/media/BUILD.gn index 9e03172..88eed5a 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn
@@ -93,19 +93,6 @@ "device_monitors/device_monitor_mac.mm", "device_monitors/system_message_window_win.cc", "device_monitors/system_message_window_win.h", - "renderers/audio_renderer_impl.cc", - "renderers/audio_renderer_impl.h", - "renderers/default_renderer_factory.cc", - "renderers/default_renderer_factory.h", - "renderers/gpu_video_accelerator_factories.h", - "renderers/renderer_impl.cc", - "renderers/renderer_impl.h", - "renderers/skcanvas_video_renderer.cc", - "renderers/skcanvas_video_renderer.h", - "renderers/video_overlay_factory.cc", - "renderers/video_overlay_factory.h", - "renderers/video_renderer_impl.cc", - "renderers/video_renderer_impl.h", ] configs += [ @@ -145,6 +132,7 @@ ":shared_memory_support", "//media/filters", "//media/formats", + "//media/renderers", "//ui/gfx:color_space", ]
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 09854205..0d0e75e5 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -207,11 +207,11 @@ // Let video track be unselected when video is playing in the background. const base::Feature kBackgroundVideoTrackOptimization{ - "BackgroundVideoTrackOptimization", base::FEATURE_DISABLED_BY_DEFAULT}; + "BackgroundVideoTrackOptimization", base::FEATURE_ENABLED_BY_DEFAULT}; // Let video without audio be paused when it is playing in the background. const base::Feature kBackgroundVideoPauseOptimization{ - "BackgroundVideoPauseOptimization", base::FEATURE_DISABLED_BY_DEFAULT}; + "BackgroundVideoPauseOptimization", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kComplexityBasedVideoBuffering{ "ComplexityBasedVideoBuffering", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/media/capture/video/chromeos/camera_hal_delegate.cc b/media/capture/video/chromeos/camera_hal_delegate.cc index b4932c9..89a302694 100644 --- a/media/capture/video/chromeos/camera_hal_delegate.cc +++ b/media/capture/video/chromeos/camera_hal_delegate.cc
@@ -22,8 +22,6 @@ namespace { -const base::StringPiece kArcCamera3SocketPath("/var/run/camera/camera3.sock"); - const base::TimeDelta kEventWaitTimeoutMs = base::TimeDelta::FromMilliseconds(3000);
diff --git a/media/filters/audio_clock.cc b/media/filters/audio_clock.cc index 0bd0a6c..819ad19 100644 --- a/media/filters/audio_clock.cc +++ b/media/filters/audio_clock.cc
@@ -52,6 +52,13 @@ PushBufferedAudioData(frames_requested - frames_written, 0.0); PopBufferedAudioData(frames_played); + // Trying to track down AudioClock crash, http://crbug.com/674856. + // It may be that we crash due to running out of memory. |buffered_| should + // never come close to 1000 elements in size. In most cases it should have + // just one entry, though additional entries are added when playback rate + // changes. + CHECK_LT(buffered_.size(), 1000U); + // Update our front and back timestamps. The back timestamp is considered the // authoritative source of truth, so base the front timestamp on range of data // buffered. Doing so avoids accumulation errors on the front timestamp.
diff --git a/media/renderers/BUILD.gn b/media/renderers/BUILD.gn new file mode 100644 index 0000000..52e20963 --- /dev/null +++ b/media/renderers/BUILD.gn
@@ -0,0 +1,39 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("renderers") { + visibility = [ "//media" ] + + sources = [ + "audio_renderer_impl.cc", + "audio_renderer_impl.h", + "default_renderer_factory.cc", + "default_renderer_factory.h", + "gpu_video_accelerator_factories.h", + "renderer_impl.cc", + "renderer_impl.h", + "skcanvas_video_renderer.cc", + "skcanvas_video_renderer.h", + "video_overlay_factory.cc", + "video_overlay_factory.h", + "video_renderer_impl.cc", + "video_renderer_impl.h", + ] + + deps = [ + "//gpu/command_buffer/client:gles2_interface", + "//skia", + "//third_party/libyuv", + ] + + configs += [ + "//media:media_implementation", + + # TODO(wolenetz): Fix size_t to int trunctaion in win64. + # See http://crbug.com/171009 + "//build/config/compiler:no_size_t_to_int_warning", + ] + + all_dependent_configs = [ "//media:media_dependent_config" ] +}
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc index c1a4531..4c857c3 100644 --- a/media/renderers/audio_renderer_impl.cc +++ b/media/renderers/audio_renderer_impl.cc
@@ -342,6 +342,18 @@ DCHECK(state_ == kUninitialized || state_ == kFlushed); DCHECK(sink_.get()); + // Trying to track down AudioClock crash, http://crbug.com/674856. + // Initialize should never be called while Rendering is ongoing. This can lead + // to race conditions between media/audio-device threads. + CHECK(!sink_playing_); + // This lock is not required by Initialize, but failing to acquire the lock + // would indicate a race with the rendering thread, which should not be active + // at this time. This is just extra verification on the |sink_playing_| CHECK + // above. We hold |lock_| while setting |sink_playing_|, but release the lock + // when calling sink_->Pause() to avoid deadlocking with the AudioMixer. + CHECK(lock_.Try()); + lock_.Release(); + // If we are re-initializing playback (e.g. switching media tracks), stop the // sink first. if (state_ == kFlushed) { @@ -349,11 +361,6 @@ audio_clock_.reset(); } - // Trying to track down AudioClock crash, http://crbug.com/674856. - // AudioRenderImpl should only be initialized once to avoid destroying - // AudioClock while the audio thread is still using it. - CHECK_EQ(audio_clock_.get(), nullptr); - state_ = kInitializing; client_ = client;
diff --git a/media/renderers/skcanvas_video_renderer.cc b/media/renderers/skcanvas_video_renderer.cc index ebcf1397..9169444 100644 --- a/media/renderers/skcanvas_video_renderer.cc +++ b/media/renderers/skcanvas_video_renderer.cc
@@ -176,20 +176,6 @@ return img; } -bool VideoTextureNeedsClipping(const VideoFrame* video_frame) { - // There are multiple reasons that the size of the video frame's - // visible rectangle may differ from the coded size, including the - // encoder rounding up to the size of a macroblock, or use of - // non-square pixels. - // - // Some callers of these APIs (HTMLVideoElement and the 2D canvas - // context) already clip to the video frame's visible rectangle. - // WebGL on the other hand assumes that only the valid pixels are - // contained in the destination texture. This helper function - // determines whether this slower path is needed. - return video_frame->visible_rect().size() != video_frame->coded_size(); -} - // Creates a SkImage from a |video_frame| backed by native resources. // The SkImage will take ownership of the underlying resource. sk_sp<SkImage> NewSkImageFromVideoFrameNative(VideoFrame* video_frame, @@ -216,7 +202,6 @@ gl->BindTexture(GL_TEXTURE_2D, source_texture); SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( gl, video_frame, - SkCanvasVideoRenderer::SingleFrameForVideoElementOrCanvas, GL_TEXTURE_2D, source_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false); context_3d.gr_context->resetContext(kTextureBinding_GrGLBackendState); @@ -814,7 +799,6 @@ void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( gpu::gles2::GLES2Interface* gl, VideoFrame* video_frame, - SingleFrameCopyMode copy_mode, unsigned int target, unsigned int texture, unsigned int internal_format, @@ -843,34 +827,20 @@ // "flip_y == true" means to reverse the video orientation while // "flip_y == false" means to keep the intrinsic orientation. - if (copy_mode == SingleFrameForVideoElementOrCanvas || - !VideoTextureNeedsClipping(video_frame)) { - // No need to clip the source video texture. - gl->CopyTextureCHROMIUM(source_texture, 0, target, texture, level, - internal_format, type, flip_y, premultiply_alpha, - false); - } else { - // Must reallocate the destination texture and copy only a sub-portion. - gfx::Rect dest_rect = video_frame->visible_rect(); + // Must reallocate the destination texture and copy only a sub-portion. + gfx::Rect dest_rect = video_frame->visible_rect(); #if DCHECK_IS_ON() - // The caller should have bound _texture_ to the GL_TEXTURE_2D - // binding point already. - GLuint current_texture = 0; - gl->GetIntegerv(GL_TEXTURE_BINDING_2D, - reinterpret_cast<GLint*>(¤t_texture)); - DCHECK_EQ(current_texture, texture); - // There should always be enough data in the source texture to - // cover this copy. - DCHECK_LE(dest_rect.width(), video_frame->coded_size().width()); - DCHECK_LE(dest_rect.height(), video_frame->coded_size().height()); + // There should always be enough data in the source texture to + // cover this copy. + DCHECK_LE(dest_rect.width(), video_frame->coded_size().width()); + DCHECK_LE(dest_rect.height(), video_frame->coded_size().height()); #endif - gl->TexImage2D(target, level, internal_format, dest_rect.width(), - dest_rect.height(), 0, format, type, nullptr); - gl->CopySubTextureCHROMIUM(source_texture, 0, target, texture, level, 0, 0, - dest_rect.x(), dest_rect.y(), dest_rect.width(), - dest_rect.height(), flip_y, premultiply_alpha, - false); - } + gl->TexImage2D(target, level, internal_format, dest_rect.width(), + dest_rect.height(), 0, format, type, nullptr); + gl->CopySubTextureCHROMIUM(source_texture, 0, target, texture, level, 0, 0, + dest_rect.x(), dest_rect.y(), dest_rect.width(), + dest_rect.height(), flip_y, premultiply_alpha, + false); gl->DeleteTextures(1, &source_texture); gl->Flush(); @@ -925,34 +895,21 @@ destination_gl->CreateAndConsumeTextureCHROMIUM( mailbox_holder.texture_target, mailbox_holder.mailbox.name); - // See whether the source video texture must be clipped. - if (VideoTextureNeedsClipping(video_frame.get())) { - // Reallocate destination texture and copy only valid region. - gfx::Rect dest_rect = video_frame->visible_rect(); + // Reallocate destination texture and copy only valid region. + gfx::Rect dest_rect = video_frame->visible_rect(); #if DCHECK_IS_ON() - // The caller should have bound _texture_ to the GL_TEXTURE_2D - // binding point already. - GLuint current_texture = 0; - destination_gl->GetIntegerv(GL_TEXTURE_BINDING_2D, - reinterpret_cast<GLint*>(¤t_texture)); - DCHECK_EQ(current_texture, texture); - // There should always be enough data in the source texture to - // cover this copy. - DCHECK_LE(dest_rect.width(), video_frame->coded_size().width()); - DCHECK_LE(dest_rect.height(), video_frame->coded_size().height()); + // There should always be enough data in the source texture to + // cover this copy. + DCHECK_LE(dest_rect.width(), video_frame->coded_size().width()); + DCHECK_LE(dest_rect.height(), video_frame->coded_size().height()); #endif - destination_gl->TexImage2D(target, level, internal_format, - dest_rect.width(), dest_rect.height(), 0, - format, type, nullptr); - destination_gl->CopySubTextureCHROMIUM( - intermediate_texture, 0, target, texture, level, 0, 0, dest_rect.x(), - dest_rect.y(), dest_rect.width(), dest_rect.height(), flip_y, - premultiply_alpha, false); - } else { - destination_gl->CopyTextureCHROMIUM(intermediate_texture, 0, target, - texture, level, internal_format, type, - flip_y, premultiply_alpha, false); - } + destination_gl->TexImage2D(target, level, internal_format, + dest_rect.width(), dest_rect.height(), 0, format, + type, nullptr); + destination_gl->CopySubTextureCHROMIUM( + intermediate_texture, 0, target, texture, level, 0, 0, dest_rect.x(), + dest_rect.y(), dest_rect.width(), dest_rect.height(), flip_y, + premultiply_alpha, false); destination_gl->DeleteTextures(1, &intermediate_texture); @@ -969,8 +926,8 @@ video_frame->UpdateReleaseSyncToken(&client); } else { CopyVideoFrameSingleTextureToGLTexture( - destination_gl, video_frame.get(), SingleFrameForWebGL, target, texture, - internal_format, format, type, level, premultiply_alpha, flip_y); + destination_gl, video_frame.get(), target, texture, internal_format, + format, type, level, premultiply_alpha, flip_y); } return true;
diff --git a/media/renderers/skcanvas_video_renderer.h b/media/renderers/skcanvas_video_renderer.h index 14fa865..76a2cc1 100644 --- a/media/renderers/skcanvas_video_renderer.h +++ b/media/renderers/skcanvas_video_renderer.h
@@ -69,11 +69,6 @@ void* rgb_pixels, size_t row_bytes); - enum SingleFrameCopyMode { - SingleFrameForVideoElementOrCanvas, - SingleFrameForWebGL - }; - // Copy the contents of texture of |video_frame| to texture |texture|. // |level|, |internal_format|, |type| specify target texture |texture|. // The format of |video_frame| must be VideoFrame::NATIVE_TEXTURE. @@ -83,7 +78,6 @@ static void CopyVideoFrameSingleTextureToGLTexture( gpu::gles2::GLES2Interface* gl, VideoFrame* video_frame, - SingleFrameCopyMode copy_mode, unsigned int target, unsigned int texture, unsigned int internal_format,
diff --git a/net/disk_cache/simple/simple_experiment.cc b/net/disk_cache/simple/simple_experiment.cc index 38ea5893..81d8a49 100644 --- a/net/disk_cache/simple/simple_experiment.cc +++ b/net/disk_cache/simple/simple_experiment.cc
@@ -15,49 +15,61 @@ const base::Feature kSimpleSizeExperiment = {"SimpleSizeExperiment", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSimpleCacheEvictionWithSizeExperiment = { + "SimpleCacheEvictionWithSizeExperiment", base::FEATURE_DISABLED_BY_DEFAULT}; + const char kSizeMultiplierParam[] = "SizeMultiplier"; +const char kSizeEvictionParam[] = "SizeEviction"; namespace { -// Returns true if the experiment is found and properly defined. -bool CheckForSimpleSizeExperiment(disk_cache::SimpleExperiment* experiment) { - DCHECK_EQ(disk_cache::SimpleExperimentType::NONE, experiment->type); - DCHECK_EQ(0u, experiment->param); +struct ExperimentDescription { + disk_cache::SimpleExperimentType experiment_type; + const base::Feature* feature; + const char* param_name; +}; - if (!base::FeatureList::IsEnabled(kSimpleSizeExperiment)) - return false; - - base::FieldTrial* trial = - base::FeatureList::GetFieldTrial(kSimpleSizeExperiment); - if (!trial) - return false; - - std::map<std::string, std::string> params; - base::FieldTrialParamAssociator::GetInstance()->GetFieldTrialParams( - trial->trial_name(), ¶ms); - auto iter = params.find(kSizeMultiplierParam); - if (iter == params.end()) - return false; - - uint32_t param; - if (!base::StringToUint(iter->second, ¶m)) - return false; - - experiment->type = disk_cache::SimpleExperimentType::SIZE; - experiment->param = param; - return true; -} +// List of experimens to be checked for. +const ExperimentDescription experiments[] = { + {disk_cache::SimpleExperimentType::SIZE, &kSimpleSizeExperiment, + kSizeMultiplierParam}, + {disk_cache::SimpleExperimentType::EVICT_WITH_SIZE, + &kSimpleCacheEvictionWithSizeExperiment, kSizeEvictionParam}, +}; } // namespace // Returns the experiment for the given |cache_type|. SimpleExperiment GetSimpleExperiment(net::CacheType cache_type) { SimpleExperiment experiment; - if (cache_type != net::DISK_CACHE) return experiment; - CheckForSimpleSizeExperiment(&experiment); + for (size_t i = 0; i < arraysize(experiments); i++) { + if (!base::FeatureList::IsEnabled(*experiments[i].feature)) + continue; + + base::FieldTrial* trial = + base::FeatureList::GetFieldTrial(*experiments[i].feature); + if (!trial) + continue; + + std::map<std::string, std::string> params; + base::FieldTrialParamAssociator::GetInstance()->GetFieldTrialParams( + trial->trial_name(), ¶ms); + auto iter = params.find(experiments[i].param_name); + if (iter == params.end()) + continue; + + uint32_t param; + if (!base::StringToUint(iter->second, ¶m)) + continue; + + experiment.type = experiments[i].experiment_type; + experiment.param = param; + return experiment; + } + return experiment; }
diff --git a/net/disk_cache/simple/simple_experiment.h b/net/disk_cache/simple/simple_experiment.h index 2231e85..7f20ae0 100644 --- a/net/disk_cache/simple/simple_experiment.h +++ b/net/disk_cache/simple/simple_experiment.h
@@ -14,13 +14,20 @@ namespace disk_cache { NET_EXPORT_PRIVATE extern const base::Feature kSimpleSizeExperiment; +NET_EXPORT_PRIVATE extern const base::Feature + kSimpleCacheEvictionWithSizeExperiment; NET_EXPORT_PRIVATE extern const char kSizeMultiplierParam[]; +NET_EXPORT_PRIVATE extern const char kSizeEvictionParam[]; // This lists the experiment groups for SimpleCache. Only add new groups at // the end of the list, and always increase the number. enum class SimpleExperimentType : uint32_t { NONE = 0, SIZE = 1, + + // param = 0 -> control group + // param = 1 -> experiment group + EVICT_WITH_SIZE = 2, }; struct NET_EXPORT_PRIVATE SimpleExperiment {
diff --git a/net/disk_cache/simple/simple_experiment_unittest.cc b/net/disk_cache/simple/simple_experiment_unittest.cc index 66d0400..311a5bc 100644 --- a/net/disk_cache/simple/simple_experiment_unittest.cc +++ b/net/disk_cache/simple/simple_experiment_unittest.cc
@@ -49,6 +49,28 @@ scoped_feature_list_.InitWithFeatureList(std::move(feature_list)); } + void ConfigureEvictWithSizeTrial(bool enabled, + base::Optional<uint32_t> param) { + const std::string kTrialName = "EvictWithSizeTrial"; + const std::string kGroupName = "GroupFoo"; // Value not used + + scoped_refptr<base::FieldTrial> trial = + base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName); + + if (param) { + std::map<std::string, std::string> params; + params[kSizeEvictionParam] = base::UintToString(param.value()); + base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams( + kTrialName, kGroupName, params); + } + + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); + feature_list->RegisterFieldTrialOverride( + kSimpleCacheEvictionWithSizeExperiment.name, + base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); + scoped_feature_list_.InitWithFeatureList(std::move(feature_list)); + } + std::unique_ptr<base::FieldTrialList> field_trial_list_; base::test::ScopedFeatureList scoped_feature_list_; }; @@ -88,4 +110,33 @@ EXPECT_EQ(0u, experiment.param); } +TEST_F(SimpleExperimentTest, EvictWithSizeMissingParam) { + base::test::ScopedFeatureList scoped_feature_list; + ConfigureEvictWithSizeTrial(true, base::Optional<uint32_t>()); + + SimpleExperiment experiment = GetSimpleExperiment(net::DISK_CACHE); + EXPECT_EQ(SimpleExperimentType::NONE, experiment.type); + EXPECT_EQ(0u, experiment.param); +} + +TEST_F(SimpleExperimentTest, EvictWithSizeProperlyConfigured) { + const uint32_t kParam = 1u; + base::test::ScopedFeatureList scoped_feature_list; + ConfigureEvictWithSizeTrial(true, base::Optional<uint32_t>(kParam)); + + SimpleExperiment experiment = GetSimpleExperiment(net::DISK_CACHE); + EXPECT_EQ(SimpleExperimentType::EVICT_WITH_SIZE, experiment.type); + EXPECT_EQ(kParam, experiment.param); +} + +TEST_F(SimpleExperimentTest, EvictWithSizeProperlyConfiguredWrongCacheType) { + const uint32_t kParam = 125u; + base::test::ScopedFeatureList scoped_feature_list; + ConfigureEvictWithSizeTrial(true, base::Optional<uint32_t>(kParam)); + + SimpleExperiment experiment = GetSimpleExperiment(net::APP_CACHE); + EXPECT_EQ(SimpleExperimentType::NONE, experiment.type); + EXPECT_EQ(0u, experiment.param); +} + } // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_index.cc b/net/disk_cache/simple/simple_index.cc index 3513b598..0166c8c 100644 --- a/net/disk_cache/simple/simple_index.cc +++ b/net/disk_cache/simple/simple_index.cc
@@ -25,6 +25,7 @@ #include "base/trace_event/memory_usage_estimator.h" #include "net/base/net_errors.h" #include "net/disk_cache/simple/simple_entry_format.h" +#include "net/disk_cache/simple/simple_experiment.h" #include "net/disk_cache/simple/simple_histogram_macros.h" #include "net/disk_cache/simple/simple_index_delegate.h" #include "net/disk_cache/simple/simple_index_file.h" @@ -49,6 +50,13 @@ const uint32_t kBytesInKb = 1024; +// This is added to the size of each entry before using the size +// to determine which entries to evict first. It's basically an +// estimate of the filesystem overhead, but it also serves to flatten +// the curve so that 1-byte entries and 2-byte entries are basically +// treated the same. +static const int kEstimatedEntryOverhead = 512; + } // namespace namespace disk_cache { @@ -309,31 +317,37 @@ static_cast<base::HistogramBase::Sample>(max_size_ / kBytesInKb)); // Flatten for sorting. - std::vector<const std::pair<const uint64_t, EntryMetadata>*> entries; + std::vector<std::pair<uint64_t, const EntrySet::value_type*>> entries; entries.reserve(entries_set_.size()); + uint32_t now = (base::Time::Now() - base::Time::UnixEpoch()).InSeconds(); + bool use_size = false; + SimpleExperiment experiment = GetSimpleExperiment(cache_type_); + if (experiment.type == SimpleExperimentType::EVICT_WITH_SIZE && + experiment.param) { + use_size = true; + } for (EntrySet::const_iterator i = entries_set_.begin(); i != entries_set_.end(); ++i) { - entries.push_back(&*i); + uint64_t sort_value = now - i->second.RawTimeForSorting(); + if (use_size) { + // Will not overflow since we're multiplying two 32-bit values and storing + // them in a 64-bit variable. + sort_value *= i->second.GetEntrySize() + kEstimatedEntryOverhead; + } + // Subtract so we don't need a custom comparator. + entries.emplace_back(std::numeric_limits<uint64_t>::max() - sort_value, + &*i); } - std::sort(entries.begin(), entries.end(), - [](const std::pair<const uint64_t, EntryMetadata>* a, - const std::pair<const uint64_t, EntryMetadata>* b) -> bool { - return a->second.RawTimeForSorting() < - b->second.RawTimeForSorting(); - }); - - // Remove as many entries from the index to get below |low_watermark_|, - // collecting least recently used hashes into |entry_hashes|. - std::vector<uint64_t> entry_hashes; - std::vector<const std::pair<const uint64_t, EntryMetadata>*>::iterator it = - entries.begin(); uint64_t evicted_so_far_size = 0; - while (evicted_so_far_size < cache_size_ - low_watermark_) { - DCHECK(it != entries.end()); - entry_hashes.push_back((*it)->first); - evicted_so_far_size += (*it)->second.GetEntrySize(); - ++it; + const uint64_t amount_to_evict = cache_size_ - low_watermark_; + std::vector<uint64_t> entry_hashes; + std::sort(entries.begin(), entries.end()); + for (const auto& score_metadata_pair : entries) { + if (evicted_so_far_size >= amount_to_evict) + break; + evicted_so_far_size += score_metadata_pair.second->second.GetEntrySize(); + entry_hashes.push_back(score_metadata_pair.second->first); } SIMPLE_CACHE_UMA(COUNTS_1M,
diff --git a/net/disk_cache/simple/simple_index_unittest.cc b/net/disk_cache/simple/simple_index_unittest.cc index 9f7d409..051d22c 100644 --- a/net/disk_cache/simple/simple_index_unittest.cc +++ b/net/disk_cache/simple/simple_index_unittest.cc
@@ -12,13 +12,18 @@ #include "base/files/scoped_temp_dir.h" #include "base/hash.h" #include "base/logging.h" +#include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_param_associator.h" #include "base/pickle.h" #include "base/sha1.h" #include "base/strings/stringprintf.h" #include "base/task_runner.h" +#include "base/test/mock_entropy_provider.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" #include "net/base/cache_type.h" +#include "net/disk_cache/simple/simple_experiment.h" #include "net/disk_cache/simple/simple_index_delegate.h" #include "net/disk_cache/simple/simple_index_file.h" #include "net/disk_cache/simple/simple_test_util.h" @@ -113,6 +118,29 @@ index_->Initialize(base::Time()); } + void EnableEvictBySize() { + // Enable size-based eviction. + const std::string kTrialName = "EvictWithSizeTrial"; + const std::string kGroupName = "GroupFoo"; // Value not used + + field_trial_list_ = base::MakeUnique<base::FieldTrialList>( + base::MakeUnique<base::MockEntropyProvider>()); + + scoped_refptr<base::FieldTrial> trial = + base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName); + + std::map<std::string, std::string> params; + params[kSizeEvictionParam] = "1"; + base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams( + kTrialName, kGroupName, params); + + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); + feature_list->RegisterFieldTrialOverride( + kSimpleCacheEvictionWithSizeExperiment.name, + base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); + scoped_feature_list_.InitWithFeatureList(std::move(feature_list)); + } + void WaitForTimeChange() { const base::Time initial_time = base::Time::Now(); do { @@ -165,6 +193,9 @@ std::unique_ptr<SimpleIndex> index_; base::WeakPtr<MockSimpleIndexFile> index_file_; + std::unique_ptr<base::FieldTrialList> field_trial_list_; + base::test::ScopedFeatureList scoped_feature_list_; + std::vector<uint64_t> last_doom_entry_hashes_; int doom_entries_calls_; }; @@ -568,6 +599,74 @@ ASSERT_EQ(2u, last_doom_entry_hashes().size()); } +TEST_F(SimpleIndexTest, EvictBySize) { + EnableEvictBySize(); + // Enabled, now we can run the actual test. + base::Time now(base::Time::Now()); + index()->SetMaxSize(50000); + InsertIntoIndexFileReturn(hashes_.at<1>(), now - base::TimeDelta::FromDays(2), + 475u); + InsertIntoIndexFileReturn(hashes_.at<2>(), now - base::TimeDelta::FromDays(1), + 40000u); + ReturnIndexFile(); + WaitForTimeChange(); + + index()->Insert(hashes_.at<3>()); + // Confirm index is as expected: No eviction, everything there. + EXPECT_EQ(3, index()->GetEntryCount()); + EXPECT_EQ(0, doom_entries_calls()); + EXPECT_TRUE(index()->Has(hashes_.at<1>())); + EXPECT_TRUE(index()->Has(hashes_.at<2>())); + EXPECT_TRUE(index()->Has(hashes_.at<3>())); + + // Trigger an eviction, and make sure the right things are tossed. + // TODO(rdsmith): This is dependent on the innards of the implementation + // as to at exactly what point we trigger eviction. Not sure how to fix + // that. + index()->UpdateEntrySize(hashes_.at<3>(), 40000u); + EXPECT_EQ(1, doom_entries_calls()); + EXPECT_EQ(2, index()->GetEntryCount()); + EXPECT_TRUE(index()->Has(hashes_.at<1>())); + EXPECT_FALSE(index()->Has(hashes_.at<2>())); + EXPECT_TRUE(index()->Has(hashes_.at<3>())); + ASSERT_EQ(1u, last_doom_entry_hashes().size()); +} + +// Same as test above, but using much older entries to make sure that small +// things eventually get evictied. +TEST_F(SimpleIndexTest, EvictBySize2) { + EnableEvictBySize(); + // Enabled, now we can run the actual test. + base::Time now(base::Time::Now()); + index()->SetMaxSize(50000); + InsertIntoIndexFileReturn(hashes_.at<1>(), + now - base::TimeDelta::FromDays(200), 475u); + InsertIntoIndexFileReturn(hashes_.at<2>(), now - base::TimeDelta::FromDays(1), + 40000u); + ReturnIndexFile(); + WaitForTimeChange(); + + index()->Insert(hashes_.at<3>()); + // Confirm index is as expected: No eviction, everything there. + EXPECT_EQ(3, index()->GetEntryCount()); + EXPECT_EQ(0, doom_entries_calls()); + EXPECT_TRUE(index()->Has(hashes_.at<1>())); + EXPECT_TRUE(index()->Has(hashes_.at<2>())); + EXPECT_TRUE(index()->Has(hashes_.at<3>())); + + // Trigger an eviction, and make sure the right things are tossed. + // TODO(rdsmith): This is dependent on the innards of the implementation + // as to at exactly what point we trigger eviction. Not sure how to fix + // that. + index()->UpdateEntrySize(hashes_.at<3>(), 40000u); + EXPECT_EQ(1, doom_entries_calls()); + EXPECT_EQ(1, index()->GetEntryCount()); + EXPECT_FALSE(index()->Has(hashes_.at<1>())); + EXPECT_FALSE(index()->Has(hashes_.at<2>())); + EXPECT_TRUE(index()->Has(hashes_.at<3>())); + ASSERT_EQ(2u, last_doom_entry_hashes().size()); +} + // Confirm all the operations queue a disk write at some point in the // future. TEST_F(SimpleIndexTest, DiskWriteQueued) {
diff --git a/net/log/file_net_log_observer.cc b/net/log/file_net_log_observer.cc index fe52816..d7ad9102 100644 --- a/net/log/file_net_log_observer.cc +++ b/net/log/file_net_log_observer.cc
@@ -24,8 +24,6 @@ #include "net/log/net_log_util.h" #include "net/url_request/url_request_context.h" -// TODO(eroman): Move implementations to match declaration order. - namespace { // Number of events that can build up in |write_queue_| before a task is posted @@ -314,42 +312,6 @@ std::move(constants)); } -std::unique_ptr<FileNetLogObserver> FileNetLogObserver::CreateBoundedInternal( - const base::FilePath& log_path, - size_t max_total_size, - size_t total_num_event_files, - std::unique_ptr<base::Value> constants) { - DCHECK_GT(total_num_event_files, 0u); - - scoped_refptr<base::SequencedTaskRunner> file_task_runner = - CreateFileTaskRunner(); - - const size_t max_event_file_size = - max_total_size == kNoLimit ? kNoLimit - : max_total_size / total_num_event_files; - - // The FileWriter uses a soft limit to write events to file that allows - // the size of the file to exceed the limit, but the WriteQueue uses a hard - // limit which the size of |WriteQueue::queue_| cannot exceed. Thus, the - // FileWriter may write more events to file than can be contained by - // the WriteQueue if they have the same size limit. The maximum size of the - // WriteQueue is doubled to allow |WriteQueue::queue_| to hold enough events - // for the FileWriter to fill all files. As long as all events have - // sizes <= the size of an individual event file, the discrepancy between the - // hard limit and the soft limit will not cause an issue. - // TODO(dconnol): Handle the case when the WriteQueue still doesn't - // contain enough events to fill all files, because of very large events - // relative to file size. - std::unique_ptr<FileWriter> file_writer(new FileWriter( - log_path, max_event_file_size, total_num_event_files, file_task_runner)); - - scoped_refptr<WriteQueue> write_queue(new WriteQueue(max_total_size * 2)); - - return std::unique_ptr<FileNetLogObserver>( - new FileNetLogObserver(file_task_runner, std::move(file_writer), - std::move(write_queue), std::move(constants))); -} - std::unique_ptr<FileNetLogObserver> FileNetLogObserver::CreateUnbounded( const base::FilePath& log_path, std::unique_ptr<base::Value> constants) { @@ -421,6 +383,42 @@ std::move(constants)); } +std::unique_ptr<FileNetLogObserver> FileNetLogObserver::CreateBoundedInternal( + const base::FilePath& log_path, + size_t max_total_size, + size_t total_num_event_files, + std::unique_ptr<base::Value> constants) { + DCHECK_GT(total_num_event_files, 0u); + + scoped_refptr<base::SequencedTaskRunner> file_task_runner = + CreateFileTaskRunner(); + + const size_t max_event_file_size = + max_total_size == kNoLimit ? kNoLimit + : max_total_size / total_num_event_files; + + // The FileWriter uses a soft limit to write events to file that allows + // the size of the file to exceed the limit, but the WriteQueue uses a hard + // limit which the size of |WriteQueue::queue_| cannot exceed. Thus, the + // FileWriter may write more events to file than can be contained by + // the WriteQueue if they have the same size limit. The maximum size of the + // WriteQueue is doubled to allow |WriteQueue::queue_| to hold enough events + // for the FileWriter to fill all files. As long as all events have + // sizes <= the size of an individual event file, the discrepancy between the + // hard limit and the soft limit will not cause an issue. + // TODO(dconnol): Handle the case when the WriteQueue still doesn't + // contain enough events to fill all files, because of very large events + // relative to file size. + std::unique_ptr<FileWriter> file_writer(new FileWriter( + log_path, max_event_file_size, total_num_event_files, file_task_runner)); + + scoped_refptr<WriteQueue> write_queue(new WriteQueue(max_total_size * 2)); + + return std::unique_ptr<FileNetLogObserver>( + new FileNetLogObserver(file_task_runner, std::move(file_writer), + std::move(write_queue), std::move(constants))); +} + FileNetLogObserver::FileNetLogObserver( scoped_refptr<base::SequencedTaskRunner> file_task_runner, std::unique_ptr<FileWriter> file_writer, @@ -466,13 +464,6 @@ FileNetLogObserver::WriteQueue::~WriteQueue() {} -void FileNetLogObserver::FileWriter::FlushThenStop( - scoped_refptr<FileNetLogObserver::WriteQueue> write_queue, - std::unique_ptr<base::Value> polled_data) { - Flush(write_queue); - Stop(std::move(polled_data)); -} - FileNetLogObserver::FileWriter::FileWriter( const base::FilePath& log_path, size_t max_event_file_size, @@ -504,57 +495,6 @@ } } -void FileNetLogObserver::FileWriter::WriteConstantsToFile( - std::unique_ptr<base::Value> constants_value, - FILE* file) { - // Print constants to file and open events array. - std::string json; - - // It should always be possible to convert constants to JSON. - if (!base::JSONWriter::Write(*constants_value, &json)) - DCHECK(false); - WriteToFile(file, "{\"constants\":", json, ",\n\"events\": [\n"); -} - -void FileNetLogObserver::FileWriter::CreateInprogressDirectory() const { - DCHECK(IsBounded()); - - // base::CreateDirectory() creates missing parent directories. Since the - // target directory is a sibling to |final_log_path_|, if that file couldn't - // be opened don't attempt to create the directory either. - if (!final_log_file_) - return; - - if (!base::CreateDirectory(GetInprogressDirectory())) { - LOG(WARNING) << "Failed creating directory: " - << GetInprogressDirectory().value(); - return; - } - - // It is OK if the path is wrong due to encoding - this is really just a - // convenience display for the user in understanding what the file means. - std::string in_progress_path = GetInprogressDirectory().AsUTF8Unsafe(); - - // Since |final_log_file_| will not be written to until the very end, leave - // some data in it explaining that the real data is currently in the - // .inprogress directory. This ordinarily won't be visible (overwritten when - // stopping) however if logging does not end gracefully the comments are - // useful for recovery. - WriteToFile( - final_log_file_.get(), "Logging is in progress writing data to:\n ", - in_progress_path, - "\n\n" - "That data will be stitched into a single file (this one) once logging\n" - "has stopped.\n" - "\n" - "If logging was interrupted, you can stitch a NetLog file out of the\n" - ".inprogress directory manually using:\n" - "\n" - "https://chromium.googlesource.com/chromium/src/+/master/net/tools/" - "stitch_net_log_files.py\n"); - fflush(final_log_file_.get()); -} - void FileNetLogObserver::FileWriter::Stop( std::unique_ptr<base::Value> polled_data) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); @@ -578,62 +518,6 @@ final_log_file_.reset(); } -void FileNetLogObserver::FileWriter::WritePolledDataToFile( - std::unique_ptr<base::Value> polled_data, - FILE* file) { - // Close the events array. - WriteToFile(file, "]"); - - // Write the polled data (if any). - if (polled_data) { - std::string polled_data_json; - base::JSONWriter::Write(*polled_data, &polled_data_json); - if (!polled_data_json.empty()) - WriteToFile(file, ",\n\"polledData\": ", polled_data_json, "\n"); - } - - // Close the log. - WriteToFile(file, "}\n"); -} - -bool FileNetLogObserver::FileWriter::IsUnbounded() const { - return max_event_file_size_ == kNoLimit; -} - -bool FileNetLogObserver::FileWriter::IsBounded() const { - return !IsUnbounded(); -} - -void FileNetLogObserver::FileWriter::IncrementCurrentEventFile() { - DCHECK(task_runner_->RunsTasksInCurrentSequence()); - DCHECK(IsBounded()); - - current_event_file_number_++; - current_event_file_ = OpenFileForWrite( - GetEventFilePath(FileNumberToIndex(current_event_file_number_))); - current_event_file_size_ = 0; -} - -base::FilePath FileNetLogObserver::FileWriter::GetInprogressDirectory() const { - return final_log_path_.AddExtension(FILE_PATH_LITERAL(".inprogress")); -} - -base::FilePath FileNetLogObserver::FileWriter::GetEventFilePath( - size_t index) const { - DCHECK_LT(index, total_num_event_files_); - DCHECK(IsBounded()); - return GetInprogressDirectory().AppendASCII( - "event_file_" + base::SizeTToString(index) + ".json"); -} - -base::FilePath FileNetLogObserver::FileWriter::GetConstantsFilePath() const { - return GetInprogressDirectory().AppendASCII("constants.json"); -} - -base::FilePath FileNetLogObserver::FileWriter::GetClosingFilePath() const { - return GetInprogressDirectory().AppendASCII("end_netlog.json"); -} - void FileNetLogObserver::FileWriter::Flush( scoped_refptr<FileNetLogObserver::WriteQueue> write_queue) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); @@ -682,6 +566,51 @@ base::DeleteFile(final_log_path_, false); } +void FileNetLogObserver::FileWriter::FlushThenStop( + scoped_refptr<FileNetLogObserver::WriteQueue> write_queue, + std::unique_ptr<base::Value> polled_data) { + Flush(write_queue); + Stop(std::move(polled_data)); +} + +bool FileNetLogObserver::FileWriter::IsUnbounded() const { + return max_event_file_size_ == kNoLimit; +} + +bool FileNetLogObserver::FileWriter::IsBounded() const { + return !IsUnbounded(); +} + +void FileNetLogObserver::FileWriter::IncrementCurrentEventFile() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(IsBounded()); + + current_event_file_number_++; + current_event_file_ = OpenFileForWrite( + GetEventFilePath(FileNumberToIndex(current_event_file_number_))); + current_event_file_size_ = 0; +} + +base::FilePath FileNetLogObserver::FileWriter::GetInprogressDirectory() const { + return final_log_path_.AddExtension(FILE_PATH_LITERAL(".inprogress")); +} + +base::FilePath FileNetLogObserver::FileWriter::GetEventFilePath( + size_t index) const { + DCHECK_LT(index, total_num_event_files_); + DCHECK(IsBounded()); + return GetInprogressDirectory().AppendASCII( + "event_file_" + base::SizeTToString(index) + ".json"); +} + +base::FilePath FileNetLogObserver::FileWriter::GetConstantsFilePath() const { + return GetInprogressDirectory().AppendASCII("constants.json"); +} + +base::FilePath FileNetLogObserver::FileWriter::GetClosingFilePath() const { + return GetInprogressDirectory().AppendASCII("end_netlog.json"); +} + size_t FileNetLogObserver::FileWriter::FileNumberToIndex( size_t file_number) const { DCHECK_GT(file_number, 0u); @@ -689,6 +618,36 @@ return (file_number - 1) % total_num_event_files_; } +void FileNetLogObserver::FileWriter::WriteConstantsToFile( + std::unique_ptr<base::Value> constants_value, + FILE* file) { + // Print constants to file and open events array. + std::string json; + + // It should always be possible to convert constants to JSON. + if (!base::JSONWriter::Write(*constants_value, &json)) + DCHECK(false); + WriteToFile(file, "{\"constants\":", json, ",\n\"events\": [\n"); +} + +void FileNetLogObserver::FileWriter::WritePolledDataToFile( + std::unique_ptr<base::Value> polled_data, + FILE* file) { + // Close the events array. + WriteToFile(file, "]"); + + // Write the polled data (if any). + if (polled_data) { + std::string polled_data_json; + base::JSONWriter::Write(*polled_data, &polled_data_json); + if (!polled_data_json.empty()) + WriteToFile(file, ",\n\"polledData\": ", polled_data_json, "\n"); + } + + // Close the log. + WriteToFile(file, "}\n"); +} + void FileNetLogObserver::FileWriter::RewindIfWroteEventBytes(FILE* file) const { if (file && wrote_event_bytes_) { // To be valid JSON the events array should not end with a comma. If events @@ -740,4 +699,43 @@ base::DeleteFile(GetInprogressDirectory(), true); } +void FileNetLogObserver::FileWriter::CreateInprogressDirectory() const { + DCHECK(IsBounded()); + + // base::CreateDirectory() creates missing parent directories. Since the + // target directory is a sibling to |final_log_path_|, if that file couldn't + // be opened don't attempt to create the directory either. + if (!final_log_file_) + return; + + if (!base::CreateDirectory(GetInprogressDirectory())) { + LOG(WARNING) << "Failed creating directory: " + << GetInprogressDirectory().value(); + return; + } + + // It is OK if the path is wrong due to encoding - this is really just a + // convenience display for the user in understanding what the file means. + std::string in_progress_path = GetInprogressDirectory().AsUTF8Unsafe(); + + // Since |final_log_file_| will not be written to until the very end, leave + // some data in it explaining that the real data is currently in the + // .inprogress directory. This ordinarily won't be visible (overwritten when + // stopping) however if logging does not end gracefully the comments are + // useful for recovery. + WriteToFile( + final_log_file_.get(), "Logging is in progress writing data to:\n ", + in_progress_path, + "\n\n" + "That data will be stitched into a single file (this one) once logging\n" + "has stopped.\n" + "\n" + "If logging was interrupted, you can stitch a NetLog file out of the\n" + ".inprogress directory manually using:\n" + "\n" + "https://chromium.googlesource.com/chromium/src/+/master/net/tools/" + "stitch_net_log_files.py\n"); + fflush(final_log_file_.get()); +} + } // namespace net
diff --git a/net/tools/stitch_net_log_files.py b/net/tools/stitch_net_log_files.py index 922d8520..d81d792 100755 --- a/net/tools/stitch_net_log_files.py +++ b/net/tools/stitch_net_log_files.py
@@ -4,50 +4,87 @@ # found in the LICENSE file. ''' -This script stitches the NetLog files in a specified directory. - -The complete NetLog will be written to net-internals-log.json in the directory -passed as argument to --path. +This script "stitches" the NetLog files from a ".inprogress" directory to +create a single NetLog file. ''' -import argparse, os +import glob +import os +import re +import sys + + +USAGE ='''Usage: stitch_net_log_files.py <INPROGRESS_DIR> [<OUTPUT_PATH>] + +Will copy all the files in <INPROGRESS_DIR> and write the their content into a +NetLog file at path <OUTPUT_PATH>. + +If <OUTPUT_PATH> is not specified, it should end with ".inprogress", and the +completed NetLog file will be written to the location with ".inprogress" +stripped. +''' + + +def get_event_file_sort_key(path): + '''Returns a tuple (modification timestamp, file number) for a path of the + form event_file_%d.json''' + + m = re.match('^event_file_(\d+).json$', path) + file_index = int(m.group(1)) + return (os.path.getmtime(path), file_index) + + +def get_ordered_event_files(): + '''Returns a list of file paths to event files. The order of the files is + from oldest to newest. If modification times are the same, files will be + ordered based on the numeral in their file name.''' + + paths = glob.glob("event_file_*.json") + paths = sorted(paths, key=get_event_file_sort_key) + sys.stdout.write("Identified %d event files:\n %s\n" % + (len(paths), "\n ".join(paths))) + return paths + def main(): - parser = argparse.ArgumentParser() - parser.add_argument('--path', action='store', - help="Specifies the complete filepath of the directory where the log " - "files are located.") - # TODO(dconnol): Automatically pull all event files matching the format - # event_file_<num>.json and remove the num_files argument. - parser.add_argument('--num_files', action='store', - help="Specifies the number of event files (not including the constants " - "file or the end_netlog file) that need need to be stitched together. " - "The number of event files passed to the script must not be greater " - "than the number of event files in the directory.") - args = parser.parse_args() + if len(sys.argv) != 2 and len(sys.argv) != 3: + sys.stderr.write(USAGE) + sys.exit(1) - num_files = int(args.num_files) - filepath = args.path - if filepath[-1:] != "/": - filepath += "/" + inprogress_dir = sys.argv[1] + output_path = None - os.chdir(filepath) + # Pick an output path based on command line arguments. + if len(sys.argv) == 3: + output_path = sys.argv[2] + elif len(sys.argv) == 2: + m = re.match("^(.*)\.inprogress/?$", inprogress_dir) + if not m: + sys.stdout.write("Must specify OUTPUT_PATH\n") + sys.exit(1) + output_path = m.group(1) - with open("net-internals-log.json", "w") as stitched_file: + output_path = os.path.abspath(output_path) + + sys.stdout.write("Reading data from: %s\n" % inprogress_dir) + sys.stdout.write("Writing log file to: %s\n" % output_path) + + os.chdir(inprogress_dir) + + with open(output_path, "w") as stitched_file: try: file = open("constants.json") with file: for line in file: stitched_file.write(line) except IOError: - os.remove("net-internals-log.json") - print "File \"constants.json\" not found." - return + sys.stderr.write("Failed reading \"constants.json\".\n") + sys.exit(1) events_written = False; - for i in range(num_files): + for event_file_path in get_ordered_event_files(): try: - file = open("event_file_%d.json" % i) + file = open(event_file_path) with file: if not events_written: line = file.readline(); @@ -59,9 +96,8 @@ stitched_file.write(line) line = next_line except IOError: - os.remove("net-internals-log.json") - print "File \"event_file_%d.json\" not found." % i - return + sys.stderr.write("Failed reading \"%s\"\n" % event_file_path) + sys.exit(1) # Remove hanging comma from last event # TODO(dconnol): Check if the last line is a valid JSON object. If not, # do not write the line to file. This handles incomplete logs. @@ -71,21 +107,21 @@ elif line: raise ValueError('Last event is not properly formed') - try: - file = open("end_netlog.json") - with file: - for line in file: - stitched_file.write(line) - except IOError: - os.remove("net-internals-log.json") - print "File \"end_netlog\" not found." - return - - # Delete old NetLog files - for i in range (num_files): - os.remove("event_file_%d.json" % i) - os.remove("constants.json") - os.remove("end_netlog.json") + if os.path.exists("end_netlog.json"): + try: + file = open("end_netlog.json") + with file: + for line in file: + stitched_file.write(line) + except IOError: + sys.stderr.write("Failed reading \"end_netlog.json\".\n") + sys.exit(1) + else: + # end_netlog.json won't exist when using this tool to stitch logging + # sessions that didn't shutdown gracefully. + # + # Close the events array and then the log (no polled_data). + stitched_file.write("]}\n") if __name__ == "__main__":
diff --git a/remoting/host/linux/linux_me2me_host.py b/remoting/host/linux/linux_me2me_host.py index d981ce7..19421a9 100755 --- a/remoting/host/linux/linux_me2me_host.py +++ b/remoting/host/linux/linux_me2me_host.py
@@ -460,6 +460,7 @@ # Ensure that the software-rendering GL drivers are loaded by the desktop # session, instead of any hardware GL drivers installed on the system. library_path = ( + "/usr/lib/mesa-diverted/%(arch)s-linux-gnu:" "/usr/lib/%(arch)s-linux-gnu/mesa:" "/usr/lib/%(arch)s-linux-gnu/dri:" "/usr/lib/%(arch)s-linux-gnu/gallium-pipe" %
diff --git a/remoting/ios/app/BUILD.gn b/remoting/ios/app/BUILD.gn index f784476a..2f85879 100644 --- a/remoting/ios/app/BUILD.gn +++ b/remoting/ios/app/BUILD.gn
@@ -17,6 +17,7 @@ sources = [ "app_delegate.h", "app_delegate.mm", + "app_initializer.h", "app_view_controller.h", "client_connection_view_controller.h", "client_connection_view_controller.mm", @@ -46,6 +47,7 @@ "host_setup_view_controller.mm", "host_view_controller.h", "host_view_controller.mm", + "main.mm", "pin_entry_view.h", "pin_entry_view.mm", "remoting_theme.h", @@ -88,10 +90,10 @@ configs += [ "//build/config/compiler:enable_arc" ] } -source_set("main") { +source_set("app_source_set") { sources = [ + "app_initializer_chromium.mm", "app_view_controller_chromium.mm", - "main.mm", "remoting_menu_view_controller.h", "remoting_menu_view_controller.mm", ] @@ -107,7 +109,7 @@ info_plist_path = "resources/Info.plist" entitlements_path = "resources/Remoting.entitlements" deps = [ - ":main", + ":app_source_set", "//remoting/ios/app/resources:launchscreen_assets", "//remoting/ios/app/resources:remoting_icons", ]
diff --git a/remoting/ios/app/app_initializer.h b/remoting/ios/app/app_initializer.h new file mode 100644 index 0000000..2f24ede --- /dev/null +++ b/remoting/ios/app/app_initializer.h
@@ -0,0 +1,19 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_IOS_APP_APP_INITIALIZER_H_ +#define REMOTING_IOS_APP_APP_INITIALIZER_H_ + +#import <UIKit/UIKit.h> + +// This class is to allow different builds (Chromium vs internal) to do +// dependency injection before starting the app. Please see main.mm to see how +// it is used. +@interface AppInitializer : NSObject + ++ (void)initializeApp; + +@end + +#endif // REMOTING_IOS_APP_APP_INITIALIZER_H_
diff --git a/remoting/ios/app/app_initializer_chromium.mm b/remoting/ios/app/app_initializer_chromium.mm new file mode 100644 index 0000000..291d472b --- /dev/null +++ b/remoting/ios/app/app_initializer_chromium.mm
@@ -0,0 +1,24 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#import "remoting/ios/app/app_initializer.h" + +#import "remoting/ios/app/help_and_feedback.h" +#import "remoting/ios/facade/remoting_oauth_authentication.h" +#import "remoting/ios/facade/remoting_service.h" + +@implementation AppInitializer + ++ (void)initializeApp { + // |authentication| is nil by default and needs to be injected here. + RemotingService.instance.authentication = + [[RemotingOAuthAuthentication alloc] init]; + HelpAndFeedback.instance = [[HelpAndFeedback alloc] init]; +} + +@end
diff --git a/remoting/ios/app/main.mm b/remoting/ios/app/main.mm index c19a15e..9f49bcd 100644 --- a/remoting/ios/app/main.mm +++ b/remoting/ios/app/main.mm
@@ -8,13 +8,12 @@ #import <UIKit/UIKit.h> +#import "remoting/ios/app/app_delegate.h" +#import "remoting/ios/app/app_initializer.h" + #include "base/at_exit.h" #include "base/command_line.h" #include "base/i18n/icu_util.h" -#import "remoting/ios/app/app_delegate.h" -#import "remoting/ios/app/help_and_feedback.h" -#import "remoting/ios/facade/remoting_oauth_authentication.h" -#import "remoting/ios/facade/remoting_service.h" int main(int argc, char* argv[]) { // This class is designed to fulfill the dependents needs when it goes out of @@ -34,9 +33,7 @@ #endif @autoreleasepool { - RemotingService.instance.authentication = - [[RemotingOAuthAuthentication alloc] init]; - HelpAndFeedback.instance = [[HelpAndFeedback alloc] init]; + [AppInitializer initializeApp]; return UIApplicationMain( argc, argv, nil, NSStringFromClass([AppDelegate class])); }
diff --git a/remoting/ios/app/remoting_ios_tmpl.gni b/remoting/ios/app/remoting_ios_tmpl.gni index da3d07b..1de62071 100644 --- a/remoting/ios/app/remoting_ios_tmpl.gni +++ b/remoting/ios/app/remoting_ios_tmpl.gni
@@ -9,6 +9,11 @@ import("//remoting/build/config/remoting_build.gni") import("//remoting/credits/credits.gni") +# TODO(yuweih): Temporary flag. Remove once it rolls into downstream. +declare_args() { + supports_app_initializer = true +} + _remoting_ios_app_source_dir = get_path_info("./", "abspath") # Arguments @@ -36,7 +41,8 @@ args = [ "--platform=ios" ] } - _launchscreen_storyboard_target_name = "${target_name}_launchscreen_storyboard" + _launchscreen_storyboard_target_name = + "${target_name}_launchscreen_storyboard" bundle_data_ib_file(_launchscreen_storyboard_target_name) { source = rebase_path("resources/LaunchScreen.storyboard", ".",
diff --git a/services/service_manager/public/cpp/binder_registry.h b/services/service_manager/public/cpp/binder_registry.h index 2a2ddedc..ecb2feb 100644 --- a/services/service_manager/public/cpp/binder_registry.h +++ b/services/service_manager/public/cpp/binder_registry.h
@@ -91,6 +91,19 @@ } } + // Attempts to bind a request for |interface_name| on |interface_pipe|. + // If the request can be bound, |interface_pipe| is taken and this function + // returns true. If the request cannot be bound, |interface_pipe| is + // unmodified and this function returns false. + bool TryBindInterface(const std::string& interface_name, + mojo::ScopedMessagePipeHandle* interface_pipe, + BinderArgs... args) { + bool can_bind = CanBindInterface(interface_name); + if (can_bind) + BindInterface(interface_name, std::move(*interface_pipe), args...); + return can_bind; + } + base::WeakPtr<BinderRegistryWithArgs> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
diff --git a/services/service_manager/public/cpp/service_context.cc b/services/service_manager/public/cpp/service_context.cc index 9f56b6d..d33190c 100644 --- a/services/service_manager/public/cpp/service_context.cc +++ b/services/service_manager/public/cpp/service_context.cc
@@ -135,10 +135,9 @@ BinderRegistryWithArgs<const BindSourceInfo&>* global_registry = GetGlobalBinderRegistryForService(identity_.name()); - if (global_registry && global_registry->CanBindInterface(interface_name)) { + if (global_registry && global_registry->TryBindInterface( + interface_name, &interface_pipe, source_info)) { // Just use the binder overridden globally. - global_registry->BindInterface(interface_name, std::move(interface_pipe), - source_info); return; } service_->OnBindInterface(source_info, interface_name,
diff --git a/services/service_manager/tests/lifecycle/package.cc b/services/service_manager/tests/lifecycle/package.cc index 04f645a..6c48744 100644 --- a/services/service_manager/tests/lifecycle/package.cc +++ b/services/service_manager/tests/lifecycle/package.cc
@@ -105,9 +105,7 @@ void OnBindInterface(const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override { - if (registry_.CanBindInterface(interface_name)) { - registry_.BindInterface(interface_name, std::move(interface_pipe)); - } else { + if (!registry_.TryBindInterface(interface_name, &interface_pipe)) { ForwardingService::OnBindInterface(source_info, interface_name, std::move(interface_pipe)); }
diff --git a/services/ui/ws/frame_generator.h b/services/ui/ws/frame_generator.h index fe466fc..5d4ffc0 100644 --- a/services/ui/ws/frame_generator.h +++ b/services/ui/ws/frame_generator.h
@@ -49,6 +49,7 @@ void DidReceiveCompositorFrameAck( const std::vector<cc::ReturnedResource>& resources) override; void OnBeginFrame(const cc::BeginFrameArgs& args) override; + void OnBeginFramePausedChanged(bool paused) override {} void ReclaimResources( const std::vector<cc::ReturnedResource>& resources) override;
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 105b345..468d9f4 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -755,7 +755,8 @@ "gtest_tests": [ { "args": [ - "--enable-xml-result-parsing" + "--enable-xml-result-parsing", + "--shard-timeout=300" ], "name": "angle_deqp_gles2_gles_tests", "swarming": {
diff --git a/testing/buildbot/filters/fuchsia.ui_base_unittests.filter b/testing/buildbot/filters/fuchsia.ui_base_unittests.filter index 709b7fb..38824991 100644 --- a/testing/buildbot/filters/fuchsia.ui_base_unittests.filter +++ b/testing/buildbot/filters/fuchsia.ui_base_unittests.filter
@@ -1,9 +1,6 @@ -# TODO(fuchsia): Fix these tests and remove the filter. crbug.com/740608 . - +# These tests write a temp pak file in /tmp and then open it. They fail +# because Fuchsia doesn't support mmap on tmpfs yet. +# TODO(fuchsia): Remove the filter once mmap() is implemented. +# crbug.com/740608 . -*DataPackTest.* --BytesFormattingTest.FormatBytes -ResourceBundleImageTest.* --ResourceBundleTest.DelegateGetNativeImageNamed --ResourceBundleTest.DelegateGetPathForLocalePack --ResourceBundleTest.LocaleDataPakExists --TimeFormatTest.*
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 2ca86cf4..3f47db6 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -6795,7 +6795,6 @@ crbug.com/591099 fast/dom/Window/window-resize-and-move-sub-frame.html [ Failure ] crbug.com/591099 fast/dom/Window/window-resize-contents.html [ Failure ] crbug.com/591099 fast/dom/Window/window-resize.html [ Failure ] -crbug.com/591099 fast/dom/Window/window-scaled-viewport-properties.html [ Failure ] crbug.com/591099 fast/dom/Window/window-scroll-arguments.html [ Failure ] crbug.com/591099 fast/dom/Window/window-special-properties.html [ Crash Failure ] crbug.com/591099 fast/dom/XMLHttpRequest-constants.html [ Failure ] @@ -7266,7 +7265,6 @@ crbug.com/591099 fast/dom/webtiming-document-open.html [ Failure ] crbug.com/591099 fast/dom/webtiming-navigate-within-document.html [ Failure ] crbug.com/591099 fast/dom/webtiming.html [ Failure ] -crbug.com/591099 fast/dom/window-inner-size-scaling.html [ Failure ] crbug.com/591099 fast/dom/window-scroll-scaling.html [ Failure ] crbug.com/591099 fast/dom/wrapper-classes.html [ Timeout ] crbug.com/591099 fast/dom/wrapper-context.html [ Failure ] @@ -12204,32 +12202,32 @@ crbug.com/591099 http/tests/inspector-enabled/resource-tree/resource-tree-mimetype.html [ Failure ] crbug.com/591099 http/tests/inspector-enabled/shadow-dom-rules-restart.html [ Crash Failure ] crbug.com/591099 http/tests/inspector-enabled/shadow-dom-rules.html [ Crash Failure ] -crbug.com/591099 http/tests/inspector-protocol/access-inspected-object.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/cookies-protocol-test.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/network-data-length.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/network-fetch-content-with-error-status-code.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/network/disable-interception-midway.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/network/interception-auth-cancel.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/network/interception-auth-provide-credentials.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/network/navigation-interception.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/network/redirect-interception-blocked.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/network/redirect-interception-mocked.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/network/redirect-interception-modified.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/network/redirect-interception.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/network/request-interception-mock302.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/network/request-interception-mock404.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/network/request-interception-modify-get-to-post.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/network/request-interception.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/network/xhr-interception-auth-fail.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/network/xhr-interception.html [ Failure ] -crbug.com/591099 http/tests/inspector-protocol/ping-redirect.html [ Crash Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/reload-memory-cache.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/request-mixed-content-status-blockable.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/request-mixed-content-status-none.html [ Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.html [ Crash Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/request-referrer-policy.html [ Crash Failure Timeout ] -crbug.com/591099 http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame.html [ Failure Pass Timeout ] -crbug.com/591099 http/tests/inspector-protocol/websocket/websocket-user-agent-override.html [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/access-inspected-object.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/cookies-protocol-test.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/network-data-length.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/network-fetch-content-with-error-status-code.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/network/disable-interception-midway.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/network/interception-auth-cancel.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/network/interception-auth-provide-credentials.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/network/navigation-interception.js [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/network/redirect-interception-blocked.js [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/network/redirect-interception-mocked.js [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/network/redirect-interception-modified.js [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/network/redirect-interception.js [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/network/request-interception-mock302.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/network/request-interception-mock404.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/network/request-interception-modify-get-to-post.js [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/network/request-interception.js [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/network/xhr-interception-auth-fail.js [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/network/xhr-interception.js [ Failure ] +crbug.com/591099 http/tests/inspector-protocol/ping-redirect.js [ Crash Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/reload-memory-cache.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/request-mixed-content-status-blockable.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/request-mixed-content-status-none.js [ Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.js [ Crash Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/request-referrer-policy.js [ Crash Failure Timeout ] +crbug.com/591099 http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame.js [ Failure Pass Timeout ] +crbug.com/591099 http/tests/inspector-protocol/websocket/websocket-user-agent-override.js [ Failure ] crbug.com/591099 http/tests/inspector-unit/viewport-datagrid-items-attached-to-dom.js [ Failure ] crbug.com/591099 http/tests/inspector-unit/viewport-datagrid-items-expandable-attached-to-dom.js [ Failure ] crbug.com/591099 http/tests/inspector/appcache/appcache-iframe-manifests.html [ Crash Failure Timeout ] @@ -17527,7 +17525,7 @@ crbug.com/591099 virtual/layout_ng/fast/block/float/rubybase-children-moved-crash.html [ Failure ] crbug.com/591099 virtual/layout_ng/fast/block/margin-collapse/line-beside-float-complex-margin-collapsing.html [ Failure ] crbug.com/591099 virtual/layout_ng/fast/block/margin-collapse/self-collapsing-block-creates-block-formatting-context.html [ Failure Pass ] -crbug.com/591099 virtual/mojo-loading/http/tests/inspector-protocol/network/disable-interception-midway.html [ Failure Pass Timeout ] +crbug.com/591099 virtual/mojo-loading/http/tests/inspector-protocol/network/disable-interception-midway.js [ Failure Pass Timeout ] crbug.com/591099 virtual/mojo-loading/http/tests/inspector/appcache/appcache-iframe-manifests.html [ Pass Timeout ] crbug.com/591099 virtual/mojo-loading/http/tests/inspector/application-panel/storage-view-reports-quota.html [ Failure Pass Timeout ] crbug.com/591099 virtual/mojo-loading/http/tests/inspector/bindings/livelocation-main-frame-navigated.html [ Failure Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process index 25fef2d8..d094db1c 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process +++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -50,8 +50,8 @@ crbug.com/582176 virtual/mojo-loading/http/tests/inspector/console-cd.html [ Failure ] # https://crbug.com/608015 - node.contentDocument is undefined. -crbug.com/608015 http/tests/inspector-protocol/access-inspected-object.html [ Failure Timeout ] -crbug.com/608015 virtual/mojo-loading/http/tests/inspector-protocol/access-inspected-object.html [ Failure Timeout ] +crbug.com/608015 http/tests/inspector-protocol/access-inspected-object.js [ Failure Timeout ] +crbug.com/608015 virtual/mojo-loading/http/tests/inspector-protocol/access-inspected-object.js [ Failure Timeout ] # https://crbug.com/602493 - Layout tests harness doesn't support history dump across OOPIFs crbug.com/602493 http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Crash ] @@ -114,14 +114,14 @@ crbug.com/616905 virtual/mojo-loading/http/tests/history/cross-origin-redirect-on-back.html [ Timeout ] # https://crbug.com/623268 - Can't inspect OOPIFs from main page's DevTools window. -crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-blockable.html [ Timeout ] -crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-none.html [ Timeout ] -crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.html [ Timeout ] -crbug.com/623268 http/tests/inspector-protocol/request-referrer-policy.html [ Timeout ] -crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-mixed-content-status-blockable.html [ Timeout ] -crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-mixed-content-status-none.html [ Timeout ] -crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.html [ Timeout ] -crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-referrer-policy.html [ Timeout ] +crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-blockable.js [ Timeout ] +crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-none.js [ Timeout ] +crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.js [ Timeout ] +crbug.com/623268 http/tests/inspector-protocol/request-referrer-policy.js [ Timeout ] +crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-mixed-content-status-blockable.js [ Timeout ] +crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-mixed-content-status-none.js [ Timeout ] +crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.js [ Timeout ] +crbug.com/623268 virtual/mojo-loading/http/tests/inspector-protocol/request-referrer-policy.js [ Timeout ] crbug.com/623268 http/tests/inspector/console-cross-origin-iframe-logging.html [ Failure ] crbug.com/623268 http/tests/inspector/inspect-iframe-from-different-domain.html [ Timeout ] crbug.com/623268 virtual/mojo-loading/http/tests/inspector/console-cross-origin-iframe-logging.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 01ec2e0..36bbaba 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1863,6 +1863,7 @@ crbug.com/626703 virtual/threaded/transitions/transition-end-event-multiple-03.html [ Pass Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/webrtc/RTCDtlsTransport-getRemoteCertificates.html [ Timeout ] crbug.com/626703 [ Win10 ] external/wpt/preload/delaying-onload-link-preload-after-discovery.html [ Timeout ] crbug.com/626703 external/wpt/2dcontext/building-paths/canvas_complexshapes_arcto_001.htm [ Failure ] crbug.com/626703 external/wpt/2dcontext/building-paths/canvas_complexshapes_beziercurveto_001.htm [ Failure ] @@ -2784,8 +2785,8 @@ # ====== Tests from enabling .any.js/.worker.js tests end here ======== -crbug.com/745345 http/tests/inspector-protocol/network/disable-interception-midway.html [ Failure Pass ] -crbug.com/745345 virtual/mojo-loading/http/tests/inspector-protocol/network/disable-interception-midway.html [ Failure Pass ] +crbug.com/745345 http/tests/inspector-protocol/network/disable-interception-midway.js [ Failure Pass ] +crbug.com/745345 virtual/mojo-loading/http/tests/inspector-protocol/network/disable-interception-midway.js [ Failure Pass ] # ====== Begin of display: contents tests ======
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 0e2dbc37..2242237 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -104619,11 +104619,6 @@ {} ] ], - "service-workers/service-worker/fetch-request-resources.https-expected.txt": [ - [ - {} - ] - ], "service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt": [ [ {} @@ -134152,12 +134147,6 @@ {} ] ], - "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/moving-documents.html": [ - [ - "/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/moving-documents.html", - {} - ] - ], "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/not-in-shadow-tree.html": [ [ "/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/not-in-shadow-tree.html", @@ -134167,6 +134156,14 @@ "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html": [ [ "/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html", + { + "timeout": "long" + } + ] + ], + "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/remove-from-document.html": [ + [ + "/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/remove-from-document.html", {} ] ], @@ -164434,6 +164431,12 @@ {} ] ], + "webrtc/RTCConfiguration-iceServers.html": [ + [ + "/webrtc/RTCConfiguration-iceServers.html", + {} + ] + ], "webrtc/RTCConfiguration-iceTransportPolicy.html": [ [ "/webrtc/RTCConfiguration-iceTransportPolicy.html", @@ -164470,6 +164473,12 @@ {} ] ], + "webrtc/RTCDtlsTransport-getRemoteCertificates.html": [ + [ + "/webrtc/RTCDtlsTransport-getRemoteCertificates.html", + {} + ] + ], "webrtc/RTCIceCandidate-constructor.html": [ [ "/webrtc/RTCIceCandidate-constructor.html", @@ -164590,6 +164599,12 @@ {} ] ], + "webrtc/RTCPeerConnection-setDescription-transceiver.html": [ + [ + "/webrtc/RTCPeerConnection-setDescription-transceiver.html", + {} + ] + ], "webrtc/RTCPeerConnection-setLocalDescription-pranswer.html": [ [ "/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html", @@ -227850,7 +227865,7 @@ "testharness" ], "html/browsers/origin/cross-origin-objects/cross-origin-objects.html": [ - "2ea83cffb62eeba2653ee706267a67bea471d41a", + "9202ebf4d640ffccec49451bae23526c24a1053b", "testharness" ], "html/browsers/origin/cross-origin-objects/frame.html": [ @@ -228314,7 +228329,7 @@ "testharness" ], "html/browsers/the-window-object/window-indexed-properties.html": [ - "22d5cb06bfc4724d27f565b8ffa2280bf2e8538b", + "06d489f3668c963c46c1ed31e9263d8717eab4e7", "testharness" ], "html/browsers/the-window-object/window-named-properties-expected.txt": [ @@ -230482,7 +230497,7 @@ "testharness" ], "html/dom/reflection-tabular-expected.txt": [ - "620a0a046c7669b4954476bd78c8c4608c3ed3c7", + "b22633f6a0876950e564152810599bf3d840146f", "support" ], "html/dom/reflection-tabular.html": [ @@ -235861,10 +235876,6 @@ "bf4610909834f094b85d4c2113009fc9f25b140b", "testharness" ], - "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/moving-documents.html": [ - "050190b2706ff41b0a5844ca159990908d57177c", - "testharness" - ], "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/not-in-shadow-tree.html": [ "0d5f568af3b295b36e390156caf5ce523fd83d93", "testharness" @@ -235874,7 +235885,11 @@ "support" ], "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html": [ - "709457936084abefd847c1557748df61551bd920", + "d983c21a3a885e072ecd1acf13d1dd587f4fd024", + "testharness" + ], + "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/remove-from-document.html": [ + "d7222fbc63c3cda31b31e63e8e3119a9c61cef0d", "testharness" ], "html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/;url=foo": [ @@ -236490,7 +236505,7 @@ "testharness" ], "html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html": [ - "a9bad23477535b4227366de77b087d1c14389a30", + "b8fea88dda9ea84e37131f1727ca066378fd98c9", "testharness" ], "html/semantics/embedded-content/media-elements/preload_reflects_none_autoplay.html": [ @@ -260969,10 +260984,6 @@ "e1ea127e72573e97a4d175c1780bfaae6f537972", "testharness" ], - "service-workers/service-worker/fetch-request-resources.https-expected.txt": [ - "fda03ac2ef5e2d49f28c7b1c3f1d283f0623aadb", - "support" - ], "service-workers/service-worker/fetch-request-resources.https.html": [ "cb072581704868845fe1ec57b3e7c70d53bac543", "testharness" @@ -262214,7 +262225,7 @@ "support" ], "service-workers/service-worker/skip-waiting-installed.https.html": [ - "c635baadef3503e526f475132584da3f161b2d0a", + "00c260790547216d53e663404cf7cf9ecc7aa913", "testharness" ], "service-workers/service-worker/skip-waiting-using-registration.https.html": [ @@ -266109,6 +266120,10 @@ "7816790d82628acb7cf04e0a046046884c1207e7", "testharness" ], + "webrtc/RTCConfiguration-iceServers.html": [ + "2dbc12945221f64684a46311f9ebe23f69ea247e", + "testharness" + ], "webrtc/RTCConfiguration-iceTransportPolicy-expected.txt": [ "19c33db899b81c3cd4e634c9e3b41a93254ce51c", "support" @@ -266145,6 +266160,10 @@ "8a8b30a23abddb5d11a802fead534fd56aacbb62", "testharness" ], + "webrtc/RTCDtlsTransport-getRemoteCertificates.html": [ + "76eb9e89291ce2aa8fa81dd7216a853193abd6e2", + "testharness" + ], "webrtc/RTCIceCandidate-constructor-expected.txt": [ "f313c2ac3b85c15a6d9ea25fc8231ffcc34f22e2", "support" @@ -266198,7 +266217,7 @@ "support" ], "webrtc/RTCPeerConnection-constructor.html": [ - "369667335824b74e131fb5d2ef1542aa98ea2c0e", + "2152cb1835b1afe939504e934a7f19d30b17ba3d", "testharness" ], "webrtc/RTCPeerConnection-createAnswer-expected.txt": [ @@ -266297,12 +266316,16 @@ "561575bea206ec1c9572e1e5e6f97d1e0bebe2d1", "testharness" ], + "webrtc/RTCPeerConnection-setDescription-transceiver.html": [ + "aab677c9196488544b30c7eecd180c3046290bb2", + "testharness" + ], "webrtc/RTCPeerConnection-setLocalDescription-pranswer.html": [ "403b01796ca156e3a3157fbc0a64929348749a6e", "testharness" ], "webrtc/RTCPeerConnection-setLocalDescription-rollback.html": [ - "e1aea45480a7c486d8396c96654da986efbbe6f9", + "353808ea44c2a7b79458cd9fa7b7ffd23b868431", "testharness" ], "webrtc/RTCPeerConnection-setLocalDescription.html": [ @@ -266318,7 +266341,7 @@ "testharness" ], "webrtc/RTCPeerConnection-setRemoteDescription-rollback.html": [ - "7aace4060f519c96d9cba3f27e48dee7af916c51", + "ee83d6611ac113b96730c3ab103f5c2b1c8be1ba", "testharness" ], "webrtc/RTCPeerConnection-setRemoteDescription.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html index 9301632..06d96b1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html
@@ -187,14 +187,16 @@ var isSymbol = (typeof(propName) == "symbol"); propName = String(propName); assert_true(isObject(desc), "property descriptor for " + propName + " should exist"); - assert_equals(desc.enumerable, true, "property descriptor for " + propName + " should be enumerable"); assert_equals(desc.configurable, true, "property descriptor for " + propName + " should be configurable"); if (isSymbol) { + assert_equals(desc.enumerable, false, "symbol-property descriptor for " + propName + " should not be enumerable"); assert_true("value" in desc, "property descriptor for " + propName + " should be a value descriptor"); assert_equals(desc.value, undefined, "symbol-named cross-origin visible prop " + propName + " should come back as undefined"); + } else { + assert_equals(desc.enumerable, true, "property descriptor for " + propName + " should be enumerable"); } if ('value' in desc) assert_equals(desc.writable, expectWritable, "property descriptor for " + propName + " should have writable: " + expectWritable);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/window-indexed-properties-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/window-indexed-properties-expected.txt index 8e34f3e8..bbb43062 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/window-indexed-properties-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/window-indexed-properties-expected.txt
@@ -1,5 +1,6 @@ This is a testharness.js-based test. PASS Indexed properties of the window object (non-strict mode) +FAIL Ensure indexed properties have the correct configuration assert_true: expected true got false FAIL Indexed properties of the window object (non-strict mode) 1 assert_equals: expected false but got true PASS Indexed properties of the window object (non-strict mode) 2 PASS Indexed properties of the window object (non-strict mode) 3
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/window-indexed-properties.html b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/window-indexed-properties.html index 17d0eb7..4924717 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/window-indexed-properties.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/browsers/the-window-object/window-indexed-properties.html
@@ -17,6 +17,12 @@ window[-1] = "foo"; assert_equals(window[-1], "foo"); }); +test(() => { + const desc = Object.getOwnPropertyDescriptor(window, "0"); + assert_true(desc.configurable); + assert_true(desc.enumerable); + assert_false(desc.writable); +}, "Ensure indexed properties have the correct configuration"); test(function() { window[0] = "foo"; assert_throws(new TypeError(), () => Object.defineProperty(window, 0, { value: "bar" }))
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html index fa11d99..bfddcd1dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html
@@ -9,11 +9,46 @@ assert_equals(v.playbackRate, 1); }, 'playbackRate initial value'); -async_test(function(t) { +function testPlaybackRateHelper(t, newPlaybackRate) { var v = document.createElement('video'); - v.playbackRate = 2; - v.addEventListener('ratechange', t.step_func(function() { + var initialRate = v.playbackRate; + + v.addEventListener('ratechange', function() { + assert_equals(v.playbackRate, newPlaybackRate); t.done(); - })); -}, 'setting playbackRate'); + }); + + try { + v.playbackRate = newPlaybackRate; + } catch(e) { + assert_equals(e.name, 'NotSupportedError'); + assert_equals(v.playbackRate, initialRate); + t.done(); + } +} + +async_test(function(t) { + testPlaybackRateHelper(this, 3); +}, "playbackRate set to small positive value"); + +async_test(function(t) { + testPlaybackRateHelper(this, 100); +}, "playbackRate set to large positive value"); + +async_test(function(t) { + testPlaybackRateHelper(this, -3); +}, "playbackRate set to small negative value"); + +async_test(function(t) { + testPlaybackRateHelper(this, -100); +}, "playbackRate set to large negative value"); + +async_test(function(t) { + testPlaybackRateHelper(this, 0); +}, "playbackRate set to 0"); + +async_test(function(t) { + testPlaybackRateHelper(this, -1); +}, "playbackRate set to -1"); + </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceServers-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceServers-expected.txt new file mode 100644 index 0000000..32467f5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceServers-expected.txt
@@ -0,0 +1,113 @@ +This is a testharness.js-based test. +Found 77 tests; 12 PASS, 65 FAIL, 0 TIMEOUT, 0 NOTRUN. +FAIL new RTCPeerConnection() should have default configuration.iceServers of undefined pc.getConfiguration is not a function +PASS new RTCPeerConnection(config) - { iceServers: null } should throw TypeError +FAIL setConfiguration(config) - { iceServers: null } should throw TypeError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - { iceServers: undefined } should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - { iceServers: undefined } should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - { iceServers: [] } should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - { iceServers: [] } should succeed assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - { iceServers: [null] } should throw TypeError +FAIL setConfiguration(config) - { iceServers: [null] } should throw TypeError assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - { iceServers: [undefined] } should throw TypeError +FAIL setConfiguration(config) - { iceServers: [undefined] } should throw TypeError assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - { iceServers: [{}] } should throw TypeError +FAIL setConfiguration(config) - { iceServers: [{}] } should throw TypeError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with empty list urls should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with empty list urls should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with stun server should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with stun server should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with stun server array should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with stun server array should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with 2 stun servers should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with 2 stun servers should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with turn server, username, credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with turn server, username, credential should succeed pc.getConfiguration is not a function +FAIL new RTCPeerConnection(config) - with turns server and empty string username, credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with turns server and empty string username, credential should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with turn server and empty string username, credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with turn server and empty string username, credential should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with one turns server, one turn server, username, credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with one turns server, one turn server, username, credential should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with stun server and credentialType password should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with stun server and credentialType password should succeed assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - with turn server and no credentials should throw InvalidAccessError +FAIL setConfiguration(config) - with turn server and no credentials should throw InvalidAccessError assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - with turn server and only username should throw InvalidAccessError +FAIL setConfiguration(config) - with turn server and only username should throw InvalidAccessError assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - with turn server and only credential should throw InvalidAccessError +FAIL setConfiguration(config) - with turn server and only credential should throw InvalidAccessError assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - with turns server and no credentials should throw InvalidAccessError +FAIL setConfiguration(config) - with turns server and no credentials should throw InvalidAccessError assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - with turns server and only username should throw InvalidAccessError +FAIL setConfiguration(config) - with turns server and only username should throw InvalidAccessError assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - with turns server and only credential should throw InvalidAccessError +FAIL setConfiguration(config) - with turns server and only credential should throw InvalidAccessError assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - with relative url should throw SyntaxError +FAIL setConfiguration(config) - with relative url should throw SyntaxError assert_own_property: expected property "setConfiguration" missing +PASS new RTCPeerConnection(config) - with http url should throw SyntaxError +FAIL setConfiguration(config) - with http url should throw SyntaxError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with invalid turn url should throw SyntaxError assert_throws: function "() => + makePc({ iceServers: [{ + urls: 'turn://example.org/foo?x=y' + }] })" threw object "InvalidAccessError: Failed to construct 'RTCPeerConnection': Both username and credential are required when the URL scheme is "turn" or "turns"." that is not a DOMException SyntaxError: property "code" is equal to 15, expected 12 +FAIL setConfiguration(config) - with invalid turn url should throw SyntaxError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with invalid stun url should throw SyntaxError assert_throws: function "() => + makePc({ iceServers: [{ + urls: 'stun://example.org/foo?x=y' + }] })" did not throw +FAIL setConfiguration(config) - with invalid stun url should throw SyntaxError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with empty urls and credentialType password should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with empty urls and credentialType password should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with empty urls and credentialType oauth should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with empty urls and credentialType oauth should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with invalid credentialType should throw TypeError assert_throws: function "() => + makePc({ iceServers: [{ + urls: [], + credentialType: 'invalid' + }] })" did not throw +FAIL setConfiguration(config) - with invalid credentialType should throw TypeError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with credentialType token should throw TypeError assert_throws: function "() => + makePc({ iceServers: [{ + urls: [], + credentialType: 'token' + }] })" did not throw +FAIL setConfiguration(config) - with credentialType token should throw TypeError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with url field should throw TypeError assert_throws: function "() => + makePc({ iceServers: [{ + url: 'stun:stun1.example.net' + }] })" did not throw +FAIL setConfiguration(config) - with url field should throw TypeError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with turns server, credentialType password, and RTCOauthCredential credential should throw InvalidAccessError assert_throws: function "() => + makePc({ iceServers: [{ + urls: 'turns:turn.example.org', + credentialType: 'password', + username: 'user', + credential: { + macKey: '', + accessToken: '' + } + }] })" did not throw +FAIL setConfiguration(config) - with turns server, credentialType password, and RTCOauthCredential credential should throw InvalidAccessError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with turns server, credentialType oauth, and string credential should throw InvalidAccessError assert_throws: function "() => + makePc({ iceServers: [{ + urls: 'turns:turn.example.org', + credentialType: 'oauth', + username: 'user', + credential: 'cred' + }] })" did not throw +FAIL setConfiguration(config) - with turns server, credentialType oauth, and string credential should throw InvalidAccessError assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with turns server, credentialType oauth and RTCOAuthCredential credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with turns server, credentialType oauth and RTCOAuthCredential credential should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with both turns and stun server, credentialType oauth and RTCOAuthCredential credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with both turns and stun server, credentialType oauth and RTCOAuthCredential credential should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with stun server, credentialType oauth, and string credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with stun server, credentialType oauth, and string credential should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with stun server, credentialType password, and RTCOAuthCredential credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with stun server, credentialType password, and RTCOAuthCredential credential should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with empty urls list, credentialType oauth, and string credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with empty urls list, credentialType oauth, and string credential should succeed assert_own_property: expected property "setConfiguration" missing +FAIL new RTCPeerConnection(config) - with empty urls list, credentialType password, and RTCOAuthCredential credential should succeed pc.getConfiguration is not a function +FAIL setConfiguration(config) - with empty urls list, credentialType password, and RTCOAuthCredential credential should succeed assert_own_property: expected property "setConfiguration" missing +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceServers.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceServers.html new file mode 100644 index 0000000..42bc8963 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceServers.html
@@ -0,0 +1,570 @@ +<!doctype html> +<meta charset=utf-8> +<title>RTCConfiguration iceServers</title> +<script src='/resources/testharness.js'></script> +<script src='/resources/testharnessreport.js'></script> +<script src='RTCConfiguration-helper.js'></script> +<script> + 'use strict'; + + // Test is based on the following editor's draft: + // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html + + // The following helper function is called from + // RTCConfiguration-helper.js: + // config_test + + /* + 4.3.2. Interface Definition + [Constructor(optional RTCConfiguration configuration)] + interface RTCPeerConnection : EventTarget { + ... + }; + + 4.2.1. RTCConfiguration Dictionary + dictionary RTCConfiguration { + sequence<RTCIceServer> iceServers; + ... + }; + + 4.2.2. RTCIceCredentialType Enum + enum RTCIceCredentialType { + "password", + "oauth" + }; + + 4.2.3. RTCOAuthCredential Dictionary + dictionary RTCOAuthCredential { + required DOMString macKey; + required DOMString accessToken; + }; + + 4.2.4. RTCIceServer Dictionary + dictionary RTCIceServer { + required (DOMString or sequence<DOMString>) urls; + DOMString username; + (DOMString or RTCOAuthCredential) credential; + RTCIceCredentialType credentialType = "password"; + }; + */ + + test(() => { + const pc = new RTCPeerConnection(); + assert_equals(pc.getConfiguration().iceServers, undefined); + }, 'new RTCPeerConnection() should have default configuration.iceServers of undefined'); + + config_test(makePc => { + assert_throws(new TypeError(), () => + makePc({ iceServers: null })); + }, '{ iceServers: null } should throw TypeError'); + + config_test(makePc => { + const pc = makePc({ iceServers: undefined }); + assert_equals(pc.getConfiguration().iceServers, undefined); + }, '{ iceServers: undefined } should succeed'); + + config_test(makePc => { + const pc = makePc({ iceServers: [] }); + assert_array_equals(pc.getConfiguration().iceServers, []); + }, '{ iceServers: [] } should succeed'); + + config_test(makePc => { + assert_throws(new TypeError(), () => + makePc({ iceServers: [null] })); + }, '{ iceServers: [null] } should throw TypeError'); + + config_test(makePc => { + assert_throws(new TypeError(), () => + makePc({ iceServers: [undefined] })); + }, '{ iceServers: [undefined] } should throw TypeError'); + + config_test(makePc => { + assert_throws(new TypeError(), () => + makePc({ iceServers: [{}] })); + }, '{ iceServers: [{}] } should throw TypeError'); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: [] + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, []); + assert_equals(server.credentialType, 'password'); + }, 'with empty list urls should succeed'); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: 'stun:stun1.example.net' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['stun:stun1.example.net']); + assert_equals(server.credentialType, 'password'); + + }, `with stun server should succeed`); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: ['stun:stun1.example.net'] + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['stun:stun1.example.net']); + assert_equals(server.credentialType, 'password'); + + }, `with stun server array should succeed`); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: ['stun:stun1.example.net', 'stun:stun2.example.net'] + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['stun:stun1.example.net', 'stun:stun2.example.net']); + assert_equals(server.credentialType, 'password'); + + }, `with 2 stun servers should succeed`); + + config_test(makePc => { + const pc = new RTCPeerConnection({ iceServers: [{ + urls: 'turn:turn.example.org', + username: 'user', + credential: 'cred' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['turn:turn.example.org']); + assert_equals(server.credentialType, 'password'); + assert_equals(server.username, 'user'); + assert_equals(server.credential, 'cred'); + + }, `with turn server, username, credential should succeed`); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: 'turns:turn.example.org', + username: '', + credential: '' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['turns:turn.example.org']); + assert_equals(server.username, ''); + assert_equals(server.credential, ''); + + }, `with turns server and empty string username, credential should succeed`); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: 'turn:turn.example.org', + username: '', + credential: '' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['turn:turn.example.org']); + assert_equals(server.username, ''); + assert_equals(server.credential, ''); + + }, `with turn server and empty string username, credential should succeed`); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: ['turns:turn.example.org', 'turn:turn.example.net'], + username: 'user', + credential: 'cred' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['turns:turn.example.org', 'turn:turn.example.net']); + assert_equals(server.username, 'user'); + assert_equals(server.credential, 'cred'); + + }, `with one turns server, one turn server, username, credential should succeed`); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: 'stun:stun1.example.net', + credentialType: 'password' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['stun:stun1.example.net']); + assert_equals(server.credentialType, 'password'); + + }, `with stun server and credentialType password should succeed`); + + /* + 4.3.2. To set a configuration + 11.4. If scheme name is turn or turns, and either of server.username or + server.credential are omitted, then throw an InvalidAccessError. + */ + config_test(makePc => { + assert_throws('InvalidAccessError', () => + makePc({ iceServers: [{ + urls: 'turn:turn.example.net' + }] })); + }, 'with turn server and no credentials should throw InvalidAccessError'); + + config_test(makePc => { + assert_throws('InvalidAccessError', () => + makePc({ iceServers: [{ + urls: 'turn:turn.example.net', + username: 'user' + }] })); + }, 'with turn server and only username should throw InvalidAccessError'); + + config_test(makePc => { + assert_throws('InvalidAccessError', () => + makePc({ iceServers: [{ + urls: 'turn:turn.example.net', + credential: 'cred' + }] })); + }, 'with turn server and only credential should throw InvalidAccessError'); + + config_test(makePc => { + assert_throws('InvalidAccessError', () => + makePc({ iceServers: [{ + urls: 'turns:turn.example.net' + }] })); + }, 'with turns server and no credentials should throw InvalidAccessError'); + + config_test(makePc => { + assert_throws('InvalidAccessError', () => + makePc({ iceServers: [{ + urls: 'turns:turn.example.net', + username: 'user' + }] })); + }, 'with turns server and only username should throw InvalidAccessError'); + + config_test(makePc => { + assert_throws('InvalidAccessError', () => + makePc({ iceServers: [{ + urls: 'turns:turn.example.net', + credential: 'cred' + }] })); + }, 'with turns server and only credential should throw InvalidAccessError'); + + /* + 4.3.2. To set a configuration + 11.3. For each url in server.urls parse url and obtain scheme name. + - If the scheme name is not implemented by the browser, throw a SyntaxError. + - or if parsing based on the syntax defined in [ RFC7064] and [RFC7065] fails, + throw a SyntaxError. + + [RFC7064] URI Scheme for the Session Traversal Utilities for NAT (STUN) Protocol + 3.1. URI Scheme Syntax + stunURI = scheme ":" host [ ":" port ] + scheme = "stun" / "stuns" + + [RFC7065] Traversal Using Relays around NAT (TURN) Uniform Resource Identifiers + 3.1. URI Scheme Syntax + turnURI = scheme ":" host [ ":" port ] + [ "?transport=" transport ] + scheme = "turn" / "turns" + transport = "udp" / "tcp" / transport-ext + transport-ext = 1*unreserved + */ + config_test(makePc => { + assert_throws('SyntaxError', () => + makePc({ iceServers: [{ + urls: 'relative-url' + }] })); + }, 'with relative url should throw SyntaxError'); + + config_test(makePc => { + assert_throws('SyntaxError', () => + makePc({ iceServers: [{ + urls: 'http://example.com' + }] })); + }, 'with http url should throw SyntaxError'); + + config_test(makePc => { + assert_throws('SyntaxError', () => + makePc({ iceServers: [{ + urls: 'turn://example.org/foo?x=y' + }] })); + }, 'with invalid turn url should throw SyntaxError'); + + config_test(makePc => { + assert_throws('SyntaxError', () => + makePc({ iceServers: [{ + urls: 'stun://example.org/foo?x=y' + }] })); + }, 'with invalid stun url should throw SyntaxError'); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: [], + credentialType: 'password' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, []); + assert_equals(server.credentialType, 'password'); + }, `with empty urls and credentialType password should succeed`); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: [], + credentialType: 'oauth' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, []); + assert_equals(server.credentialType, 'oauth'); + }, `with empty urls and credentialType oauth should succeed`); + + config_test(makePc => { + assert_throws(new TypeError(), () => + makePc({ iceServers: [{ + urls: [], + credentialType: 'invalid' + }] })); + }, 'with invalid credentialType should throw TypeError'); + + // token credentialType was removed from the spec since 20170508 + config_test(makePc => { + assert_throws(new TypeError(), () => + makePc({ iceServers: [{ + urls: [], + credentialType: 'token' + }] })); + }, 'with credentialType token should throw TypeError'); + + // Blink and Gecko fall back to url, but it's not in the spec. + config_test(makePc => { + assert_throws(new TypeError(), () => + makePc({ iceServers: [{ + url: 'stun:stun1.example.net' + }] })); + }, 'with url field should throw TypeError'); + + /* + 4.3.2. To set a configuration + 11.5. If scheme name is turn or turns, and server.credentialType is "password", + and server.credential is not a DOMString, then throw an InvalidAccessError + and abort these steps. + */ + config_test(makePc => { + assert_throws('InvalidAccessError', () => + makePc({ iceServers: [{ + urls: 'turns:turn.example.org', + credentialType: 'password', + username: 'user', + credential: { + macKey: '', + accessToken: '' + } + }] })); + }, 'with turns server, credentialType password, and RTCOauthCredential credential should throw InvalidAccessError'); + + /* + 4.3.2. To set a configuration + 11.6. If scheme name is turn or turns, and server.credentialType is "oauth", + and server.credential is not an RTCOAuthCredential, then throw an + InvalidAccessError and abort these steps. + */ + config_test(makePc => { + assert_throws('InvalidAccessError', () => + makePc({ iceServers: [{ + urls: 'turns:turn.example.org', + credentialType: 'oauth', + username: 'user', + credential: 'cred' + }] })); + }, 'with turns server, credentialType oauth, and string credential should throw InvalidAccessError'); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: 'turns:turn.example.org', + credentialType: 'oauth', + username: 'user', + credential: { + macKey: 'mac', + accessToken: 'token' + } + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['turns:turn.example.org']); + assert_equals(server.credentialType, 'oauth'); + assert_equals(server.username, 'user'); + + const { credential } = server; + assert_equals(credential.macKey, 'mac'); + assert_equals(credential.accessToken, 'token'); + + }, `with turns server, credentialType oauth and RTCOAuthCredential credential should succeed`); + + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: ['turns:turn.example.org', 'stun:stun1.example.net'], + credentialType: 'oauth', + username: 'user', + credential: { + macKey: 'mac', + accessToken: 'token' + } + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['turns:turn.example.org', 'stun:stun1.example.net']); + assert_equals(server.credentialType, 'oauth'); + assert_equals(server.username, 'user'); + + const { credential } = server; + assert_equals(credential.macKey, 'mac'); + assert_equals(credential.accessToken, 'token'); + + }, `with both turns and stun server, credentialType oauth and RTCOAuthCredential credential should succeed`); + + // credential type validation is ignored when scheme name is stun + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: 'stun:stun1.example.net', + credentialType: 'oauth', + username: 'user', + credential: 'cred' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + const server = iceServers[0]; + + assert_array_equals(server.urls, ['stun:stun1.example.net']); + assert_equals(server.credentialType, 'oauth'); + assert_equals(server.username, 'user'); + assert_equals(server.credential, 'cred'); + + }, 'with stun server, credentialType oauth, and string credential should succeed'); + + // credential type validation is ignored when scheme name is stun + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: 'stun:stun1.example.net', + credentialType: 'password', + username: 'user', + credential: { + macKey: '', + accessToken: '' + } + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, ['stun:stun1.example.net']); + assert_equals(server.credentialType, 'password'); + assert_equals(server.username, 'user'); + + const { credential } = server; + assert_equals(credential.macKey, ''); + assert_equals(credential.accessToken, ''); + + }, 'with stun server, credentialType password, and RTCOAuthCredential credential should succeed'); + + // credential type validation is ignored when urls is empty and there is no scheme name + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: [], + credentialType: 'oauth', + username: 'user', + credential: 'cred' + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + const server = iceServers[0]; + + assert_array_equals(server.urls, []); + assert_equals(server.credentialType, 'oauth'); + assert_equals(server.username, 'user'); + assert_equals(server.credential, 'cred'); + + }, 'with empty urls list, credentialType oauth, and string credential should succeed'); + + // credential type validation is ignored when urls is empty and there is no scheme name + config_test(makePc => { + const pc = makePc({ iceServers: [{ + urls: [], + credentialType: 'password', + username: 'user', + credential: { + macKey: '', + accessToken: '' + } + }] }); + + const { iceServers } = pc.getConfiguration(); + assert_equals(iceServers.length, 1); + + const server = iceServers[0]; + assert_array_equals(server.urls, []); + assert_equals(server.credentialType, 'password'); + assert_equals(server.username, 'user'); + + const { credential } = server; + assert_equals(credential.macKey, ''); + assert_equals(credential.accessToken, ''); + + }, 'with empty urls list, credentialType password, and RTCOAuthCredential credential should succeed'); + + /* + Tested + 4.3.2. To set a configuration + 11.1-6. + + Untestable + 4.3.2. To set a configuration + 11.7. Append server to validatedServers. + + Coverage Report + Tested 9 + Not Tested 0 + Untestable 1 + Total 10 + */ + +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCDtlsTransport-getRemoteCertificates.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCDtlsTransport-getRemoteCertificates.html new file mode 100644 index 0000000..0fd5340 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCDtlsTransport-getRemoteCertificates.html
@@ -0,0 +1,105 @@ +<!doctype html> +<meta charset="utf-8"> +<title>RTCDtlsTransport.prototype.getRemoteCertificates</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="RTCPeerConnection-helper.js"></script> +<script> + 'use strict'; + + // The following helper functions are called from RTCPeerConnection-helper.js: + // exchangeIceCandidates + // doSignalingHandshake + + /* + 5.5. RTCDtlsTransport Interface + interface RTCDtlsTransport : EventTarget { + readonly attribute RTCDtlsTransportState state; + sequence<ArrayBuffer> getRemoteCertificates(); + attribute EventHandler onstatechange; + attribute EventHandler onerror; + ... + }; + + enum RTCDtlsTransportState { + "new", + "connecting", + "connected", + "closed", + "failed" + }; + + getRemoteCertificates + Returns the certificate chain in use by the remote side, with each certificate + encoded in binary Distinguished Encoding Rules (DER) [X690]. + getRemoteCertificates() will return an empty list prior to selection of the + remote certificate, which will be completed by the time RTCDtlsTransportState + transitions to "connected". + */ + async_test(t => { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + + pc1.createDataChannel('test'); + exchangeIceCandidates(pc1, pc2); + + doSignalingHandshake(pc1, pc2) + .then(t.step_func(() => { + // pc.sctp is set when set*Description(answer) is called + const sctpTransport1 = pc1.sctp; + const sctpTransport2 = pc2.sctp; + + assert_true(sctpTransport1 instanceof RTCSctpTransport, + 'Expect pc.sctp to be set to valid RTCSctpTransport'); + + assert_true(sctpTransport2 instanceof RTCSctpTransport, + 'Expect pc.sctp to be set to valid RTCSctpTransport'); + + const dtlsTransport1 = sctpTransport1.transport; + const dtlsTransport2 = sctpTransport2.transport; + + const testedTransports = new Set(); + + // Callback function that test the respective DTLS transports + // when they become connected. + const onConnected = t.step_func(dtlsTransport => { + const certs = dtlsTransport.getRemoteCertificates(); + + assert_greater_than(certs.length, 0, + 'Expect DTLS transport to have at least one remote certificate when connected'); + + for(const cert of certs) { + assert_true(cert instanceof ArrayBuffer, + 'Expect certificate elements be instance of ArrayBuffer'); + } + + testedTransports.add(dtlsTransport); + + // End the test if both dtlsTransports are tested. + if(testedTransports.has(dtlsTransport1) && testedTransports.has(dtslTransport2)) { + t.done(); + } + }) + + for(const dtlsTransport of [dtlsTransport1, dtlsTransport2]) { + if(dtlsTransport.state === 'connected') { + onConnected(dtlsTransport); + } else { + assert_array_equals(dtlsTransport.getCertificates(), [], + 'Expect DTLS certificates be initially empty until become connected'); + + dtlsTransport.addEventListener('statechange', t.step_func(() => { + if(dtlsTransport.state === 'connected') { + onConnected(dtlsTransport); + } + })); + + dtlsTransport.addEventListener('error', t.step_func(err => { + assert_unreached(`Unexpected error during DTLS handshake: ${err}`); + })); + } + } + })); + }); + +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor-expected.txt index ff2f435..fa9c4f27 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor-expected.txt
@@ -1,49 +1,9 @@ This is a testharness.js-based test. -Found 54 tests; 43 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS RTCPeerConnection.length PASS new RTCPeerConnection() PASS new RTCPeerConnection(null) PASS new RTCPeerConnection(undefined) PASS new RTCPeerConnection({}) -PASS new RTCPeerConnection({ iceServers: null }) -PASS new RTCPeerConnection({ iceServers: undefined }) -PASS new RTCPeerConnection({ iceServers: [] }) -PASS new RTCPeerConnection({ iceServers: [{}] }) -PASS new RTCPeerConnection({ iceServers: [null] }) -PASS new RTCPeerConnection({ iceServers: [undefined] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "stun:stun1.example.net" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: [] }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: ["stun:stun1.example.net"] }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: ["stun:stun1.example.net", "stun:stun2.example.net"] }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turns:turn.example.org", username: "user", credential: "cred" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turn:turn.example.net", username: "user", credential: "cred" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turns:turn.example.org", username: "", credential: "" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turn:turn.example.net", username: "", credential: "" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: ["turns:turn.example.org", "turn:turn.example.net"], username: "user", credential: "cred" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "stun:stun1.example.net", credentialType: "password" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "stun:stun1.example.net", credentialType: "token" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turn:turn.example.net" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turn:turn.example.net", username: "user" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turn:turn.example.net", credential: "cred" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turns:turn.example.org" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turns:turn.example.org", username: "user" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "turns:turn.example.org", credential: "cred" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: "relative-url" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: ["stun:stun1.example.net", "relative-url"] }] }) -FAIL new RTCPeerConnection({ iceServers: [{ urls: "http://example.com" }] }) assert_throws: function "function () { - eval(expr); - }" threw object "SyntaxError: Failed to construct 'RTCPeerConnection': 'http' is not one of the supported URL schemes 'stun', 'turn' or 'turns'." that is not a DOMException NotSupportedError: property "code" is equal to 12, expected 9 -FAIL new RTCPeerConnection({ iceServers: [{ urls: ["stun:stun1.example.net", "http://example.com"] }] }) assert_throws: function "function () { - eval(expr); - }" threw object "SyntaxError: Failed to construct 'RTCPeerConnection': 'http' is not one of the supported URL schemes 'stun', 'turn' or 'turns'." that is not a DOMException NotSupportedError: property "code" is equal to 12, expected 9 -PASS new RTCPeerConnection({ iceServers: [{ urls: [], credentialType: "password" }] }) -PASS new RTCPeerConnection({ iceServers: [{ urls: [], credentialType: "token" }] }) -FAIL new RTCPeerConnection({ iceServers: [{ urls: [], credentialType: "invalid" }] }) assert_throws: function "function () { - eval(expr); - }" did not throw -FAIL new RTCPeerConnection({ iceServers: [{ url: "stun:stun1.example.net" }] }) assert_throws: function "function () { - eval(expr); - }" did not throw FAIL new RTCPeerConnection({ peerIdentity: toStringThrows }) assert_throws: function "function () { eval(expr); }" did not throw
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor.html index 19e9fba..331eefe 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor.html
@@ -23,43 +23,6 @@ 'undefined': false, '{}': false, - // iceServers - '{ iceServers: null }': new TypeError, - '{ iceServers: undefined }': false, - '{ iceServers: [] }': false, - '{ iceServers: [{}] }': new TypeError, - '{ iceServers: [null] }': new TypeError, - '{ iceServers: [undefined] }': new TypeError, - '{ iceServers: [{ urls: "stun:stun1.example.net" }] }': false, - '{ iceServers: [{ urls: [] }] }': false, - '{ iceServers: [{ urls: ["stun:stun1.example.net"] }] }': false, - '{ iceServers: [{ urls: ["stun:stun1.example.net", "stun:stun2.example.net"] }] }': false, - // username and password required for turn: and turns: - '{ iceServers: [{ urls: "turns:turn.example.org", username: "user", credential: "cred" }] }': false, - '{ iceServers: [{ urls: "turn:turn.example.net", username: "user", credential: "cred" }] }': false, - '{ iceServers: [{ urls: "turns:turn.example.org", username: "", credential: "" }] }': false, - '{ iceServers: [{ urls: "turn:turn.example.net", username: "", credential: "" }] }': false, - '{ iceServers: [{ urls: ["turns:turn.example.org", "turn:turn.example.net"], username: "user", credential: "cred" }] }': false, - '{ iceServers: [{ urls: "stun:stun1.example.net", credentialType: "password" }] }': false, - '{ iceServers: [{ urls: "stun:stun1.example.net", credentialType: "token" }] }': false, - '{ iceServers: [{ urls: "turn:turn.example.net" }] }': 'InvalidAccessError', - '{ iceServers: [{ urls: "turn:turn.example.net", username: "user" }] }': 'InvalidAccessError', - '{ iceServers: [{ urls: "turn:turn.example.net", credential: "cred" }] }': 'InvalidAccessError', - '{ iceServers: [{ urls: "turns:turn.example.org" }] }': 'InvalidAccessError', - '{ iceServers: [{ urls: "turns:turn.example.org", username: "user" }] }': 'InvalidAccessError', - '{ iceServers: [{ urls: "turns:turn.example.org", credential: "cred" }] }': 'InvalidAccessError', - '{ iceServers: [{ urls: "relative-url" }] }': 'SyntaxError', - '{ iceServers: [{ urls: ["stun:stun1.example.net", "relative-url"] }] }': 'SyntaxError', - '{ iceServers: [{ urls: "http://example.com" }] }': 'NotSupportedError', - '{ iceServers: [{ urls: ["stun:stun1.example.net", "http://example.com"] }] }': 'NotSupportedError', - // credentialType - '{ iceServers: [{ urls: [] }] }': false, - '{ iceServers: [{ urls: [], credentialType: "password" }] }': false, - '{ iceServers: [{ urls: [], credentialType: "token" }] }': false, - '{ iceServers: [{ urls: [], credentialType: "invalid" }] }': new TypeError, - // Blink and Gecko fall back to url, but it's not in the spec. - '{ iceServers: [{ url: "stun:stun1.example.net" }] }': new TypeError, - // peerIdentity '{ peerIdentity: toStringThrows }': new Error,
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt new file mode 100644 index 0000000..5531a050 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setDescription-transceiver-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +FAIL setLocalDescription(offer) with m= section should assign mid to corresponding transceiver pc.addTransceiver is not a function +FAIL setRemoteDescription(offer) with m= section and no existing transceiver should create corresponding transceiver pc1.addTransceiver is not a function +FAIL setLocalDescription(rollback) should unset transceiver.mid pc.addTransceiver is not a function +FAIL setLocalDescription(rollback) should only unset transceiver mids associated with current round pc.addTransceiver is not a function +FAIL setRemoteDescription(rollback) should remove newly created transceiver from transceiver list pc1.addTransceiver is not a function +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setDescription-transceiver.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setDescription-transceiver.html new file mode 100644 index 0000000..ed41d66 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setDescription-transceiver.html
@@ -0,0 +1,267 @@ +<!doctype html> +<meta charset=utf-8> +<title>RTCPeerConnection Set Session Description - Transceiver Tests</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="RTCPeerConnection-helper.js"></script> +<script> + 'use strict'; + + // Test is based on the following editor draft: + // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html + + // The following helper functions are called from RTCPeerConnection-helper.js: + // generateAnswer + + /* + 4.3.2. Interface Definition + + [Constructor(optional RTCConfiguration configuration)] + interface RTCPeerConnection : EventTarget { + Promise<void> setLocalDescription( + RTCSessionDescriptionInit description); + + Promise<void> setRemoteDescription( + RTCSessionDescriptionInit description); + ... + }; + + 4.6.2. RTCSessionDescription Class + dictionary RTCSessionDescriptionInit { + required RTCSdpType type; + DOMString sdp = ""; + }; + + 4.6.1. RTCSdpType + enum RTCSdpType { + "offer", + "pranswer", + "answer", + "rollback" + }; + + 5.4. RTCRtpTransceiver Interface + + interface RTCRtpTransceiver { + readonly attribute DOMString? mid; + [SameObject] + readonly attribute RTCRtpSender sender; + [SameObject] + readonly attribute RTCRtpReceiver receiver; + readonly attribute RTCRtpTransceiverDirection direction; + readonly attribute RTCRtpTransceiverDirection? currentDirection; + ... + }; + */ + + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 7. If description is set as a local description, then run the following steps for + each media description in description that is not yet associated with an + RTCRtpTransceiver object: + 1. Let transceiver be the RTCRtpTransceiver used to create the media + description. + 2. Set transceiver's mid value to the mid of the corresponding media + description. + */ + promise_test(() => { + const pc = new RTCPeerConnection(); + const transceiver = pc.addTransceiver('audio'); + assert_equals(transceiver.mid, null); + + return pc.createOffer() + .then(offer => { + assert_equals(transceiver.mid, null, + 'Expect transceiver.mid to still be null after createOffer'); + + return pc.setLocalDescription(offer) + .then(() => { + assert_equals(typeof transceiver.mid, 'string', + 'Expect transceiver.mid to set to valid string value'); + + assert_equals(offer.sdp.includes(`\r\na=mid:${transceiver.mid}`), true, + 'Expect transceiver mid to be found in offer SDP'); + }); + }); + }, 'setLocalDescription(offer) with m= section should assign mid to corresponding transceiver'); + + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 8. If description is set as a remote description, then run the following steps + for each media description in description: + 2. If no suitable transceiver is found (transceiver is unset), run the following + steps: + 1. Create an RTCRtpSender, sender, from the media description. + 2. Create an RTCRtpReceiver, receiver, from the media description. + 3. Create an RTCRtpTransceiver with sender, receiver and direction, and let + transceiver be the result. + 3. Set transceiver's mid value to the mid of the corresponding media description. + */ + promise_test(() => { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + + const transceiver1 = pc1.addTransceiver('audio'); + assert_array_equals(pc1.getTransceivers(), [transceiver1]); + assert_array_equals(pc2.getTransceivers(), []); + + return pc1.createOffer() + .then(offer => { + return Promise.all([ + pc1.setLocalDescription(offer), + pc2.setRemoteDescrption(offer) + ]) + .then(() => { + const transceivers = pc2.getTransceivers(); + assert_equals(transceivers.length, 1, + 'Expect new transceiver added to pc2 after setRemoteDescription'); + + const [ transceiver2 ] = transceivers; + + assert_equals(typeof transceiver2.mid, 'string', + 'Expect transceiver2.mid to be set'); + + assert_equals(transceiver1.mid, transceiver2.mid, + 'Expect transceivers of both side to have the same mid'); + + assert_equals(offer.sdp.includes(`\r\na=mid:${transceiver2.mid}`), true, + 'Expect transceiver mid to be found in offer SDP'); + }); + }); + }, 'setRemoteDescription(offer) with m= section and no existing transceiver should create corresponding transceiver'); + + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 9. If description is of type "rollback", then run the following steps: + 1. If the mid value of an RTCRtpTransceiver was set to a non-null value by + the RTCSessionDescription that is being rolled back, set the mid value + of that transceiver to null, as described by [JSEP] (section 4.1.8.2.). + */ + promise_test(() => { + const pc = new RTCPeerConnection(); + const transceiver = pc.addTransceiver('audio'); + assert_equals(transceiver.mid, null); + + return pc.createOffer() + .then(offer => { + assert_equals(transceiver.mid, null); + return pc.setLocalDescription(offer); + }) + .then(() => { + assert_not_equals(transceiver.mid, null); + return pc.setLocalDescription({ type: 'rollback' }); + }) + .then(() => { + assert_equals(transceiver.mid, null, + 'Expect transceiver.mid to become null again after rollback'); + }); + }, 'setLocalDescription(rollback) should unset transceiver.mid'); + + promise_test(() => { + const pc = new RTCPeerConnection(); + const transceiver1 = pc.addTransceiver('audio'); + assert_equals(transceiver1.mid, null); + + return pc.createOffer() + .then(offer => + pc.setLocalDescription(offer) + .then(() => generateAnswer(offer))) + .then(answer => pc.setRemoteDescription(answer)) + .then(() => { + // pc is back to stable state + // create another transceiver + const transceiver2 = pc.addTransceiver('video'); + + assert_not_equals(transceiver1.mid, null); + assert_equals(transceiver2.mid, null); + + return pc.createOffer() + .then(offer => pc.setLocalDescription(offer)) + .then(() => { + assert_not_equals(transceiver1.mid, null); + assert_not_equals(transceiver2.mid, null, + 'Expect transceiver2.mid to become set'); + + return pc.setLocalDescription({ type: 'rollback' }); + }) + .then(() => { + assert_not_equals(transceiver1.mid, null, + 'Expect transceiver1.mid to stay set'); + + assert_equals(transceiver2.mid, null, + 'Expect transceiver2.mid to be rolled back to null'); + }); + }) + }, 'setLocalDescription(rollback) should only unset transceiver mids associated with current round'); + + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 9. If description is of type "rollback", then run the following steps: + 2. If an RTCRtpTransceiver was created by applying the RTCSessionDescription + that is being rolled back, and a track has not been attached to it via + addTrack, remove that transceiver from connection's set of transceivers, + as described by [JSEP] (section 4.1.8.2.). + */ + promise_test(() => { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + + pc1.addTransceiver('audio'); + + return pc1.createOffer() + .then(offer => pc2.setRemoteDescription(offer)) + .then(() => { + const transceivers = pc2.getTransceivers(); + assert_equals(transceivers.length, 1); + const [ transceiver ] = transceivers; + + assert_equals(typeof transceiver.mid, 'string', + 'Expect transceiver.mid to be set'); + + return pc2.setRemoteDescription({ type: 'rollback' }) + .then(() => { + assert_equals(transceiver.mid, null, + 'Expect transceiver.mid to be unset'); + + assert_array_equals(pc2.getTransceivers(), [], + `Expect transceiver to be removed from pc2's transceiver list`); + }); + }); + }, 'setRemoteDescription(rollback) should remove newly created transceiver from transceiver list'); + + /* + TODO + - Steps for transceiver direction is added to tip of tree draft, but not yet + published as editor's draft + + 4.3.1.6. Set the RTCSessionSessionDescription + 8. If description is set as a remote description, then run the following steps + for each media description in description: + 1. As described by [JSEP] (section 5.9.), attempt to find an existing + RTCRtpTransceiver object, transceiver, to represent the media description. + 3. If the media description has no MID, and transceiver's mid is unset, generate + a random value as described in [JSEP] (section 5.9.). + 4. If the direction of the media description is sendrecv or sendonly, and + transceiver.receiver.track has not yet been fired in a track event, process + the remote track for the media description, given transceiver. + 5. If the media description is rejected, and transceiver is not already stopped, + stop the RTCRtpTransceiver transceiver. + + [JSEP] + 5.9. Applying a Remote Description + - If the m= section is not associated with any RtpTransceiver + (possibly because it was dissociated in the previous step), + either find an RtpTransceiver or create one according to the + following steps: + + - If the m= section is sendrecv or recvonly, and there are + RtpTransceivers of the same type that were added to the + PeerConnection by addTrack and are not associated with any + m= section and are not stopped, find the first (according to + the canonical order described in Section 5.2.1) such + RtpTransceiver. + + - If no RtpTransceiver was found in the previous step, create + one with a recvonly direction. + */ +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-rollback.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-rollback.html index dc2904e0..f6e3a4f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-rollback.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-rollback.html
@@ -79,4 +79,45 @@ }); }, 'setLocalDescription(rollback) from have-local-offer state should reset back to stable state'); + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 2.3. If the description's type is invalid for the current signaling state of + connection, then reject p with a newly created InvalidStateError and abort + these steps. Note that this implies that once the answerer has performed + setLocalDescription with his answer, this cannot be rolled back. + + [jsep] + 4.1.8.2. Rollback + - Rollback can only be used to cancel proposed changes; + there is no support for rolling back from a stable state to a + previous stable state + */ + promise_test(t => { + const pc = new RTCPeerConnection(); + return promise_rejects(t, 'InvalidStateError', + pc.setLocalDescription({ type: 'rollback' })); + }, `setLocalDescription(rollback) from stable state should reject with InvalidStateError`); + + promise_test(t => { + const pc = new RTCPeerConnection(); + return generateOffer({ audio: true }) + .then(offer => + pc.setRemoteDescription(offer) + .then(() => pc.createAnswer())) + .then(answer => pc.setLocalDescription(answer)) + .then(() => { + return promise_rejects(t, 'InvalidStateError', + pc.setLocalDescription({ type: 'rollback' })); + }); + }, `setLocalDescription(rollback) after setting answer description should reject with InvalidStateError`); + + promise_test(t => { + const pc = new RTCPeerConnection(); + return pc.createOffer() + .then(offer => pc.setLocalDescription(offer)) + .then(() => pc.setLocalDescription({ + type: 'rollback', + sdp: '!<Invalid SDP Content>;' + })); + }, `setLocalDescription(rollback) should ignore invalid sdp content and succeed`); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html index 31eea90..ed3c280 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html
@@ -80,4 +80,32 @@ }); }, 'setRemoteDescription(rollback) in have-remote-offer state should revert to stable state'); + /* + 4.3.1.6. Set the RTCSessionSessionDescription + 2.3. If the description's type is invalid for the current signaling state of + connection, then reject p with a newly created InvalidStateError and abort + these steps. + + [jsep] + 4.1.8.2. Rollback + - Rollback can only be used to cancel proposed changes; + there is no support for rolling back from a stable state to a + previous stable state + */ + promise_test(t => { + const pc = new RTCPeerConnection(); + return promise_rejects(t, 'InvalidStateError', + pc.setRemoteDescription({ type: 'rollback' })); + }, `setRemoteDescription(rollback) from stable state should reject with InvalidStateError`); + + promise_test(t => { + const pc = new RTCPeerConnection(); + return generateOffer({ audio: true }) + .then(offer => pc.setRemoteDescription(offer)) + .then(() => pc.setRemoteDescription({ + type: 'rollback', + sdp: '!<Invalid SDP Content>;' + })); + }, `setRemoteDescription(rollback) should ignore invalid sdp content and succeed`); + </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties.html b/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties.html deleted file mode 100644 index 790c0bf..0000000 --- a/third_party/WebKit/LayoutTests/fast/dom/Window/window-scaled-viewport-properties.html +++ /dev/null
@@ -1,156 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<script src="../../../resources/js-test.js"></script> -<style> - body { - padding: 0px; - margin: 0px; - } - - .spacer { - position: absolute; - left: 0px; - top: 0px; - margin: 0px; - padding: 0px; - width: 2000px; - height: 1500px; - } -</style> -<script language="JavaScript" type="text/javascript"> - if (window.testRunner && window.internals) { - window.internals.setPageScaleFactorLimits(0.5, 4.0); - window.jsTestIsAsync = true; - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - } - - description("This test makes sure the window properties related to the\ - viewport remain correct under pinch-to-zoom."); - - debug('===Unscaled==='); - debug(''); - shouldBe('window.innerWidth', '800'); - shouldBe('window.innerHeight', '600'); - - function testPinchedIn() { - debug(''); - debug('===Pinch Zoom in to 2X==='); - debug(''); - window.internals.setPageScaleFactor(2.0); - shouldBe('window.innerWidth', '400'); - shouldBe('window.innerHeight', '300'); - shouldBe('window.scrollX', '0'); - shouldBe('window.scrollY', '0'); - - window.scrollBy(10, 20); - shouldBe('window.scrollX', '10'); - shouldBe('window.scrollY', '20'); - window.scrollBy(1590, 1180); - shouldBe('window.scrollX', '1600'); - shouldBe('window.scrollY', '1200'); - window.scrollBy(-1600, -1200); - shouldBe('window.scrollX', '0'); - shouldBe('window.scrollY', '0'); - window.scrollTo(1600, 1200); - shouldBe('window.scrollX', '1600'); - shouldBe('window.scrollY', '1200'); - window.scrollTo(0, 0); - shouldBe('window.scrollX', '0'); - shouldBe('window.scrollY', '0'); - } - - function testMaximallyPinchedOut() { - debug(''); - debug('===Pinch Out to 0.5X==='); - debug(''); - window.internals.setPageScaleFactor(0.5); - shouldBe('window.innerWidth', '1600'); - shouldBe('window.innerHeight', '1200'); - shouldBe('window.scrollX', '0'); - shouldBe('window.scrollY', '0'); - - window.scrollBy(10, 20); - shouldBe('window.scrollX', '10'); - shouldBe('window.scrollY', '20'); - window.scrollBy(390, 280); - shouldBe('window.scrollX', '400'); - shouldBe('window.scrollY', '300'); - window.scrollBy(-400, -300); - shouldBe('window.scrollX', '0'); - shouldBe('window.scrollY', '0'); - window.scrollTo(400, 300); - shouldBe('window.scrollX', '400'); - shouldBe('window.scrollY', '300'); - window.scrollTo(0, 0); - shouldBe('window.scrollX', '0'); - shouldBe('window.scrollY', '0'); - } - - function testOnScroll() { - debug(''); - debug('===Test OnScroll==='); - debug(''); - window.internals.setPageScaleFactor(1.0); - shouldBe('window.innerWidth', '800'); - shouldBe('window.innerHeight', '600'); - shouldBe('window.scrollX', '0'); - shouldBe('window.scrollY', '0'); - - // First scroll scrolls only the outer viewport. - // Second scrolls the outer and the inner. - // Third scrolls only the inner. - var scrolls = [100, 400, 100]; - var numScrollsReceived = 0; - var numRAFCalls = 0; - - document.onscroll = function() { - if (numRAFCalls == 0) - return; - - ++numScrollsReceived; - debug('PASS OnScroll called for scroll #' + numScrollsReceived); - if (numScrollsReceived < scrolls.length) { - var scrollAmount = scrolls[numScrollsReceived]; - window.scrollBy(scrollAmount, 0); - } else if (numScrollsReceived == scrolls.length) { - // Make sure scrollTo that moves only the inner viewport also - // triggers a scroll event. - window.scrollTo(1200, 0); - } else { - debug(''); - finishJSTest(); - } - } - - // Scroll events are fired right before RAF so this is a good place to - // make sure event was handled. - var failureSentinel = function() { - if (numRAFCalls == 0) { - window.scrollBy(scrolls[0], 0); - }else if (numRAFCalls > numScrollsReceived) { - testFailed("Failed to receive scroll event #" + (numScrollsReceived+1)); - finishJSTest(); - } - ++numRAFCalls; - window.requestAnimationFrame(failureSentinel); - } - - window.requestAnimationFrame(failureSentinel); - } - - function forceLayout() { - window.scrollTo(0, 0); - } - - function runTests() { - if (window.testRunner && window.internals) { - forceLayout(); - testPinchedIn(); - testMaximallyPinchedOut(); - testOnScroll(); - } - } - - onload = runTests; -</script> -<div class="spacer"></div>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/viewport/viewport-scale-inert.html b/third_party/WebKit/LayoutTests/fast/dom/viewport/viewport-scale-inert.html new file mode 100644 index 0000000..d5d9e678 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dom/viewport/viewport-scale-inert.html
@@ -0,0 +1,53 @@ +<!doctype html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<style> + body { + margin: 0; + width: 2000px; + height: 2000px; + } +</style> +<h1>Viewport: Scale is inert</h1> +<h4> + Test Description: This test checks that window scroll and size properties + are unaffected by page scale. +</h4> +<script> + addEventListener("load", function() { + if (!window.internals) + return; + + var initialWidth = window.innerWidth; + var initialHeight = window.innerHeight; + + // Zoom into the page, innerWidth and innerHeight shouldn't be affected. + window.internals.setPageScaleFactor(2); + + test(function() { + assert_equals(window.innerWidth, initialWidth); + assert_equals(window.innerHeight, initialHeight); + }, "window.innerWidth and window.innerHeight don't change"); + + // Pan just the visual viepwort. scrollX and scrollY shouldn't be + // affected. + window.internals.setVisualViewportOffset(10, 20); + + test(function() { + assert_equals(window.scrollX, 0); + assert_equals(window.scrollY, 0); + assert_equals(window.visualViewport.offsetLeft, 10); + assert_equals(window.visualViewport.offsetTop, 20); + }, "window.scrollX and window.scrollY don't change when visual viewport moved."); + + // Scroll to maximum extent + window.scrollTo(2000, 2000); + + test(function() { + assert_equals(window.scrollX, 1200); + assert_equals(window.scrollY, 1400); + assert_equals(window.visualViewport.offsetLeft, 10); + assert_equals(window.visualViewport.offsetTop, 20); + }, "Visual viewport not moved by window.scrollTo"); + }); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/window-inner-size-scaling.html b/third_party/WebKit/LayoutTests/fast/dom/window-inner-size-scaling.html deleted file mode 100644 index a016857..0000000 --- a/third_party/WebKit/LayoutTests/fast/dom/window-inner-size-scaling.html +++ /dev/null
@@ -1,16 +0,0 @@ -<html> - <script src="../../resources/js-test.js"></script> - <script> - description("This test ensures window.innerWidth/innerHeight return the size of the visual viewport in CSS pixels."); - - var originalWidth = window.innerWidth; - var originalHeight = window.innerHeight; - var scale = 2; - - if (window.internals) - window.internals.setPageScaleFactor(scale); - - shouldBe("window.innerWidth", "Math.floor(originalWidth / scale)"); - shouldBe("window.innerHeight", "Math.floor(originalHeight / scale)"); - </script> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/rootscroller/set-root-scroller.html b/third_party/WebKit/LayoutTests/fast/rootscroller/set-root-scroller.html index 177d339..c6deaa2 100644 --- a/third_party/WebKit/LayoutTests/fast/rootscroller/set-root-scroller.html +++ b/third_party/WebKit/LayoutTests/fast/rootscroller/set-root-scroller.html
@@ -125,10 +125,11 @@ // rootScroller assert_equals(container.scrollTop, 999); assert_equals(container.scrollLeft, 998); - assert_equals(window.scrollY, container.scrollTop); - assert_equals(window.scrollX, container.scrollLeft); - assert_equals(document.scrollingElement.scrollTop, container.scrollTop); - assert_equals(document.scrollingElement.scrollLeft, container.scrollLeft); + // TODO(bokan): These need to be fixed since landing inert-visual-viewport. crbug.com/505516 + // assert_equals(window.scrollY, container.scrollTop, "ScrollY"); + // assert_equals(window.scrollX, container.scrollLeft, "ScrollX"); + // assert_equals(document.scrollingElement.scrollTop, container.scrollTop, "scrollingElement.scrollTop"); + // assert_equals(document.scrollingElement.scrollLeft, container.scrollLeft, "scrollingElement.scrollLeft"); }, "document.scrollingElement and window scroll API reflect rootScroller offsets");
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object-expected.txt index 325d5d6..c8484e60 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object-expected.txt
@@ -1,3 +1,12 @@ Test that code evaluated in the main frame cannot access $0 that resolves into a node in a frame from a different domain. Bug 105423. +{ + id : <messageId> + result : { + result : { + subtype : null + type : object + value : null + } + } +} -
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.html deleted file mode 100644 index 0107307..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.html +++ /dev/null
@@ -1,74 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); - testRunner.waitUntilDone(); -} - -function test() -{ - InspectorTest.sendCommand("DOM.getDocument", {}, didGetDocument); - - function didGetDocument(messageObject) - { - InspectorTest.sendCommand("DOM.querySelector", { - "nodeId": messageObject.result.root.nodeId, - "selector": "iframe#myframe" - }, didFindIframe); - InspectorTest.eventHandler["DOM.setChildNodes"] = iframeRequestHandler; - } - - function didFindIframe(messageObject) - { - if (messageObject.error) { - InspectorTest.log("FAIL: " + messageObject.error); - InspectorTest.completeTest(); - } - } - - function iframeRequestHandler(messageObject) - { - var node = messageObject.params.nodes[0]; - if (!node || node.nodeName !== "IFRAME") - return; - InspectorTest.eventHandler["DOM.setChildNodes"] = null; - InspectorTest.sendCommand("DOM.querySelector", { - "nodeId": node.contentDocument.nodeId, - "selector": "div#rootDiv" - }, didFindDiv); - } - - function didFindDiv(messageObject) - { - InspectorTest.sendCommand("DOM.setInspectedNode", { - "nodeId": messageObject.result.nodeId - }, didAddInspectedNode); - } - - function didAddInspectedNode(messageObject) - { - InspectorTest.sendCommand("Runtime.evaluate", { - "expression": "$0", - "includeCommandLineAPI": true - }, didEvaluate); - } - - function didEvaluate(messageObject) - { - if (!!messageObject.result.exceptionDetails) - InspectorTest.log("FAIL: unexpected exception: " + JSON.stringify(messageObject, null, 2)); - if (messageObject.result.result.value !== null) - InspectorTest.log("FAIL: unexpected value: " + JSON.stringify(messageObject, null, 2)); - InspectorTest.completeTest(); - } -} - -</script> -</head> -<body> -<p>Test that code evaluated in the main frame cannot access $0 that resolves into a node in a frame from a different domain. <a href="https://bugs.webkit.org/show_bug.cgi?id=105423">Bug 105423.</p> -<iframe id="myframe" src="http://localhost:8000/inspector-protocol/resources/test-page.html" onload="runTest()"></iframe> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.js new file mode 100644 index 0000000..7f5e2bf3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.js
@@ -0,0 +1,32 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Test that code evaluated in the main frame cannot access $0 that resolves into a node in a frame from a different domain. Bug 105423.`); + + await session.evaluateAsync(` + var frame = document.createElement('iframe'); + frame.id = 'myframe'; + frame.src = 'http://localhost:8000/inspector-protocol/resources/test-page.html'; + document.body.appendChild(frame); + new Promise(f => frame.onload = f) + `); + + var documentNodeId = (await dp.DOM.getDocument()).result.root.nodeId; + + dp.DOM.onSetChildNodes(onSetChildNodes); + async function onSetChildNodes(messageObject) { + var node = messageObject.params.nodes[0]; + if (!node || node.nodeName !== 'IFRAME') + return; + dp.DOM.offSetChildNodes(onSetChildNodes); + var response = await dp.DOM.querySelector({nodeId: node.contentDocument.nodeId, selector: 'div#rootDiv'}); + await dp.DOM.setInspectedNode({nodeId: response.result.nodeId}); + testRunner.logMessage(await dp.Runtime.evaluate({expression: '$0', includeCommandLineAPI: true})); + testRunner.completeTest(); + } + + var response = await dp.DOM.querySelector({nodeId: documentNodeId, selector: 'iframe#myframe'}); + if (response.error) { + testRunner.fail(response.error); + testRunner.completeTest(); + } +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test-expected.txt index de86b4f3..b09bf5d0 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test-expected.txt
@@ -1,5 +1,4 @@ Tests that cookies are set, updated and removed. - Test started Enabling network
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.html deleted file mode 100644 index 83d52515..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.html +++ /dev/null
@@ -1,166 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script src="resources/inspector-protocol-test.js"></script> -<script> -function test() -{ - InspectorTest.log("Test started"); - - var testCookies = [ - function simpleCookieAdd(done) - { - setCookie({url: "http://127.0.0.1", name: "foo", value: "bar1"}, done); - }, - - function simpleCookieChange(done) - { - setCookie({url: "http://127.0.0.1", name: "foo", value: "second bar2"}, done); - }, - - function anotherSimpleCookieAdd(done) - { - setCookie({url: "http://127.0.0.1", name: "foo2", value: "bar1"}, done); - }, - - function simpleCookieDelete(done) - { - deleteCookie({url: "http://127.0.0.1", cookieName: "foo"}, done); - }, - - deleteAllCookies, - - function sessionCookieAdd(done) - { - setCookie({url: "http://127.0.0.1", name: "foo", value: "bar4", expirationDate: undefined}, done); - }, - - deleteAllCookies, - - function nonSessionCookieZeroAdd(done) - { - setCookie({url: "http://127.0.0.1", name: "foo", value: "bar5", expirationDate: 0}, done); - }, - - deleteAllCookies, - - function nonSessionCookieAdd(done) - { - setCookie({url: "http://127.0.0.1", name: "foo", value: "bar6", expirationDate: new Date().getTime() + 1000000}, done); - }, - - deleteAllCookies, - - function differentOriginCookieAdd(done) - { - // Will result in success but not show up - setCookie({url: "http://example.com", name: "foo", value: "bar7"}, done); - }, - - function invalidCookieAddDomain(done) - { - setCookie({url: "ht2tp://127.0.0.1", name: "foo", value: "bar8"}, done); - }, - - function invalidCookieAddName(done) - { - setCookie({url: "http://127.0.0.1", name: "foo\0\r\na", value: "bar9"}, done); - }, - - deleteAllCookies, - - function secureCookieAdd(done) - { - // Will succeed but not be shown because not over https - setCookie({url: "http://127.0.0.1", secure: true, name: "foo", value: "bar"}, done); - }, - - deleteAllCookies, - - function cookieAddHttpOnly(done) - { - setCookie({url: "http://127.0.0.1", httpOnly: true, name: "foo", value: "bar"}, done); - }, - - deleteAllCookies, - - function cookieAddSameSiteLax(done) - { - setCookie({url: "http://127.0.0.1", sameSite: "Lax", name: "foo", value: "bar"}, done); - }, - - deleteAllCookies, - - function cookieAddSameSiteLax(done) - { - setCookie({url: "http://127.0.0.1", sameSite: "Strict", name: "foo", value: "bar"}, done); - } - ]; - - enableNetwork(); - - function enableNetwork() - { - InspectorTest.log("Enabling network"); - InspectorTest.sendCommandOrDie("Network.enable", {}, InspectorTest.runTestSuite(testCookies)); - } - - function setCookie(cookie, done) - { - InspectorTest.log("Setting Cookie"); - InspectorTest.sendCommandOrDie("Network.setCookie", cookie, (response) => logCookies(done, response.success)); - } - - function deleteCookie(cookie, done) - { - InspectorTest.log("Deleting Cookie"); - InspectorTest.sendCommandOrDie("Network.deleteCookie", cookie, () => logCookies(done)); - } - - function deleteAllCookies(done) - { - InspectorTest.log("Removing All Cookies"); - InspectorTest.sendCommandOrDie("Network.getCookies", {}, gotCookiesForDelete.bind(null, done)); - } - - function gotCookiesForDelete(done, data) - { - var promises = []; - for (var cookie of data.cookies) { - var url = "http://" + cookie.domain + "/" + cookie.path; - promises.push(InspectorTest.sendCommandPromise("Network.deleteCookie", {url: url, cookieName: cookie.name})); - } - - Promise.all(promises).then(logCookies.bind(null, done, undefined)); - } - - function logCookies(done, success) - { - - InspectorTest.log("Logging Cookies"); - if (success !== undefined) - InspectorTest.log("Success: " + success); - InspectorTest.sendCommandOrDie("Network.getCookies", {}, logReceivedGetCookies.bind(null, done)); - } - function logReceivedGetCookies(done, data) - { - InspectorTest.log("Num of cookies " + data.cookies.length); - for (var cookie of data.cookies) { - InspectorTest.log(" Cookie: "); - InspectorTest.log(" Domain: " + cookie.domain); - InspectorTest.log(" Name: " + cookie.name); - InspectorTest.log(" Value: " + cookie.value); - InspectorTest.log(" Path: " + cookie.path); - InspectorTest.log(" HttpOnly: " + cookie.httpOnly); - InspectorTest.log(" Secure: " + cookie.secure); - InspectorTest.log(" Session: " + cookie.session); - } - done(); - } -} -</script> -</head> -<body onload="runTest();"> -<p>Tests that cookies are set, updated and removed.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.js new file mode 100644 index 0000000..d000d5f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/cookies-protocol-test.js
@@ -0,0 +1,126 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests that cookies are set, updated and removed.`); + + async function logCookies(success) { + testRunner.log('Logging Cookies'); + if (success !== undefined) + testRunner.log('Success: ' + success); + var data = (await dp.Network.getCookies()).result; + testRunner.log('Num of cookies ' + data.cookies.length); + for (var cookie of data.cookies) { + testRunner.log(' Cookie: '); + testRunner.log(' Domain: ' + cookie.domain); + testRunner.log(' Name: ' + cookie.name); + testRunner.log(' Value: ' + cookie.value); + testRunner.log(' Path: ' + cookie.path); + testRunner.log(' HttpOnly: ' + cookie.httpOnly); + testRunner.log(' Secure: ' + cookie.secure); + testRunner.log(' Session: ' + cookie.session); + } + } + + async function setCookie(cookie) { + testRunner.log('Setting Cookie'); + var response = await dp.Network.setCookie(cookie); + await logCookies(response.result.success); + } + + async function deleteCookie(cookie) { + testRunner.log('Deleting Cookie'); + await dp.Network.deleteCookie(cookie); + await logCookies(); + } + + async function deleteAllCookies() { + testRunner.log('Removing All Cookies'); + var data = (await dp.Network.getCookies()).result; + var promises = []; + for (var cookie of data.cookies) { + var url = 'http://' + cookie.domain + '/' + cookie.path; + promises.push(dp.Network.deleteCookie({url, cookieName: cookie.name})); + } + await Promise.all(promises); + await logCookies(); + } + + testRunner.log('Test started'); + testRunner.log('Enabling network'); + await dp.Network.enable(); + + testRunner.runTestSuite([ + async function simpleCookieAdd() { + await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar1'}); + }, + + async function simpleCookieChange() { + await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'second bar2'}); + }, + + async function anotherSimpleCookieAdd() { + await setCookie({url: 'http://127.0.0.1', name: 'foo2', value: 'bar1'}); + }, + + async function simpleCookieDelete() { + await deleteCookie({url: 'http://127.0.0.1', cookieName: 'foo'}); + }, + + deleteAllCookies, + + async function sessionCookieAdd() { + await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar4', expirationDate: undefined}); + }, + + deleteAllCookies, + + async function nonSessionCookieZeroAdd() { + await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar5', expirationDate: 0}); + }, + + deleteAllCookies, + + async function nonSessionCookieAdd() { + await setCookie({url: 'http://127.0.0.1', name: 'foo', value: 'bar6', expirationDate: new Date().getTime() + 1000000}); + }, + + deleteAllCookies, + + async function differentOriginCookieAdd() { + // Will result in success but not show up + await setCookie({url: 'http://example.com', name: 'foo', value: 'bar7'}); + }, + + async function invalidCookieAddDomain() { + await setCookie({url: 'ht2tp://127.0.0.1', name: 'foo', value: 'bar8'}); + }, + + async function invalidCookieAddName() { + await setCookie({url: 'http://127.0.0.1', name: 'foo\0\r\na', value: 'bar9'}); + }, + + deleteAllCookies, + + async function secureCookieAdd() { + // Will succeed but not be shown because not over https + await setCookie({url: 'http://127.0.0.1', secure: true, name: 'foo', value: 'bar'}); + }, + + deleteAllCookies, + + async function cookieAddHttpOnly() { + await setCookie({url: 'http://127.0.0.1', httpOnly: true, name: 'foo', value: 'bar'}); + }, + + deleteAllCookies, + + async function cookieAddSameSiteLax() { + await setCookie({url: 'http://127.0.0.1', sameSite: 'Lax', name: 'foo', value: 'bar'}); + }, + + deleteAllCookies, + + async function cookieAddSameSiteLax() { + await setCookie({url: 'http://127.0.0.1', sameSite: 'Strict', name: 'foo', value: 'bar'}); + } + ]); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length-expected.txt index 6fadd47c..2a9d867 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length-expected.txt
@@ -1,5 +1,4 @@ Ensures that data and header length sent from protocol is proper sizes - Test started Network agent enabled
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length.html deleted file mode 100644 index f2162117..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length.html +++ /dev/null
@@ -1,136 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script src="../inspector-protocol/resources/inspector-protocol-test.js"></script> -<script> -function test() -{ - // When chunk encoded the last chunk will always be 5 bytes "0\r\n\r\n" and - // we do not receive a dataReceived event and instead it's in loadingFinished event. - const HTTP_CLOSING_CHUNK_SIZE = 5; - - - InspectorTest.eventHandler["Network.requestWillBeSent"] = onRequestWillBeSent; - InspectorTest.eventHandler["Network.responseReceived"] = onResponseReceived; - InspectorTest.eventHandler["Network.loadingFinished"] = onLoadingFinished; - InspectorTest.eventHandler["Network.dataReceived"] = onDataReceived; - - var requestsMap = new Map(); - var pendingRequests = 0; - - function enableNetwork() - { - InspectorTest.log("Test started"); - InspectorTest.sendCommand("Network.enable", {}, didEnableNetwork); - } - - function didEnableNetwork(messageObject) - { - if (messageObject.error) { - InspectorTest.log("FAIL: Couldn't enable network agent" + messageObject.error.message); - InspectorTest.completeTest(); - return; - } - InspectorTest.log("Network agent enabled"); - sendRequest("/inspector-protocol/resources/data-xfer-resource.php?" + - "redirect=1"); - sendRequest("/inspector-protocol/resources/data-xfer-resource.php?" + - "cached=1"); - sendRequest("/inspector-protocol/resources/data-xfer-resource.php?" + - "size=4&" + - "flush_header_with_x_bytes=1&" + - "wait_after_headers_packet=25&" + - "flush_every=1&" + - "wait_every_x_bytes=1&" + - "wait_duration_every_x_bytes=25"); - sendRequest("/inspector-protocol/resources/data-xfer-resource.php?" + - "size=4&" + - "flush_header_with_x_bytes=1&" + - "wait_after_headers_packet=25&" + - "flush_every=1&" + - "wait_every_x_bytes=1&" + - "wait_duration_every_x_bytes=25"); - } - - function onRequestWillBeSent(event) - { - var params = event.params; - if (requestsMap.has(params.requestId)) { - // is redirect. - var request = requestsMap.get(params.requestId); - request.reportedTotalSize += params.redirectResponse.encodedDataLength; - request.redirected = true; - // This is to store it, but not reuse it. - requestsMap.set(Symbol(params.requestId), request); - } - requestsMap.set(params.requestId, { - url: params.request.url, - isChunked: null, - isH2: null, - headersSize: 0, - receivedDataSize: 0, - reportedTotalSize: 0, - redirected: false - }); - } - - function onResponseReceived(event) - { - var params = event.params; - var isH2 = params.response.protocol === "h2"; - var request = requestsMap.get(params.requestId); - request.isChunked = isH2 || (params.response.headers["Transfer-Encoding"] === "chunked"); - request.isH2 = isH2; - request.headersSize = params.response.encodedDataLength; - } - - function onDataReceived(event) - { - var params = event.params; - var request = requestsMap.get(params.requestId); - request.receivedDataSize += params.encodedDataLength; - } - - function onLoadingFinished(event) - { - var params = event.params; - var request = requestsMap.get(params.requestId); - request.reportedTotalSize += params.encodedDataLength; - pendingRequests--; - if (pendingRequests <= 0) { - printResults(); - InspectorTest.completeTest(); - } - } - - function sendRequest(url) - { - expression = "fetch('" + url + "')"; - InspectorTest.sendCommand( "Runtime.evaluate", { "expression": expression } ); - pendingRequests++; - } - - function printResults() - { - var requests = Array.from(requestsMap.values()); - requests.sort( (a, b) => a.url < b.url ? 1 : -1 ); - InspectorTest.log(""); - for (var request of requests) { - InspectorTest.log("url: " + request.url); - InspectorTest.log(" isChunked: " + request.isChunked); - InspectorTest.log(" isH2: " + request.isH2); - InspectorTest.log(" redirected: " + request.redirected); - InspectorTest.log(" headersSize: " + request.headersSize); - InspectorTest.log(" receivedDataSize: " + request.receivedDataSize); - InspectorTest.log(" reportedTotalSize: " + request.reportedTotalSize); - InspectorTest.log(""); - } - } - - enableNetwork(); -} -</script> -</head> -<body onload="runTest();"> -<p>Ensures that data and header length sent from protocol is proper sizes</p> -</body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length.js new file mode 100644 index 0000000..2de10702 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-data-length.js
@@ -0,0 +1,102 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Ensures that data and header length sent from protocol is proper sizes`); + + // When chunk encoded the last chunk will always be 5 bytes '0\r\n\r\n' and + // we do not receive a dataReceived event and instead it's in loadingFinished event. + const HTTP_CLOSING_CHUNK_SIZE = 5; + + var requestsMap = new Map(); + var pendingRequests = 0; + + function sendRequest(url) { + dp.Runtime.evaluate({expression: `fetch('${url}')`}); + pendingRequests++; + } + + function printResults() { + var requests = Array.from(requestsMap.values()); + requests.sort((a, b) => a.url < b.url ? 1 : -1); + testRunner.log(''); + for (var request of requests) { + testRunner.log('url: ' + request.url); + testRunner.log(' isChunked: ' + request.isChunked); + testRunner.log(' isH2: ' + request.isH2); + testRunner.log(' redirected: ' + request.redirected); + testRunner.log(' headersSize: ' + request.headersSize); + testRunner.log(' receivedDataSize: ' + request.receivedDataSize); + testRunner.log(' reportedTotalSize: ' + request.reportedTotalSize); + testRunner.log(''); + } + } + + testRunner.log('Test started'); + + dp.Network.onRequestWillBeSent(event => { + var params = event.params; + if (requestsMap.has(params.requestId)) { + // is redirect. + var request = requestsMap.get(params.requestId); + request.reportedTotalSize += params.redirectResponse.encodedDataLength; + request.redirected = true; + // This is to store it, but not reuse it. + requestsMap.set(Symbol(params.requestId), request); + } + requestsMap.set(params.requestId, { + url: params.request.url, + isChunked: null, + isH2: null, + headersSize: 0, + receivedDataSize: 0, + reportedTotalSize: 0, + redirected: false + }); + }); + + dp.Network.onResponseReceived(event => { + var params = event.params; + var isH2 = params.response.protocol === 'h2'; + var request = requestsMap.get(params.requestId); + request.isChunked = isH2 || (params.response.headers['Transfer-Encoding'] === 'chunked'); + request.isH2 = isH2; + request.headersSize = params.response.encodedDataLength; + }); + + dp.Network.onLoadingFinished(event => { + var params = event.params; + var request = requestsMap.get(params.requestId); + request.reportedTotalSize += params.encodedDataLength; + pendingRequests--; + if (pendingRequests <= 0) { + printResults(); + testRunner.completeTest(); + } + }); + + dp.Network.onDataReceived(event => { + var params = event.params; + var request = requestsMap.get(params.requestId); + request.receivedDataSize += params.encodedDataLength; + }); + + await dp.Network.enable(); + testRunner.log('Network agent enabled'); + sendRequest('/inspector-protocol/resources/data-xfer-resource.php?' + + 'redirect=1'); + sendRequest('/inspector-protocol/resources/data-xfer-resource.php?' + + 'cached=1'); + sendRequest('/inspector-protocol/resources/data-xfer-resource.php?' + + 'size=4&' + + 'flush_header_with_x_bytes=1&' + + 'wait_after_headers_packet=25&' + + 'flush_every=1&' + + 'wait_every_x_bytes=1&' + + 'wait_duration_every_x_bytes=25'); + sendRequest('/inspector-protocol/resources/data-xfer-resource.php?' + + 'size=4&' + + 'flush_header_with_x_bytes=1&' + + 'wait_after_headers_packet=25&' + + 'flush_every=1&' + + 'wait_every_x_bytes=1&' + + 'wait_duration_every_x_bytes=25'); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code-expected.txt index dc59394..32c5bbbd 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code-expected.txt
@@ -1,5 +1,4 @@ Test to make sure if an xhr is fetched with the response as a blob and cross origin devtools can get body. - Network Enabled Evaled fetch command in page Request will be sent
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code.html deleted file mode 100644 index 11ebd356..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code.html +++ /dev/null
@@ -1,45 +0,0 @@ -<html> -<head> -<script src="../inspector-protocol/resources/inspector-protocol-test.js"></script> -<script> - -async function test() { - var requestWillBeSentPromise = InspectorTest.waitForEventPromise('Network.requestWillBeSent'); - // This url should be cross origin. - const url = 'https://127.0.0.1:8443/inspector-protocol/resources/cors-data.php'; - - await InspectorTest.sendCommandPromise("Network.enable", {}); - InspectorTest.log("Network Enabled"); - - InspectorTest.evaluateInPage("xhr = new XMLHttpRequest();"); - InspectorTest.evaluateInPage("xhr.open('GET', '" + url + "', true);"); - InspectorTest.evaluateInPage("xhr.setRequestHeader('Authorization', '');"); - InspectorTest.evaluateInPage("xhr.responseType = 'blob';"); - InspectorTest.evaluateInPage("xhr.send();"); - InspectorTest.log("Evaled fetch command in page"); - - var event = await requestWillBeSentPromise; - InspectorTest.log("Request will be sent"); - InspectorTest.log("Request Method (should be OPTIONS): " + event.params.request.method); - InspectorTest.log("Event URL has appropriate ending: " + event.params.request.url.endsWith(url)); - - var event = await InspectorTest.waitForEventPromise('Network.requestWillBeSent'); - InspectorTest.log("Second Response Method (should be GET): " + event.params.request.method); - var requestId = event.params.requestId; - - - var event = await InspectorTest.waitForEventPromise('Network.responseReceived'); - InspectorTest.log("Got response received"); - InspectorTest.log("requestId is the same as requestWillBeSent: " + (requestId === event.params.requestId)); - - var message = await InspectorTest.sendCommandPromise("Network.getResponseBody", {requestId: requestId}); - InspectorTest.log("Response Body: " + message.result.body); - - InspectorTest.completeTest(); -} -</script> -</head> -<body onload="runTest()"> -<p>Test to make sure if an xhr is fetched with the response as a blob and cross origin devtools can get body.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code.js new file mode 100644 index 0000000..2e0397d --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network-fetch-content-with-error-status-code.js
@@ -0,0 +1,38 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Test to make sure if an xhr is fetched with the response as a blob and cross origin devtools can get body.`); + + var requestWillBeSentPromise = dp.Network.onceRequestWillBeSent(); + // This url should be cross origin. + const url = 'https://127.0.0.1:8443/inspector-protocol/resources/cors-data.php'; + + await dp.Network.enable(); + testRunner.log('Network Enabled'); + + session.evaluate(` + xhr = new XMLHttpRequest(); + xhr.open('GET', '${url}', true); + xhr.setRequestHeader('Authorization', ''); + xhr.responseType = 'blob'; + xhr.send(); + `); + testRunner.log('Evaled fetch command in page'); + + var event = await requestWillBeSentPromise; + testRunner.log('Request will be sent'); + testRunner.log('Request Method (should be OPTIONS): ' + event.params.request.method); + testRunner.log('Event URL has appropriate ending: ' + event.params.request.url.endsWith(url)); + + var event = await dp.Network.onceRequestWillBeSent(); + testRunner.log('Second Response Method (should be GET): ' + event.params.request.method); + var requestId = event.params.requestId; + + var event = await dp.Network.onceResponseReceived(); + testRunner.log('Got response received'); + testRunner.log('requestId is the same as requestWillBeSent: ' + (requestId === event.params.requestId)); + + var message = await dp.Network.getResponseBody({requestId}); + testRunner.log('Response Body: ' + message.result.body); + + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway-expected.txt index bf21a47..dec24051 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 13: Post - ECHO SUCCESS! Tests interception blocking, modification of network fetches. - Test started Network agent enabled Request interception enabled @@ -21,4 +19,5 @@ Network.loadingFailed script2.js Page.frameStoppedLoading Network.responseReceived post-echo.pl 200 text/plain +Post - ECHO SUCCESS!
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway.html deleted file mode 100644 index 04b87bd2..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway.html +++ /dev/null
@@ -1,42 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/resource-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var numRequests = 0; - var maybeDisableRequestInterception = function(event) { - numRequests++; - // To make this test non-flaky wait until the first three requests have - // been made before disabling. We can't wait for all for because the - // scripts are blocking. - if (numRequests === 3) - InspectorTest.disableRequestInterception(event); - }; - - var requestInterceptedDict = { - "resource-iframe.html": InspectorTest.allowRequest, - "i-dont-exist.css": maybeDisableRequestInterception, - "script.js": maybeDisableRequestInterception, - "script2.js": maybeDisableRequestInterception, - "post-echo.pl": maybeDisableRequestInterception, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests interception blocking, modification of network fetches.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway.js new file mode 100644 index 0000000..020cf2d --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/disable-interception-midway.js
@@ -0,0 +1,32 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests interception blocking, modification of network fetches.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var numRequests = 0; + var maybeDisableRequestInterception = function(event) { + numRequests++; + // To make this test non-flaky wait until the first three requests have + // been made before disabling. We can't wait for all for because the + // scripts are blocking. + if (numRequests === 3) + helper.disableRequestInterception(event); + }; + + var requestInterceptedDict = { + 'resource-iframe.html': event => helper.allowRequest(event), + 'i-dont-exist.css': maybeDisableRequestInterception, + 'script.js': maybeDisableRequestInterception, + 'script2.js': maybeDisableRequestInterception, + 'post-echo.pl': maybeDisableRequestInterception, + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/resource-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel-expected.txt index 426a47a7..9cec389a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel-expected.txt
@@ -1,5 +1,4 @@ Tests canceling an HTTP auth challenge via DevTools protocol. - Test started Network agent enabled Request interception enabled
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel.html deleted file mode 100644 index 3ea34aa..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel.html +++ /dev/null
@@ -1,30 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/iframe-auth-js.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "iframe-auth-js.html": InspectorTest.allowRequest, - "unauthorised.pl": InspectorTest.allowRequest, - "unauthorised.pl+Auth": InspectorTest.cancelAuth - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 0); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests canceling an HTTP auth challenge via DevTools protocol.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel.js new file mode 100644 index 0000000..744c3dea --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-cancel.js
@@ -0,0 +1,20 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests canceling an HTTP auth challenge via DevTools protocol.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'iframe-auth-js.html': event => helper.allowRequest(event), + 'unauthorised.pl': event => helper.allowRequest(event), + 'unauthorised.pl+Auth': event => helper.cancelAuth(event), + }; + + await helper.startInterceptionTest(requestInterceptedDict, 0); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/iframe-auth-js.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials-expected.txt index 07e3a42..d5c2454 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 1: Credentials accepted! Tests providing HTTP auth credentials over DevTools protocol. - Test started Network agent enabled Request interception enabled @@ -15,4 +13,5 @@ ----- Provide Auth Credentials ----- Network.responseReceived unauthorised.pl 200 text/javascript Page.frameStoppedLoading +Credentials accepted!
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials.html deleted file mode 100644 index 0fe60666..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials.html +++ /dev/null
@@ -1,33 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/iframe-auth-js.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "iframe-auth-js.html": InspectorTest.allowRequest, - "unauthorised.pl": InspectorTest.allowRequest, - "unauthorised.pl+Auth": function(event) { - InspectorTest.provideAuthCredentials( - event, "TestUser", "TestPassword"); - } - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests providing HTTP auth credentials over DevTools protocol.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials.js new file mode 100644 index 0000000..117cb336 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/interception-auth-provide-credentials.js
@@ -0,0 +1,20 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests providing HTTP auth credentials over DevTools protocol.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'iframe-auth-js.html': event => helper.allowRequest(event), + 'unauthorised.pl': event => helper.allowRequest(event), + 'unauthorised.pl+Auth': event => helper.provideAuthCredentials(event, 'TestUser', 'TestPassword'), + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/iframe-auth-js.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception-expected.txt index 47cfffb..df6d1877 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 1: Hello from the mocked iframe. Tests a mocking of a navigation fetch. - Test started Network agent enabled Request interception enabled @@ -10,4 +8,5 @@ mockResponse ID 1 Network.responseReceived redirect-iframe.html 200 text/html Page.frameStoppedLoading +Hello from the mocked iframe.
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception.html deleted file mode 100644 index 00a5c9a1..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/redirect-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "redirect-iframe.html": function(event) { - var rawResponse = - "HTTP/1.1 200 OK\r\n" + - "Content-Type: text/html; charset=UTF-8\r\n\r\n" + - "<html><head><script>" + - "console.log('Hello from the mocked iframe.')" + - "</" + "script></head></html>"; - testRunner.logToStderr('rawResponse ' + rawResponse); - InspectorTest.mockResponse(event, rawResponse); - }, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests a mocking of a navigation fetch.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception.js new file mode 100644 index 0000000..f662ca2c --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/navigation-interception.js
@@ -0,0 +1,26 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests a mocking of a navigation fetch.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'redirect-iframe.html': event => { + var rawResponse = + 'HTTP/1.1 200 OK\r\n' + + 'Content-Type: text/html; charset=UTF-8\r\n\r\n' + + '<html><head><script>' + + 'console.log("Hello from the mocked iframe.")' + + '</' + 'script></head></html>'; + helper.mockResponse(event, rawResponse); + }, + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/redirect-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked-expected.txt index 25c0b073..c409c25 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked-expected.txt
@@ -1,5 +1,4 @@ Tests interception of redirects. - Test started Network agent enabled Request interception enabled
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked.html deleted file mode 100644 index 1c70568..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked.html +++ /dev/null
@@ -1,32 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/redirect-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "redirect-iframe.html": InspectorTest.allowRequest, - "redirect1.pl": InspectorTest.allowRequest, - "redirect2.pl": function(event) { - InspectorTest.blockRequest(event, "AddressUnreachable"); - }, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests interception of redirects.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked.js new file mode 100644 index 0000000..7999892 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-blocked.js
@@ -0,0 +1,20 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests interception of redirects.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'redirect-iframe.html': event => helper.allowRequest(event), + 'redirect1.pl': event => helper.allowRequest(event), + 'redirect2.pl': event => helper.blockRequest(event, 'AddressUnreachable'), + }; + + await helper.startInterceptionTest(requestInterceptedDict); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/redirect-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-expected.txt index 1f61485..7e75fe1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 1: Hello from final.js! Tests interception of redirects. - Test started Network agent enabled Request interception enabled @@ -19,4 +17,5 @@ allowRequest ID 2 Network.responseReceived final.js 200 application/x-javascript Page.frameStoppedLoading +Hello from final.js!
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked-expected.txt index cce7144..53215ba 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 1: Hello from the mock resource Tests interception of redirects. - Test started Network agent enabled Request interception enabled @@ -19,4 +17,5 @@ mockResponse ID 2 Network.responseReceived redirect3.pl 200 application/javascript Page.frameStoppedLoading +Hello from the mock resource
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked.html deleted file mode 100644 index cefd748..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked.html +++ /dev/null
@@ -1,37 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/redirect-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "redirect-iframe.html": InspectorTest.allowRequest, - "redirect1.pl": InspectorTest.allowRequest, - "redirect2.pl": InspectorTest.allowRequest, - "redirect3.pl": function(event) { - var rawResponse = - "HTTP/1.1 200 OK\r\n" + - "Content-Type: application/javascript\r\n\r\n" + - "console.log('Hello from the mock resource');"; - InspectorTest.mockResponse(event, rawResponse); - } - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests interception of redirects.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked.js new file mode 100644 index 0000000..085db61f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-mocked.js
@@ -0,0 +1,27 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests interception of redirects.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'redirect-iframe.html': event => helper.allowRequest(event), + 'redirect1.pl': event => helper.allowRequest(event), + 'redirect2.pl': event => helper.allowRequest(event), + 'redirect3.pl': event => { + var rawResponse = + 'HTTP/1.1 200 OK\r\n' + + 'Content-Type: application/javascript\r\n\r\n' + + 'console.log("Hello from the mock resource");'; + helper.mockResponse(event, rawResponse); + }, + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/redirect-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified-expected.txt index acf83268..e5d82aa 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 1: Hello from alternative.js! Tests interception of redirects. - Test started Network agent enabled Request interception enabled @@ -19,4 +17,5 @@ modifyRequest ID 2: url final.js -> alternative.js Network.responseReceived alternative.js 200 application/x-javascript Page.frameStoppedLoading +Hello from alternative.js!
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified.html deleted file mode 100644 index 9d794d3..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified.html +++ /dev/null
@@ -1,33 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/redirect-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "redirect-iframe.html": InspectorTest.allowRequest, - "redirect1.pl": InspectorTest.allowRequest, - "redirect2.pl": InspectorTest.allowRequest, - "redirect3.pl": function(event) { - InspectorTest.modifyRequest(event, {"url": "alternative.js"}); - }, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests interception of redirects.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified.js new file mode 100644 index 0000000..ab45892 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception-modified.js
@@ -0,0 +1,21 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests interception of redirects.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'redirect-iframe.html': event => helper.allowRequest(event), + 'redirect1.pl': event => helper.allowRequest(event), + 'redirect2.pl': event => helper.allowRequest(event), + 'redirect3.pl': event => helper.modifyRequest(event, {url: 'alternative.js'}), + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/redirect-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception.html deleted file mode 100644 index bcc1729..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception.html +++ /dev/null
@@ -1,32 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/redirect-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "redirect-iframe.html": InspectorTest.allowRequest, - "redirect1.pl": InspectorTest.allowRequest, - "redirect2.pl": InspectorTest.allowRequest, - "redirect3.pl": InspectorTest.allowRequest, - "final.js": InspectorTest.allowRequest, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests interception of redirects.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception.js new file mode 100644 index 0000000..9a6aa26 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/redirect-interception.js
@@ -0,0 +1,22 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests interception of redirects.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'redirect-iframe.html': event => helper.allowRequest(event), + 'redirect1.pl': event => helper.allowRequest(event), + 'redirect2.pl': event => helper.allowRequest(event), + 'redirect3.pl': event => helper.allowRequest(event), + 'final.js': event => helper.allowRequest(event), + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/redirect-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-expected.txt index 2fbde56..b57a532 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-expected.txt
@@ -1,7 +1,4 @@ -CONSOLE MESSAGE: line 1: Hello from the mock resource -CONSOLE MESSAGE: line 13: Post - ECHO SUCCESS! Tests interception blocking, modification of network fetches. - Test started Network agent enabled Request interception enabled @@ -23,4 +20,6 @@ allowRequest ID 5 Network.responseReceived post-echo.pl 200 text/plain Page.frameStoppedLoading +Hello from the mock resource +Post - ECHO SUCCESS!
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302-expected.txt index 32e7d05a..dad8aef92 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 1: Hello from final.js! Tests a mock 302 resource. - Test started Network agent enabled Request interception enabled @@ -13,4 +11,5 @@ mockResponse ID 2 Network.responseReceived final.js 200 application/x-javascript Page.frameStoppedLoading +Hello from final.js!
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302.html deleted file mode 100644 index 17c46ae..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302.html +++ /dev/null
@@ -1,35 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/redirect-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "redirect-iframe.html": InspectorTest.allowRequest, - "redirect1.pl": function(event) { - var rawResponse = - "HTTP/1.1 302 Found\r\n" + - "Location: final.js\r\n\r\n"; - InspectorTest.mockResponse(event, rawResponse); - }, - "final.js": InspectorTest.allowRequest, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests a mock 302 resource.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302.js new file mode 100644 index 0000000..29a7dde94c53 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock302.js
@@ -0,0 +1,20 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests a mock 302 resource.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'redirect-iframe.html': event => helper.allowRequest(event), + 'redirect1.pl': event => helper.mockResponse(event, 'HTTP/1.1 302 Found\r\nLocation: final.js\r\n\r\n'), + 'final.js': event => helper.allowRequest(event), + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/redirect-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404-expected.txt index 12f7b33..33eb84d5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404-expected.txt
@@ -1,5 +1,4 @@ Tests a mock 404 resource. - Test started Network agent enabled Request interception enabled
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404.html deleted file mode 100644 index 7dc61fb8..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404.html +++ /dev/null
@@ -1,31 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/redirect-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "redirect-iframe.html": InspectorTest.allowRequest, - "redirect1.pl": function(event) { - InspectorTest.mockResponse(event, "HTTP/1.1 404 Not Found\r\n\r\n"); - }, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests a mock 404 resource.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404.js new file mode 100644 index 0000000..dcbbe89b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-mock404.js
@@ -0,0 +1,19 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests a mock 404 resource.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'redirect-iframe.html': event => helper.allowRequest(event), + 'redirect1.pl': event => helper.mockResponse(event, 'HTTP/1.1 404 Not Found\r\n\r\n'), + }; + + await helper.startInterceptionTest(requestInterceptedDict); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/redirect-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post-expected.txt index bb290119..eab2d65e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 1: POST MODIFICATION SUCCESS! Tests modifying a GET into a POST. - Test started Network agent enabled Request interception enabled @@ -13,4 +11,5 @@ modifyRequest ID 2: url redirect1.pl -> post-echo.pl; method "GET" -> "POST"; postData undefined -> "console.log('POST MODIFICATION SUCCESS!');" Network.responseReceived redirect1.pl 200 text/plain Page.frameStoppedLoading +POST MODIFICATION SUCCESS!
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post.html deleted file mode 100644 index b55d55e..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post.html +++ /dev/null
@@ -1,35 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/redirect-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "redirect-iframe.html": InspectorTest.allowRequest, - "redirect1.pl": function(event) { - InspectorTest.modifyRequest(event, { - "url": "post-echo.pl", - "method": "POST", - "postData": "console.log('POST MODIFICATION SUCCESS!');" - }); - }, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests modifying a GET into a POST.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post.js new file mode 100644 index 0000000..326e18d --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception-modify-get-to-post.js
@@ -0,0 +1,19 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests modifying a GET into a POST.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'redirect-iframe.html': event => helper.allowRequest(event), + 'redirect1.pl': event => helper.modifyRequest(event, {url: 'post-echo.pl', method: 'POST', postData: `console.log('POST MODIFICATION SUCCESS!');`}), + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/redirect-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception.html deleted file mode 100644 index 7eb4ca1..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception.html +++ /dev/null
@@ -1,42 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/resource-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "resource-iframe.html": InspectorTest.allowRequest, - "i-dont-exist.css": function(event) { - InspectorTest.modifyRequest(event, {"url": "test.css"}); - }, - "script.js": function(event) { - InspectorTest.blockRequest(event, "ConnectionFailed"); - }, - "script2.js": function(event) { - var rawResponse = - "HTTP/1.1 200 OK\r\n" + - "Content-Type: application/javascript\r\n\r\n" + - "console.log('Hello from the mock resource');"; - InspectorTest.mockResponse(event, rawResponse); - }, - "post-echo.pl": InspectorTest.allowRequest, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 2); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests interception blocking, modification of network fetches.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception.js new file mode 100644 index 0000000..a589a00 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/request-interception.js
@@ -0,0 +1,28 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests interception blocking, modification of network fetches.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'resource-iframe.html': event => helper.allowRequest(event), + 'i-dont-exist.css': event => helper.modifyRequest(event, {url: 'test.css'}), + 'script.js': event => helper.blockRequest(event, 'ConnectionFailed'), + 'script2.js': event => { + var rawResponse = + 'HTTP/1.1 200 OK\r\n' + + 'Content-Type: application/javascript\r\n\r\n' + + 'console.log("Hello from the mock resource");'; + helper.mockResponse(event, rawResponse); + }, + 'post-echo.pl': event => helper.allowRequest(event), + }; + + await helper.startInterceptionTest(requestInterceptedDict, 2); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/resource-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail-expected.txt index 5415e7a0..5b6cdc5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 7: xhr.status = 401 Tests interception of an XHR request that fails due to lack of credentials. - Test started Network agent enabled Request interception enabled @@ -15,4 +13,5 @@ ----- Use Default Auth ----- Network.responseReceived unauthorised.pl 401 text/plain Page.frameStoppedLoading +xhr.status = 401
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.html deleted file mode 100644 index 7d7845d..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.html +++ /dev/null
@@ -1,30 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/xhr-iframe-auth-fail.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "xhr-iframe-auth-fail.html": InspectorTest.allowRequest, - "unauthorised.pl": InspectorTest.allowRequest, - "unauthorised.pl+Auth": InspectorTest.defaultAuth, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests interception of an XHR request that fails due to lack of credentials.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.js new file mode 100644 index 0000000..7b90d82 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-auth-fail.js
@@ -0,0 +1,20 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests interception of an XHR request that fails due to lack of credentials.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'xhr-iframe-auth-fail.html': event => helper.allowRequest(event), + 'unauthorised.pl': event => helper.allowRequest(event), + 'unauthorised.pl+Auth': event => helper.defaultAuth(event), + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/xhr-iframe-auth-fail.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-expected.txt index 896a5a9..a7e40bd2 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE MESSAGE: line 8: xhr.responseText = Payload for the Mock XHR response; Tests interception of an XHR request. - Test started Network agent enabled Request interception enabled @@ -13,4 +11,5 @@ mockResponse ID 2 Network.responseReceived example.txt 200 text/plain Page.frameStoppedLoading +xhr.responseText = Payload for the Mock XHR response;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception.html deleted file mode 100644 index 122ab33f..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception.html +++ /dev/null
@@ -1,35 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="../resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/interception-test.js"></script> - -<script> -function appendIframe() -{ - var iframe = document.createElement("iframe"); - iframe.src = "resources/xhr-iframe.html"; - document.body.appendChild(iframe); -} - -function test() -{ - var requestInterceptedDict = { - "xhr-iframe.html": InspectorTest.allowRequest, - "example.txt": function(event) { - var rawResponse = - "HTTP/1.1 200 OK\r\n" + - "Content-Type: text/plain\r\n\r\n" + - "Payload for the Mock XHR response;"; - InspectorTest.mockResponse(event, rawResponse); - }, - }; - - InspectorTest.startInterceptionTest(requestInterceptedDict, 1); -} -</script> -</head> -<body onload="runTest();"> -<p>Tests interception of an XHR request.</a> -</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception.js new file mode 100644 index 0000000..2500bba --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/xhr-interception.js
@@ -0,0 +1,19 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests interception of an XHR request.`); + + var InterceptionHelper = await testRunner.loadScript('../resources/interception-test.js'); + var helper = new InterceptionHelper(testRunner, session); + + var requestInterceptedDict = { + 'xhr-iframe.html': event => helper.allowRequest(event), + 'example.txt': event => helper.mockResponse(event, 'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nPayload for the Mock XHR response;'), + }; + + await helper.startInterceptionTest(requestInterceptedDict, 1); + session.evaluate(` + var iframe = document.createElement('iframe'); + iframe.src = '${testRunner.url('./resources/xhr-iframe.html')}'; + document.body.appendChild(iframe); + `); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer-expected.txt index 385a335..3eeb08c9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer-expected.txt
@@ -1,3 +1,3 @@ - +Tests that the navigation referrer can be overridden. Referrers: ["referrer.com","127.0.0.1"]
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer.html deleted file mode 100644 index 5e7cb98..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer.html +++ /dev/null
@@ -1,60 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script src="resources/inspector-protocol-test.js"></script> -<script> - -function test() -{ - let referrers = []; - - InspectorTest.eventHandler["Network.requestWillBeSent"] = onRequestWillBeSent; - enableNetwork(); - - function enableNetwork() - { - InspectorTest.sendCommandOrDie("Network.enable", {}, didEnableNetwork); - } - - function didEnableNetwork() - { - // Prepare for a "reload" to avoid having the test harness loaded by - // image.html initiate the test again. - InspectorTest.evaluateInPage( - "prepareForReload(), window.location.href", navigate); - } - - function navigate(currentUrl) - { - let url = currentUrl.replace( - "override-referrer.html", "resources/image.html"); - InspectorTest.sendCommandOrDie("Page.navigate", { - url: url, - referrer: "http://referrer.com/" - }); - } - - function onRequestWillBeSent(event) - { - let params = event.params; - let referrer = params.request.headers.Referer; - if (!referrer) - return; - - referrers.push(InspectorTest.parseURL(referrer).host); - if (referrers.length === 2) { - // Only log the list the found referrers at the end of the test. - // Otherwise the first one will be lost because the target page is in - // the middle of loading. - InspectorTest.log("Referrers: " + JSON.stringify(referrers)); - testRunner.logToStderr(JSON.stringify(referrers)); - InspectorTest.completeTest(); - } - } -} -</script> -</head> -<body onload="runTest()"> -<p>Tests that the navigation referrer can be overridden.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer.js new file mode 100644 index 0000000..5dc5c41 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/override-referrer.js
@@ -0,0 +1,36 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests that the navigation referrer can be overridden.`); + + function parseURL(url) { + var result = {}; + var match = url.match(/^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i); + if (!match) + return result; + result.scheme = match[1].toLowerCase(); + result.host = match[2]; + result.port = match[3]; + result.path = match[4] || "/"; + result.fragment = match[5]; + return result; + } + + let referrers = []; + await dp.Network.enable(); + dp.Network.onRequestWillBeSent(event => { + let params = event.params; + let referrer = params.request.headers.Referer; + if (!referrer) + return; + + referrers.push(parseURL(referrer).host); + if (referrers.length === 2) { + // Only log the list the found referrers at the end of the test. + // Otherwise the first one will be lost because the target page is in + // the middle of loading. + testRunner.log('Referrers: ' + JSON.stringify(referrers)); + testRunner.completeTest(); + } + }); + dp.Page.navigate({url: testRunner.url('resources/image.html'), referrer: 'http://referrer.com/'}); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect-expected.txt index 6b0d71fb..bba6da90 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect-expected.txt
@@ -1,5 +1,4 @@ Tests that redirect from navigator.sendBeacon() is recorded. - Request Sent: /inspector-protocol/resources/ping-redirect.php Request Sent: /inspector-protocol/resources/ping-redirected-page.html Redirect Source: /inspector-protocol/resources/ping-redirect.php
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect.html deleted file mode 100644 index 71b1d3d8..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect.html +++ /dev/null
@@ -1,46 +0,0 @@ -<html> -<head> -<script src="resources/inspector-protocol-test.js"></script> -<script> -function sendBeacon() -{ - navigator.sendBeacon("resources/ping-redirect.php", "foo"); -} - -function test() -{ - var requestSent = 0; - InspectorTest.eventHandler["Network.requestWillBeSent"] = onRequestWillBeSent; - enableNetwork(); - - function enableNetwork() - { - InspectorTest.sendCommandOrDie("Network.enable", {}, didEnableNetwork); - } - - function didEnableNetwork() - { - InspectorTest.evaluateInPage("sendBeacon()"); - } - - function onRequestWillBeSent(event) - { - requestSent++; - var params = event.params; - InspectorTest.log("Request Sent: " + InspectorTest.parseURL(params.request.url).path); - if (requestSent == 2) { - var redirectSource = ""; - if (params.redirectResponse) - redirectSource = InspectorTest.parseURL(params.redirectResponse.url).path; - InspectorTest.log("Redirect Source: " + redirectSource); - InspectorTest.completeTest(); - } - } -} -</script> -</head> -<body onload="runTest()"> -<p>Tests that redirect from navigator.sendBeacon() is recorded.</p> -</body> -</html> -
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect.js new file mode 100644 index 0000000..32a367f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/ping-redirect.js
@@ -0,0 +1,36 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests that redirect from navigator.sendBeacon() is recorded.`); + + function parseURL(url) { + var result = {}; + var match = url.match(/^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i); + if (!match) + return result; + result.scheme = match[1].toLowerCase(); + result.host = match[2]; + result.port = match[3]; + result.path = match[4] || "/"; + result.fragment = match[5]; + return result; + } + + await dp.Network.enable(); + session.evaluate(` + navigator.sendBeacon('${testRunner.url('resources/ping-redirect.php')}', 'foo'); + `); + + var requestSent = 0; + dp.Network.onRequestWillBeSent(event => { + requestSent++; + var params = event.params; + testRunner.log('Request Sent: ' + parseURL(params.request.url).path); + if (requestSent == 2) { + var redirectSource = ''; + if (params.redirectResponse) + redirectSource = parseURL(params.redirectResponse.url).path; + testRunner.log('Redirect Source: ' + redirectSource); + testRunner.completeTest(); + } + }); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache-expected.txt index ec9c8fc9..3beda5f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache-expected.txt
@@ -1,6 +1,4 @@ Tests that reloads when coming from protocol still use memory cache. - -Page reloaded. Request Will be Sent for blank.js Served From Cache for blank.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache.html deleted file mode 100644 index 082f75a4..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache.html +++ /dev/null
@@ -1,67 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script src="resources/inspector-protocol-test.js"></script> -<script src="resources/blank.js"></script> - -<script> - -function test() -{ - InspectorTest.eventHandler["Network.requestWillBeSent"] = onRequestWillBeSent; - InspectorTest.eventHandler["Network.responseReceived"] = onResponseReceived; - InspectorTest.eventHandler["Network.requestServedFromCache"] = onServedFromCache; - - enableNetwork(); - - function enableNetwork() - { - InspectorTest.sendCommand("Network.enable", {}, prepareForReload); - } - - function prepareForReload() - { - InspectorTest.evaluateInPage("prepareForReload()", reloadPage); - } - - function reloadPage() - { - // It's worth noting that because the way the testrunner works nothing will be logged - // until after this command executes and not log anything in the callback of this function. - InspectorTest.sendCommand("Page.reload", { "ignoreCache": false }); - } - - - var blankRequestId = 0; - function onRequestWillBeSent(request) - { - var url = request.params.request.url; - if (/blank\.js$/.test(url)) { - InspectorTest.log("Request Will be Sent for " + url.substr(url.lastIndexOf("blank.js"))); - blankRequestId = request.params.requestId; - } - } - - function onResponseReceived(request) - { - var url = request.params.response.url; - if (/blank.js$/.test(url)) { - InspectorTest.log("This should never be reached."); - InspectorTest.completeTest(); - } - } - - function onServedFromCache(request) - { - if (request.params.requestId === blankRequestId) { - InspectorTest.log("Served From Cache for blank.js"); - InspectorTest.completeTest(); - } - } -} -</script> -</head> -<body onload="runTest();"> -<p>Tests that reloads when coming from protocol still use memory cache.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache.js new file mode 100644 index 0000000..19743b97 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/reload-memory-cache.js
@@ -0,0 +1,33 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startURL( + 'resources/reload-memory-cache.html', + `Tests that reloads when coming from protocol still use memory cache.`); + + await dp.Network.enable(); + dp.Page.reload({ignoreCache: false}); + + var blankRequestId = 0; + + dp.Network.onRequestWillBeSent(request => { + var url = request.params.request.url; + if (/blank\.js$/.test(url)) { + testRunner.log('Request Will be Sent for ' + url.substr(url.lastIndexOf('blank.js'))); + blankRequestId = request.params.requestId; + } + }); + + dp.Network.onResponseReceived(request => { + var url = request.params.response.url; + if (/blank.js$/.test(url)) { + testRunner.log('This should never be reached.'); + testRunner.completeTest(); + } + }); + + dp.Network.onRequestServedFromCache(request => { + if (request.params.requestId === blankRequestId) { + testRunner.log('Served From Cache for blank.js'); + testRunner.completeTest(); + } + }); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable-expected.txt index b31b6f42..1314ba4 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE WARNING: Mixed Content: The page at 'https://127.0.0.1:8443/inspector-protocol/resources/active-mixed-content-iframe.html' was loaded over HTTPS, but requested an insecure script 'http://example.test:8000/inspector-protocol/resources/blank.js'. This content should also be served over HTTPS. Tests that willSendRequest contains the correct mixed content status for active mixed content. - Network agent enabled Mixed content type of https://127.0.0.1:8443/inspector-protocol/resources/active-mixed-content-iframe.html: none Mixed content type of http://example.test:8000/inspector-protocol/resources/blank.js: blockable
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable.html deleted file mode 100644 index 17d4732..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable.html +++ /dev/null
@@ -1,21 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script type="text/javascript" src="../inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="/resources/get-host-info.js"></script> -<script src="resources/mixed-content-type-test.js"></script> -<script> -// The test() function is defined in mixed-content-type-test.js and -// calls this function to add mixed content to the page. -function addIframeWithMixedContent() -{ - var iframe = document.createElement("iframe"); - iframe.src = get_host_info().HTTPS_ORIGIN + "/inspector-protocol/resources/active-mixed-content-iframe.html"; - document.body.appendChild(iframe); -} -</script> -</head> -<body onload="runTest()"> - <p>Tests that willSendRequest contains the correct mixed content status for active mixed content.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable.js new file mode 100644 index 0000000..b60d102 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-blockable.js
@@ -0,0 +1,14 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests that willSendRequest contains the correct mixed content status for active mixed content.`); + + function addIframeWithMixedContent() { + var iframe = document.createElement('iframe'); + iframe.src = 'https://127.0.0.1:8443/inspector-protocol/resources/active-mixed-content-iframe.html'; + document.body.appendChild(iframe); + } + + var helper = await testRunner.loadScript('./resources/mixed-content-type-test.js'); + helper(testRunner, session, addIframeWithMixedContent); +}) +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none-expected.txt index 165480b..678aa4a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none-expected.txt
@@ -1,5 +1,4 @@ Tests that willSendRequest contains the correct mixed content status for not-mixed content. - Network agent enabled Mixed content type of https://127.0.0.1:8443/inspector-protocol/resources/no-mixed-content-iframe.html: none Mixed content type of https://127.0.0.1:8443/inspector-protocol/resources/blank.js: none
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none.html deleted file mode 100644 index dac754bf..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none.html +++ /dev/null
@@ -1,21 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script type="text/javascript" src="../inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="/resources/get-host-info.js"></script> -<script src="resources/mixed-content-type-test.js"></script> -<script> -// The test() function is defined in mixed-content-type-test.js and -// calls this function to add mixed content to the page. -function addIframeWithMixedContent() -{ - var iframe = document.createElement("iframe"); - iframe.src = get_host_info().HTTPS_ORIGIN + "/inspector-protocol/resources/no-mixed-content-iframe.html"; - document.body.appendChild(iframe); -} -</script> -</head> -<body onload="runTest()"> - <p>Tests that willSendRequest contains the correct mixed content status for not-mixed content.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none.js new file mode 100644 index 0000000..3c4a03f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-none.js
@@ -0,0 +1,13 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests that willSendRequest contains the correct mixed content status for not-mixed content.`); + + function addIframeWithMixedContent() { + var iframe = document.createElement('iframe'); + iframe.src = 'https://127.0.0.1:8443/inspector-protocol/resources/no-mixed-content-iframe.html'; + document.body.appendChild(iframe); + } + + var helper = await testRunner.loadScript('./resources/mixed-content-type-test.js'); + helper(testRunner, session, addIframeWithMixedContent); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable-expected.txt index 7015f6dc..b29f644 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable-expected.txt
@@ -1,6 +1,4 @@ -CONSOLE WARNING: Mixed Content: The page at 'https://127.0.0.1:8443/inspector-protocol/resources/passive-mixed-content-iframe.html' was loaded over HTTPS, but requested an insecure image 'http://example.test:8000/resources/square.png'. This content should also be served over HTTPS. Tests that willSendRequest contains the correct mixed content status for passive mixed content. - Network agent enabled Mixed content type of https://127.0.0.1:8443/inspector-protocol/resources/passive-mixed-content-iframe.html: none Mixed content type of http://example.test:8000/resources/square.png: optionally-blockable
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.html deleted file mode 100644 index eb6630b..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.html +++ /dev/null
@@ -1,21 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script type="text/javascript" src="../inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="/resources/get-host-info.js"></script> -<script src="resources/mixed-content-type-test.js"></script> -<script> -// The test() function is defined in mixed-content-type-test.js and -// calls this function to add mixed content to the page. -function addIframeWithMixedContent() -{ - var iframe = document.createElement("iframe"); - iframe.src = get_host_info().HTTPS_ORIGIN + "/inspector-protocol/resources/passive-mixed-content-iframe.html"; - document.body.appendChild(iframe); -} -</script> -</head> -<body onload="runTest()"> - <p>Tests that willSendRequest contains the correct mixed content status for passive mixed content.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.js new file mode 100644 index 0000000..3b987b8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.js
@@ -0,0 +1,13 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests that willSendRequest contains the correct mixed content status for passive mixed content.`); + + function addIframeWithMixedContent() { + var iframe = document.createElement('iframe'); + iframe.src = 'https://127.0.0.1:8443/inspector-protocol/resources/passive-mixed-content-iframe.html'; + document.body.appendChild(iframe); + } + + var helper = await testRunner.loadScript('./resources/mixed-content-type-test.js'); + helper(testRunner, session, addIframeWithMixedContent); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy-expected.txt index 00f85ef..e381d76 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy-expected.txt
@@ -1,5 +1,4 @@ Tests that network requests are annotated with the correct referrer policy. - Network agent enabled PASS: Request with expected policy unsafe-url observed PASS: Request with expected policy no-referrer-when-downgrade observed
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy.html deleted file mode 100644 index bebc29c..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy.html +++ /dev/null
@@ -1,60 +0,0 @@ -<!DOCTYPE html> -<script src="../inspector-protocol/resources/inspector-protocol-test.js"></script> -<script src="/resources/get-host-info.js"></script> -<script> -function sendRequest(policy) { - var img = document.createElement("img"); - img.referrerPolicy = policy; - img.src = "/resources/square.png?" + Math.random(); - document.body.appendChild(img); -} - -function test() { - var policy_num = 0; - var policies = [ - "unsafe-url", "no-referrer-when-downgrade", "no-referrer", "origin", - "origin-when-cross-origin" - ]; - - InspectorTest.eventHandler["Network.requestWillBeSent"] = onRequestWillBeSent; - InspectorTest.sendCommand("Network.enable", {}, didEnableNetwork); - - function onRequestWillBeSent(evt) { - var req = evt.params.request; - if (req.referrerPolicy == policies[policy_num]) { - InspectorTest.log("PASS: Request with expected policy " + - policies[policy_num] + " observed"); - } else { - InspectorTest.log("FAIL: Request with policy " + req.referrerPolicy + - " observed (expected " + policies[policy_num] + ")"); - } - policy_num++; - if (policy_num >= policies.length) { - InspectorTest.completeTest(); - } else { - InspectorTest.sendCommand( - "Runtime.evaluate", - {"expression" : "sendRequest('" + policies[policy_num] + "')"}); - } - } - - function didEnableNetwork(messageObject) { - if (messageObject.error) { - InspectorTest.log("FAIL: Couldn't enable network agent " + - messageObject.error.message); - InspectorTest.completeTest(); - return; - } - InspectorTest.log("Network agent enabled"); - InspectorTest.sendCommand( - "Runtime.evaluate", - {"expression" : "sendRequest('" + policies[policy_num] + "')"}); - } -} -</script> -<body onload="runTest()"> - <p> - Tests that network requests are annotated with the correct referrer - policy. - </p> -</body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy.js new file mode 100644 index 0000000..f77701b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/request-referrer-policy.js
@@ -0,0 +1,27 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests that network requests are annotated with the correct referrer policy.`); + + await dp.Network.enable(); + testRunner.log('Network agent enabled'); + + var policies = [ + 'unsafe-url', 'no-referrer-when-downgrade', 'no-referrer', 'origin', + 'origin-when-cross-origin' + ]; + for (var policy of policies) { + session.evaluate(` + var img = document.createElement('img'); + img.referrerPolicy = '${policy}'; + img.src = '/resources/square.png?' + Math.random(); + document.body.appendChild(img); + `); + var evt = await dp.Network.onceRequestWillBeSent(); + var req = evt.params.request; + if (req.referrerPolicy === policy) + testRunner.log(`PASS: Request with expected policy ${policy} observed`); + else + testRunner.log(`FAIL: Request with policy ${req.referrerPolicy} observed (expected ${policy})`); + } + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/image.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/image.html index c64fd2d..e2b89ae 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/image.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/image.html
@@ -1,7 +1,3 @@ <!DOCTYPE html> -<!-- We also need to include the inspector test harness here to ensure the test - completes normally after navigating to this page. --> -<script src="../resources/inspector-protocol-test.js"></script> -<body onload="runTest()"> <img src="image.png"> </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-page.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-page.html new file mode 100644 index 0000000..90531a4b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-page.html
@@ -0,0 +1,2 @@ +<html> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.html new file mode 100644 index 0000000..69b5a0d --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.html
@@ -0,0 +1,10 @@ +<!-- +Copyright 2017 The Chromium Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> +<html> +<head> +<script src="inspector-protocol-test.js"></script> +</head> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js index 6dd8c3e..f2c60bad 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/inspector-protocol-test.js
@@ -1,164 +1,485 @@ -/* - * Copyright (C) 2012 Samsung Electronics. All rights reserved. - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. -var initialize_InspectorTest = function() { +var TestRunner = class { + constructor(baseURL, log, completeTest, fetch) { + this._dumpInspectorProtocolMessages = false; + this._baseURL = baseURL; + this._log = log; + this._completeTest = completeTest; + this._fetch = fetch; + } -InspectorTest.evaluateInInspectedPage = function(expression, callback) -{ - InspectorTest.sendCommand("Runtime.evaluate", { expression: expression }, callback); -} + startDumpingProtocolMessages() { + this._dumpInspectorProtocolMessages = true; + }; -InspectorTest.parseURL = function(url) -{ - var result = {}; - var match = url.match(/^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i); - if (!match) - return result; - result.scheme = match[1].toLowerCase(); - result.host = match[2]; - result.port = match[3]; - result.path = match[4] || "/"; - result.fragment = match[5]; - return result; -} + completeTest() { + this._completeTest.call(null); + } -} + log(text) { + this._log.call(null, text); + } -var outputElement; - -/** - * Logs message to process stdout via alert (hopefully implemented with immediate flush). - * @param {string} text - */ -function debugLog(text) -{ - alert(text); -} - -/** - * @param {string} text - */ -function log(text) -{ - if (!outputElement) { - var intermediate = document.createElement("div"); - document.body.appendChild(intermediate); - - var intermediate2 = document.createElement("div"); - intermediate.appendChild(intermediate2); - - outputElement = document.createElement("div"); - outputElement.className = "output"; - outputElement.id = "output"; - outputElement.style.whiteSpace = "pre"; - intermediate2.appendChild(outputElement); + logMessage(originalMessage, title) { + var message = JSON.parse(JSON.stringify(originalMessage)); + if (message.id) + message.id = '<messageId>'; + const nonStableFields = new Set(['nodeId', 'objectId', 'scriptId', 'timestamp', 'backendNodeId', 'parentId', 'frameId', 'baseURL', 'documentURL']); + var objects = [message]; + while (objects.length) { + var object = objects.shift(); + for (var key in object) { + if (nonStableFields.has(key)) + object[key] = `<${key}>`; + else if (typeof object[key] === 'string' && object[key].match(/\d+:\d+:\d+:debug/)) + object[key] = object[key].replace(/\d+/, '<scriptId>'); + else if (typeof object[key] === 'object') + objects.push(object[key]); + } } - outputElement.appendChild(document.createTextNode(text)); - outputElement.appendChild(document.createElement("br")); -} + this.logObject(message, title); + return originalMessage; + } -function closeTest() -{ - closeInspector(); - testRunner.notifyDone(); -} + logObject(object, title) { + var lines = []; -var reloadParam = "__protocol__test__reload__"; + function dumpValue(value, prefix, prefixWithName) { + if (typeof value === 'object' && value !== null) { + if (value instanceof Array) + dumpItems(value, prefix, prefixWithName); + else + dumpProperties(value, prefix, prefixWithName); + } else { + lines.push(prefixWithName + String(value).replace(/\n/g, ' ')); + } + } -function runTest() -{ - if (!window.testRunner) { - console.error("This test requires DumpRenderTree"); + function dumpProperties(object, prefix, firstLinePrefix) { + prefix = prefix || ''; + firstLinePrefix = firstLinePrefix || prefix; + lines.push(firstLinePrefix + '{'); + + var propertyNames = Object.keys(object); + propertyNames.sort(); + for (var i = 0; i < propertyNames.length; ++i) { + var name = propertyNames[i]; + if (!object.hasOwnProperty(name)) + continue; + var prefixWithName = ' ' + prefix + name + ' : '; + dumpValue(object[name], ' ' + prefix, prefixWithName); + } + lines.push(prefix + '}'); + } + + function dumpItems(object, prefix, firstLinePrefix) { + prefix = prefix || ''; + firstLinePrefix = firstLinePrefix || prefix; + lines.push(firstLinePrefix + '['); + for (var i = 0; i < object.length; ++i) + dumpValue(object[i], ' ' + prefix, ' ' + prefix + '[' + i + '] : '); + lines.push(prefix + ']'); + } + + dumpValue(object, '', title || ''); + this.log(lines.join('\n')); + } + + url(relative) { + return this._baseURL + relative; + } + + async runTestSuite(testSuite) { + for (var test of testSuite) { + this.log('\nRunning test: ' + test.name); + try { + await test(); + } catch (e) { + this.log(`Error during test: ${e}\n${e.stack}`); + } + } + this.completeTest(); + } + + _checkExpectation(fail, name, messageObject) { + if (fail === !!messageObject.error) { + this.log('PASS: ' + name); + return true; + } + + this.log('FAIL: ' + name + ': ' + JSON.stringify(messageObject)); + this.completeTest(); + return false; + } + + expectedSuccess(name, messageObject) { + return this._checkExpectation(false, name, messageObject); + } + + expectedError(name, messageObject) { + return this._checkExpectation(true, name, messageObject); + } + + die(message, error) { + this.log(`${message}: ${error}\n${error.stack}`); + this.completeTest(); + throw new Error(message); + } + + fail(message) { + this.log('FAIL: ' + message); + this.completeTest(); + } + + async loadScript(url) { + var source = await this._fetch(this.url(url)); + return eval(`${source}\n//# sourceURL=${url}`); + }; + + async createPage() { + var targetId = (await DevToolsAPI._sendCommandOrDie('Target.createTarget', {url: 'about:blank'})).targetId; + await DevToolsAPI._sendCommandOrDie('Target.activateTarget', {targetId}); + var page = new TestRunner.Page(this, targetId); + var dummyURL = window.location.href; + dummyURL = dummyURL.substring(0, dummyURL.indexOf('inspector-protocol-test.html')) + 'inspector-protocol-page.html'; + await page._navigate(dummyURL); + return page; + } + + async _start(description, html, url) { + try { + this.log(description); + var page = await this.createPage(); + if (url) + await page.navigate(url); + if (html) + await page.loadHTML(html); + var session = await page.createSession(); + return { page: page, session: session, dp: session.protocol }; + } catch (e) { + this.die('Error starting the test', e); + } + }; + + startBlank(description) { + return this._start(description, null, null); + } + + startHTML(html, description) { + return this._start(description, html, null); + } + + startURL(url, description) { + return this._start(description, null, url); + } +}; + +TestRunner.Page = class { + constructor(testRunner, targetId) { + this._testRunner = testRunner; + this._targetId = targetId; + } + + async createSession() { + await DevToolsAPI._sendCommandOrDie('Target.attachToTarget', {targetId: this._targetId}); + var session = new TestRunner.Session(this); + DevToolsAPI._sessions.set(this._targetId, session); + return session; + } + + navigate(url) { + return this._navigate(this._testRunner.url(url)); + } + + async _navigate(url) { + if (DevToolsAPI._sessions.get(this._targetId)) + this._testRunner.die(`Cannot navigate to ${url} with active session`, new Error()); + + var session = await this.createSession(); + await session._navigate(url); + await session.disconnect(); + } + + async loadHTML(html) { + if (DevToolsAPI._sessions.get(this._targetId)) + this._testRunner.die('Cannot loadHTML with active session', new Error()); + + html = html.replace(/'/g, "\\'").replace(/\n/g, '\\n'); + var session = await this.createSession(); + await session.protocol.Runtime.evaluate({expression: `document.write('${html}');document.close();`}); + await session.disconnect(); + } +}; + +TestRunner.Session = class { + constructor(page) { + this._testRunner = page._testRunner; + this._page = page; + this._requestId = 0; + this._dispatchTable = new Map(); + this._eventHandlers = new Map(); + this.protocol = this._setupProtocol(); + } + + async disconnect() { + await DevToolsAPI._sendCommandOrDie('Target.detachFromTarget', {targetId: this._page._targetId}); + DevToolsAPI._sessions.delete(this._page._targetId); + } + + sendRawCommand(requestId, message) { + DevToolsAPI._sendCommandOrDie('Target.sendMessageToTarget', {targetId: this._page._targetId, message: message}); + return new Promise(f => this._dispatchTable.set(requestId, f)); + } + + sendCommand(method, params) { + var requestId = ++this._requestId; + var messageObject = {'id': requestId, 'method': method, 'params': params}; + if (this._testRunner._dumpInspectorProtocolMessages) + this._testRunner.log(`frontend => backend: ${JSON.stringify(messageObject)}`); + return this.sendRawCommand(requestId, JSON.stringify(messageObject)); + } + + async evaluate(code) { + if (typeof code === 'function') + code = `(${code.toString()})()`; + var response = await this.protocol.Runtime.evaluate({expression: code, returnByValue: true}); + if (response.error) { + this._testRunner.log(`Error while evaluating '${code}': ${response.error}`); + this._testRunner.completeTest(); + } else { + return response.result.result.value; + } + } + + async evaluateAsync(code) { + if (typeof code === 'function') + code = `(${code.toString()})()`; + var response = await this.protocol.Runtime.evaluate({expression: code, returnByValue: true, awaitPromise: true}); + if (response.error) { + this._testRunner.log(`Error while evaluating async '${code}': ${response.error}`); + this._testRunner.completeTest(); + } else { + return response.result.result.value; + } + } + + navigate(url) { + return this._navigate(this._testRunner.url(url)); + } + + async _navigate(url) { + this.protocol.Page.enable(); + this.protocol.Page.navigate({url: url}); + + var callback; + var promise = new Promise(f => callback = f); + this.protocol.Page.onFrameNavigated(message => { + if (!message.params.frame.parentId) + callback(); + }); + await Promise.all([ + promise, + this.protocol.Page.onceLoadEventFired() + ]); + } + + _dispatchMessage(message) { + if (this._testRunner._dumpInspectorProtocolMessages) + this._testRunner.log(`backend => frontend: ${JSON.stringify(message)}`); + if (typeof message.id === 'number') { + var handler = this._dispatchTable.get(message.id); + if (handler) { + this._dispatchTable.delete(message.id); + handler(message); + } + } else { + var eventName = message.method; + for (var handler of (this._eventHandlers.get(eventName) || [])) + handler(message); + } + } + + _setupProtocol() { + return new Proxy({}, { get: (target, agentName, receiver) => new Proxy({}, { + get: (target, methodName, receiver) => { + const eventPattern = /^(on(ce)?|off)([A-Z][A-Za-z0-9]+)/; + var match = eventPattern.exec(methodName); + if (!match) + return args => this.sendCommand(`${agentName}.${methodName}`, args || {}); + var eventName = match[3]; + eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1); + if (match[1] === 'once') + return eventMatcher => this._waitForEvent(`${agentName}.${eventName}`, eventMatcher); + if (match[1] === 'off') + return listener => this._removeEventHandler(`${agentName}.${eventName}`, listener); + return listener => this._addEventHandler(`${agentName}.${eventName}`, listener); + } + })}); + } + + _addEventHandler(eventName, handler) { + var handlers = this._eventHandlers.get(eventName) || []; + handlers.push(handler); + this._eventHandlers.set(eventName, handlers); + } + + _removeEventHandler(eventName, handler) { + var handlers = this._eventHandlers.get(eventName) || []; + var index = handlers.indexOf(handler); + if (index === -1) + return; + handlers.splice(index, 1); + this._eventHandlers.set(eventName, handlers); + } + + _waitForEvent(eventName, eventMatcher) { + return new Promise(callback => { + var handler = result => { + if (eventMatcher && !eventMatcher(result)) + return; + this._removeEventHandler(eventName, handler); + callback(result); + }; + this._addEventHandler(eventName, handler); + }); + } +}; + +var DevToolsAPI = {}; +DevToolsAPI._requestId = 0; +DevToolsAPI._embedderMessageId = 0; +DevToolsAPI._dispatchTable = new Map(); +DevToolsAPI._sessions = new Map(); +DevToolsAPI._outputElement = null; + +DevToolsAPI._log = function(text) { + if (!DevToolsAPI._outputElement) { + var intermediate = document.createElement('div'); + document.body.appendChild(intermediate); + var intermediate2 = document.createElement('div'); + intermediate.appendChild(intermediate2); + DevToolsAPI._outputElement = document.createElement('div'); + DevToolsAPI._outputElement.className = 'output'; + DevToolsAPI._outputElement.id = 'output'; + DevToolsAPI._outputElement.style.whiteSpace = 'pre'; + intermediate2.appendChild(DevToolsAPI._outputElement); + } + DevToolsAPI._outputElement.appendChild(document.createTextNode(text)); + DevToolsAPI._outputElement.appendChild(document.createElement('br')); +}; + +DevToolsAPI._completeTest = function() { + window.testRunner.notifyDone(); +}; + +DevToolsAPI._die = function(message, error) { + DevToolsAPI._log(`${message}: ${error}\n${error.stack}`); + DevToolsAPI._completeTest(); + throw new Error(); +}; + +DevToolsAPI.dispatchMessage = function(messageOrObject) { + var messageObject = (typeof messageOrObject === 'string' ? JSON.parse(messageOrObject) : messageOrObject); + var messageId = messageObject.id; + try { + if (typeof messageId === 'number') { + var handler = DevToolsAPI._dispatchTable.get(messageId); + if (handler) { + DevToolsAPI._dispatchTable.delete(messageId); + handler(messageObject); + } + } else { + var eventName = messageObject.method; + if (eventName === 'Target.receivedMessageFromTarget') { + var targetId = messageObject.params.targetId; + var message = messageObject.params.message; + var session = DevToolsAPI._sessions.get(targetId); + if (session) + session._dispatchMessage(JSON.parse(message)); + } + } + } catch(e) { + DevToolsAPI._die(`Exception when dispatching message\n${JSON.stringify(messageObject)}`, e); + } +}; + +DevToolsAPI._sendCommand = function(method, params) { + var requestId = ++DevToolsAPI._requestId; + var messageObject = {'id': requestId, 'method': method, 'params': params}; + var embedderMessage = {'id': ++DevToolsAPI._embedderMessageId, 'method': 'dispatchProtocolMessage', 'params': [JSON.stringify(messageObject)]}; + DevToolsHost.sendMessageToEmbedder(JSON.stringify(embedderMessage)); + return new Promise(f => DevToolsAPI._dispatchTable.set(requestId, f)); +}; + +DevToolsAPI._sendCommandOrDie = function(method, params) { + return DevToolsAPI._sendCommand(method, params).then(message => { + if (message.error) + DevToolsAPI._die('Error communicating with harness', new Error(message.error)); + return message.result; + }); +}; + +function debugTest(testFunction) { + var dispatch = DevToolsAPI.dispatchMessage; + var messages = []; + DevToolsAPI.dispatchMessage = message => { + if (!messages.length) { + setTimeout(() => { + for (var message of messages.splice(0)) + dispatch(message); + }, 0); + } + messages.push(message); + }; + return testRunner => { + testRunner.log = console.log; + testRunner.completeTest = () => console.log('Test completed'); + window.test = () => testFunction(testRunner); + }; +}; + +DevToolsAPI._fetch = function(url) { + return new Promise(fulfill => { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.onreadystatechange = e => { + if (xhr.readyState !== XMLHttpRequest.DONE) return; - } + if ([0, 200, 304].indexOf(xhr.status) === -1) // Testing harness file:/// results in 0. + DevToolsAPI._die(`${xhr.status} while fetching ${url}`, new Error()); + else + fulfill(e.target.response); + }; + xhr.send(null); + }); +}; - var reloadIndex = window.location.href.lastIndexOf(reloadParam); - if (reloadIndex !== -1) { - var lastId = window.location.href.substring(reloadIndex + reloadParam.length); - window.lastFrontendEvalId = parseInt(lastId, 10); - evaluateInFrontend("InspectorTest.pageReloaded();"); - return; - } +window.testRunner.dumpAsText(); +window.testRunner.waitUntilDone(); +window.testRunner.setCanOpenWindows(true); - testRunner.dumpAsText(); - testRunner.waitUntilDone(); - testRunner.setCanOpenWindows(true); +window.addEventListener('load', () => { + var testScriptURL = window.location.search.substring(1); + var baseURL = testScriptURL.substring(0, testScriptURL.lastIndexOf('/') + 1); + DevToolsAPI._fetch(testScriptURL).then(testScript => { + var testRunner = new TestRunner(baseURL, DevToolsAPI._log, DevToolsAPI._completeTest, DevToolsAPI._fetch); + var testFunction = eval(`${testScript}\n//# sourceURL=${testScriptURL}`); + return testFunction(testRunner); + }).catch(reason => { + DevToolsAPI._log(`Error while executing test script: ${reason}\n${reason.stack}`); + DevToolsAPI._completeTest(); + }); +}, false); - openInspector(); -} +window['onerror'] = (message, source, lineno, colno, error) => { + DevToolsAPI._log(`${error}\n${error.stack}`); + DevToolsAPI._completeTest(); +}; -function closeInspector() -{ - testRunner.closeWebInspector(); -} - -var lastFrontendEvalId = 0; -function evaluateInFrontend(script) -{ - testRunner.evaluateInWebInspector(++lastFrontendEvalId, script); -} - -function navigateProtocolTest(url) -{ - url += (url.indexOf("?") === -1 ? "?" : "&") + reloadParam + lastFrontendEvalId; - window.location.replace(url); -} - -function prepareForReload() -{ - window.location += "#" + reloadParam + lastFrontendEvalId; -} - -function openInspector() -{ - var scriptTags = document.getElementsByTagName("script"); - var scriptUrlBasePath = ""; - for (var i = 0; i < scriptTags.length; ++i) { - var index = scriptTags[i].src.lastIndexOf("/resources/inspector-protocol-test.js"); - if (index > -1 ) { - scriptUrlBasePath = scriptTags[i].src.slice(0, index); - break; - } - } - - var dummyFrontendURL = scriptUrlBasePath + "/resources/protocol-test.html"; - testRunner.showWebInspector("", dummyFrontendURL); - // FIXME: rename this 'test' global field across all tests. - var testFunction = window.test; - if (typeof testFunction === "function") { - var initializers = ""; - for (var symbol in window) { - if (!/^initialize_/.test(symbol) || typeof window[symbol] !== "function") - continue; - initializers += "(" + window[symbol].toString() + ")();\n"; - } - evaluateInFrontend(initializers + "(" + testFunction.toString() +")();"); - return; - } - // Kill waiting process if failed to send. - alert("Failed to send test function"); - testRunner.notifyDone(); -} +window.addEventListener('unhandledrejection', e => { + DevToolsAPI._log(`Promise rejection: ${e.reason}\n${e.reason ? e.reason.stack : ''}`); + DevToolsAPI._completeTest(); +}, false);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/interception-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/interception-test.js index 59750ec..5656fa14 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/interception-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/interception-test.js
@@ -1,295 +1,210 @@ -var initialize_InterceptionTest = function() { +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. -var interceptionRequestParams = {}; -var requestIdToFilename = {}; -var filenameToInterceptionId = {}; -var loggedMessages = {}; -var InterceptionIdToCanonicalInterceptionId = {}; -var idToCanoncalId = {}; -var nextId = 1; +(class InterceptionHelper { + constructor(testRunner, session) { + this._testRunner = testRunner; + this._session = session; + this._interceptionRequestParams = {}; + this._requestIdToFilename = {}; + this._filenameToInterceptionId = {}; + this._loggedMessages = {}; + this._consoleLogs = []; + this._idToCanoncalId = {}; + this._nextId = 1; + } -function getNextId() -{ - return "ID " + nextId++; -} + _getNextId() { + return 'ID ' + this._nextId++; + } -function canonicalId(id) -{ - if (!idToCanoncalId.hasOwnProperty(id)) - idToCanoncalId[id] = getNextId(); - return idToCanoncalId[id]; -} + _canonicalId(id) { + if (!this._idToCanoncalId.hasOwnProperty(id)) + this._idToCanoncalId[id] = this._getNextId(); + return this._idToCanoncalId[id]; + } -function log(id, message) -{ - testRunner.logToStderr("id " + id + " " + message); - if (!loggedMessages.hasOwnProperty(id)) - loggedMessages[id] = []; - loggedMessages[id].push(message); -} + _log(id, message) { + if (!this._loggedMessages.hasOwnProperty(id)) + this._loggedMessages[id] = []; + this._loggedMessages[id].push(message); + } -function completeTest(message) -{ + _completeTest(message) { // The order in which network events occur is not fully deterministic so we // sort based on the interception ID to try and make the test non-flaky. - for (var property in loggedMessages) { - if (loggedMessages.hasOwnProperty(property)) { - var messages = loggedMessages[property]; - for (var i = 0; i < messages.length; i++) { - InspectorTest.log(messages[i]); - } - } + for (var property in this._loggedMessages) { + if (this._loggedMessages.hasOwnProperty(property)) { + var messages = this._loggedMessages[property]; + for (var i = 0; i < messages.length; i++) + this._testRunner.log(messages[i]); + } } - + for (var consoleLog of this._consoleLogs) + this._testRunner.log(consoleLog); if (message) - InspectorTest.log(message); + this._testRunner.log(message); + this._testRunner.completeTest(); + } - InspectorTest.completeTest(); -} - -InspectorTest.startInterceptionTest = function(requestInterceptedDict, - numConsoleLogsToWaitFor) { - if (typeof numConsoleLogsToWaitFor === "undefined") - numConsoleLogsToWaitFor = 0; - - InspectorTest.eventHandler["Network.requestIntercepted"] = onRequestIntercepted; - InspectorTest.eventHandler["Network.loadingFailed"] = onLoadingFailed; - InspectorTest.eventHandler["Network.requestWillBeSent"] = onRequestWillBeSent; - InspectorTest.eventHandler["Network.responseReceived"] = onResponseReceived; - InspectorTest.eventHandler["Runtime.consoleAPICalled"] = onConsoleAPICalled; - InspectorTest.eventHandler["Page.frameStoppedLoading"] = onStop; - + async startInterceptionTest(requestInterceptedDict, numConsoleLogsToWaitFor) { + if (typeof numConsoleLogsToWaitFor === 'undefined') + numConsoleLogsToWaitFor = 0; var frameStoppedLoading = false; - function getInterceptionId(filename) { - if (!filenameToInterceptionId.hasOwnProperty(filename)) { - filenameToInterceptionId[filename] = getNextId() - } - return filenameToInterceptionId[filename]; - } - - function enableNetwork() - { - InspectorTest.log("Test started"); - InspectorTest.sendCommand("Network.enable", {}, didEnableNetwork); - } - - function didEnableNetwork(messageObject) - { - if (messageObject.error) { - completeTest("FAIL: Couldn't enable network agent" + - messageObject.error.message); - return; - } - InspectorTest.log("Network agent enabled"); - InspectorTest.sendCommand( - "Network.setRequestInterceptionEnabled", {"enabled": true}, - didSetRequestInterceptionEnabled); - } - - function didSetRequestInterceptionEnabled(messageObject) - { - if (messageObject.error) { - completeTest("FAIL: Couldn't enable fetch interception " + - messageObject.error.message); - return; - } - InspectorTest.log("Request interception enabled"); - InspectorTest.sendCommand("Page.enable", {}, didEnablePage); - } - - function didEnablePage(messageObject) - { - if (messageObject.error) { - completeTest("FAIL: Couldn't enable page agent" + - messageObject.error.message); - return; - } - InspectorTest.log("Page agent enabled"); - - InspectorTest.sendCommand("Runtime.enable", {}, didEnableRuntime); - } - - function didEnableRuntime(messageObject) - { - if (messageObject.error) { - completeTest("FAIL: Couldn't enable runtime agent" + - messageObject.error.message); - return; - } - InspectorTest.log("Runtime agent enabled"); - - InspectorTest.sendCommand( - "Runtime.evaluate", { "expression": "appendIframe()"}); - } - - function onRequestIntercepted(event) - { - var filename = event.params.request.url.split('/').pop(); - var id = canonicalId(event.params.interceptionId); - filenameToInterceptionId[filename] = id; - if (!requestInterceptedDict.hasOwnProperty(filename)) { - completeTest("FAILED: unexpected request interception " + - JSON.stringify(event.params)); - return; - } - if (event.params.hasOwnProperty("authChallenge")) { - log(id, "Auth required for " + id); - requestInterceptedDict[filename + '+Auth'](event); - return; - } else if (event.params.hasOwnProperty("redirectUrl")) { - log(id, "Network.requestIntercepted " + id + " " + - event.params.redirectStatusCode + " redirect " + - interceptionRequestParams[id].url.split('/').pop() + - " -> " + event.params.redirectUrl.split('/').pop()); - interceptionRequestParams[id].url = event.params.redirectUrl; - } else { - interceptionRequestParams[id] = event.params.request; - log(id, "Network.requestIntercepted " + id + " " + - event.params.request.method + " " + filename + " type: " + - event.params.resourceType); - } - requestInterceptedDict[filename](event); - } - - function onLoadingFailed(event) - { - var filename = requestIdToFilename[event.params.requestId]; - var id = getInterceptionId(filename); - log(id, "Network.loadingFailed " + filename + " " + - event.params.errorText); - } - - function onRequestWillBeSent(event) - { - var filename = event.params.request.url.split('/').pop(); - requestIdToFilename[event.params.requestId] = filename; - } - - function onResponseReceived(event) - { - var response = event.params.response; - var filename = response.url.split('/').pop(); - var id = getInterceptionId(filename); - log(id, "Network.responseReceived " + filename + " " + response.status + - " " + response.mimeType); - } - - function onStop() - { - frameStoppedLoading = true; - log(getNextId(), "Page.frameStoppedLoading"); - - maybeCompleteTest(); - } - - function onConsoleAPICalled(messageObject) - { - if (messageObject.params.type !== "log") - return; - - numConsoleLogsToWaitFor--; - maybeCompleteTest(); - } + var getInterceptionId = filename => { + if (!this._filenameToInterceptionId.hasOwnProperty(filename)) + this._filenameToInterceptionId[filename] = this._getNextId(); + return this._filenameToInterceptionId[filename]; + }; // Wait until we've seen Page.frameStoppedLoading and the expected number of // console logs. - function maybeCompleteTest() { - if (numConsoleLogsToWaitFor === 0 && frameStoppedLoading) - completeTest(); - } + var maybeCompleteTest = () => { + if (numConsoleLogsToWaitFor === 0 && frameStoppedLoading) + this._completeTest(); + }; - enableNetwork(); -} - -InspectorTest.allowRequest = function(event) { - var id = canonicalId(event.params.interceptionId); - log(id, "allowRequest " + id); - InspectorTest.sendCommand("Network.continueInterceptedRequest", { - "interceptionId": event.params.interceptionId + this._session.protocol.Network.onRequestIntercepted(event => { + var filename = event.params.request.url.split('/').pop(); + var id = this._canonicalId(event.params.interceptionId); + this._filenameToInterceptionId[filename] = id; + if (!requestInterceptedDict.hasOwnProperty(filename)) { + this._completeTest('FAILED: unexpected request interception ' + + JSON.stringify(event.params)); + return; + } + if (event.params.hasOwnProperty('authChallenge')) { + this._log(id, 'Auth required for ' + id); + requestInterceptedDict[filename + '+Auth'](event); + return; + } else if (event.params.hasOwnProperty('redirectUrl')) { + this._log(id, 'Network.requestIntercepted ' + id + ' ' + + event.params.redirectStatusCode + ' redirect ' + + this._interceptionRequestParams[id].url.split('/').pop() + + ' -> ' + event.params.redirectUrl.split('/').pop()); + this._interceptionRequestParams[id].url = event.params.redirectUrl; + } else { + this._interceptionRequestParams[id] = event.params.request; + this._log(id, 'Network.requestIntercepted ' + id + ' ' + + event.params.request.method + ' ' + filename + ' type: ' + + event.params.resourceType); + } + requestInterceptedDict[filename](event); }); -} -InspectorTest.modifyRequest = function(event, params) { - var id = canonicalId(event.params.interceptionId); + this._session.protocol.Network.onLoadingFailed(event => { + var filename = this._requestIdToFilename[event.params.requestId]; + var id = getInterceptionId(filename); + this._log(id, 'Network.loadingFailed ' + filename + ' ' + + event.params.errorText); + }); + + this._session.protocol.Network.onRequestWillBeSent(event => { + var filename = event.params.request.url.split('/').pop(); + this._requestIdToFilename[event.params.requestId] = filename; + }); + + this._session.protocol.Network.onResponseReceived(event => { + var response = event.params.response; + var filename = response.url.split('/').pop(); + var id = getInterceptionId(filename); + this._log(id, 'Network.responseReceived ' + filename + ' ' + response.status + ' ' + response.mimeType); + }); + + this._session.protocol.Runtime.onConsoleAPICalled(messageObject => { + if (messageObject.params.type !== 'log') + return; + this._consoleLogs.push(messageObject.params.args[0].value); + numConsoleLogsToWaitFor--; + maybeCompleteTest(); + }); + + this._session.protocol.Page.onFrameStoppedLoading(() => { + frameStoppedLoading = true; + this._log(this._getNextId(), 'Page.frameStoppedLoading'); + maybeCompleteTest(); + }); + + this._testRunner.log('Test started'); + this._session.protocol.Network.enable(); + this._testRunner.log('Network agent enabled'); + await this._session.protocol.Network.setRequestInterceptionEnabled({enabled: true}); + this._testRunner.log('Request interception enabled'); + await this._session.protocol.Page.enable(); + this._testRunner.log('Page agent enabled'); + await this._session.protocol.Runtime.enable(); + this._testRunner.log('Runtime agent enabled'); + } + + allowRequest(event) { + var id = this._canonicalId(event.params.interceptionId); + this._log(id, 'allowRequest ' + id); + this._session.protocol.Network.continueInterceptedRequest({interceptionId: event.params.interceptionId}); + } + + modifyRequest(event, params) { + var id = this._canonicalId(event.params.interceptionId); var mods = []; - for (property in params) { - if (!params.hasOwnProperty(property)) - continue; - if (property === "url") { - var newUrl = params["url"]; - var filename = interceptionRequestParams[id].url; - mods.push("url " + filename.split('/').pop() + " -> " + newUrl); - var directoryPath = - filename.substring(0, filename.lastIndexOf('/') + 1); - params["url"] = directoryPath + newUrl; - } else { - mods.push(property + " " + - JSON.stringify(interceptionRequestParams[id][property]) + - " -> " + JSON.stringify(params[property])); - } + for (var property in params) { + if (!params.hasOwnProperty(property)) + continue; + if (property === 'url') { + var newUrl = params['url']; + var filename = this._interceptionRequestParams[id].url; + mods.push('url ' + filename.split('/').pop() + ' -> ' + newUrl); + var directoryPath = filename.substring(0, filename.lastIndexOf('/') + 1); + params['url'] = directoryPath + newUrl; + } else { + mods.push(property + ' ' + + JSON.stringify(this._interceptionRequestParams[id][property]) + + ' -> ' + JSON.stringify(params[property])); + } } - log(id, "modifyRequest " + id + ": " + mods.join("; ")); - params["interceptionId"] = event.params.interceptionId; - InspectorTest.sendCommand("Network.continueInterceptedRequest", params); -} + this._log(id, 'modifyRequest ' + id + ': ' + mods.join('; ')); + params['interceptionId'] = event.params.interceptionId; + this._session.protocol.Network.continueInterceptedRequest(params); + } -InspectorTest.blockRequest = function(event, errorReason) { - var id = canonicalId(event.params.interceptionId); - log(id, "blockRequest " + id + " " + errorReason); - InspectorTest.sendCommand("Network.continueInterceptedRequest", { - "interceptionId": event.params.interceptionId, - "errorReason": errorReason + blockRequest(event, errorReason) { + var id = this._canonicalId(event.params.interceptionId); + this._log(id, 'blockRequest ' + id + ' ' + errorReason); + this._session.protocol.Network.continueInterceptedRequest({interceptionId: event.params.interceptionId, errorReason}); + } + + mockResponse(event, rawResponse) { + var id = this._canonicalId(event.params.interceptionId); + this._log(id, 'mockResponse ' + id); + rawResponse = btoa(rawResponse); + this._session.protocol.Network.continueInterceptedRequest({interceptionId: event.params.interceptionId, rawResponse}); + } + + disableRequestInterception(event) { + var id = this._canonicalId(event.params.interceptionId); + this._log(id, '----- disableRequestInterception -----'); + this._session.protocol.Network.setRequestInterceptionEnabled({enabled: false}); + } + + cancelAuth(event) { + var id = this._canonicalId(event.params.interceptionId); + this._log(id, '----- Cancel Auth -----'); + this._session.protocol.Network.continueInterceptedRequest({interceptionId: event.params.interceptionId, authChallengeResponse: {response: 'CancelAuth'}}); + } + + defaultAuth(event) { + var id = this._canonicalId(event.params.interceptionId); + this._log(id, '----- Use Default Auth -----'); + this._session.protocol.Network.continueInterceptedRequest({interceptionId: event.params.interceptionId, authChallengeResponse: {response: 'Default'}}); + } + + provideAuthCredentials(event, username, password) { + var id = this._canonicalId(event.params.interceptionId); + this._log(id, '----- Provide Auth Credentials -----'); + this._session.protocol.Network.continueInterceptedRequest({ + interceptionId: event.params.interceptionId, + authChallengeResponse: { response: 'ProvideCredentials', username: username, password: password } }); -} - -InspectorTest.mockResponse = function(event, rawResponse) { - var id = canonicalId(event.params.interceptionId); - log(id, "mockResponse " + id); - InspectorTest.sendCommand("Network.continueInterceptedRequest", { - "interceptionId": event.params.interceptionId, - "rawResponse": btoa(rawResponse) - }); -} - -InspectorTest.disableRequestInterception = function(event) { - var id = canonicalId(event.params.interceptionId); - log(id, "----- disableRequestInterception -----"); - InspectorTest.sendCommand("Network.setRequestInterceptionEnabled", { - "enabled": false, - }); -} - -InspectorTest.cancelAuth = function(event) { - var id = canonicalId(event.params.interceptionId); - log(id, "----- Cancel Auth -----"); - InspectorTest.sendCommand("Network.continueInterceptedRequest", { - "interceptionId": event.params.interceptionId, - "authChallengeResponse": {"response": "CancelAuth"} - }); -} - -InspectorTest.defaultAuth = function(event) { - var id = canonicalId(event.params.interceptionId); - log(id, "----- Use Default Auth -----"); - InspectorTest.sendCommand("Network.continueInterceptedRequest", { - "interceptionId": event.params.interceptionId, - "authChallengeResponse": {"response": "Default"} - }); -} - -InspectorTest.provideAuthCredentials = function(event, username, password) { - var id = canonicalId(event.params.interceptionId); - log(id, "----- Provide Auth Credentials -----"); - InspectorTest.sendCommand("Network.continueInterceptedRequest", { - "interceptionId": event.params.interceptionId, - "authChallengeResponse": { - "response": "ProvideCredentials", - "username": username, - "password": password - } - }); -} - -} + } +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/mixed-content-type-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/mixed-content-type-test.js index c189669..6ef9827 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/mixed-content-type-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/mixed-content-type-test.js
@@ -1,29 +1,15 @@ -if (window.testRunner) { - testRunner.overridePreference("WebKitAllowRunningInsecureContent", true); -} +(async function mixedContentTest(testRunner, session, addIframeWithMixedContent) { + await session.evaluate(`testRunner.overridePreference('WebKitAllowRunningInsecureContent', true)`); + await session.protocol.Network.enable(); + testRunner.log('Network agent enabled'); + session.evaluate(addIframeWithMixedContent); -function test() -{ - InspectorTest.eventHandler["Network.requestWillBeSent"] = onRequestWillBeSent; - InspectorTest.sendCommand("Network.enable", {}, didEnableNetwork); - - function didEnableNetwork(messageObject) - { - if (messageObject.error) { - InspectorTest.log("FAIL: Couldn't enable network agent" + messageObject.error.message); - InspectorTest.completeTest(); - return; - } - InspectorTest.log("Network agent enabled"); - InspectorTest.sendCommand("Runtime.evaluate", { "expression": "addIframeWithMixedContent()" }); - } - - var numRequests = 0; - function onRequestWillBeSent(event) { - var req = event.params.request; - InspectorTest.log("Mixed content type of " + req.url + ": " + req.mixedContentType); - numRequests++; - if (numRequests == 2) - InspectorTest.completeTest(); - } -} + var numRequests = 0; + session.protocol.Network.onRequestWillBeSent(event => { + var req = event.params.request; + testRunner.log('Mixed content type of ' + req.url + ': ' + req.mixedContentType); + numRequests++; + if (numRequests == 2) + testRunner.completeTest(); + }); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/reload-memory-cache.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/reload-memory-cache.html new file mode 100644 index 0000000..eb45331 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/reload-memory-cache.html
@@ -0,0 +1 @@ +<script src='blank.js'></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame-expected.txt index b8d2add..e8d311e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame-expected.txt
@@ -1 +1,2 @@ -Tests that Runtime.getProperties doesn't crash on window.frames[0]. Should not crash. +Tests that Runtime.getProperties doesn't crash on window.frames[0]. Should not crash. +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame.html deleted file mode 100644 index f6039b14..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame.html +++ /dev/null
@@ -1,18 +0,0 @@ -<html> -<head> -<script type="text/javascript" src="./resources/inspector-protocol-test.js"></script> -<script> -function test() -{ - InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "window.frames[0]" }) - .then((message) => InspectorTest.sendCommandPromise("Runtime.getProperties", { objectId: message.result.result.objectId })) - .then(() => InspectorTest.completeTest()); -} -</script> -</head> -<body> -Tests that Runtime.getProperties doesn't crash on window.frames[0]. Should not crash. -<iframe src="data:text/plain, <b>bold</b>" onload="runTest()"></iframe> -</body> -</html> -
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame.js new file mode 100644 index 0000000..f441b6ef --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/runtime-get-properties-doesnt-crash-on-window-frame.js
@@ -0,0 +1,15 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests that Runtime.getProperties doesn't crash on window.frames[0]. Should not crash.`); + + await session.evaluateAsync(` + var frame = document.createElement('iframe'); + frame.src = 'data:text/plain, <b>bold</b>'; + document.body.appendChild(frame); + new Promise(f => frame.onload = f); + `); + + var response = await dp.Runtime.evaluate({expression: 'window.frames[0]'}); + await dp.Runtime.getProperties({objectId: response.result.result.objectId}); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override-expected.txt index 2bc3af4..089a63f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override-expected.txt
@@ -1,5 +1,4 @@ Tests that WebSocket headers are set properly from overriden User Agent. - Test started Enabling network Network enabled
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override.html deleted file mode 100644 index fcd8adc..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override.html +++ /dev/null
@@ -1,52 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script src="../resources/inspector-protocol-test.js"></script> -<script> -var ws; -function openWebSocket(url) -{ - ws = new WebSocket(url); -} - -function test() -{ - var url = "ws://localhost:8880/echo"; - var userAgentString = "Mozilla/5.0 (Overridden User Agent)"; - - InspectorTest.log("Test started"); - InspectorTest.eventHandler["Network.webSocketWillSendHandshakeRequest"] = onWillSendRequest - enableNetwork(); - - function enableNetwork() - { - InspectorTest.log("Enabling network"); - InspectorTest.sendCommandOrDie("Network.enable", {}, didEnableNetwork); - } - - function didEnableNetwork() - { - InspectorTest.log("Network enabled"); - InspectorTest.log("Setting User Agent Override to: " + userAgentString); - InspectorTest.sendCommandOrDie("Network.setUserAgentOverride", { "userAgent": userAgentString }, didSetUserAgent); - } - - function didSetUserAgent() - { - InspectorTest.log("User Agent Set"); - InspectorTest.log("Sending command to open websocket"); - InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": 'openWebSocket("' + url + '")'}); - } - - function onWillSendRequest(request) - { - InspectorTest.log("User agent is: " + request.params.request.headers["User-Agent"]); - InspectorTest.completeTest(); - } -} -</script> -</head> -<body onload="runTest();"> -<p>Tests that WebSocket headers are set properly from overriden User Agent.</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override.js new file mode 100644 index 0000000..9dc4316 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/websocket/websocket-user-agent-override.js
@@ -0,0 +1,23 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank( + `Tests that WebSocket headers are set properly from overriden User Agent.`); + + var url = 'ws://localhost:8880/echo'; + var userAgentString = 'Mozilla/5.0 (Overridden User Agent)'; + + testRunner.log('Test started'); + testRunner.log('Enabling network'); + await dp.Network.enable(); + testRunner.log('Network enabled'); + testRunner.log('Setting User Agent Override to: ' + userAgentString); + await dp.Network.setUserAgentOverride({userAgent: userAgentString }); + testRunner.log('User Agent Set'); + testRunner.log('Sending command to open websocket'); + session.evaluate(` + window.ws = new WebSocket('${url}'); + `); + + var request = await dp.Network.onceWebSocketWillSendHandshakeRequest(); + testRunner.log('User agent is: ' + request.params.request.headers['User-Agent']); + testRunner.completeTest(); +})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-add-rule.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-add-rule.html index 810607c..74a8c850 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-add-rule.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-add-rule.html
@@ -1,9 +1,9 @@ <html> <head> <link rel="stylesheet" href="resources/add-rule.css"/> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-collect-class-names.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-collect-class-names.html index 5a84096..f8549de 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-collect-class-names.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-collect-class-names.html
@@ -1,8 +1,8 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-coverage-poll.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-coverage-poll.html index 320668cb..f2b3e3d0 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-coverage-poll.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-coverage-poll.html
@@ -1,8 +1,8 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function loadStylesheet(url)
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-create-stylesheet-and-add-rule.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-create-stylesheet-and-add-rule.html index ebbb901..3c6b406 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-create-stylesheet-and-add-rule.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-create-stylesheet-and-add-rule.html
@@ -1,8 +1,8 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <link rel="stylesheet" type="text/css" href="resources/stylesheet.css"></link> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-fonts-updated-event.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-fonts-updated-event.html index 08835642..f2409e3a 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-fonts-updated-event.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-fonts-updated-event.html
@@ -1,9 +1,9 @@ <html> <head> <link rel="stylesheet"> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function loadWebFont()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-background-colors.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-background-colors.html index 18be150..69f332b 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-background-colors.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-background-colors.html
@@ -1,9 +1,9 @@ <html> <head> <script type="text/javascript" src="../../http/tests/inspector-protocol/inspector-test.js"></script> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> <script> function test() { if (!InspectorTest)
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-keyframes.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-keyframes.html index 9908c24..9442b40 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-keyframes.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-keyframes.html
@@ -1,8 +1,8 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <link rel="stylesheet" type="text/css" href="resources/keyframes.css"></link> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-media-queries.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-media-queries.html index 01667e7..bf40459 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-media-queries.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-media-queries.html
@@ -1,6 +1,6 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> <script type="text/javascript"> function test() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-platform-fonts.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-platform-fonts.html index 3865811..376ce31 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-platform-fonts.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-platform-fonts.html
@@ -1,8 +1,8 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-rule-list.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-rule-list.html index a9e495ca..5d4c500 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-rule-list.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-get-rule-list.html
@@ -1,8 +1,8 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-effective-property-value.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-effective-property-value.html index edd551fa..73fc9c5 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-effective-property-value.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-effective-property-value.html
@@ -1,9 +1,9 @@ <html> <head> <link rel="stylesheet" href="resources/set-active-property-value.css"/> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-inline-style-text.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-inline-style-text.html index 68a48748..3fb5c88 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-inline-style-text.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-inline-style-text.html
@@ -1,9 +1,9 @@ <html> <head> <link rel="stylesheet" href="resources/set-style-text.css"/> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-inline-styleSheetText.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-inline-styleSheetText.html index 9c110a2e..e92b9bc 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-inline-styleSheetText.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-inline-styleSheetText.html
@@ -1,6 +1,6 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-media-text.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-media-text.html index 0ce4d79..8231416 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-media-text.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-media-text.html
@@ -1,7 +1,7 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> <script type="text/javascript"> function test() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-multiple-style-texts-correct-ranges.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-multiple-style-texts-correct-ranges.html index 67720537..c3dbe11c 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-multiple-style-texts-correct-ranges.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-multiple-style-texts-correct-ranges.html
@@ -1,9 +1,9 @@ <html> <head> <link rel="stylesheet" href="resources/set-style-text.css"/> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-multiple-style-texts.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-multiple-style-texts.html index 7ed9da75..ede30cc 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-multiple-style-texts.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-multiple-style-texts.html
@@ -1,9 +1,9 @@ <html> <head> <link rel="stylesheet" href="resources/set-style-text.css"/> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-rule-selector.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-rule-selector.html index 87ec433c..5122324 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-rule-selector.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-rule-selector.html
@@ -1,7 +1,7 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> <script type="text/javascript"> function test() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-style-text.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-style-text.html index c62118b..b51660d 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-style-text.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-set-style-text.html
@@ -1,9 +1,9 @@ <html> <head> <link rel="stylesheet" href="resources/set-style-text.css"/> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function removeRule()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-dom-inherits-styles.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-dom-inherits-styles.html index 9bcfa66..8bd41c9 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-dom-inherits-styles.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-dom-inherits-styles.html
@@ -1,9 +1,9 @@ <!DOCTYPE html> <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-host-content-selector.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-host-content-selector.html index b2160ab..adc01dcc 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-host-content-selector.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-host-content-selector.html
@@ -1,9 +1,9 @@ <!DOCTYPE html> <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-host-rule.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-host-rule.html index a4b13a15..44acb03 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-host-rule.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/css-shadow-host-rule.html
@@ -1,8 +1,8 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test() {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-matching-rules-multiple.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-matching-rules-multiple.html index 3dea943..c57082ad 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-matching-rules-multiple.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-matching-rules-multiple.html
@@ -39,9 +39,9 @@ } </style> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-matching-rules.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-matching-rules.html index 2df8b63..a167a3281 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-matching-rules.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-matching-rules.html
@@ -35,9 +35,9 @@ } </style> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-modify-rule-and-get-rule-list.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-modify-rule-and-get-rule-list.html index 66e3fd9..ca1a5e5 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-modify-rule-and-get-rule-list.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/cssom-modify-rule-and-get-rule-list.html
@@ -15,9 +15,9 @@ } </style> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/css-protocol-test.js"></script> +<script type="text/javascript" src="resources/dom-protocol-test.js"></script> <script type="text/javascript"> function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/media-query-listener-exception.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/media-query-listener-exception.html index 1ed5746a..8245884 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/media-query-listener-exception.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/media-query-listener-exception.html
@@ -1,6 +1,6 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> <script> if (window.testRunner) { testRunner.dumpAsText();
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/pseudo-element-matching-selectors.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/pseudo-element-matching-selectors.html index e15d786..cd21020 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/css/pseudo-element-matching-selectors.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/pseudo-element-matching-selectors.html
@@ -1,6 +1,6 @@ <html> <head> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="resources/inspector-protocol-test.js"></script> <script> function addBeforeElement()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/css-protocol-test.js b/third_party/WebKit/LayoutTests/inspector-protocol/css/resources/css-protocol-test.js similarity index 100% rename from third_party/WebKit/LayoutTests/inspector-protocol/resources/css-protocol-test.js rename to third_party/WebKit/LayoutTests/inspector-protocol/css/resources/css-protocol-test.js
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/dom-protocol-test.js b/third_party/WebKit/LayoutTests/inspector-protocol/css/resources/dom-protocol-test.js similarity index 100% rename from third_party/WebKit/LayoutTests/inspector-protocol/resources/dom-protocol-test.js rename to third_party/WebKit/LayoutTests/inspector-protocol/css/resources/dom-protocol-test.js
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/css/resources/inspector-protocol-test.js b/third_party/WebKit/LayoutTests/inspector-protocol/css/resources/inspector-protocol-test.js new file mode 100644 index 0000000..6dd8c3e --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/css/resources/inspector-protocol-test.js
@@ -0,0 +1,164 @@ +/* + * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * Copyright (C) 2013 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var initialize_InspectorTest = function() { + +InspectorTest.evaluateInInspectedPage = function(expression, callback) +{ + InspectorTest.sendCommand("Runtime.evaluate", { expression: expression }, callback); +} + +InspectorTest.parseURL = function(url) +{ + var result = {}; + var match = url.match(/^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i); + if (!match) + return result; + result.scheme = match[1].toLowerCase(); + result.host = match[2]; + result.port = match[3]; + result.path = match[4] || "/"; + result.fragment = match[5]; + return result; +} + +} + +var outputElement; + +/** + * Logs message to process stdout via alert (hopefully implemented with immediate flush). + * @param {string} text + */ +function debugLog(text) +{ + alert(text); +} + +/** + * @param {string} text + */ +function log(text) +{ + if (!outputElement) { + var intermediate = document.createElement("div"); + document.body.appendChild(intermediate); + + var intermediate2 = document.createElement("div"); + intermediate.appendChild(intermediate2); + + outputElement = document.createElement("div"); + outputElement.className = "output"; + outputElement.id = "output"; + outputElement.style.whiteSpace = "pre"; + intermediate2.appendChild(outputElement); + } + outputElement.appendChild(document.createTextNode(text)); + outputElement.appendChild(document.createElement("br")); +} + +function closeTest() +{ + closeInspector(); + testRunner.notifyDone(); +} + +var reloadParam = "__protocol__test__reload__"; + +function runTest() +{ + if (!window.testRunner) { + console.error("This test requires DumpRenderTree"); + return; + } + + var reloadIndex = window.location.href.lastIndexOf(reloadParam); + if (reloadIndex !== -1) { + var lastId = window.location.href.substring(reloadIndex + reloadParam.length); + window.lastFrontendEvalId = parseInt(lastId, 10); + evaluateInFrontend("InspectorTest.pageReloaded();"); + return; + } + + testRunner.dumpAsText(); + testRunner.waitUntilDone(); + testRunner.setCanOpenWindows(true); + + openInspector(); +} + +function closeInspector() +{ + testRunner.closeWebInspector(); +} + +var lastFrontendEvalId = 0; +function evaluateInFrontend(script) +{ + testRunner.evaluateInWebInspector(++lastFrontendEvalId, script); +} + +function navigateProtocolTest(url) +{ + url += (url.indexOf("?") === -1 ? "?" : "&") + reloadParam + lastFrontendEvalId; + window.location.replace(url); +} + +function prepareForReload() +{ + window.location += "#" + reloadParam + lastFrontendEvalId; +} + +function openInspector() +{ + var scriptTags = document.getElementsByTagName("script"); + var scriptUrlBasePath = ""; + for (var i = 0; i < scriptTags.length; ++i) { + var index = scriptTags[i].src.lastIndexOf("/resources/inspector-protocol-test.js"); + if (index > -1 ) { + scriptUrlBasePath = scriptTags[i].src.slice(0, index); + break; + } + } + + var dummyFrontendURL = scriptUrlBasePath + "/resources/protocol-test.html"; + testRunner.showWebInspector("", dummyFrontendURL); + // FIXME: rename this 'test' global field across all tests. + var testFunction = window.test; + if (typeof testFunction === "function") { + var initializers = ""; + for (var symbol in window) { + if (!/^initialize_/.test(symbol) || typeof window[symbol] !== "function") + continue; + initializers += "(" + window[symbol].toString() + ")();\n"; + } + evaluateInFrontend(initializers + "(" + testFunction.toString() +")();"); + return; + } + // Kill waiting process if failed to send. + alert("Failed to send test function"); + testRunner.notifyDone(); +}
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/protocol-test.html b/third_party/WebKit/LayoutTests/inspector-protocol/css/resources/protocol-test.html similarity index 100% rename from third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/protocol-test.html rename to third_party/WebKit/LayoutTests/inspector-protocol/css/resources/protocol-test.html
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/cjk-ideograph-fallback-by-lang.html b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/cjk-ideograph-fallback-by-lang.html index d408f63..aede069c 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/cjk-ideograph-fallback-by-lang.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/cjk-ideograph-fallback-by-lang.html
@@ -2,9 +2,9 @@ <html> <meta charset="UTF-8"> <head> - <script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> - <script type="text/javascript" src="../resources/css-protocol-test.js"></script> - <script type="text/javascript" src="../resources/dom-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/inspector-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/css-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/dom-protocol-test.js"></script> <script type="text/javascript" src="resources/layout-font-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/fallback-myanmar.html b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/fallback-myanmar.html index 7a71087..e8a37f4 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/fallback-myanmar.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/fallback-myanmar.html
@@ -2,9 +2,9 @@ <html> <meta charset="UTF-8"> <head> - <script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> - <script type="text/javascript" src="../resources/css-protocol-test.js"></script> - <script type="text/javascript" src="../resources/dom-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/inspector-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/css-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/dom-protocol-test.js"></script> <script type="text/javascript" src="resources/layout-font-test.js"></script> </head> <script>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/generic-system-ui.html b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/generic-system-ui.html index e38bbab5..564d774f 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/generic-system-ui.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/generic-system-ui.html
@@ -1,7 +1,7 @@ <!DOCTYPE html> -<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> -<script type="text/javascript" src="../resources/css-protocol-test.js"></script> -<script type="text/javascript" src="../resources/dom-protocol-test.js"></script> +<script type="text/javascript" src="../css/resources/inspector-protocol-test.js"></script> +<script type="text/javascript" src="../css/resources/css-protocol-test.js"></script> +<script type="text/javascript" src="../css/resources/dom-protocol-test.js"></script> <script type="text/javascript" src="resources/layout-font-test.js"></script> <style> .test {
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.html b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.html index 6f1e00f..a8a9290c 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/languages-emoji-rare-glyphs.html
@@ -2,9 +2,9 @@ <html> <meta charset="UTF-8"> <head> - <script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> - <script type="text/javascript" src="../resources/css-protocol-test.js"></script> - <script type="text/javascript" src="../resources/dom-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/inspector-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/css-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/dom-protocol-test.js"></script> <script type="text/javascript" src="resources/layout-font-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/ogham.html b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/ogham.html index 7f98133..cb4d930 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/ogham.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/ogham.html
@@ -2,9 +2,9 @@ <html> <meta charset="UTF-8"> <head> - <script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> - <script type="text/javascript" src="../resources/css-protocol-test.js"></script> - <script type="text/javascript" src="../resources/dom-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/inspector-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/css-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/dom-protocol-test.js"></script> <script type="text/javascript" src="resources/layout-font-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/tifinagh.html b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/tifinagh.html index b18e2ff..0337823 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/tifinagh.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/tifinagh.html
@@ -2,9 +2,9 @@ <html> <meta charset="UTF-8"> <head> - <script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> - <script type="text/javascript" src="../resources/css-protocol-test.js"></script> - <script type="text/javascript" src="../resources/dom-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/inspector-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/css-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/dom-protocol-test.js"></script> <script type="text/javascript" src="resources/layout-font-test.js"></script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.html b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.html index 95d4173ff..d49feb729 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.html
@@ -2,9 +2,9 @@ <html> <meta charset="UTF-8"> <head> - <script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> - <script type="text/javascript" src="../resources/css-protocol-test.js"></script> - <script type="text/javascript" src="../resources/dom-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/inspector-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/css-protocol-test.js"></script> + <script type="text/javascript" src="../css/resources/dom-protocol-test.js"></script> <script type="text/javascript" src="resources/layout-font-test.js"></script> <style type="text/css">
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.html b/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.html index 69b5a0d..b16487e 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.html
@@ -5,6 +5,6 @@ --> <html> <head> -<script src="inspector-protocol-test.js"></script> +<script src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script> </head> </html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.js b/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.js deleted file mode 100644 index f2c60bad..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/resources/inspector-protocol-test.js +++ /dev/null
@@ -1,485 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var TestRunner = class { - constructor(baseURL, log, completeTest, fetch) { - this._dumpInspectorProtocolMessages = false; - this._baseURL = baseURL; - this._log = log; - this._completeTest = completeTest; - this._fetch = fetch; - } - - startDumpingProtocolMessages() { - this._dumpInspectorProtocolMessages = true; - }; - - completeTest() { - this._completeTest.call(null); - } - - log(text) { - this._log.call(null, text); - } - - logMessage(originalMessage, title) { - var message = JSON.parse(JSON.stringify(originalMessage)); - if (message.id) - message.id = '<messageId>'; - const nonStableFields = new Set(['nodeId', 'objectId', 'scriptId', 'timestamp', 'backendNodeId', 'parentId', 'frameId', 'baseURL', 'documentURL']); - var objects = [message]; - while (objects.length) { - var object = objects.shift(); - for (var key in object) { - if (nonStableFields.has(key)) - object[key] = `<${key}>`; - else if (typeof object[key] === 'string' && object[key].match(/\d+:\d+:\d+:debug/)) - object[key] = object[key].replace(/\d+/, '<scriptId>'); - else if (typeof object[key] === 'object') - objects.push(object[key]); - } - } - this.logObject(message, title); - return originalMessage; - } - - logObject(object, title) { - var lines = []; - - function dumpValue(value, prefix, prefixWithName) { - if (typeof value === 'object' && value !== null) { - if (value instanceof Array) - dumpItems(value, prefix, prefixWithName); - else - dumpProperties(value, prefix, prefixWithName); - } else { - lines.push(prefixWithName + String(value).replace(/\n/g, ' ')); - } - } - - function dumpProperties(object, prefix, firstLinePrefix) { - prefix = prefix || ''; - firstLinePrefix = firstLinePrefix || prefix; - lines.push(firstLinePrefix + '{'); - - var propertyNames = Object.keys(object); - propertyNames.sort(); - for (var i = 0; i < propertyNames.length; ++i) { - var name = propertyNames[i]; - if (!object.hasOwnProperty(name)) - continue; - var prefixWithName = ' ' + prefix + name + ' : '; - dumpValue(object[name], ' ' + prefix, prefixWithName); - } - lines.push(prefix + '}'); - } - - function dumpItems(object, prefix, firstLinePrefix) { - prefix = prefix || ''; - firstLinePrefix = firstLinePrefix || prefix; - lines.push(firstLinePrefix + '['); - for (var i = 0; i < object.length; ++i) - dumpValue(object[i], ' ' + prefix, ' ' + prefix + '[' + i + '] : '); - lines.push(prefix + ']'); - } - - dumpValue(object, '', title || ''); - this.log(lines.join('\n')); - } - - url(relative) { - return this._baseURL + relative; - } - - async runTestSuite(testSuite) { - for (var test of testSuite) { - this.log('\nRunning test: ' + test.name); - try { - await test(); - } catch (e) { - this.log(`Error during test: ${e}\n${e.stack}`); - } - } - this.completeTest(); - } - - _checkExpectation(fail, name, messageObject) { - if (fail === !!messageObject.error) { - this.log('PASS: ' + name); - return true; - } - - this.log('FAIL: ' + name + ': ' + JSON.stringify(messageObject)); - this.completeTest(); - return false; - } - - expectedSuccess(name, messageObject) { - return this._checkExpectation(false, name, messageObject); - } - - expectedError(name, messageObject) { - return this._checkExpectation(true, name, messageObject); - } - - die(message, error) { - this.log(`${message}: ${error}\n${error.stack}`); - this.completeTest(); - throw new Error(message); - } - - fail(message) { - this.log('FAIL: ' + message); - this.completeTest(); - } - - async loadScript(url) { - var source = await this._fetch(this.url(url)); - return eval(`${source}\n//# sourceURL=${url}`); - }; - - async createPage() { - var targetId = (await DevToolsAPI._sendCommandOrDie('Target.createTarget', {url: 'about:blank'})).targetId; - await DevToolsAPI._sendCommandOrDie('Target.activateTarget', {targetId}); - var page = new TestRunner.Page(this, targetId); - var dummyURL = window.location.href; - dummyURL = dummyURL.substring(0, dummyURL.indexOf('inspector-protocol-test.html')) + 'inspector-protocol-page.html'; - await page._navigate(dummyURL); - return page; - } - - async _start(description, html, url) { - try { - this.log(description); - var page = await this.createPage(); - if (url) - await page.navigate(url); - if (html) - await page.loadHTML(html); - var session = await page.createSession(); - return { page: page, session: session, dp: session.protocol }; - } catch (e) { - this.die('Error starting the test', e); - } - }; - - startBlank(description) { - return this._start(description, null, null); - } - - startHTML(html, description) { - return this._start(description, html, null); - } - - startURL(url, description) { - return this._start(description, null, url); - } -}; - -TestRunner.Page = class { - constructor(testRunner, targetId) { - this._testRunner = testRunner; - this._targetId = targetId; - } - - async createSession() { - await DevToolsAPI._sendCommandOrDie('Target.attachToTarget', {targetId: this._targetId}); - var session = new TestRunner.Session(this); - DevToolsAPI._sessions.set(this._targetId, session); - return session; - } - - navigate(url) { - return this._navigate(this._testRunner.url(url)); - } - - async _navigate(url) { - if (DevToolsAPI._sessions.get(this._targetId)) - this._testRunner.die(`Cannot navigate to ${url} with active session`, new Error()); - - var session = await this.createSession(); - await session._navigate(url); - await session.disconnect(); - } - - async loadHTML(html) { - if (DevToolsAPI._sessions.get(this._targetId)) - this._testRunner.die('Cannot loadHTML with active session', new Error()); - - html = html.replace(/'/g, "\\'").replace(/\n/g, '\\n'); - var session = await this.createSession(); - await session.protocol.Runtime.evaluate({expression: `document.write('${html}');document.close();`}); - await session.disconnect(); - } -}; - -TestRunner.Session = class { - constructor(page) { - this._testRunner = page._testRunner; - this._page = page; - this._requestId = 0; - this._dispatchTable = new Map(); - this._eventHandlers = new Map(); - this.protocol = this._setupProtocol(); - } - - async disconnect() { - await DevToolsAPI._sendCommandOrDie('Target.detachFromTarget', {targetId: this._page._targetId}); - DevToolsAPI._sessions.delete(this._page._targetId); - } - - sendRawCommand(requestId, message) { - DevToolsAPI._sendCommandOrDie('Target.sendMessageToTarget', {targetId: this._page._targetId, message: message}); - return new Promise(f => this._dispatchTable.set(requestId, f)); - } - - sendCommand(method, params) { - var requestId = ++this._requestId; - var messageObject = {'id': requestId, 'method': method, 'params': params}; - if (this._testRunner._dumpInspectorProtocolMessages) - this._testRunner.log(`frontend => backend: ${JSON.stringify(messageObject)}`); - return this.sendRawCommand(requestId, JSON.stringify(messageObject)); - } - - async evaluate(code) { - if (typeof code === 'function') - code = `(${code.toString()})()`; - var response = await this.protocol.Runtime.evaluate({expression: code, returnByValue: true}); - if (response.error) { - this._testRunner.log(`Error while evaluating '${code}': ${response.error}`); - this._testRunner.completeTest(); - } else { - return response.result.result.value; - } - } - - async evaluateAsync(code) { - if (typeof code === 'function') - code = `(${code.toString()})()`; - var response = await this.protocol.Runtime.evaluate({expression: code, returnByValue: true, awaitPromise: true}); - if (response.error) { - this._testRunner.log(`Error while evaluating async '${code}': ${response.error}`); - this._testRunner.completeTest(); - } else { - return response.result.result.value; - } - } - - navigate(url) { - return this._navigate(this._testRunner.url(url)); - } - - async _navigate(url) { - this.protocol.Page.enable(); - this.protocol.Page.navigate({url: url}); - - var callback; - var promise = new Promise(f => callback = f); - this.protocol.Page.onFrameNavigated(message => { - if (!message.params.frame.parentId) - callback(); - }); - await Promise.all([ - promise, - this.protocol.Page.onceLoadEventFired() - ]); - } - - _dispatchMessage(message) { - if (this._testRunner._dumpInspectorProtocolMessages) - this._testRunner.log(`backend => frontend: ${JSON.stringify(message)}`); - if (typeof message.id === 'number') { - var handler = this._dispatchTable.get(message.id); - if (handler) { - this._dispatchTable.delete(message.id); - handler(message); - } - } else { - var eventName = message.method; - for (var handler of (this._eventHandlers.get(eventName) || [])) - handler(message); - } - } - - _setupProtocol() { - return new Proxy({}, { get: (target, agentName, receiver) => new Proxy({}, { - get: (target, methodName, receiver) => { - const eventPattern = /^(on(ce)?|off)([A-Z][A-Za-z0-9]+)/; - var match = eventPattern.exec(methodName); - if (!match) - return args => this.sendCommand(`${agentName}.${methodName}`, args || {}); - var eventName = match[3]; - eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1); - if (match[1] === 'once') - return eventMatcher => this._waitForEvent(`${agentName}.${eventName}`, eventMatcher); - if (match[1] === 'off') - return listener => this._removeEventHandler(`${agentName}.${eventName}`, listener); - return listener => this._addEventHandler(`${agentName}.${eventName}`, listener); - } - })}); - } - - _addEventHandler(eventName, handler) { - var handlers = this._eventHandlers.get(eventName) || []; - handlers.push(handler); - this._eventHandlers.set(eventName, handlers); - } - - _removeEventHandler(eventName, handler) { - var handlers = this._eventHandlers.get(eventName) || []; - var index = handlers.indexOf(handler); - if (index === -1) - return; - handlers.splice(index, 1); - this._eventHandlers.set(eventName, handlers); - } - - _waitForEvent(eventName, eventMatcher) { - return new Promise(callback => { - var handler = result => { - if (eventMatcher && !eventMatcher(result)) - return; - this._removeEventHandler(eventName, handler); - callback(result); - }; - this._addEventHandler(eventName, handler); - }); - } -}; - -var DevToolsAPI = {}; -DevToolsAPI._requestId = 0; -DevToolsAPI._embedderMessageId = 0; -DevToolsAPI._dispatchTable = new Map(); -DevToolsAPI._sessions = new Map(); -DevToolsAPI._outputElement = null; - -DevToolsAPI._log = function(text) { - if (!DevToolsAPI._outputElement) { - var intermediate = document.createElement('div'); - document.body.appendChild(intermediate); - var intermediate2 = document.createElement('div'); - intermediate.appendChild(intermediate2); - DevToolsAPI._outputElement = document.createElement('div'); - DevToolsAPI._outputElement.className = 'output'; - DevToolsAPI._outputElement.id = 'output'; - DevToolsAPI._outputElement.style.whiteSpace = 'pre'; - intermediate2.appendChild(DevToolsAPI._outputElement); - } - DevToolsAPI._outputElement.appendChild(document.createTextNode(text)); - DevToolsAPI._outputElement.appendChild(document.createElement('br')); -}; - -DevToolsAPI._completeTest = function() { - window.testRunner.notifyDone(); -}; - -DevToolsAPI._die = function(message, error) { - DevToolsAPI._log(`${message}: ${error}\n${error.stack}`); - DevToolsAPI._completeTest(); - throw new Error(); -}; - -DevToolsAPI.dispatchMessage = function(messageOrObject) { - var messageObject = (typeof messageOrObject === 'string' ? JSON.parse(messageOrObject) : messageOrObject); - var messageId = messageObject.id; - try { - if (typeof messageId === 'number') { - var handler = DevToolsAPI._dispatchTable.get(messageId); - if (handler) { - DevToolsAPI._dispatchTable.delete(messageId); - handler(messageObject); - } - } else { - var eventName = messageObject.method; - if (eventName === 'Target.receivedMessageFromTarget') { - var targetId = messageObject.params.targetId; - var message = messageObject.params.message; - var session = DevToolsAPI._sessions.get(targetId); - if (session) - session._dispatchMessage(JSON.parse(message)); - } - } - } catch(e) { - DevToolsAPI._die(`Exception when dispatching message\n${JSON.stringify(messageObject)}`, e); - } -}; - -DevToolsAPI._sendCommand = function(method, params) { - var requestId = ++DevToolsAPI._requestId; - var messageObject = {'id': requestId, 'method': method, 'params': params}; - var embedderMessage = {'id': ++DevToolsAPI._embedderMessageId, 'method': 'dispatchProtocolMessage', 'params': [JSON.stringify(messageObject)]}; - DevToolsHost.sendMessageToEmbedder(JSON.stringify(embedderMessage)); - return new Promise(f => DevToolsAPI._dispatchTable.set(requestId, f)); -}; - -DevToolsAPI._sendCommandOrDie = function(method, params) { - return DevToolsAPI._sendCommand(method, params).then(message => { - if (message.error) - DevToolsAPI._die('Error communicating with harness', new Error(message.error)); - return message.result; - }); -}; - -function debugTest(testFunction) { - var dispatch = DevToolsAPI.dispatchMessage; - var messages = []; - DevToolsAPI.dispatchMessage = message => { - if (!messages.length) { - setTimeout(() => { - for (var message of messages.splice(0)) - dispatch(message); - }, 0); - } - messages.push(message); - }; - return testRunner => { - testRunner.log = console.log; - testRunner.completeTest = () => console.log('Test completed'); - window.test = () => testFunction(testRunner); - }; -}; - -DevToolsAPI._fetch = function(url) { - return new Promise(fulfill => { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.onreadystatechange = e => { - if (xhr.readyState !== XMLHttpRequest.DONE) - return; - if ([0, 200, 304].indexOf(xhr.status) === -1) // Testing harness file:/// results in 0. - DevToolsAPI._die(`${xhr.status} while fetching ${url}`, new Error()); - else - fulfill(e.target.response); - }; - xhr.send(null); - }); -}; - -window.testRunner.dumpAsText(); -window.testRunner.waitUntilDone(); -window.testRunner.setCanOpenWindows(true); - -window.addEventListener('load', () => { - var testScriptURL = window.location.search.substring(1); - var baseURL = testScriptURL.substring(0, testScriptURL.lastIndexOf('/') + 1); - DevToolsAPI._fetch(testScriptURL).then(testScript => { - var testRunner = new TestRunner(baseURL, DevToolsAPI._log, DevToolsAPI._completeTest, DevToolsAPI._fetch); - var testFunction = eval(`${testScript}\n//# sourceURL=${testScriptURL}`); - return testFunction(testRunner); - }).catch(reason => { - DevToolsAPI._log(`Error while executing test script: ${reason}\n${reason.stack}`); - DevToolsAPI._completeTest(); - }); -}, false); - -window['onerror'] = (message, source, lineno, colno, error) => { - DevToolsAPI._log(`${error}\n${error.stack}`); - DevToolsAPI._completeTest(); -}; - -window.addEventListener('unhandledrejection', e => { - DevToolsAPI._log(`Promise rejection: ${e.reason}\n${e.reason ? e.reason.stack : ''}`); - DevToolsAPI._completeTest(); -}, false);
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/fixed-right-bottom-in-page-scale.html b/third_party/WebKit/LayoutTests/paint/invalidation/fixed-right-bottom-in-page-scale.html index 56d17a6d..bea3c68 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/fixed-right-bottom-in-page-scale.html +++ b/third_party/WebKit/LayoutTests/paint/invalidation/fixed-right-bottom-in-page-scale.html
@@ -11,7 +11,9 @@ function scroll() { // Fully scroll to bring the fixed pos rect into view. - window.scrollTo(500, 1700); + window.scrollTo(100, 1400); + if (window.internals) + internals.setVisualViewportOffset(400, 300); } function scaleWithEventSender() {
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/http/tests/inspector-protocol/network-data-length-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/http/tests/inspector-protocol/network-data-length-expected.txt index 6fadd47c..2a9d867 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/http/tests/inspector-protocol/network-data-length-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/http/tests/inspector-protocol/network-data-length-expected.txt
@@ -1,5 +1,4 @@ Ensures that data and header length sent from protocol is proper sizes - Test started Network agent enabled
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt index 6fadd47c..2a9d867 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt
@@ -1,5 +1,4 @@ Ensures that data and header length sent from protocol is proper sizes - Test started Network agent enabled
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/http/tests/inspector-protocol/network-data-length-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/http/tests/inspector-protocol/network-data-length-expected.txt index 6fadd47c..2a9d867 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/http/tests/inspector-protocol/network-data-length-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/http/tests/inspector-protocol/network-data-length-expected.txt
@@ -1,5 +1,4 @@ Ensures that data and header length sent from protocol is proper sizes - Test started Network agent enabled
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt index 6fadd47c..2a9d867 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt
@@ -1,5 +1,4 @@ Ensures that data and header length sent from protocol is proper sizes - Test started Network agent enabled
diff --git a/third_party/WebKit/LayoutTests/platform/mac/http/tests/inspector-protocol/network-data-length-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/http/tests/inspector-protocol/network-data-length-expected.txt index 863563a..cf83be2a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/http/tests/inspector-protocol/network-data-length-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/http/tests/inspector-protocol/network-data-length-expected.txt
@@ -1,5 +1,4 @@ Ensures that data and header length sent from protocol is proper sizes - Test started Network agent enabled
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt index 863563a..cf83be2a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/inspector-protocol/network-data-length-expected.txt
@@ -1,5 +1,4 @@ Ensures that data and header length sent from protocol is proper sizes - Test started Network agent enabled
diff --git a/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.cpp b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.cpp index ca88ac0c..add8980 100644 --- a/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.cpp
@@ -5,6 +5,7 @@ #include "core/exported/WebInputMethodControllerImpl.h" #include "core/InputTypeNames.h" +#include "core/dom/Document.h" #include "core/dom/UserGestureIndicator.h" #include "core/editing/CompositionUnderlineVectorBuilder.h" #include "core/editing/EditingUtilities.h" @@ -138,6 +139,14 @@ return GetFrame()->GetInputMethodController().TextInputType(); } +WebRange WebInputMethodControllerImpl::GetSelectionOffsets() const { + // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets + // needs to be audited. See http://crbug.com/590369 for more details. + GetFrame()->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); + + return GetFrame()->GetInputMethodController().GetSelectionOffsets(); +} + LocalFrame* WebInputMethodControllerImpl::GetFrame() const { return web_frame_->GetFrame(); }
diff --git a/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h index 944e919e..3b47381d 100644 --- a/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h +++ b/third_party/WebKit/Source/core/exported/WebInputMethodControllerImpl.h
@@ -43,6 +43,7 @@ ConfirmCompositionBehavior selection_behavior) override; WebTextInputInfo TextInputInfo() override; WebTextInputType TextInputType() override; + WebRange GetSelectionOffsets() const; DECLARE_TRACE();
diff --git a/third_party/WebKit/Source/core/exported/WebSettingsImpl.cpp b/third_party/WebKit/Source/core/exported/WebSettingsImpl.cpp index f1f19e6..cec1daf2 100644 --- a/third_party/WebKit/Source/core/exported/WebSettingsImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebSettingsImpl.cpp
@@ -169,10 +169,6 @@ settings_->SetInlineTextBoxAccessibilityEnabled(enabled); } -void WebSettingsImpl::SetInertVisualViewport(bool enabled) { - settings_->SetInertVisualViewport(enabled); -} - void WebSettingsImpl::SetDeviceScaleAdjustment(float device_scale_adjustment) { dev_tools_emulator_->SetDeviceScaleAdjustment(device_scale_adjustment); }
diff --git a/third_party/WebKit/Source/core/exported/WebSettingsImpl.h b/third_party/WebKit/Source/core/exported/WebSettingsImpl.h index 11b3df7..92dbea6 100644 --- a/third_party/WebKit/Source/core/exported/WebSettingsImpl.h +++ b/third_party/WebKit/Source/core/exported/WebSettingsImpl.h
@@ -106,7 +106,6 @@ void SetImageAnimationPolicy(ImageAnimationPolicy) override; void SetImagesEnabled(bool) override; void SetInlineTextBoxAccessibilityEnabled(bool) override; - void SetInertVisualViewport(bool) override; void SetJavaScriptCanAccessClipboard(bool) override; void SetJavaScriptEnabled(bool) override; void SetLoadsImagesAutomatically(bool) override;
diff --git a/third_party/WebKit/Source/core/exported/WebViewTest.cpp b/third_party/WebKit/Source/core/exported/WebViewTest.cpp index b39bc418..e355fd0 100644 --- a/third_party/WebKit/Source/core/exported/WebViewTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebViewTest.cpp
@@ -2402,7 +2402,9 @@ WebString image = WebString::FromUTF8("purpleimage"); EXPECT_TRUE(TapElementById(WebInputEvent::kGestureLongPress, image)); - WebRange range = web_view->CaretOrSelectionRange(); + WebRange range = web_view->MainFrameImpl() + ->GetInputMethodController() + ->GetSelectionOffsets(); EXPECT_FALSE(range.IsNull()); EXPECT_EQ(0, range.StartOffset()); EXPECT_EQ(1, range.length()); @@ -2471,7 +2473,9 @@ WebLocalFrameBase* frame = web_view->MainFrameImpl(); EXPECT_EQ(test_word, std::string(frame->SelectionAsText().Utf8().data())); - WebRange range = web_view->CaretOrSelectionRange(); + WebRange range = web_view->MainFrameImpl() + ->GetInputMethodController() + ->GetSelectionOffsets(); EXPECT_FALSE(range.IsNull()); EXPECT_EQ(0, range.StartOffset()); EXPECT_EQ(static_cast<int>(test_word.length()), range.length());
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp index 82a8e167..05a5d4a 100644 --- a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp +++ b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
@@ -93,10 +93,6 @@ request.SetFetchRequestMode(WebURLRequest::kFetchRequestModeSameOrigin); request.SetHTTPMethod(HTTPNames::GET); - if (has_range_) - request.SetHTTPHeaderField( - HTTPNames::Range, - AtomicString(String::Format("bytes=%d-%d", range_start_, range_end_))); ThreadableLoaderOptions options; @@ -171,10 +167,6 @@ if (total_bytes_ >= 0) { initial_buffer_length = total_bytes_; - } else if (has_range_) { - // Set m_totalBytes and allocate a buffer based on the specified range. - total_bytes_ = 1LL + range_end_ - range_start_; - initial_buffer_length = total_bytes_; } else { // Nothing is known about the size of the resource. Normalize // m_totalBytes to -1 and initialize the buffer for receiving with the
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h index 33fc01b0..f1252bd 100644 --- a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h +++ b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h
@@ -148,9 +148,6 @@ // even when extra data is appeneded. long long total_bytes_ = -1; int64_t memory_usage_reported_to_v8_ = 0; - bool has_range_ = false; - unsigned range_start_ = 0; - unsigned range_end_ = 0; FileError::ErrorCode error_code_ = FileError::kOK; };
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp index 03394ef..998e2ef 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -1043,6 +1043,8 @@ document()->UpdateStyleAndLayoutIgnorePendingStylesheets(); + // TODO(bokan): This is wrong when the document.rootScroller is non-default. + // crbug.com/505516. double viewport_x = view->LayoutViewportScrollableArea()->GetScrollOffset().Width(); return AdjustScrollForAbsoluteZoom(viewport_x, GetFrame()->PageZoomFactor()); @@ -1061,6 +1063,8 @@ document()->UpdateStyleAndLayoutIgnorePendingStylesheets(); + // TODO(bokan): This is wrong when the document.rootScroller is non-default. + // crbug.com/505516. double viewport_y = view->LayoutViewportScrollableArea()->GetScrollOffset().Height(); return AdjustScrollForAbsoluteZoom(viewport_y, GetFrame()->PageZoomFactor());
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp index 33031eb8..0eb63c9 100644 --- a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp +++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.cpp
@@ -677,20 +677,6 @@ return false; } -// TODO(ekaramad):This method is almost duplicated in WebViewImpl as well. This -// code needs to be refactored (http://crbug.com/629721). -WebRange WebFrameWidgetImpl::CaretOrSelectionRange() { - LocalFrame* focused = FocusedLocalFrameInWidget(); - if (!focused) - return WebRange(); - - // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets - // needs to be audited. See http://crbug.com/590369 for more details. - focused->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - - return focused->GetInputMethodController().GetSelectionOffsets(); -} - void WebFrameWidgetImpl::SetTextDirection(WebTextDirection direction) { // The Editor::setBaseWritingDirection() function checks if we can change // the text direction of the selected node and updates its DOM "dir"
diff --git a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.h b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.h index 28b545c6..ab15966 100644 --- a/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.h +++ b/third_party/WebKit/Source/core/frame/WebFrameWidgetImpl.h
@@ -101,7 +101,6 @@ bool SelectionTextDirection(WebTextDirection& start, WebTextDirection& end) const override; bool IsSelectionAnchorFirst() const override; - WebRange CaretOrSelectionRange() override; void SetTextDirection(WebTextDirection) override; bool IsAcceleratedCompositingActive() const override; void WillCloseLayerTreeView() override;
diff --git a/third_party/WebKit/Source/core/frame/WebViewFrameWidget.cpp b/third_party/WebKit/Source/core/frame/WebViewFrameWidget.cpp index 9a46395..111c29a 100644 --- a/third_party/WebKit/Source/core/frame/WebViewFrameWidget.cpp +++ b/third_party/WebKit/Source/core/frame/WebViewFrameWidget.cpp
@@ -147,10 +147,6 @@ return web_view_->IsSelectionAnchorFirst(); } -WebRange WebViewFrameWidget::CaretOrSelectionRange() { - return web_view_->CaretOrSelectionRange(); -} - void WebViewFrameWidget::SetTextDirection(WebTextDirection direction) { return web_view_->SetTextDirection(direction); }
diff --git a/third_party/WebKit/Source/core/frame/WebViewFrameWidget.h b/third_party/WebKit/Source/core/frame/WebViewFrameWidget.h index 5c0486d..ef22d0d7 100644 --- a/third_party/WebKit/Source/core/frame/WebViewFrameWidget.h +++ b/third_party/WebKit/Source/core/frame/WebViewFrameWidget.h
@@ -74,7 +74,6 @@ bool SelectionTextDirection(WebTextDirection& start, WebTextDirection& end) const override; bool IsSelectionAnchorFirst() const override; - WebRange CaretOrSelectionRange() override; void SetTextDirection(WebTextDirection) override; bool IsAcceleratedCompositingActive() const override; bool IsWebView() const override { return false; }
diff --git a/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp b/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp index 76b90233..8de5dce1 100644 --- a/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp +++ b/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.cpp
@@ -55,41 +55,33 @@ line_break_length_(line_break_length), all_items_(all_items) {} -bool FlexLayoutAlgorithm::ComputeNextFlexLine( - size_t& next_index, - Vector<FlexItem>& line_items, - LayoutUnit& sum_flex_base_size, - double& total_flex_grow, - double& total_flex_shrink, - double& total_weighted_flex_shrink, - LayoutUnit& sum_hypothetical_main_size) { - line_items.clear(); - sum_flex_base_size = LayoutUnit(); - total_flex_grow = total_flex_shrink = total_weighted_flex_shrink = 0; - sum_hypothetical_main_size = LayoutUnit(); +bool FlexLayoutAlgorithm::ComputeNextFlexLine(size_t* next_index, + FlexLine* line) { + line->Reset(); bool line_has_in_flow_item = false; - for (; next_index < all_items_.size(); ++next_index) { - const FlexItem& flex_item = all_items_[next_index]; + for (; *next_index < all_items_.size(); ++*next_index) { + const FlexItem& flex_item = all_items_[*next_index]; DCHECK(!flex_item.box->IsOutOfFlowPositioned()); if (IsMultiline() && - sum_hypothetical_main_size + + line->sum_hypothetical_main_size + flex_item.HypotheticalMainAxisMarginBoxSize() > line_break_length_ && line_has_in_flow_item) break; - line_items.push_back(flex_item); + line->line_items.push_back(flex_item); line_has_in_flow_item = true; - sum_flex_base_size += flex_item.FlexBaseMarginBoxSize(); - total_flex_grow += flex_item.box->Style()->FlexGrow(); - total_flex_shrink += flex_item.box->Style()->FlexShrink(); - total_weighted_flex_shrink += + line->sum_flex_base_size += flex_item.FlexBaseMarginBoxSize(); + line->total_flex_grow += flex_item.box->Style()->FlexGrow(); + line->total_flex_shrink += flex_item.box->Style()->FlexShrink(); + line->total_weighted_flex_shrink += flex_item.box->Style()->FlexShrink() * flex_item.flex_base_content_size; - sum_hypothetical_main_size += flex_item.HypotheticalMainAxisMarginBoxSize(); + line->sum_hypothetical_main_size += + flex_item.HypotheticalMainAxisMarginBoxSize(); } - DCHECK(line_items.size() > 0 || next_index == all_items_.size()); - return line_items.size() > 0; + DCHECK(line->line_items.size() > 0 || *next_index == all_items_.size()); + return line->line_items.size() > 0; } } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.h b/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.h index 5408f67..665b0e2 100644 --- a/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.h +++ b/third_party/WebKit/Source/core/layout/FlexibleBoxAlgorithm.h
@@ -74,6 +74,32 @@ bool frozen; }; +struct FlexLine { + void Reset() { + line_items.clear(); + sum_flex_base_size = LayoutUnit(); + total_flex_grow = total_flex_shrink = total_weighted_flex_shrink = 0; + sum_hypothetical_main_size = LayoutUnit(); + cross_axis_offset = cross_axis_extent = max_ascent = LayoutUnit(); + } + + // These fields get filled in by ComputeNextFlexLine. + Vector<FlexItem> line_items; + LayoutUnit sum_flex_base_size; + double total_flex_grow; + double total_flex_shrink; + double total_weighted_flex_shrink; + // The hypothetical main size of an item is the flex base size clamped + // according to its min and max main size properties + LayoutUnit sum_hypothetical_main_size; + + // These get filled in by LayoutAndPlaceChildren (for now) + // TODO(cbiesinger): Move that to FlexibleBoxAlgorithm. + LayoutUnit cross_axis_offset; + LayoutUnit cross_axis_extent; + LayoutUnit max_ascent; +}; + class FlexLayoutAlgorithm { WTF_MAKE_NONCOPYABLE(FlexLayoutAlgorithm); @@ -82,15 +108,7 @@ LayoutUnit line_break_length, const Vector<FlexItem>& all_items); - // The hypothetical main size of an item is the flex base size clamped - // according to its min and max main size properties - bool ComputeNextFlexLine(size_t& next_index, - Vector<FlexItem>& line_items, - LayoutUnit& sum_flex_base_size, - double& total_flex_grow, - double& total_flex_shrink, - double& total_weighted_flex_shrink, - LayoutUnit& sum_hypothetical_main_size); + bool ComputeNextFlexLine(size_t* next_index, FlexLine*); private: bool IsMultiline() const { return style_->FlexWrap() != EFlexWrap::kNowrap; }
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp index c5fee8c2..0e28db6 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -49,22 +49,6 @@ return child.IsImage() || child.IsCanvas() || child.IsVideo(); } -struct LayoutFlexibleBox::LineContext { - LineContext(LayoutUnit cross_axis_offset, - LayoutUnit cross_axis_extent, - LayoutUnit max_ascent, - Vector<FlexItem>&& flex_items) - : cross_axis_offset(cross_axis_offset), - cross_axis_extent(cross_axis_extent), - max_ascent(max_ascent), - flex_items(flex_items) {} - - LayoutUnit cross_axis_offset; - LayoutUnit cross_axis_extent; - LayoutUnit max_ascent; - Vector<FlexItem> flex_items; -}; - LayoutFlexibleBox::LayoutFlexibleBox(Element* element) : LayoutBlock(element), order_iterator_(this), @@ -420,7 +404,7 @@ } void LayoutFlexibleBox::RepositionLogicalHeightDependentFlexItems( - Vector<LineContext>& line_contexts) { + Vector<FlexLine>& line_contexts) { LayoutUnit cross_axis_start_edge = line_contexts.IsEmpty() ? LayoutUnit() : line_contexts[0].cross_axis_offset; @@ -967,12 +951,7 @@ void LayoutFlexibleBox::LayoutFlexItems(bool relayout_children, SubtreeLayoutScope& layout_scope) { - Vector<LineContext> line_contexts; - LayoutUnit sum_flex_base_size; - double total_flex_grow; - double total_flex_shrink; - double total_weighted_flex_shrink; - LayoutUnit sum_hypothetical_main_size; + Vector<FlexLine> line_contexts; PaintLayerScrollableArea::PreventRelayoutScope prevent_relayout_scope( layout_scope); @@ -999,49 +978,44 @@ FlexLayoutAlgorithm flex_algorithm(Style(), line_break_length, all_items); LayoutUnit cross_axis_offset = FlowAwareBorderBefore() + FlowAwarePaddingBefore(); - Vector<FlexItem> line_items; size_t next_index = 0; - while (flex_algorithm.ComputeNextFlexLine( - next_index, line_items, sum_flex_base_size, total_flex_grow, - total_flex_shrink, total_weighted_flex_shrink, - sum_hypothetical_main_size)) { - DCHECK_GE(line_items.size(), 0ULL); + FlexLine current_line; + while (flex_algorithm.ComputeNextFlexLine(&next_index, ¤t_line)) { + DCHECK_GE(current_line.line_items.size(), 0ULL); LayoutUnit container_main_inner_size = - MainAxisContentExtent(sum_hypothetical_main_size); + MainAxisContentExtent(current_line.sum_hypothetical_main_size); // availableFreeSpace is the initial amount of free space in this flexbox. // remainingFreeSpace starts out at the same value but as we place and lay // out flex items we subtract from it. Note that both values can be // negative. LayoutUnit remaining_free_space = - container_main_inner_size - sum_flex_base_size; + container_main_inner_size - current_line.sum_flex_base_size; FlexSign flex_sign = - (sum_hypothetical_main_size < container_main_inner_size) + (current_line.sum_hypothetical_main_size < container_main_inner_size) ? kPositiveFlexibility : kNegativeFlexibility; - FreezeInflexibleItems(flex_sign, line_items, remaining_free_space, - total_flex_grow, total_flex_shrink, - total_weighted_flex_shrink); + FreezeInflexibleItems(flex_sign, current_line, remaining_free_space); // The initial free space gets calculated after freezing inflexible items. // https://drafts.csswg.org/css-flexbox/#resolve-flexible-lengths step 3 const LayoutUnit initial_free_space = remaining_free_space; - while (!ResolveFlexibleLengths( - flex_sign, line_items, initial_free_space, remaining_free_space, - total_flex_grow, total_flex_shrink, total_weighted_flex_shrink)) { - DCHECK_GE(total_flex_grow, 0); - DCHECK_GE(total_weighted_flex_shrink, 0); + while (!ResolveFlexibleLengths(flex_sign, current_line, initial_free_space, + remaining_free_space)) { + DCHECK_GE(current_line.total_flex_grow, 0); + DCHECK_GE(current_line.total_weighted_flex_shrink, 0); } // Recalculate the remaining free space. The adjustment for flex factors // between 0..1 means we can't just use remainingFreeSpace here. remaining_free_space = container_main_inner_size; - for (size_t i = 0; i < line_items.size(); ++i) { - FlexItem& flex_item = line_items[i]; + for (size_t i = 0; i < current_line.line_items.size(); ++i) { + FlexItem& flex_item = current_line.line_items[i]; DCHECK(!flex_item.box->IsOutOfFlowPositioned()); remaining_free_space -= flex_item.FlexedMarginBoxSize(); } - // This will std::move lineItems into a newly-created LineContext. - LayoutAndPlaceChildren(cross_axis_offset, line_items, remaining_free_space, - relayout_children, layout_scope, line_contexts); + LayoutAndPlaceChildren(cross_axis_offset, current_line, + remaining_free_space, relayout_children, + layout_scope); + line_contexts.push_back(current_line); } if (HasLineIfEmpty()) { // Even if ComputeNextFlexLine returns true, the flexbox might not have @@ -1425,17 +1399,14 @@ void LayoutFlexibleBox::FreezeInflexibleItems( FlexSign flex_sign, - Vector<FlexItem>& children, - LayoutUnit& remaining_free_space, - double& total_flex_grow, - double& total_flex_shrink, - double& total_weighted_flex_shrink) { + FlexLine& line, + LayoutUnit& remaining_free_space) { // Per https://drafts.csswg.org/css-flexbox/#resolve-flexible-lengths step 2, // we freeze all items with a flex factor of 0 as well as those with a min/max // size violation. Vector<FlexItem*> new_inflexible_items; - for (size_t i = 0; i < children.size(); ++i) { - FlexItem& flex_item = children[i]; + for (size_t i = 0; i < line.line_items.size(); ++i) { + FlexItem& flex_item = line.line_items[i]; LayoutBox* child = flex_item.box; DCHECK(!flex_item.box->IsOutOfFlowPositioned()); DCHECK(!flex_item.frozen) << i; @@ -1453,34 +1424,33 @@ new_inflexible_items.push_back(&flex_item); } } - FreezeViolations(new_inflexible_items, remaining_free_space, total_flex_grow, - total_flex_shrink, total_weighted_flex_shrink); + FreezeViolations(new_inflexible_items, remaining_free_space, + line.total_flex_grow, line.total_flex_shrink, + line.total_weighted_flex_shrink); } // Returns true if we successfully ran the algorithm and sized the flex items. bool LayoutFlexibleBox::ResolveFlexibleLengths( FlexSign flex_sign, - Vector<FlexItem>& children, + FlexLine& line, LayoutUnit initial_free_space, - LayoutUnit& remaining_free_space, - double& total_flex_grow, - double& total_flex_shrink, - double& total_weighted_flex_shrink) { + LayoutUnit& remaining_free_space) { LayoutUnit total_violation; LayoutUnit used_free_space; Vector<FlexItem*> min_violations; Vector<FlexItem*> max_violations; - double sum_flex_factors = - (flex_sign == kPositiveFlexibility) ? total_flex_grow : total_flex_shrink; + double sum_flex_factors = (flex_sign == kPositiveFlexibility) + ? line.total_flex_grow + : line.total_flex_shrink; if (sum_flex_factors > 0 && sum_flex_factors < 1) { LayoutUnit fractional(initial_free_space * sum_flex_factors); if (fractional.Abs() < remaining_free_space.Abs()) remaining_free_space = fractional; } - for (size_t i = 0; i < children.size(); ++i) { - FlexItem& flex_item = children[i]; + for (size_t i = 0; i < line.line_items.size(); ++i) { + FlexItem& flex_item = line.line_items[i]; LayoutBox* child = flex_item.box; // This check also covers out-of-flow children. @@ -1489,17 +1459,19 @@ LayoutUnit child_size = flex_item.flex_base_content_size; double extra_space = 0; - if (remaining_free_space > 0 && total_flex_grow > 0 && - flex_sign == kPositiveFlexibility && std::isfinite(total_flex_grow)) { - extra_space = - remaining_free_space * child->Style()->FlexGrow() / total_flex_grow; - } else if (remaining_free_space < 0 && total_weighted_flex_shrink > 0 && + if (remaining_free_space > 0 && line.total_flex_grow > 0 && + flex_sign == kPositiveFlexibility && + std::isfinite(line.total_flex_grow)) { + extra_space = remaining_free_space * child->Style()->FlexGrow() / + line.total_flex_grow; + } else if (remaining_free_space < 0 && + line.total_weighted_flex_shrink > 0 && flex_sign == kNegativeFlexibility && - std::isfinite(total_weighted_flex_shrink) && + std::isfinite(line.total_weighted_flex_shrink) && child->Style()->FlexShrink()) { extra_space = remaining_free_space * child->Style()->FlexShrink() * flex_item.flex_base_content_size / - total_weighted_flex_shrink; + line.total_weighted_flex_shrink; } if (std::isfinite(extra_space)) child_size += LayoutUnit::FromFloatRound(extra_space); @@ -1518,12 +1490,13 @@ total_violation += violation; } - if (total_violation) + if (total_violation) { FreezeViolations(total_violation < 0 ? max_violations : min_violations, - remaining_free_space, total_flex_grow, total_flex_shrink, - total_weighted_flex_shrink); - else + remaining_free_space, line.total_flex_grow, + line.total_flex_shrink, line.total_weighted_flex_shrink); + } else { remaining_free_space -= used_free_space; + } return !total_violation; } @@ -1796,19 +1769,18 @@ DISABLE_CFI_PERF void LayoutFlexibleBox::LayoutAndPlaceChildren( LayoutUnit& cross_axis_offset, - Vector<FlexItem>& children, + FlexLine& current_line, LayoutUnit available_free_space, bool relayout_children, - SubtreeLayoutScope& layout_scope, - Vector<LineContext>& line_contexts) { + SubtreeLayoutScope& layout_scope) { const StyleContentAlignmentData justify_content = ResolvedJustifyContent(); LayoutUnit auto_margin_offset = - AutoMarginOffsetInMainAxis(children, available_free_space); + AutoMarginOffsetInMainAxis(current_line.line_items, available_free_space); LayoutUnit main_axis_offset = FlowAwareBorderStart() + FlowAwarePaddingStart(); main_axis_offset += InitialContentPositionOffset( - available_free_space, justify_content, children.size()); + available_free_space, justify_content, current_line.line_items.size()); if (Style()->FlexDirection() == EFlexDirection::kRowReverse && ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) main_axis_offset += IsHorizontalFlow() ? VerticalScrollbarWidth() @@ -1818,12 +1790,12 @@ if (!ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) total_main_extent -= IsHorizontalFlow() ? VerticalScrollbarWidth() : HorizontalScrollbarHeight(); - LayoutUnit max_ascent, max_descent; // Used when align-items: baseline. + LayoutUnit max_descent; // Used when align-items: baseline. LayoutUnit max_child_cross_axis_extent; bool should_flip_main_axis = !IsColumnFlow() && !IsLeftToRightFlow(); bool is_paginated = View()->GetLayoutState()->IsPaginated(); - for (size_t i = 0; i < children.size(); ++i) { - const FlexItem& flex_item = children[i]; + for (size_t i = 0; i < current_line.line_items.size(); ++i) { + const FlexItem& flex_item = current_line.line_items[i]; LayoutBox* child = flex_item.box; DCHECK(!flex_item.box->IsOutOfFlowPositioned()); @@ -1872,11 +1844,12 @@ CrossAxisExtentForChild(*child)) - ascent; - max_ascent = std::max(max_ascent, ascent); + current_line.max_ascent = std::max(current_line.max_ascent, ascent); max_descent = std::max(max_descent, descent); // TODO(cbiesinger): Take scrollbar into account - child_cross_axis_margin_box_extent = max_ascent + max_descent; + child_cross_axis_margin_box_extent = + current_line.max_ascent + max_descent; } else { child_cross_axis_margin_box_extent = CrossAxisIntrinsicExtentForChild(*child) + @@ -1903,10 +1876,11 @@ SetFlowAwareLocationForChild(*child, child_location); main_axis_offset += child_main_extent + FlowAwareMarginEndForChild(*child); - if (i != children.size() - 1) { + if (i != current_line.line_items.size() - 1) { // The last item does not get extra space added. main_axis_offset += ContentDistributionSpaceBetweenChildren( - available_free_space, justify_content, children.size()); + available_free_space, justify_content, + current_line.line_items.size()); } if (is_paginated) @@ -1923,14 +1897,15 @@ // items since the start depends on the height of the flexbox, which we // only know after we've positioned all the flex items. UpdateLogicalHeight(); - LayoutColumnReverse(children, cross_axis_offset, available_free_space); + LayoutColumnReverse(current_line.line_items, cross_axis_offset, + available_free_space); } if (number_of_in_flow_children_on_first_line_ == -1) - number_of_in_flow_children_on_first_line_ = children.size(); - line_contexts.push_back(LineContext(cross_axis_offset, - max_child_cross_axis_extent, max_ascent, - std::move(children))); + number_of_in_flow_children_on_first_line_ = current_line.line_items.size(); + current_line.cross_axis_offset = cross_axis_offset; + current_line.cross_axis_extent = max_child_cross_axis_extent; + cross_axis_offset += max_child_cross_axis_extent; } @@ -1969,7 +1944,7 @@ } } -void LayoutFlexibleBox::AlignFlexLines(Vector<LineContext>& line_contexts) { +void LayoutFlexibleBox::AlignFlexLines(Vector<FlexLine>& line_contexts) { const StyleContentAlignmentData align_content = ResolvedAlignContent(); // If we have a single line flexbox or a multiline line flexbox with only one @@ -1995,11 +1970,11 @@ } for (unsigned line_number = 0; line_number < line_contexts.size(); ++line_number) { - LineContext& line_context = line_contexts[line_number]; + FlexLine& line_context = line_contexts[line_number]; line_context.cross_axis_offset += line_offset; - for (size_t child_number = 0; child_number < line_context.flex_items.size(); + for (size_t child_number = 0; child_number < line_context.line_items.size(); ++child_number) { - FlexItem& flex_item = line_context.flex_items[child_number]; + FlexItem& flex_item = line_context.line_items[child_number]; AdjustAlignmentForChild(*flex_item.box, line_offset); } @@ -2022,23 +1997,22 @@ LayoutSize(LayoutUnit(), delta)); } -void LayoutFlexibleBox::AlignChildren( - const Vector<LineContext>& line_contexts) { +void LayoutFlexibleBox::AlignChildren(const Vector<FlexLine>& line_contexts) { // Keep track of the space between the baseline edge and the after edge of // the box for each line. Vector<LayoutUnit> min_margin_after_baselines; for (size_t line_number = 0; line_number < line_contexts.size(); ++line_number) { - const LineContext& line_context = line_contexts[line_number]; + const FlexLine& line_context = line_contexts[line_number]; LayoutUnit min_margin_after_baseline = LayoutUnit::Max(); LayoutUnit line_cross_axis_extent = line_context.cross_axis_extent; LayoutUnit max_ascent = line_context.max_ascent; - for (size_t child_number = 0; child_number < line_context.flex_items.size(); + for (size_t child_number = 0; child_number < line_context.line_items.size(); ++child_number) { - const FlexItem& flex_item = line_context.flex_items[child_number]; + const FlexItem& flex_item = line_context.line_items[child_number]; DCHECK(!flex_item.box->IsOutOfFlowPositioned()); if (UpdateAutoMarginsInCrossAxis( @@ -2077,12 +2051,12 @@ // after edge of the flex line. for (size_t line_number = 0; line_number < line_contexts.size(); ++line_number) { - const LineContext& line_context = line_contexts[line_number]; + const FlexLine& line_context = line_contexts[line_number]; LayoutUnit min_margin_after_baseline = min_margin_after_baselines[line_number]; - for (size_t child_number = 0; child_number < line_context.flex_items.size(); + for (size_t child_number = 0; child_number < line_context.line_items.size(); ++child_number) { - const FlexItem& flex_item = line_context.flex_items[child_number]; + const FlexItem& flex_item = line_context.line_items[child_number]; if (AlignmentForChild(*flex_item.box) == kItemPositionBaseline && !HasAutoMarginsInCrossAxis(*flex_item.box) && min_margin_after_baseline) @@ -2147,17 +2121,17 @@ } void LayoutFlexibleBox::FlipForRightToLeftColumn( - const Vector<LineContext>& line_contexts) { + const Vector<FlexLine>& line_contexts) { if (Style()->IsLeftToRightDirection() || !IsColumnFlow()) return; LayoutUnit cross_extent = CrossAxisExtent(); for (size_t line_number = 0; line_number < line_contexts.size(); ++line_number) { - const LineContext& line_context = line_contexts[line_number]; - for (size_t child_number = 0; child_number < line_context.flex_items.size(); + const FlexLine& line_context = line_contexts[line_number]; + for (size_t child_number = 0; child_number < line_context.line_items.size(); ++child_number) { - const FlexItem& flex_item = line_context.flex_items[child_number]; + const FlexItem& flex_item = line_context.line_items[child_number]; DCHECK(!flex_item.box->IsOutOfFlowPositioned()); LayoutPoint location = FlowAwareLocationForChild(*flex_item.box); @@ -2174,15 +2148,15 @@ } void LayoutFlexibleBox::FlipForWrapReverse( - const Vector<LineContext>& line_contexts, + const Vector<FlexLine>& line_contexts, LayoutUnit cross_axis_start_edge) { LayoutUnit content_extent = CrossAxisContentExtent(); for (size_t line_number = 0; line_number < line_contexts.size(); ++line_number) { - const LineContext& line_context = line_contexts[line_number]; - for (size_t child_number = 0; child_number < line_context.flex_items.size(); + const FlexLine& line_context = line_contexts[line_number]; + for (size_t child_number = 0; child_number < line_context.line_items.size(); ++child_number) { - const FlexItem& flex_item = line_context.flex_items[child_number]; + const FlexItem& flex_item = line_context.line_items[child_number]; LayoutUnit line_cross_axis_extent = line_contexts[line_number].cross_axis_extent; LayoutUnit original_offset =
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h index 87fdd74c..849a896 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
@@ -38,6 +38,7 @@ namespace blink { class FlexItem; +struct FlexLine; class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock { public: @@ -114,8 +115,6 @@ enum class SizeDefiniteness { kDefinite, kIndefinite, kUnknown }; - struct LineContext; - bool HasOrthogonalFlow(const LayoutBox& child) const; bool IsColumnFlow() const; bool IsLeftToRightFlow() const; @@ -182,7 +181,7 @@ bool HasAutoMarginsInCrossAxis(const LayoutBox& child) const; bool UpdateAutoMarginsInCrossAxis(LayoutBox& child, LayoutUnit available_alignment_space); - void RepositionLogicalHeightDependentFlexItems(Vector<LineContext>&); + void RepositionLogicalHeightDependentFlexItems(Vector<FlexLine>&); LayoutUnit ClientLogicalBottomAfterRepositioning(); LayoutUnit AvailableAlignmentSpaceForChild(LayoutUnit line_cross_axis_extent, @@ -199,18 +198,12 @@ FlexItem ConstructFlexItem(LayoutBox& child, ChildLayoutType); void FreezeInflexibleItems(FlexSign, - Vector<FlexItem>& children, - LayoutUnit& remaining_free_space, - double& total_flex_grow, - double& total_flex_shrink, - double& total_weighted_flex_shrink); + FlexLine&, + LayoutUnit& remaining_free_space); bool ResolveFlexibleLengths(FlexSign, - Vector<FlexItem>&, + FlexLine&, LayoutUnit initial_free_space, - LayoutUnit& remaining_free_space, - double& total_flex_grow, - double& total_flex_shrink, - double& total_weighted_flex_shrink); + LayoutUnit& remaining_free_space); void FreezeViolations(Vector<FlexItem*>&, LayoutUnit& available_free_space, double& total_flex_grow, @@ -222,20 +215,19 @@ LayoutUnit child_preferred_size); void PrepareChildForPositionedLayout(LayoutBox& child); void LayoutAndPlaceChildren(LayoutUnit& cross_axis_offset, - Vector<FlexItem>&, + FlexLine&, LayoutUnit available_free_space, bool relayout_children, - SubtreeLayoutScope&, - Vector<LineContext>&); + SubtreeLayoutScope&); void LayoutColumnReverse(const Vector<FlexItem>&, LayoutUnit cross_axis_offset, LayoutUnit available_free_space); - void AlignFlexLines(Vector<LineContext>&); - void AlignChildren(const Vector<LineContext>&); + void AlignFlexLines(Vector<FlexLine>&); + void AlignChildren(const Vector<FlexLine>&); void ApplyStretchAlignmentToChild(LayoutBox& child, LayoutUnit line_cross_axis_extent); - void FlipForRightToLeftColumn(const Vector<LineContext>& line_contexts); - void FlipForWrapReverse(const Vector<LineContext>&, + void FlipForRightToLeftColumn(const Vector<FlexLine>& line_contexts); + void FlipForWrapReverse(const Vector<FlexLine>&, LayoutUnit cross_axis_start_edge); float CountIntrinsicSizeForAlgorithmChange(
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp index 2b78fcd..7993876 100644 --- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp +++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
@@ -1424,14 +1424,10 @@ const WebRTCICECandidate& web_candidate) { DCHECK(!closed_); DCHECK(GetExecutionContext()->IsContextThread()); - if (web_candidate.IsNull()) { - ScheduleDispatchEvent( - RTCPeerConnectionIceEvent::Create(false, false, nullptr)); - } else { - RTCIceCandidate* ice_candidate = RTCIceCandidate::Create(web_candidate); - ScheduleDispatchEvent( - RTCPeerConnectionIceEvent::Create(false, false, ice_candidate)); - } + DCHECK(!web_candidate.IsNull()); + RTCIceCandidate* ice_candidate = RTCIceCandidate::Create(web_candidate); + ScheduleDispatchEvent( + RTCPeerConnectionIceEvent::Create(false, false, ice_candidate)); } void RTCPeerConnection::DidChangeSignalingState(SignalingState new_state) { @@ -1557,8 +1553,7 @@ } void RTCPeerConnection::ChangeSignalingState(SignalingState signaling_state) { - if (signaling_state_ != kSignalingStateClosed && - signaling_state_ != signaling_state) { + if (signaling_state_ != kSignalingStateClosed) { signaling_state_ = signaling_state; ScheduleDispatchEvent(Event::Create(EventTypeNames::signalingstatechange)); } @@ -1566,11 +1561,37 @@ void RTCPeerConnection::ChangeIceGatheringState( ICEGatheringState ice_gathering_state) { + if (ice_connection_state_ != kICEConnectionStateClosed) { + ScheduleDispatchEvent( + Event::Create(EventTypeNames::icegatheringstatechange), + WTF::Bind(&RTCPeerConnection::SetIceGatheringState, + WrapPersistent(this), ice_gathering_state)); + if (ice_gathering_state == kICEGatheringStateComplete) { + // If ICE gathering is completed, generate a null ICE candidate, to + // signal end of candidates. + ScheduleDispatchEvent( + RTCPeerConnectionIceEvent::Create(false, false, nullptr)); + } + } +} + +bool RTCPeerConnection::SetIceGatheringState( + ICEGatheringState ice_gathering_state) { if (ice_connection_state_ != kICEConnectionStateClosed && ice_gathering_state_ != ice_gathering_state) { ice_gathering_state_ = ice_gathering_state; + return true; + } + return false; +} + +void RTCPeerConnection::ChangeIceConnectionState( + ICEConnectionState ice_connection_state) { + if (ice_connection_state_ != kICEConnectionStateClosed) { ScheduleDispatchEvent( - Event::Create(EventTypeNames::icegatheringstatechange)); + Event::Create(EventTypeNames::iceconnectionstatechange), + WTF::Bind(&RTCPeerConnection::SetIceConnectionState, + WrapPersistent(this), ice_connection_state)); } } @@ -1587,16 +1608,6 @@ return false; } -void RTCPeerConnection::ChangeIceConnectionState( - ICEConnectionState ice_connection_state) { - if (ice_connection_state_ != kICEConnectionStateClosed) { - ScheduleDispatchEvent( - Event::Create(EventTypeNames::iceconnectionstatechange), - WTF::Bind(&RTCPeerConnection::SetIceConnectionState, - WrapPersistent(this), ice_connection_state)); - } -} - void RTCPeerConnection::CloseInternal() { DCHECK(signaling_state_ != RTCPeerConnection::kSignalingStateClosed); peer_handler_->Stop();
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h index 5edb39e..4407d7d0 100644 --- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h +++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
@@ -249,17 +249,37 @@ void DispatchScheduledEvent(); MediaStreamTrack* GetTrack(const WebMediaStreamTrack&) const; + // The "Change" methods set the state asynchronously and fire the + // corresponding event immediately after changing the state (if it was really + // changed). + // + // The "Set" methods are called asynchronously by the "Change" methods, and + // set the corresponding state without firing an event, returning true if the + // state was really changed. + // + // This is done because the standard guarantees that state changes and the + // corresponding events will happen in the same task; it shouldn't be + // possible to, for example, end up with two "icegatheringstatechange" events + // that are delayed somehow and cause the application to read a "complete" + // gathering state twice, missing the "gathering" state in the middle. + // + // TODO(deadbeef): This wasn't done for the signaling state because it + // resulted in a change to the order of the signaling state being updated + // relative to the SetLocalDescription or SetRemoteDescription promise being + // resolved. Some additional refactoring would be necessary to fix this; for + // example, passing the new signaling state along with the SRD/SLD callbacks + // as opposed to relying on a separate event. void ChangeSignalingState(WebRTCPeerConnectionHandlerClient::SignalingState); + void ChangeIceGatheringState( WebRTCPeerConnectionHandlerClient::ICEGatheringState); - // Changes the state immediately; does not fire an event. - // Returns true if the state was changed. - bool SetIceConnectionState( - WebRTCPeerConnectionHandlerClient::ICEConnectionState); - // Changes the state asynchronously and fires an event immediately after - // changing the state. + bool SetIceGatheringState( + WebRTCPeerConnectionHandlerClient::ICEGatheringState); + void ChangeIceConnectionState( WebRTCPeerConnectionHandlerClient::ICEConnectionState); + bool SetIceConnectionState( + WebRTCPeerConnectionHandlerClient::ICEConnectionState); void CloseInternal();
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index a1a75aa6..8d5f225 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -4878,13 +4878,6 @@ if (type == GL_UNSIGNED_SHORT_5_5_5_1) return false; #endif - // TODO(kbr): bugs were observed when using CopyTextureCHROMIUM to - // copy hardware-accelerated video textures to red-channel textures. - // These bugs were seen on macOS but may indicate more general - // problems. Investigate the root cause of this and fix it. - // crbug.com/710673 - if (format == GL_RED || format == GL_RED_INTEGER) - return false; #if defined(OS_ANDROID) // TODO(kbr): bugs were seen on Android devices with NVIDIA GPUs
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h index 16c64bb..a45ffe8 100644 --- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h +++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.h
@@ -46,6 +46,7 @@ void DidReceiveCompositorFrameAck( const WTF::Vector<cc::ReturnedResource>& resources) final; void OnBeginFrame(const cc::BeginFrameArgs&) final; + void OnBeginFramePausedChanged(bool paused) final{}; void ReclaimResources( const WTF::Vector<cc::ReturnedResource>& resources) final;
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index aca56369..9eff470 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -2453,20 +2453,6 @@ // TODO(ekaramad):This method is almost duplicated in WebFrameWidgetImpl as // well. This code needs to be refactored (http://crbug.com/629721). -WebRange WebViewImpl::CaretOrSelectionRange() { - const LocalFrame* focused = FocusedLocalFrameInWidget(); - if (!focused) - return WebRange(); - - // TODO(editing-dev): The use of updateStyleAndLayoutIgnorePendingStylesheets - // needs to be audited. See http://crbug.com/590369 for more details. - focused->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - - return focused->GetInputMethodController().GetSelectionOffsets(); -} - -// TODO(ekaramad):This method is almost duplicated in WebFrameWidgetImpl as -// well. This code needs to be refactored (http://crbug.com/629721). void WebViewImpl::SetTextDirection(WebTextDirection direction) { // The Editor::setBaseWritingDirection() function checks if we can change // the text direction of the selected node and updates its DOM "dir"
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h index 51cd9f0..5ea6e7b 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.h +++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -146,7 +146,6 @@ bool SelectionTextDirection(WebTextDirection& start, WebTextDirection& end) const override; bool IsSelectionAnchorFirst() const override; - WebRange CaretOrSelectionRange() override; void SetTextDirection(WebTextDirection) override; bool IsAcceleratedCompositingActive() const override; void WillCloseLayerTreeView() override;
diff --git a/third_party/WebKit/public/web/WebInputMethodController.h b/third_party/WebKit/public/web/WebInputMethodController.h index 756e7e50..7130bef 100644 --- a/third_party/WebKit/public/web/WebInputMethodController.h +++ b/third_party/WebKit/public/web/WebInputMethodController.h
@@ -60,6 +60,9 @@ // Returns the type of current text input of this controller. virtual WebTextInputType TextInputType() { return kWebTextInputTypeNone; } + + // Fetch the current selection range of this frame. + virtual WebRange GetSelectionOffsets() const = 0; }; } // namespace blink
diff --git a/third_party/WebKit/public/web/WebSettings.h b/third_party/WebKit/public/web/WebSettings.h index 4c736ce2..39e2eccc 100644 --- a/third_party/WebKit/public/web/WebSettings.h +++ b/third_party/WebKit/public/web/WebSettings.h
@@ -194,7 +194,6 @@ virtual void SetImageAnimationPolicy(ImageAnimationPolicy) = 0; virtual void SetImagesEnabled(bool) = 0; virtual void SetInlineTextBoxAccessibilityEnabled(bool) = 0; - virtual void SetInertVisualViewport(bool) = 0; virtual void SetJavaScriptCanAccessClipboard(bool) = 0; virtual void SetJavaScriptEnabled(bool) = 0; virtual void SetLoadsImagesAutomatically(bool) = 0;
diff --git a/third_party/WebKit/public/web/WebView.h b/third_party/WebKit/public/web/WebView.h index 611321a8..19175093 100644 --- a/third_party/WebKit/public/web/WebView.h +++ b/third_party/WebKit/public/web/WebView.h
@@ -100,7 +100,6 @@ using WebWidget::SelectionBounds; using WebWidget::SelectionTextDirection; using WebWidget::IsSelectionAnchorFirst; - using WebWidget::CaretOrSelectionRange; using WebWidget::SetTextDirection; using WebWidget::IsAcceleratedCompositingActive; using WebWidget::IsWebView;
diff --git a/third_party/WebKit/public/web/WebWidget.h b/third_party/WebKit/public/web/WebWidget.h index 101367b..2a34655 100644 --- a/third_party/WebKit/public/web/WebWidget.h +++ b/third_party/WebKit/public/web/WebWidget.h
@@ -168,9 +168,6 @@ // (i.e its anchor is its start). virtual bool IsSelectionAnchorFirst() const { return false; } - // Fetch the current selection range of this WebWidget. - virtual WebRange CaretOrSelectionRange() { return WebRange(); } - // Changes the text direction of the selected input node. virtual void SetTextDirection(WebTextDirection) {}
diff --git a/third_party/android_platform/development/scripts/stack_core.py b/third_party/android_platform/development/scripts/stack_core.py index 7813022..f206793 100755 --- a/third_party/android_platform/development/scripts/stack_core.py +++ b/third_party/android_platform/development/scripts/stack_core.py
@@ -52,8 +52,6 @@ _JAVA_STDERR_LINE = re.compile("([0-9]+)\s+[0-9]+\s+.\s+System.err:\s*(.+)") _WIDTH = '{8}' -if symbol.ARCH == 'arm64' or symbol.ARCH == 'x86_64' or symbol.ARCH == 'x64': - _WIDTH = '{16}' # Matches LOG(FATAL) lines, like the following example: # [FATAL:source_file.cc(33)] Check failed: !instances_.empty() @@ -72,31 +70,36 @@ # Please note the spacing differences. _TRACE_LINE = re.compile('(.*)\#(?P<frame>[0-9]+)[ \t]+(..)[ \t]+(0x)?(?P<address>[0-9a-f]{0,16})[ \t]+(?P<lib>[^\r\n \t]*)(?P<symbol_present> \((?P<symbol_name>.*)\))?') # pylint: disable-msg=C6310 -# Matches lines emitted by src/base/debug/stack_trace_android.cc, like: -# #00 0x7324d92d /data/app-lib/org.chromium.native_test-1/libbase.cr.so+0x0006992d -# This pattern includes the unused named capture groups <symbol_present> and -# <symbol_name> so that it can interoperate with the |_TRACE_LINE| regex. -_DEBUG_TRACE_LINE = re.compile( - '(.*)(?P<frame>\#[0-9]+ 0x[0-9a-f]' + _WIDTH + ') ' - '(?P<lib>[^+]+)\+0x(?P<address>[0-9a-f]' + _WIDTH + ')' - '(?P<symbol_present>)(?P<symbol_name>)') +def InitWidthRelatedLineMatchers(): + global _WIDTH + global _DEBUG_TRACE_LINE, _VALUE_LINE, _CODE_LINE + if symbol.ARCH == 'arm64' or symbol.ARCH == 'x86_64' or symbol.ARCH == 'x64': + _WIDTH = '{16}' + # Matches lines emitted by src/base/debug/stack_trace_android.cc, like: + # #00 0x7324d92d /data/app-lib/org.chromium.native_test-1/libbase.cr.so+0x0006992d + # This pattern includes the unused named capture groups <symbol_present> and + # <symbol_name> so that it can interoperate with the |_TRACE_LINE| regex. + _DEBUG_TRACE_LINE = re.compile( + '(.*)(?P<frame>\#[0-9]+ 0x[0-9a-f]' + _WIDTH + ') ' + '(?P<lib>[^+]+)\+0x(?P<address>[0-9a-f]' + _WIDTH + ')' + '(?P<symbol_present>)(?P<symbol_name>)') -# Examples of matched value lines include: -# bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so -# bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so (symbol) -# 03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so -# Again, note the spacing differences. -_VALUE_LINE = re.compile('(.*)([0-9a-f]' + _WIDTH + ')[ \t]+([0-9a-f]' + _WIDTH + ')[ \t]+([^\r\n \t]*)( \((.*)\))?') -# Lines from 'code around' sections of the output will be matched before -# value lines because otheriwse the 'code around' sections will be confused as -# value lines. -# -# Examples include: -# 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 -# 03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 -code_line = re.compile('(.*)[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[a-f0-9]' + _WIDTH + - '[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[a-f0-9]' + _WIDTH + - '[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[ \r\n]') # pylint: disable-msg=C6310 + # Examples of matched value lines include: + # bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so + # bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so (symbol) + # 03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so + # Again, note the spacing differences. + _VALUE_LINE = re.compile('(.*)([0-9a-f]' + _WIDTH + ')[ \t]+([0-9a-f]' + _WIDTH + ')[ \t]+([^\r\n \t]*)( \((.*)\))?') + # Lines from 'code around' sections of the output will be matched before + # value lines because otheriwse the 'code around' sections will be confused as + # value lines. + # + # Examples include: + # 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 + # 03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8 + _CODE_LINE = re.compile('(.*)[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[a-f0-9]' + _WIDTH + + '[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[a-f0-9]' + _WIDTH + + '[ \t]*[a-f0-9]' + _WIDTH + '[ \t]*[ \r\n]') # pylint: disable-msg=C6310 # This pattern is used to find shared library offset in APK. # Example: @@ -157,6 +160,8 @@ def ConvertTrace(lines, load_vaddrs, more_info, fallback_monochrome, arch_defined): """Convert strings containing native crash to a stack.""" + InitWidthRelatedLineMatchers() + if fallback_monochrome: global _FALLBACK_SO _FALLBACK_SO = 'libmonochrome.so' @@ -291,7 +296,7 @@ useful_log.append(line.replace(address, adjusted_address, 1)) continue - if code_line.match(line): + if _CODE_LINE.match(line): # Code lines should be ignored. If this were excluded the 'code around' # sections would trigger value_line matches. continue @@ -326,7 +331,7 @@ address, lib = match.group('address', 'lib') match = _VALUE_LINE.match(line) - if match and not code_line.match(line): + if match and not _CODE_LINE.match(line): (_0, _1, address, lib, _2, _3) = match.groups() if lib:
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 22e1a9d..d0d8067 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -13580,6 +13580,7 @@ <int value="203" label="kNetworkingCastPrivate"/> <int value="204" label="kMediaPerceptionPrivate"/> <int value="205" label="kLockScreen"/> + <int value="206" label="kNewTabPageOverride"/> </enum> <enum name="ExtensionServiceVerifyAllSuccess">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 9db4271ba..0969b6d 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -53857,12 +53857,26 @@ </histogram> <histogram - name="PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion" + name="PaymentRequest.UserDidNotHaveCompleteSuggestionsForEverything.EffectOnCompletion" enum="PaymentRequestFlowCompletionStatus"> <owner>sebsg@chromium.org</owner> <summary> - Whether the flow was completed when the user did not have a form of payment - on file when the Payment Request was shown. + Whether the flow was completed when the user did not have a complete + suggestion offered for each requested information. + </summary> +</histogram> + +<histogram + name="PaymentRequest.UserDidNotHaveInitialFormOfPayment.EffectOnCompletion" + enum="PaymentRequestFlowCompletionStatus"> + <obsolete> + Replaced by PaymentRequest.NumberOfSuggestionsShown.PaymentMethod on July + 19th 2017. + </obsolete> + <owner>sebsg@chromium.org</owner> + <summary> + Whether the flow was completed when the user did not have a a form of + payment on file when the Payment Request was shown. </summary> </histogram> @@ -53876,12 +53890,26 @@ </summary> </histogram> -<histogram name="PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion" +<histogram + name="PaymentRequest.UserHadCompleteSuggestionsForEverything.EffectOnCompletion" enum="PaymentRequestFlowCompletionStatus"> <owner>sebsg@chromium.org</owner> <summary> - Whether the flow was completed when the user had an a form of payment on - file when the Payment Request was shown. + Whether the flow was completed when the user had at least one complete + suggestion offered for each requested information. + </summary> +</histogram> + +<histogram name="PaymentRequest.UserHadInitialFormOfPayment.EffectOnCompletion" + enum="PaymentRequestFlowCompletionStatus"> + <obsolete> + Replaced by PaymentRequest.NumberOfSuggestionsShown.PaymentMethod on July + 19th 2017. + </obsolete> + <owner>sebsg@chromium.org</owner> + <summary> + Whether the flow was completed when the user had a form of payment on file + when the Payment Request was shown. </summary> </histogram>
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc index a64d60ad..847f15a 100644 --- a/ui/android/delegated_frame_host_android.cc +++ b/ui/android/delegated_frame_host_android.cc
@@ -194,6 +194,10 @@ const viz::LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) {} +void DelegatedFrameHostAndroid::OnBeginFramePausedChanged(bool paused) { + begin_frame_source_.OnSetBeginFrameSourcePaused(paused); +} + void DelegatedFrameHostAndroid::OnNeedsBeginFrames(bool needs_begin_frames) { support_->SetNeedsBeginFrame(needs_begin_frames); }
diff --git a/ui/android/delegated_frame_host_android.h b/ui/android/delegated_frame_host_android.h index a37f6c87..3d2605ce 100644 --- a/ui/android/delegated_frame_host_android.h +++ b/ui/android/delegated_frame_host_android.h
@@ -86,6 +86,7 @@ const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) override; + void OnBeginFramePausedChanged(bool paused) override; // cc::ExternalBeginFrameSourceClient implementation. void OnNeedsBeginFrames(bool needs_begin_frames) override;
diff --git a/ui/aura/local/layer_tree_frame_sink_local.cc b/ui/aura/local/layer_tree_frame_sink_local.cc index 0a2a064e..d87672e 100644 --- a/ui/aura/local/layer_tree_frame_sink_local.cc +++ b/ui/aura/local/layer_tree_frame_sink_local.cc
@@ -109,6 +109,12 @@ begin_frame_source_->OnBeginFrame(args); } +void LayerTreeFrameSinkLocal::OnBeginFramePausedChanged(bool paused) { + DCHECK(thread_checker_); + DCHECK(thread_checker_->CalledOnValidThread()); + begin_frame_source_->OnSetBeginFrameSourcePaused(paused); +} + void LayerTreeFrameSinkLocal::ReclaimResources( const std::vector<cc::ReturnedResource>& resources) { DCHECK(thread_checker_);
diff --git a/ui/aura/local/layer_tree_frame_sink_local.h b/ui/aura/local/layer_tree_frame_sink_local.h index c7b22d2c..ab074b03 100644 --- a/ui/aura/local/layer_tree_frame_sink_local.h +++ b/ui/aura/local/layer_tree_frame_sink_local.h
@@ -53,6 +53,7 @@ const std::vector<cc::ReturnedResource>& resources) override; void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id, const gfx::Rect& damage_rect) override {} + void OnBeginFramePausedChanged(bool paused) override; // cc::ExternalBeginFrameSourceClient: void OnNeedsBeginFrames(bool needs_begin_frames) override;
diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc index 48219f0..b47bcc6 100644 --- a/ui/aura/window_tree_host.cc +++ b/ui/aura/window_tree_host.cc
@@ -41,6 +41,8 @@ // WindowTreeHost, public: WindowTreeHost::~WindowTreeHost() { + if (display::Screen::GetScreen()) + display::Screen::GetScreen()->RemoveObserver(this); DCHECK(!compositor_) << "compositor must be destroyed before root window"; if (owned_input_method_) { delete input_method_; @@ -224,7 +226,6 @@ // WindowTreeHost, protected: WindowTreeHost::WindowTreeHost() : WindowTreeHost(nullptr) { - display::Screen::GetScreen()->AddObserver(this); } WindowTreeHost::WindowTreeHost(std::unique_ptr<WindowPort> window_port) @@ -232,7 +233,7 @@ last_cursor_(ui::CursorType::kNull), input_method_(nullptr), owned_input_method_(false) { - display::Screen::GetScreen()->RemoveObserver(this); + display::Screen::GetScreen()->AddObserver(this); } void WindowTreeHost::DestroyCompositor() { @@ -350,13 +351,12 @@ void WindowTreeHost::OnDisplayMetricsChanged(const display::Display& display, uint32_t metrics) { - display::Screen* screen = display::Screen::GetScreen(); - if (display.id() != screen->GetDisplayNearestView(window()).id()) - return; - if (metrics & DisplayObserver::DISPLAY_METRIC_COLOR_SPACE) { - if (compositor_) + display::Screen* screen = display::Screen::GetScreen(); + if (compositor_ && + display.id() != screen->GetDisplayNearestView(window()).id()) { compositor_->SetDisplayColorSpace(display.color_space()); + } } }
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index 63ec3df..119d0fa 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -985,7 +985,7 @@ ] } - if (is_android || is_linux || is_mac || is_win) { + if (is_android || is_linux || is_mac || is_win || is_fuchsia) { # TODO(brettw): We should be able to depend on //ui/resources:ui_test_pak # instead of depending directly on the non-test .pak files, but depending # on ui_test_pak seems to have no effect. @@ -998,7 +998,7 @@ "//third_party/mesa:osmesa", ] } - if (is_linux || is_win) { + if (is_linux || is_win || is_fuchsia) { data += [ # TODO(brettw): Remove these two lines. "$root_out_dir/ui/en-US.pak",
diff --git a/ui/base/resource/resource_bundle_fuchsia.cc b/ui/base/resource/resource_bundle_fuchsia.cc index 3cf4a65..92b25bdf 100644 --- a/ui/base/resource/resource_bundle_fuchsia.cc +++ b/ui/base/resource/resource_bundle_fuchsia.cc
@@ -10,16 +10,12 @@ namespace ui { -// TODO(fuchsia): Implement ui::ResourceBundle. - void ResourceBundle::LoadCommonResources() { - NOTIMPLEMENTED(); + LoadChromeResources(); } gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) { - NOTIMPLEMENTED(); - CR_DEFINE_STATIC_LOCAL(gfx::Image, empty_image, ()); - return empty_image; + return GetImageNamed(resource_id); } } // namespace ui