diff --git a/DEPS b/DEPS index 0ead00e..93a093a 100644 --- a/DEPS +++ b/DEPS
@@ -403,7 +403,7 @@ # For Linux and Chromium OS. 'src/third_party/cros_system_api': - Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '0fed00b89ef09f5cafa1d4ed1f6c816b9710053e', + Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'e79b0c771217d6b84b85c692ae5740df8e8a2b36', # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite':
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 0bf51f9..2e817ae 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -481,6 +481,8 @@ # TODO(pcc): Make this conditional on is_official_build rather than on gn # flags for specific features. if (!is_debug && (allow_posix_link_time_opt || is_cfi) && !is_nacl) { + assert(use_lld || is_chromeos, "gold plugin only supported with ChromeOS") + if (use_thin_lto) { cflags += [ "-flto=thin" ] ldflags += [ "-flto=thin" ]
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 83369d9..73f3bf0 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -120,6 +120,14 @@ } declare_args() { + # Set to true to use lld, the LLVM linker. This flag may be used on Windows, + # Linux or Fuchsia. + use_lld = (is_win && host_os != "win") || is_fuchsia || + ((allow_posix_link_time_opt || is_cfi) && target_os == "linux" && + !is_chromeos && target_cpu == "x64") +} + +declare_args() { # Whether to use the gold linker from binutils instead of lld or bfd. use_gold = (!use_lld && !(is_chromecast && is_linux &&
diff --git a/build/toolchain/toolchain.gni b/build/toolchain/toolchain.gni index 70e0fa9..79f8ff8 100644 --- a/build/toolchain/toolchain.gni +++ b/build/toolchain/toolchain.gni
@@ -60,12 +60,6 @@ # Clang compiler version. Clang files are placed at version-dependent paths. clang_version = "5.0.0" } - - # Set to true to use lld, the LLVM linker. This flag may be used on Windows - # or Linux. - use_lld = (is_win && host_os != "win") || is_fuchsia || - (allow_posix_link_time_opt && target_os == "linux" && - !is_chromeos && target_cpu == "x64") } # Check target_os here instead of is_ios as this file is loaded for secondary
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index 3938185..1417d93 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/media/media_browsertest.h" @@ -107,6 +108,9 @@ // The type of video src used to load media. enum class SrcType { SRC, MSE }; +// How the CDM is hosted, using pepper or mojo. +enum class CdmHostType { kPepper, kMojo }; + // Must be in sync with CONFIG_CHANGE_TYPE in eme_player_js/global.js enum class ConfigChangeType { CLEAR_TO_CLEAR = 0, @@ -278,6 +282,7 @@ #endif // BUILDFLAG(ENABLE_PEPPER_CDMS) void SetUpCommandLineForKeySystem(const std::string& key_system, + CdmHostType cdm_host_type, base::CommandLine* command_line) { if (GetServerConfig(key_system)) // Since the web and license servers listen on different ports, we need to @@ -291,20 +296,28 @@ media::kClearKeyCdmAdapterFileName, media::kClearKeyCdmDisplayName, media::kClearKeyCdmPepperMimeType); - command_line->AppendSwitchASCII(switches::kEnableFeatures, - media::kExternalClearKeyForTesting.name); + if (cdm_host_type == CdmHostType::kMojo) { + scoped_feature_list_.InitWithFeatures( + {media::kExternalClearKeyForTesting, media::kMojoCdm}, {}); + } else { + scoped_feature_list_.InitWithFeatures( + {media::kExternalClearKeyForTesting}, {}); + } } #endif // BUILDFLAG(ENABLE_PEPPER_CDMS) } + + base::test::ScopedFeatureList scoped_feature_list_; }; #if BUILDFLAG(ENABLE_PEPPER_CDMS) // Tests encrypted media playback using ExternalClearKey key system in // decrypt-and-decode mode. -class ECKEncryptedMediaTest : public EncryptedMediaTestBase { +class ECKEncryptedMediaTest : public EncryptedMediaTestBase, + public testing::WithParamInterface<CdmHostType> { public: - // We use special |key_system| names to do non-playback related tests, e.g. - // kExternalClearKeyFileIOTestKeySystem is used to test file IO. + // We use special |key_system| names to do non-playback related tests, + // e.g. kExternalClearKeyFileIOTestKeySystem is used to test file IO. void TestNonPlaybackCases(const std::string& key_system, const std::string& expected_title) { // Since we do not test playback, arbitrarily choose a test file and source @@ -319,15 +332,18 @@ const std::string& session_to_load, const std::string& expected_title) { RunEncryptedMediaTest(kDefaultEmePlayer, "bear-320x240-v_enc-v.webm", - kWebMVP8VideoOnly, key_system, SrcType::SRC, + kWebMVP8VideoOnly, key_system, SrcType::MSE, session_to_load, false, PlayCount::ONCE, expected_title); } + bool IsUsingMojoCdm() const { return GetParam() == CdmHostType::kMojo; } + protected: void SetUpCommandLine(base::CommandLine* command_line) override { EncryptedMediaTestBase::SetUpCommandLine(command_line); - SetUpCommandLineForKeySystem(kExternalClearKeyKeySystem, command_line); + SetUpCommandLineForKeySystem(kExternalClearKeyKeySystem, GetParam(), + command_line); } }; @@ -337,7 +353,8 @@ protected: void SetUpCommandLine(base::CommandLine* command_line) override { EncryptedMediaTestBase::SetUpCommandLine(command_line); - SetUpCommandLineForKeySystem(kWidevineKeySystem, command_line); + SetUpCommandLineForKeySystem(kWidevineKeySystem, CdmHostType::kPepper, + command_line); } }; @@ -351,9 +368,10 @@ // Note: Only parameterized (*_P) tests can be used. Non-parameterized (*_F) // tests will crash at GetParam(). To add non-parameterized tests, use // EncryptedMediaTestBase or one of its subclasses (e.g. WVEncryptedMediaTest). -class EncryptedMediaTest : public EncryptedMediaTestBase, - public testing::WithParamInterface< - std::tr1::tuple<const char*, SrcType>> { +class EncryptedMediaTest + : public EncryptedMediaTestBase, + public testing::WithParamInterface< + std::tr1::tuple<const char*, SrcType, CdmHostType>> { public: std::string CurrentKeySystem() { return std::tr1::get<0>(GetParam()); @@ -363,6 +381,8 @@ return std::tr1::get<1>(GetParam()); } + CdmHostType CurrentCdmHostType() { return std::tr1::get<2>(GetParam()); } + void TestSimplePlayback(const std::string& encrypted_media, const std::string& media_type) { RunSimpleEncryptedMediaTest(encrypted_media, media_type, CurrentKeySystem(), @@ -449,7 +469,8 @@ protected: void SetUpCommandLine(base::CommandLine* command_line) override { EncryptedMediaTestBase::SetUpCommandLine(command_line); - SetUpCommandLineForKeySystem(CurrentKeySystem(), command_line); + SetUpCommandLineForKeySystem(CurrentKeySystem(), CurrentCdmHostType(), + command_line); } }; @@ -459,26 +480,40 @@ INSTANTIATE_TEST_CASE_P(MSE_ClearKey, EncryptedMediaTest, Combine(Values(kClearKeyKeySystem), - Values(SrcType::MSE))); + Values(SrcType::MSE), + Values(CdmHostType::kPepper))); // External Clear Key is currently only used on platforms that use Pepper CDMs. #if BUILDFLAG(ENABLE_PEPPER_CDMS) INSTANTIATE_TEST_CASE_P(SRC_ExternalClearKey, EncryptedMediaTest, Combine(Values(kExternalClearKeyKeySystem), - Values(SrcType::SRC))); + Values(SrcType::SRC), + Values(CdmHostType::kPepper))); INSTANTIATE_TEST_CASE_P(MSE_ExternalClearKey, EncryptedMediaTest, Combine(Values(kExternalClearKeyKeySystem), - Values(SrcType::MSE))); -#else + Values(SrcType::MSE), + Values(CdmHostType::kPepper))); + +// External Clear Key does not work with mojo CDM on Mac yet. +// See http://crbug.com/736106 +#if !defined(OS_MACOSX) +INSTANTIATE_TEST_CASE_P(MSE_ExternalClearKey_Mojo, + EncryptedMediaTest, + Combine(Values(kExternalClearKeyKeySystem), + Values(SrcType::MSE), + Values(CdmHostType::kMojo))); +#endif // !defined(OS_MACOSX) +#else // BUILDFLAG(ENABLE_PEPPER_CDMS) // To reduce test time, only run ClearKey SRC tests when we are not running // ExternalClearKey SRC tests. INSTANTIATE_TEST_CASE_P(SRC_ClearKey, EncryptedMediaTest, Combine(Values(kClearKeyKeySystem), - Values(SrcType::SRC))); + Values(SrcType::SRC), + Values(CdmHostType::kPepper))); #endif // BUILDFLAG(ENABLE_PEPPER_CDMS) #if defined(WIDEVINE_CDM_AVAILABLE) @@ -486,7 +521,14 @@ INSTANTIATE_TEST_CASE_P(MSE_Widevine, EncryptedMediaTest, Combine(Values(kWidevineKeySystem), - Values(SrcType::MSE))); + Values(SrcType::MSE), + Values(CdmHostType::kPepper))); + +INSTANTIATE_TEST_CASE_P(MSE_Widevine_Mojo, + EncryptedMediaTest, + Combine(Values(kWidevineKeySystem), + Values(SrcType::MSE), + Values(CdmHostType::kMojo))); #endif // !defined(OS_CHROMEOS) #endif // defined(WIDEVINE_CDM_AVAILABLE) @@ -648,53 +690,98 @@ } #endif // defined(WIDEVINE_CDM_AVAILABLE) +INSTANTIATE_TEST_CASE_P(Pepper, + ECKEncryptedMediaTest, + Values(CdmHostType::kPepper)); + +// External Clear Key does not work with mojo CDM on Mac yet. +// See http://crbug.com/736106 +#if !defined(OS_MACOSX) +INSTANTIATE_TEST_CASE_P(Mojo, + ECKEncryptedMediaTest, + Values(CdmHostType::kMojo)); +#endif // !defined(OS_MACOSX) + #if BUILDFLAG(ENABLE_PEPPER_CDMS) -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, InitializeCDMFail) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, InitializeCDMFail) { TestNonPlaybackCases(kExternalClearKeyInitializeFailKeySystem, kEmeNotSupportedError); } // When CDM crashes, we should still get a decode error and all sessions should // be closed. -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, CDMCrashDuringDecode) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, CDMCrashDuringDecode) { + // TODO(xhwang): Handle mojo CDM crash correctly. See http://crbug.com/730766 + if (IsUsingMojoCdm()) { + DVLOG(0) << "Skipping test; Not working with mojo CDM yet."; + return; + } + IgnorePluginCrash(); TestNonPlaybackCases(kExternalClearKeyCrashKeySystem, kEmeSessionClosedAndError); } // Testing that the media browser test does fail on plugin crash. -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, CDMExpectedCrash) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, CDMExpectedCrash) { + // TODO(xhwang): Handle mojo CDM crash correctly. See http://crbug.com/730766 + if (IsUsingMojoCdm()) { + DVLOG(0) << "Skipping test; Not working with mojo CDM yet."; + return; + } + // Plugin crash is not ignored by default, the test is expected to fail. EXPECT_NONFATAL_FAILURE(TestNonPlaybackCases(kExternalClearKeyCrashKeySystem, kEmeSessionClosedAndError), "Failing test due to plugin crash."); } -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, FileIOTest) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, FileIOTest) { + // TODO(jrummell): Support file IO in mojo CDM. See http://crbug.com/479923 + if (IsUsingMojoCdm()) { + DVLOG(0) << "Skipping test; Not working with mojo CDM yet."; + return; + } + TestNonPlaybackCases(kExternalClearKeyFileIOTestKeySystem, kUnitTestSuccess); } // TODO(xhwang): Investigate how to fake capturing activities to test the // network link detection logic in OutputProtectionProxy. -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, OutputProtectionTest) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, OutputProtectionTest) { + // TODO(xhwang): Support output protection in mojo CDM. See + // http://crbug.com/479843 + if (IsUsingMojoCdm()) { + DVLOG(0) << "Skipping test; Not working with mojo CDM yet."; + return; + } + TestNonPlaybackCases(kExternalClearKeyOutputProtectionTestKeySystem, kUnitTestSuccess); } -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, PlatformVerificationTest) { +// TODO(xhwang): Update this test to cover mojo PlatformVerification service +// on ChromeOS. See http://crbug.com/479836 +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, PlatformVerificationTest) { TestNonPlaybackCases(kExternalClearKeyPlatformVerificationTestKeySystem, kUnitTestSuccess); } -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, Renewal) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, Renewal) { + // TODO(xhwang): Fix renewal time. See http://crbug.com/730762 + if (IsUsingMojoCdm()) { + DVLOG(0) << "Skipping test; Not working with mojo CDM yet."; + return; + } + TestPlaybackCase(kExternalClearKeyRenewalKeySystem, kNoSessionToLoad, kEnded); } -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, LoadLoadableSession) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, LoadLoadableSession) { TestPlaybackCase(kExternalClearKeyKeySystem, kLoadableSession, kEnded); } -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, LoadUnknownSession) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, LoadUnknownSession) { TestPlaybackCase(kExternalClearKeyKeySystem, kUnknownSession, kEmeSessionNotFound); } @@ -702,14 +789,14 @@ const char kExternalClearKeyDecryptOnlyKeySystem[] = "org.chromium.externalclearkey.decryptonly"; -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, DecryptOnly_VideoAudio_WebM) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, DecryptOnly_VideoAudio_WebM) { RunSimpleEncryptedMediaTest( "bear-320x240-av_enc-av.webm", kWebMVorbisAudioVP8Video, kExternalClearKeyDecryptOnlyKeySystem, SrcType::MSE); } #if BUILDFLAG(USE_PROPRIETARY_CODECS) -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, DecryptOnly_VideoOnly_MP4_VP9) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, DecryptOnly_VideoOnly_MP4_VP9) { RunSimpleEncryptedMediaTest( "bear-320x240-v_frag-vp9-cenc.mp4", kMP4VideoVp9Only, kExternalClearKeyDecryptOnlyKeySystem, SrcType::MSE); @@ -718,7 +805,14 @@ #endif // BUILDFLAG(ENABLE_PEPPER_CDMS) #if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) -IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, VerifyCdmHostTest) { +IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, VerifyCdmHostTest) { + // TODO(xhwang): Enable CDM host verification in mojo CDM. See + // http://crbug.com/730770 + if (IsUsingMojoCdm()) { + DVLOG(0) << "Skipping test; Not working with mojo CDM yet."; + return; + } + TestNonPlaybackCases(kExternalClearKeyVerifyCdmHostTestKeySystem, kUnitTestSuccess); }
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc index 5f3c17c5..9e20e63c 100644 --- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -46,6 +46,7 @@ #include "components/ntp_snippets/features.h" #include "components/ntp_snippets/ntp_snippets_constants.h" #include "components/ntp_snippets/remote/persistent_scheduler.h" +#include "components/ntp_snippets/remote/prefetched_pages_tracker.h" #include "components/ntp_snippets/remote/remote_suggestions_database.h" #include "components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h" #include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h" @@ -83,6 +84,7 @@ #include "chrome/browser/android/offline_pages/request_coordinator_factory.h" #include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h" #include "components/ntp_snippets/offline_pages/recent_tab_suggestions_provider.h" +#include "components/ntp_snippets/remote/prefetched_pages_tracker_impl.h" #include "components/offline_pages/core/background/request_coordinator.h" #include "components/offline_pages/core/offline_page_feature.h" #include "components/offline_pages/core/offline_page_model.h" @@ -105,6 +107,7 @@ using ntp_snippets::GetPushUpdatesSubscriptionEndpoint; using ntp_snippets::GetPushUpdatesUnsubscriptionEndpoint; using ntp_snippets::PersistentScheduler; +using ntp_snippets::PrefetchedPagesTracker; using ntp_snippets::RemoteSuggestionsDatabase; using ntp_snippets::RemoteSuggestionsFetcherImpl; using ntp_snippets::RemoteSuggestionsProviderImpl; @@ -124,10 +127,11 @@ #endif // OS_ANDROID #if BUILDFLAG(ENABLE_OFFLINE_PAGES) +using ntp_snippets::PrefetchedPagesTrackerImpl; using ntp_snippets::RecentTabSuggestionsProvider; using offline_pages::OfflinePageModel; -using offline_pages::RequestCoordinator; using offline_pages::OfflinePageModelFactory; +using offline_pages::RequestCoordinator; using offline_pages::RequestCoordinatorFactory; #endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) @@ -298,7 +302,8 @@ void RegisterArticleProviderIfEnabled(ContentSuggestionsService* service, Profile* profile, SigninManagerBase* signin_manager, - UserClassifier* user_classifier) { + UserClassifier* user_classifier, + OfflinePageModel* offline_page_model) { if (!IsArticleProviderEnabled()) { return; } @@ -337,6 +342,11 @@ chrome::android::kContentSuggestionsSettings)) { additional_toggle_pref = prefs::kSearchSuggestEnabled; } + std::unique_ptr<PrefetchedPagesTracker> prefetched_pages_tracker; +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + prefetched_pages_tracker = + base::MakeUnique<PrefetchedPagesTrackerImpl>(offline_page_model); +#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) auto suggestions_fetcher = base::MakeUnique<RemoteSuggestionsFetcherImpl>( signin_manager, token_service, request_context, pref_service, language_model, base::Bind(&safe_json::SafeJsonParser::Parse), @@ -349,7 +359,8 @@ request_context.get()), base::MakeUnique<RemoteSuggestionsDatabase>(database_dir, task_runner), base::MakeUnique<RemoteSuggestionsStatusService>( - signin_manager, pref_service, additional_toggle_pref)); + signin_manager, pref_service, additional_toggle_pref), + std::move(prefetched_pages_tracker)); service->remote_suggestions_scheduler()->SetProvider(provider.get()); service->set_remote_suggestions_provider(provider.get()); @@ -510,7 +521,7 @@ std::move(scheduler)); RegisterArticleProviderIfEnabled(service, profile, signin_manager, - user_classifier_raw); + user_classifier_raw, offline_page_model); RegisterBookmarkProviderIfEnabled(service, profile); RegisterForeignSessionsProviderIfEnabled(service, profile);
diff --git a/chrome/browser/search/hotword_audio_history_handler.cc b/chrome/browser/search/hotword_audio_history_handler.cc index 1553fc8..0d418db30 100644 --- a/chrome/browser/search/hotword_audio_history_handler.cc +++ b/chrome/browser/search/hotword_audio_history_handler.cc
@@ -54,6 +54,8 @@ void HotwordAudioHistoryHandler::GetAudioHistoryEnabled( const HotwordAudioHistoryCallback& callback) { +// Please add network traffic annotation if you want to remove this #if. +#if defined(OS_CHROMEOS) history::WebHistoryService* web_history = GetWebHistory(); if (web_history) { web_history->GetAudioHistoryEnabled( @@ -66,11 +68,17 @@ PrefService* prefs = profile_->GetPrefs(); callback.Run(false, prefs->GetBoolean(prefs::kHotwordAudioLoggingEnabled)); } +#else + NOTREACHED() + << ": This functions is supposed to be called only in Chrome OS."; +#endif // defined(OS_CHROMEOS) } void HotwordAudioHistoryHandler::SetAudioHistoryEnabled( const bool enabled, const HotwordAudioHistoryCallback& callback) { +// Please add network traffic annotation if you want to remove this #if. +#if defined(OS_CHROMEOS) history::WebHistoryService* web_history = GetWebHistory(); if (web_history) { web_history->SetAudioHistoryEnabled( @@ -84,6 +92,10 @@ PrefService* prefs = profile_->GetPrefs(); callback.Run(false, prefs->GetBoolean(prefs::kHotwordAudioLoggingEnabled)); } +#else + NOTREACHED() + << ": This functions is supposed to be called only in Chrome OS."; +#endif // defined(OS_CHROMEOS) } void HotwordAudioHistoryHandler::GetAudioHistoryComplete(
diff --git a/chrome/browser/search/hotword_service.cc b/chrome/browser/search/hotword_service.cc index 1abfa69b..4407c118 100644 --- a/chrome/browser/search/hotword_service.cc +++ b/chrome/browser/search/hotword_service.cc
@@ -365,8 +365,14 @@ &HotwordService::MaybeReinstallHotwordExtension), weak_factory_.GetWeakPtr())); +// This service is actually used only on ChromeOS, and the next function +// results in a sequence of calls that triggers +// HotwordAudioHistoryHandler::GetAudioHistoryEnabled which is not supported +// on other platforms. +#if defined(OS_CHROMEOS) SetAudioHistoryHandler(new HotwordAudioHistoryHandler( profile_, base::ThreadTaskRunnerHandle::Get())); +#endif if (HotwordServiceFactory::IsAlwaysOnAvailable() && IsHotwordAllowed()) {
diff --git a/chrome/browser/ssl/security_state_tab_helper_browser_tests.cc b/chrome/browser/ssl/security_state_tab_helper_browser_tests.cc index 34fc79dd..a16b6173 100644 --- a/chrome/browser/ssl/security_state_tab_helper_browser_tests.cc +++ b/chrome/browser/ssl/security_state_tab_helper_browser_tests.cc
@@ -68,6 +68,8 @@ const base::FilePath::CharType kDocRoot[] = FILE_PATH_LITERAL("chrome/test/data"); +const std::string kTestCertificateIssuerName = "Test Root CA"; + // Inject a script into every frame in the page. Used by tests that check for // visible password fields to wait for notifications about these // fields. Notifications about visible password fields are queued at the end of @@ -166,11 +168,14 @@ ASSERT_EQ(cert_status == VALID_CERTIFICATE ? 2u : 1u, secure_explanations.size()); if (cert_status == VALID_CERTIFICATE) { + ASSERT_EQ(kTestCertificateIssuerName, + expected_cert->issuer().GetDisplayName()); EXPECT_EQ(l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE), secure_explanations[0].summary); - EXPECT_EQ( - l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION), - secure_explanations[0].description); + EXPECT_EQ(l10n_util::GetStringFUTF8( + IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION, + base::UTF8ToUTF16(kTestCertificateIssuerName)), + secure_explanations[0].description); net::X509Certificate* cert = browser->tab_strip_model() ->GetActiveWebContents() ->GetController() @@ -2120,16 +2125,16 @@ // Populate description string replacement with values corresponding // to test constants. std::vector<base::string16> description_replacements; - description_replacements.push_back( - l10n_util::GetStringUTF16(IDS_SSL_AN_OBSOLETE_PROTOCOL)); description_replacements.push_back(base::ASCIIToUTF16("TLS 1.1")); description_replacements.push_back( - l10n_util::GetStringUTF16(IDS_SSL_A_STRONG_KEY_EXCHANGE)); + l10n_util::GetStringUTF16(IDS_SSL_AN_OBSOLETE_PROTOCOL)); description_replacements.push_back(base::ASCIIToUTF16("ECDHE_RSA")); description_replacements.push_back( - l10n_util::GetStringUTF16(IDS_SSL_AN_OBSOLETE_CIPHER)); + l10n_util::GetStringUTF16(IDS_SSL_A_STRONG_KEY_EXCHANGE)); description_replacements.push_back( base::ASCIIToUTF16("AES_128_CBC with HMAC-SHA1")); + description_replacements.push_back( + l10n_util::GetStringUTF16(IDS_SSL_AN_OBSOLETE_CIPHER)); base::string16 obsolete_description = l10n_util::GetStringFUTF16( IDS_OBSOLETE_SSL_DESCRIPTION, description_replacements, nullptr);
diff --git a/chrome/test/data/nacl/BUILD.gn b/chrome/test/data/nacl/BUILD.gn index 8258044c..4a46affe 100644 --- a/chrome/test/data/nacl/BUILD.gn +++ b/chrome/test/data/nacl/BUILD.gn
@@ -2,9 +2,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/compiler/compiler.gni") import("//build/config/features.gni") import("//build/config/nacl/config.gni") -import("//build/toolchain/toolchain.gni") import("//ppapi/native_client/nacl_test_data.gni") group("nacl") {
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker.h b/components/ntp_snippets/remote/prefetched_pages_tracker.h index 9766ad3..b81e78c1 100644 --- a/components/ntp_snippets/remote/prefetched_pages_tracker.h +++ b/components/ntp_snippets/remote/prefetched_pages_tracker.h
@@ -27,7 +27,7 @@ virtual void AddInitializationCompletedCallback( base::OnceCallback<void()> callback) = 0; - virtual bool PrefetchedOfflinePageExists(const GURL url) const = 0; + virtual bool PrefetchedOfflinePageExists(const GURL& url) const = 0; }; } // namespace ntp_snippets
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc index b00b339..df17693 100644 --- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc +++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
@@ -67,7 +67,7 @@ } bool PrefetchedPagesTrackerImpl::PrefetchedOfflinePageExists( - const GURL url) const { + const GURL& url) const { DCHECK(initialized_); return prefetched_urls_.count(url) == 1; }
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.h b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.h index 3c6b41ac..045c98e 100644 --- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.h +++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.h
@@ -34,7 +34,7 @@ bool IsInitialized() const override; void AddInitializationCompletedCallback( base::OnceCallback<void()> callback) override; - bool PrefetchedOfflinePageExists(const GURL url) const override; + bool PrefetchedOfflinePageExists(const GURL& url) const override; // OfflinePageModel::Observer implementation. void OfflinePageModelLoaded(offline_pages::OfflinePageModel* model) override;
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc b/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc index db8a5ae..ebeb516 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl.cc
@@ -63,6 +63,14 @@ const char kOrderNewRemoteCategoriesBasedOnArticlesCategory[] = "order_new_remote_categories_based_on_articles_category"; +// Not more than this number of prefetched suggestions will be kept longer. +const int kMaxAdditionalPrefetchedSuggestions = 5; + +// Only prefetched suggestions published not later than this are considered to +// be kept longer. +const base::TimeDelta kMaxAgeForAdditionalPrefetchedSuggestion = + base::TimeDelta::FromHours(36); + bool IsOrderingNewRemoteCategoriesBasedOnArticlesCategoryEnabled() { return variations::GetVariationParamByFeatureAsBool( ntp_snippets::kArticleSuggestionsFeature, @@ -98,6 +106,10 @@ NOTREACHED() << "Articles category was not found."; } +bool IsKeepingPrefetchedSuggestionsEnabled() { + return base::FeatureList::IsEnabled(kKeepPrefetchedContentSuggestions); +} + template <typename SuggestionPtrContainer> std::unique_ptr<std::vector<std::string>> GetSuggestionIDVector( const SuggestionPtrContainer& suggestions) { @@ -342,7 +354,8 @@ std::unique_ptr<RemoteSuggestionsFetcher> suggestions_fetcher, std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, std::unique_ptr<RemoteSuggestionsDatabase> database, - std::unique_ptr<RemoteSuggestionsStatusService> status_service) + std::unique_ptr<RemoteSuggestionsStatusService> status_service, + std::unique_ptr<PrefetchedPagesTracker> prefetched_pages_tracker) : RemoteSuggestionsProvider(observer), state_(State::NOT_INITED), pref_service_(pref_service), @@ -358,7 +371,8 @@ fetch_when_ready_(false), fetch_when_ready_interactive_(false), clear_history_dependent_state_when_initialized_(false), - clock_(base::MakeUnique<base::DefaultClock>()) { + clock_(base::MakeUnique<base::DefaultClock>()), + prefetched_pages_tracker_(std::move(prefetched_pages_tracker)) { RestoreCategoriesFromPrefs(); // The articles category always exists. Add it if we didn't get it from prefs. // TODO(treib): Rethink this. @@ -752,6 +766,16 @@ return; } + if (IsKeepingPrefetchedSuggestionsEnabled() && prefetched_pages_tracker_ && + !prefetched_pages_tracker_->IsInitialized()) { + // Wait until the tracker is initialized. + prefetched_pages_tracker_->AddInitializationCompletedCallback( + base::BindOnce(&RemoteSuggestionsProviderImpl::OnFetchFinished, + base::Unretained(this), callback, interactive_request, + status, std::move(fetched_categories))); + return; + } + // Record the fetch time of a successfull background fetch. if (!interactive_request && status.IsSuccess()) { pref_service_->SetInt64(prefs::kLastSuccessfulBackgroundFetchTime, @@ -792,7 +816,8 @@ content->included_in_last_server_response = true; SanitizeReceivedSuggestions(content->dismissed, &fetched_category.suggestions); - IntegrateSuggestions(content, std::move(fetched_category.suggestions)); + IntegrateSuggestions(fetched_category.category, content, + std::move(fetched_category.suggestions)); } // Add new remote categories to the ranker. @@ -868,6 +893,7 @@ } void RemoteSuggestionsProviderImpl::IntegrateSuggestions( + Category category, CategoryContent* content, RemoteSuggestion::PtrVector new_suggestions) { DCHECK(ready()); @@ -888,6 +914,51 @@ // IDs though). EraseByPrimaryID(&content->suggestions, *GetSuggestionIDVector(new_suggestions)); + + // If enabled, keep some older prefetched article suggestions, otherwise the + // user has little time to see them. + if (IsKeepingPrefetchedSuggestionsEnabled() && + category == articles_category_ && prefetched_pages_tracker_) { + DCHECK(prefetched_pages_tracker_->IsInitialized()); + + // Select suggestions to keep. + std::sort(content->suggestions.begin(), content->suggestions.end(), + [](const std::unique_ptr<RemoteSuggestion>& first, + const std::unique_ptr<RemoteSuggestion>& second) { + return first->fetch_date() > second->fetch_date(); + }); + std::vector<std::unique_ptr<RemoteSuggestion>> + additional_prefetched_suggestions, other_suggestions; + for (auto& remote_suggestion : content->suggestions) { + const GURL& url = remote_suggestion->amp_url().is_empty() + ? remote_suggestion->url() + : remote_suggestion->amp_url(); + if (prefetched_pages_tracker_->PrefetchedOfflinePageExists(url) && + clock_->Now() - remote_suggestion->fetch_date() < + kMaxAgeForAdditionalPrefetchedSuggestion && + additional_prefetched_suggestions.size() < + kMaxAdditionalPrefetchedSuggestions) { + additional_prefetched_suggestions.push_back( + std::move(remote_suggestion)); + } else { + other_suggestions.push_back(std::move(remote_suggestion)); + } + } + + // Mix them into the new set according to their score. + for (auto& remote_suggestion : additional_prefetched_suggestions) { + new_suggestions.push_back(std::move(remote_suggestion)); + } + std::sort(new_suggestions.begin(), new_suggestions.end(), + [](const std::unique_ptr<RemoteSuggestion>& first, + const std::unique_ptr<RemoteSuggestion>& second) { + return first->score() > second->score(); + }); + + // Treat remaining suggestions as usual. + content->suggestions = std::move(other_suggestions); + } + // Do not delete the thumbnail images as they are still handy on open NTPs. database_->DeleteSnippets(GetSuggestionIDVector(content->suggestions)); // Note, that ArchiveSuggestions will clear |content->suggestions|.
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl.h b/components/ntp_snippets/remote/remote_suggestions_provider_impl.h index a5ac7f57..dac737b 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl.h +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl.h
@@ -26,6 +26,7 @@ #include "components/ntp_snippets/content_suggestion.h" #include "components/ntp_snippets/content_suggestions_provider.h" #include "components/ntp_snippets/remote/json_to_categories.h" +#include "components/ntp_snippets/remote/prefetched_pages_tracker.h" #include "components/ntp_snippets/remote/remote_suggestion.h" #include "components/ntp_snippets/remote/remote_suggestions_fetcher.h" #include "components/ntp_snippets/remote/remote_suggestions_provider.h" @@ -123,7 +124,8 @@ std::unique_ptr<RemoteSuggestionsFetcher> suggestions_fetcher, std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher, std::unique_ptr<RemoteSuggestionsDatabase> database, - std::unique_ptr<RemoteSuggestionsStatusService> status_service); + std::unique_ptr<RemoteSuggestionsStatusService> status_service, + std::unique_ptr<PrefetchedPagesTracker> prefetched_pages_tracker); ~RemoteSuggestionsProviderImpl() override; @@ -334,8 +336,9 @@ void SanitizeReceivedSuggestions(const RemoteSuggestion::PtrVector& dismissed, RemoteSuggestion::PtrVector* suggestions); - // Adds newly available suggestions to |content|. - void IntegrateSuggestions(CategoryContent* content, + // Adds newly available suggestions to |content| corresponding to |category|. + void IntegrateSuggestions(Category category, + CategoryContent* content, RemoteSuggestion::PtrVector new_suggestions); // Dismisses a suggestion within a given category content. @@ -464,6 +467,9 @@ // A clock for getting the time. This allows to inject a clock in tests. std::unique_ptr<base::Clock> clock_; + // Prefetched pages tracker to query which urls have been prefetched. + std::unique_ptr<PrefetchedPagesTracker> prefetched_pages_tracker_; + DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderImpl); };
diff --git a/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc index 8a4a178..d2b95e9 100644 --- a/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc +++ b/components/ntp_snippets/remote/remote_suggestions_provider_impl_unittest.cc
@@ -88,6 +88,11 @@ namespace { +ACTION_P(MoveFirstArgumentPointeeTo, ptr) { + // 0-based indexation. + *ptr = std::move(*arg0); +} + ACTION_P(MoveSecondArgumentPointeeTo, ptr) { // 0-based indexation. *ptr = std::move(*arg1); @@ -117,6 +122,11 @@ const int kUnknownRemoteCategoryId = 1234; +const int kMaxAdditionalPrefetchedSuggestions = 5; + +const base::TimeDelta kMaxAgeForAdditionalPrefetchedSuggestion = + base::TimeDelta::FromHours(36); + base::Time GetDefaultCreationTime() { base::Time out_time; EXPECT_TRUE(base::Time::FromUTCExploded(kDefaultCreationTime, &out_time)); @@ -219,7 +229,8 @@ const base::Time& creation_time, const base::Time& expiry_time, const std::string& publisher, - const std::string& amp_url) { + const std::string& amp_url, + double score) { const std::string ids_string = base::JoinString(ids, "\",\n \""); return base::StringPrintf( "{\n" @@ -233,19 +244,29 @@ " \"expirationTime\": \"%s\",\n" " \"attribution\": \"%s\",\n" " \"imageUrl\": \"%s\",\n" - " \"ampUrl\": \"%s\"\n" + " \"ampUrl\": \"%s\",\n" + " \"score\": %f\n" " }", ids_string.c_str(), kSuggestionTitle, kSuggestionText, url.c_str(), FormatTime(creation_time).c_str(), FormatTime(expiry_time).c_str(), - publisher.c_str(), kSuggestionSalientImage, amp_url.c_str()); + publisher.c_str(), kSuggestionSalientImage, amp_url.c_str(), score); } std::string GetSuggestionWithSources(const std::string& source_url, const std::string& publisher, const std::string& amp_url) { return GetSuggestionWithUrlAndTimesAndSource( - {kSuggestionUrl}, source_url, GetDefaultCreationTime(), - GetDefaultExpirationTime(), publisher, amp_url); + {source_url}, source_url, GetDefaultCreationTime(), + GetDefaultExpirationTime(), publisher, amp_url, /*score=*/1); +} + +std::string GetSuggestionWithSourcesAndScore(const std::string& source_url, + const std::string& publisher, + const std::string& amp_url, + double score) { + return GetSuggestionWithUrlAndTimesAndSource( + {source_url}, source_url, GetDefaultCreationTime(), + GetDefaultExpirationTime(), publisher, amp_url, score); } std::string GetSuggestionWithUrlAndTimes( @@ -254,7 +275,7 @@ const base::Time& expiry_time) { return GetSuggestionWithUrlAndTimesAndSource( {url}, url, content_creation_time, expiry_time, kSuggestionPublisherName, - kSuggestionAmpUrl); + kSuggestionAmpUrl, /*score=*/1); } std::string GetSuggestionWithTimes(const base::Time& content_creation_time, @@ -428,6 +449,22 @@ MOCK_CONST_METHOD0(GetFetchUrlForDebugging, const GURL&()); }; +class MockPrefetchedPagesTracker : public PrefetchedPagesTracker { + public: + MOCK_CONST_METHOD0(IsInitialized, bool()); + + // GMock does not support movable-only types (e.g. OnceCallback), therefore, + // the call is redirected to a mock method with a pointer to the callback. + void AddInitializationCompletedCallback( + base::OnceCallback<void()> callback) override { + AddInitializationCompletedCallback(&callback); + } + MOCK_METHOD1(AddInitializationCompletedCallback, + void(base::OnceCallback<void()>* callback)); + + MOCK_CONST_METHOD1(PrefetchedOfflinePageExists, bool(const GURL& url)); +}; + } // namespace class RemoteSuggestionsProviderImplTest : public ::testing::Test { @@ -466,7 +503,8 @@ std::unique_ptr<RemoteSuggestionsProviderImpl> MakeSuggestionsProvider( bool set_empty_response = true) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/false); + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/false); WaitForSuggestionsProviderInitialization(provider.get(), set_empty_response); return provider; @@ -475,7 +513,8 @@ // TODO(vitaliii): Rewrite tests and always use mock suggestions fetcher. std::unique_ptr<RemoteSuggestionsProviderImpl> MakeSuggestionsProviderWithoutInitialization( - bool use_mock_suggestions_fetcher) { + bool use_mock_suggestions_fetcher, + bool use_mock_prefetched_pages_tracker) { scoped_refptr<base::SingleThreadTaskRunner> task_runner( base::ThreadTaskRunnerHandle::Get()); scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = @@ -496,6 +535,13 @@ } suggestions_fetcher_ = suggestions_fetcher.get(); + std::unique_ptr<PrefetchedPagesTracker> prefetched_pages_tracker; + if (use_mock_prefetched_pages_tracker) { + prefetched_pages_tracker = + base::MakeUnique<StrictMock<MockPrefetchedPagesTracker>>(); + } + prefetched_pages_tracker_ = prefetched_pages_tracker.get(); + auto image_fetcher = base::MakeUnique<NiceMock<MockImageFetcher>>(); image_fetcher_ = image_fetcher.get(); @@ -512,15 +558,16 @@ scheduler_.get(), std::move(suggestions_fetcher), std::move(image_fetcher), std::move(database), base::MakeUnique<RemoteSuggestionsStatusService>( - utils_.fake_signin_manager(), utils_.pref_service(), - std::string())); + utils_.fake_signin_manager(), utils_.pref_service(), std::string()), + std::move(prefetched_pages_tracker)); } std::unique_ptr<RemoteSuggestionsProviderImpl> MakeSuggestionsProviderWithoutInitializationWithStrictScheduler() { scheduler_ = base::MakeUnique<StrictMock<MockScheduler>>(); return MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/false); + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/false); } void WaitForSuggestionsProviderInitialization( @@ -579,6 +626,9 @@ RemoteSuggestionsFetcher* suggestions_fetcher() { return suggestions_fetcher_; } + PrefetchedPagesTracker* prefetched_pages_tracker() { + return prefetched_pages_tracker_; + } // TODO(tschumann): Make this a strict-mock. We want to avoid unneccesary // network requests. NiceMock<MockImageFetcher>* image_fetcher() { return image_fetcher_; } @@ -643,6 +693,19 @@ {kArticleSuggestionsFeature.name}); } + void EnableKeepingPrefetchedContentSuggestions() { + // params_manager supports only one + // |SetVariationParamsWithFeatureAssociations| at a time, so we clear + // previous settings first and then set everything we need. + params_manager_.ClearAllVariationParams(); + params_manager_.SetVariationParamsWithFeatureAssociations( + kKeepPrefetchedContentSuggestions.name, + {{"content_suggestions_backend", + kTestContentSuggestionsServerEndpoint}}, + {kArticleSuggestionsFeature.name, + kKeepPrefetchedContentSuggestions.name}); + } + private: variations::testing::VariationParamsManager params_manager_; test::RemoteSuggestionsTestUtils utils_; @@ -655,6 +718,7 @@ UserClassifier user_classifier_; std::unique_ptr<FakeContentSuggestionsProviderObserver> observer_; RemoteSuggestionsFetcher* suggestions_fetcher_; + PrefetchedPagesTracker* prefetched_pages_tracker_; NiceMock<MockImageFetcher>* image_fetcher_; FakeImageDecoder image_decoder_; std::unique_ptr<MockScheduler> scheduler_; @@ -1113,7 +1177,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldNotChangeSuggestionsInOtherSurfacesWhenFetchingMore) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/true); + /*use_mock_suggestions_fetcher=*/true, + /*use_mock_prefetched_pages_tracker=*/false); WaitForSuggestionsProviderInitialization(provider.get(), /*set_empty_response=*/true); @@ -1186,7 +1251,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldNotAffectFetchMoreInOtherSurfacesWhenFetchingMore) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/true); + /*use_mock_suggestions_fetcher=*/true, + /*use_mock_prefetched_pages_tracker=*/false); WaitForSuggestionsProviderInitialization(provider.get(), /*set_empty_response=*/true); auto* mock_fetcher = static_cast<StrictMock<MockRemoteSuggestionsFetcher>*>( @@ -1309,7 +1375,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ReturnFetchRequestEmptyBeforeInit) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/false); + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/false); MockFunction<void(Status, const std::vector<ContentSuggestion>&)> loaded; EXPECT_CALL(loaded, Call(Field(&Status::code, StatusCode::TEMPORARY_ERROR), IsEmpty())); @@ -1443,7 +1510,8 @@ EXPECT_CALL(*image_fetcher(), StartOrQueueNetworkRequest(_, _, _, _)) .WillOnce(WithArgs<0, 2>(Invoke(CreateFunctor(cb)))); image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1)); - gfx::Image image = FetchImage(provider.get(), MakeArticleID(kSuggestionUrl)); + gfx::Image image = + FetchImage(provider.get(), MakeArticleID("http://site.com")); EXPECT_FALSE(image.IsEmpty()); EXPECT_EQ(1, image.Width()); @@ -1453,7 +1521,7 @@ SizeIs(1)); // Dismiss the suggestion. - provider->DismissSuggestion(MakeArticleID(kSuggestionUrl)); + provider->DismissSuggestion(MakeArticleID("http://site.com")); EXPECT_THAT(provider->GetSuggestionsForTesting(articles_category()), IsEmpty()); @@ -1461,7 +1529,7 @@ // might still reference it). This should come from the database -- no network // fetch necessary. image_decoder()->SetDecodedImage(gfx::test::CreateImage(1, 1)); - image = FetchImage(provider.get(), MakeArticleID(kSuggestionUrl)); + image = FetchImage(provider.get(), MakeArticleID("http://site.com")); EXPECT_FALSE(image.IsEmpty()); EXPECT_EQ(1, image.Width()); @@ -1589,7 +1657,7 @@ SizeIs(1)); const RemoteSuggestion& suggestion = *provider->GetSuggestionsForTesting(articles_category()).front(); - EXPECT_EQ(suggestion.id(), kSuggestionUrl); + EXPECT_EQ(suggestion.id(), "http://source1.com"); EXPECT_EQ(suggestion.url(), GURL("http://source1.com")); EXPECT_EQ(suggestion.publisher_name(), std::string("Source 1")); EXPECT_EQ(suggestion.amp_url(), GURL("http://source1.amp.com")); @@ -1691,7 +1759,7 @@ LoadFromJSONString(provider.get(), GetTestJson({GetSuggestionWithUrlAndTimesAndSource( source_urls, source_urls[0], creation, expiry, - publishers[0], amp_urls[0])})); + publishers[0], amp_urls[0], /*score=*/1)})); ASSERT_THAT(provider->GetSuggestionsForTesting(articles_category()), SizeIs(1)); // Dismiss the suggestion via the mashable source corpus ID. @@ -1703,7 +1771,7 @@ LoadFromJSONString(provider.get(), GetTestJson({GetSuggestionWithUrlAndTimesAndSource( source_urls, source_urls[1], creation, expiry, - publishers[1], amp_urls[1])})); + publishers[1], amp_urls[1], /*score=*/1)})); EXPECT_THAT(provider->GetSuggestionsForTesting(articles_category()), IsEmpty()); } @@ -1870,7 +1938,8 @@ // is triggered since the suggestions DB is empty. Therefore the provider must // not be initialized until the test clock is set. auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/false); + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/false); auto simple_test_clock = base::MakeUnique<base::SimpleTestClock>(); base::SimpleTestClock* simple_test_clock_ptr = simple_test_clock.get(); @@ -1980,7 +2049,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldExcludeKnownSuggestionsWithoutTruncatingWhenFetchingMore) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/true); + /*use_mock_suggestions_fetcher=*/true, + /*use_mock_prefetched_pages_tracker=*/false); WaitForSuggestionsProviderInitialization(provider.get(), /*set_empty_response=*/true); auto* mock_fetcher = static_cast<StrictMock<MockRemoteSuggestionsFetcher>*>( @@ -2005,7 +2075,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldExcludeDismissedSuggestionsWhenFetchingMore) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/true); + /*use_mock_suggestions_fetcher=*/true, + /*use_mock_prefetched_pages_tracker=*/false); WaitForSuggestionsProviderInitialization(provider.get(), /*set_empty_response=*/true); @@ -2052,7 +2123,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldTruncateExcludedDismissedSuggestionsWhenFetchingMore) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/true); + /*use_mock_suggestions_fetcher=*/true, + /*use_mock_prefetched_pages_tracker=*/false); WaitForSuggestionsProviderInitialization(provider.get(), /*set_empty_response=*/true); @@ -2105,7 +2177,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldPreferLatestExcludedDismissedSuggestionsWhenFetchingMore) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/true); + /*use_mock_suggestions_fetcher=*/true, + /*use_mock_prefetched_pages_tracker=*/false); WaitForSuggestionsProviderInitialization(provider.get(), /*set_empty_response=*/true); @@ -2164,7 +2237,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldExcludeDismissedSuggestionsFromAllCategoriesWhenFetchingMore) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/true); + /*use_mock_suggestions_fetcher=*/true, + /*use_mock_prefetched_pages_tracker=*/false); WaitForSuggestionsProviderInitialization(provider.get(), /*set_empty_response=*/true); @@ -2233,7 +2307,8 @@ TEST_F(RemoteSuggestionsProviderImplTest, ShouldPreferTargetCategoryExcludedDismissedSuggestionsWhenFetchingMore) { auto provider = MakeSuggestionsProviderWithoutInitialization( - /*use_mock_suggestions_fetcher=*/true); + /*use_mock_suggestions_fetcher=*/true, + /*use_mock_prefetched_pages_tracker=*/false); WaitForSuggestionsProviderInitialization(provider.get(), /*set_empty_response=*/true); @@ -2296,4 +2371,322 @@ std::vector<ContentSuggestion> suggestions) {})); } +TEST_F(RemoteSuggestionsProviderImplTest, + ShouldFetchNormallyWithoutPrefetchedPagesTracker) { + EnableKeepingPrefetchedContentSuggestions(); + auto provider = MakeSuggestionsProvider(); + LoadFromJSONString(provider.get(), GetTestJson({GetSuggestion()})); + EXPECT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(1)); +} + +TEST_F(RemoteSuggestionsProviderImplTest, + ShouldKeepPrefetchedSuggestionsAfterFetchWhenEnabled) { + EnableKeepingPrefetchedContentSuggestions(); + auto provider = MakeSuggestionsProviderWithoutInitialization( + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/true); + auto* mock_tracker = static_cast<StrictMock<MockPrefetchedPagesTracker>*>( + prefetched_pages_tracker()); + WaitForSuggestionsProviderInitialization(provider.get(), + /*set_empty_response=*/false); + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + LoadFromJSONString( + provider.get(), + GetTestJson({GetSuggestionWithSources("http://prefeched.com", "publisher", + "http://amp.prefetched.com")})); + + ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(1)); + + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + EXPECT_CALL(*mock_tracker, + PrefetchedOfflinePageExists(GURL("http://amp.prefetched.com"))) + .WillOnce(Return(true)); + LoadFromJSONString( + provider.get(), + GetTestJson({GetSuggestionWithSources("http://other.com", "publisher", + "http://amp.other.com")})); + + EXPECT_THAT(observer().SuggestionsForCategory(articles_category()), + UnorderedElementsAre( + Property(&ContentSuggestion::id, + Property(&ContentSuggestion::ID::id_within_category, + "http://prefeched.com")), + Property(&ContentSuggestion::id, + Property(&ContentSuggestion::ID::id_within_category, + "http://other.com")))); +} + +TEST_F(RemoteSuggestionsProviderImplTest, + ShouldIgnoreNotPrefetchedSuggestionsAfterFetchWhenEnabled) { + EnableKeepingPrefetchedContentSuggestions(); + auto provider = MakeSuggestionsProviderWithoutInitialization( + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/true); + auto* mock_tracker = static_cast<StrictMock<MockPrefetchedPagesTracker>*>( + prefetched_pages_tracker()); + WaitForSuggestionsProviderInitialization(provider.get(), + /*set_empty_response=*/false); + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + LoadFromJSONString(provider.get(), + GetTestJson({GetSuggestionWithSources( + "http://not_prefeched.com", "publisher", + "http://amp.not_prefetched.com")})); + + ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(1)); + + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + EXPECT_CALL(*mock_tracker, PrefetchedOfflinePageExists( + GURL("http://amp.not_prefetched.com"))) + .WillOnce(Return(false)); + LoadFromJSONString( + provider.get(), + GetTestJson({GetSuggestionWithSources("http://other.com", "publisher", + "http://amp.other.com")})); + + EXPECT_THAT(observer().SuggestionsForCategory(articles_category()), + UnorderedElementsAre( + Property(&ContentSuggestion::id, + Property(&ContentSuggestion::ID::id_within_category, + "http://other.com")))); +} + +TEST_F(RemoteSuggestionsProviderImplTest, + ShouldLimitKeptPrefetchedSuggestionsAfterFetchWhenEnabled) { + EnableKeepingPrefetchedContentSuggestions(); + auto provider = MakeSuggestionsProviderWithoutInitialization( + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/true); + auto* mock_tracker = static_cast<StrictMock<MockPrefetchedPagesTracker>*>( + prefetched_pages_tracker()); + WaitForSuggestionsProviderInitialization(provider.get(), + /*set_empty_response=*/false); + + const int prefetched_suggestions_count = + 2 * kMaxAdditionalPrefetchedSuggestions + 1; + std::vector<std::string> prefetched_suggestions; + for (int i = 0; i < prefetched_suggestions_count; ++i) { + prefetched_suggestions.push_back(GetSuggestionWithSources( + base::StringPrintf("http://prefetched.com/%d", i), "publisher", + base::StringPrintf("http://amp.prefetched.com/%d", i))); + } + + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + LoadFromJSONString(provider.get(), GetTestJson(prefetched_suggestions)); + ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(prefetched_suggestions_count)); + + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + for (int i = 0; i < prefetched_suggestions_count; ++i) { + EXPECT_CALL(*mock_tracker, + PrefetchedOfflinePageExists(GURL( + base::StringPrintf("http://amp.prefetched.com/%d", i)))) + .WillOnce(Return(true)); + } + LoadFromJSONString(provider.get(), + GetTestJson({GetSuggestionWithSources( + "http://not_prefeched.com", "publisher", + "http://amp.not_prefetched.com")})); + + ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(kMaxAdditionalPrefetchedSuggestions + 1)); +} + +TEST_F(RemoteSuggestionsProviderImplTest, + ShouldMixInPrefetchedSuggestionsByScoreAfterFetchWhenEnabled) { + EnableKeepingPrefetchedContentSuggestions(); + auto provider = MakeSuggestionsProviderWithoutInitialization( + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/true); + auto* mock_tracker = static_cast<StrictMock<MockPrefetchedPagesTracker>*>( + prefetched_pages_tracker()); + WaitForSuggestionsProviderInitialization(provider.get(), + /*set_empty_response=*/false); + + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + LoadFromJSONString( + provider.get(), + GetTestJson({GetSuggestionWithSourcesAndScore( + "http://prefeched.com/1", "publisher", + "http://amp.prefetched.com/1", /*score=*/1), + GetSuggestionWithSourcesAndScore( + "http://prefeched.com/3", "publisher", + "http://amp.prefetched.com/3", /*score=*/3)})); + ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(2)); + + EXPECT_CALL(*mock_tracker, + PrefetchedOfflinePageExists(GURL("http://amp.prefetched.com/1"))) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_tracker, + PrefetchedOfflinePageExists(GURL("http://amp.prefetched.com/3"))) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + LoadFromJSONString(provider.get(), + GetTestJson({GetSuggestionWithSourcesAndScore( + "http://new.com/2", "publisher", + "http://amp.new.com/2", /*score=*/2), + GetSuggestionWithSourcesAndScore( + "http://new.com/4", "publisher", + "http://amp.new.com/4", /*score=*/4)})); + + EXPECT_THAT( + observer().SuggestionsForCategory(articles_category()), + ElementsAre( + Property(&ContentSuggestion::id, MakeArticleID("http://new.com/4")), + Property(&ContentSuggestion::id, + Property(&ContentSuggestion::ID::id_within_category, + "http://prefeched.com/3")), + Property(&ContentSuggestion::id, + Property(&ContentSuggestion::ID::id_within_category, + "http://new.com/2")), + Property(&ContentSuggestion::id, + Property(&ContentSuggestion::ID::id_within_category, + "http://prefeched.com/1")))); +} + +TEST_F( + RemoteSuggestionsProviderImplTest, + ShouldKeepMostRecentlyFetchedPrefetchedSuggestionsFirstAfterFetchWhenEnabled) { + EnableKeepingPrefetchedContentSuggestions(); + auto provider = MakeSuggestionsProviderWithoutInitialization( + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/true); + auto* mock_tracker = static_cast<StrictMock<MockPrefetchedPagesTracker>*>( + prefetched_pages_tracker()); + WaitForSuggestionsProviderInitialization(provider.get(), + /*set_empty_response=*/false); + + const int prefetched_suggestions_count = + 2 * kMaxAdditionalPrefetchedSuggestions + 1; + + for (int i = 0; i < prefetched_suggestions_count; ++i) { + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + if (i != 0) { + EXPECT_CALL(*mock_tracker, + PrefetchedOfflinePageExists(GURL(base::StringPrintf( + "http://amp.prefetched.com/%d", i - 1)))) + .WillRepeatedly(Return(true)); + } + LoadFromJSONString( + provider.get(), + GetTestJson({GetSuggestionWithSources( + base::StringPrintf("http://prefetched.com/%d", i), "publisher", + base::StringPrintf("http://amp.prefetched.com/%d", i))})); + } + + const std::vector<ContentSuggestion>& actual_suggestions = + observer().SuggestionsForCategory(articles_category()); + + ASSERT_THAT(actual_suggestions, + SizeIs(kMaxAdditionalPrefetchedSuggestions + 1)); + + int matched = 0; + for (int i = prefetched_suggestions_count - 1; i >= 0; --i) { + EXPECT_THAT(actual_suggestions, + Contains(Property(&ContentSuggestion::id, + MakeArticleID(base::StringPrintf( + "http://prefetched.com/%d", i))))); + ++matched; + if (matched == kMaxAdditionalPrefetchedSuggestions + 1) { + break; + } + } +} + +TEST_F(RemoteSuggestionsProviderImplTest, + ShouldNotKeepStalePrefetchedSuggestionsAfterFetchWhenEnabled) { + EnableKeepingPrefetchedContentSuggestions(); + auto provider = MakeSuggestionsProviderWithoutInitialization( + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/true); + auto* mock_tracker = static_cast<StrictMock<MockPrefetchedPagesTracker>*>( + prefetched_pages_tracker()); + + auto* fetcher = + static_cast<RemoteSuggestionsFetcherImpl*>(suggestions_fetcher()); + auto wrapped_fetcher_clock = base::MakeUnique<base::SimpleTestClock>(); + base::SimpleTestClock* fetcher_clock = wrapped_fetcher_clock.get(); + fetcher->SetClockForTesting(std::move(wrapped_fetcher_clock)); + + auto wrapped_provider_clock = base::MakeUnique<base::SimpleTestClock>(); + base::SimpleTestClock* provider_clock = wrapped_provider_clock.get(); + provider->SetClockForTesting(std::move(wrapped_provider_clock)); + + provider_clock->SetNow(GetDefaultCreationTime() + + base::TimeDelta::FromHours(10)); + fetcher_clock->SetNow(provider_clock->Now()); + + WaitForSuggestionsProviderInitialization(provider.get(), + /*set_empty_response=*/false); + + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + LoadFromJSONString( + provider.get(), + GetTestJson({GetSuggestionWithSources("http://prefeched.com", "publisher", + "http://amp.prefetched.com")})); + ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(1)); + + provider_clock->Advance(kMaxAgeForAdditionalPrefetchedSuggestion - + base::TimeDelta::FromSeconds(1)); + fetcher_clock->SetNow(provider_clock->Now()); + + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + EXPECT_CALL(*mock_tracker, + PrefetchedOfflinePageExists(GURL("http://amp.prefetched.com"))) + .WillOnce(Return(true)); + LoadFromJSONString( + provider.get(), + GetTestJson({GetSuggestionWithSources("http://other.com", "publisher", + "http://amp.other.com")})); + ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(2)); + + provider_clock->Advance(base::TimeDelta::FromSeconds(2)); + fetcher_clock->SetNow(provider_clock->Now()); + + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + EXPECT_CALL(*mock_tracker, + PrefetchedOfflinePageExists(GURL("http://amp.prefetched.com"))) + .WillOnce(Return(true)); + LoadFromJSONString( + provider.get(), + GetTestJson({GetSuggestionWithSources("http://other.com", "publisher", + "http://amp.other.com")})); + EXPECT_THAT(observer().SuggestionsForCategory(articles_category()), + ElementsAre(Property(&ContentSuggestion::id, + MakeArticleID("http://other.com")))); +} + +TEST_F(RemoteSuggestionsProviderImplTest, + ShouldWaitForPrefetchedPagesTrackerInitialization) { + EnableKeepingPrefetchedContentSuggestions(); + auto provider = MakeSuggestionsProviderWithoutInitialization( + /*use_mock_suggestions_fetcher=*/false, + /*use_mock_prefetched_pages_tracker=*/true); + auto* mock_tracker = static_cast<StrictMock<MockPrefetchedPagesTracker>*>( + prefetched_pages_tracker()); + WaitForSuggestionsProviderInitialization(provider.get(), + /*set_empty_response=*/false); + + base::OnceCallback<void()> initialization_completed_callback; + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(false)); + EXPECT_CALL(*mock_tracker, AddInitializationCompletedCallback(_)) + .WillOnce(MoveFirstArgumentPointeeTo(&initialization_completed_callback)); + LoadFromJSONString( + provider.get(), + GetTestJson({GetSuggestionWithSources("http://prefeched.com", "publisher", + "http://amp.prefetched.com")})); + EXPECT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(0)); + + EXPECT_CALL(*mock_tracker, IsInitialized()).WillRepeatedly(Return(true)); + std::move(initialization_completed_callback).Run(); + EXPECT_THAT(observer().SuggestionsForCategory(articles_category()), + SizeIs(1)); +} + } // namespace ntp_snippets
diff --git a/components/security_state/content/content_utils.cc b/components/security_state/content/content_utils.cc index f1dc115..3432722 100644 --- a/components/security_state/content/content_utils.cc +++ b/components/security_state/content/content_utils.cc
@@ -112,19 +112,19 @@ str_id = (status & net::OBSOLETE_SSL_MASK_PROTOCOL) ? IDS_SSL_AN_OBSOLETE_PROTOCOL : IDS_SSL_A_STRONG_PROTOCOL; - description_replacements.push_back(l10n_util::GetStringUTF16(str_id)); description_replacements.push_back(protocol_name); + description_replacements.push_back(l10n_util::GetStringUTF16(str_id)); str_id = (status & net::OBSOLETE_SSL_MASK_KEY_EXCHANGE) ? IDS_SSL_AN_OBSOLETE_KEY_EXCHANGE : IDS_SSL_A_STRONG_KEY_EXCHANGE; - description_replacements.push_back(l10n_util::GetStringUTF16(str_id)); description_replacements.push_back(key_exchange_name); + description_replacements.push_back(l10n_util::GetStringUTF16(str_id)); str_id = (status & net::OBSOLETE_SSL_MASK_CIPHER) ? IDS_SSL_AN_OBSOLETE_CIPHER : IDS_SSL_A_STRONG_CIPHER; - description_replacements.push_back(l10n_util::GetStringUTF16(str_id)); description_replacements.push_back(cipher_name); + description_replacements.push_back(l10n_util::GetStringUTF16(str_id)); security_style_explanations->info_explanations.push_back( content::SecurityStyleExplanation( @@ -297,12 +297,26 @@ } else { // If the certificate does not have errors and is not using SHA1, then add // an explanation that the certificate is valid. + + base::string16 issuer_name; + if (security_info.certificate) { + // This results in the empty string if there is no relevant display name. + issuer_name = base::UTF8ToUTF16( + security_info.certificate->issuer().GetDisplayName()); + } else { + issuer_name = base::string16(); + } + if (issuer_name.empty()) { + issuer_name.assign( + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); + } + if (!security_info.sha1_in_chain) { security_style_explanations->secure_explanations.push_back( content::SecurityStyleExplanation( l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE), - l10n_util::GetStringUTF8( - IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION), + l10n_util::GetStringFUTF8( + IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION, issuer_name), !!security_info.certificate)); } }
diff --git a/components/security_state/content/content_utils_unittest.cc b/components/security_state/content/content_utils_unittest.cc index 090a835..2fbf436bb 100644 --- a/components/security_state/content/content_utils_unittest.cc +++ b/components/security_state/content/content_utils_unittest.cc
@@ -164,7 +164,7 @@ return false; } -// Test that connection explanations are formated as expected. Note the strings +// Test that connection explanations are formatted as expected. Note the strings // are not translated and so will be the same in any locale. TEST(SecurityStateContentUtilsTest, ConnectionExplanation) { // Test a modern configuration with a key exchange group. @@ -185,9 +185,9 @@ ASSERT_TRUE(FindSecurityStyleExplanation( explanations.secure_explanations, "Secure connection", &explanation)); EXPECT_EQ( - "The connection to this site is encrypted and authenticated using a " - "strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA with " - "X25519), and a strong cipher (CHACHA20_POLY1305).", + "The connection to this site is encrypted and authenticated using TLS " + "1.2 (a strong protocol), ECDHE_RSA with X25519 (a strong key " + "exchange), and CHACHA20_POLY1305 (a strong cipher).", explanation.description); } @@ -201,9 +201,9 @@ ASSERT_TRUE(FindSecurityStyleExplanation( explanations.secure_explanations, "Secure connection", &explanation)); EXPECT_EQ( - "The connection to this site is encrypted and authenticated using a " - "strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA), and a " - "strong cipher (CHACHA20_POLY1305).", + "The connection to this site is encrypted and authenticated using TLS " + "1.2 (a strong protocol), ECDHE_RSA (a strong key exchange), and " + "CHACHA20_POLY1305 (a strong cipher).", explanation.description); } @@ -220,9 +220,38 @@ ASSERT_TRUE(FindSecurityStyleExplanation( explanations.secure_explanations, "Secure connection", &explanation)); EXPECT_EQ( - "The connection to this site is encrypted and authenticated using a " - "strong protocol (TLS 1.3), a strong key exchange (X25519), and a " - "strong cipher (AES_128_GCM).", + "The connection to this site is encrypted and authenticated using TLS " + "1.3 (a strong protocol), X25519 (a strong key exchange), and " + "AES_128_GCM (a strong cipher).", + explanation.description); + } +} + +// Test that obsolete connection explanations are formatted as expected. +TEST(SecurityStateContentUtilsTest, ObsoleteConnectionExplanation) { + security_state::SecurityInfo security_info; + security_info.cert_status = net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; + security_info.scheme_is_cryptographic = true; + net::SSLConnectionStatusSetCipherSuite( + 0xc013 /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */, + &security_info.connection_status); + net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2, + &security_info.connection_status); + security_info.key_exchange_group = 29; // X25519 + security_info.obsolete_ssl_status = + net::ObsoleteSSLMask::OBSOLETE_SSL_MASK_CIPHER; + + { + content::SecurityStyleExplanations explanations; + GetSecurityStyle(security_info, &explanations); + content::SecurityStyleExplanation explanation; + ASSERT_TRUE(FindSecurityStyleExplanation(explanations.info_explanations, + "Obsolete connection settings", + &explanation)); + EXPECT_EQ( + "The connection to this site uses TLS 1.2 (a strong protocol), " + "ECDHE_RSA with X25519 (a strong key exchange), and AES_128_CBC with " + "HMAC-SHA1 (an obsolete cipher).", explanation.description); } }
diff --git a/components/security_state_strings.grdp b/components/security_state_strings.grdp index 482b6c9..6094c157 100644 --- a/components/security_state_strings.grdp +++ b/components/security_state_strings.grdp
@@ -38,7 +38,7 @@ Valid certificate </message> <message name="IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION" desc="Description of a site that has a valid server certificate." translateable="false"> - The connection to this site is using a valid, trusted server certificate. + The connection to this site is using a valid, trusted server certificate issued by <ph name="ISSUER">$1<ex>Let's Encrypt Authority X3</ex></ph>. </message> <message name="IDS_STRONG_SSL_SUMMARY" desc="Summary phrase for a site that uses a modern, secure TLS protocol and cipher." translateable="false"> Secure connection @@ -50,13 +50,13 @@ Public-Key-Pinning was bypassed by a local root certificate. </message> <message name="IDS_STRONG_SSL_DESCRIPTION" desc="Description of a site that uses a modern, secure TLS protocol and cipher." translateable="false"> - The connection to this site is encrypted and authenticated using a strong protocol (<ph name="PROTOCOL_VERSION">$1<ex>TLS 1.2</ex></ph>), a strong key exchange (<ph name="KEY_EXCHANGE">$2<ex>ECDHE_RSA</ex></ph>), and a strong cipher (<ph name="CIPHER_SUTE">$3<ex>AES_128_GCM</ex></ph>). + The connection to this site is encrypted and authenticated using <ph name="PROTOCOL_VERSION">$1<ex>TLS 1.2</ex></ph> (a strong protocol), <ph name="KEY_EXCHANGE">$2<ex>ECDHE_RSA</ex></ph> (a strong key exchange), and <ph name="CIPHER_SUTE">$3<ex>AES_128_GCM</ex></ph> (a strong cipher). </message> <message name="IDS_OBSOLETE_SSL_SUMMARY" desc="Summary phrase for a site that uses an outdated SSL settings (protocol, key exchange, or cipher)." translateable="false"> Obsolete connection settings </message> <message name="IDS_OBSOLETE_SSL_DESCRIPTION" desc="Description of a site that uses an outdated TLS protocol or cipher." translateable="false"> - The connection to this site uses <ph name="A_PROTOCOL">$1<ex>an obsolete protocol</ex></ph> (<ph name="PROTOCOL">$2<ex>TLS 1.0</ex></ph>), <ph name="A_KEY_EXCHANGE">$3<ex>an obsolete key exchange</ex></ph> (<ph name="KEY_EXCHANGE">$4<ex>ECDHE_RSA</ex></ph>), and <ph name="A_CIPHER">$5<ex>an obsolete cipher</ex></ph> (<ph name="CIPHER">$6<ex>AES_256_CBC with HMAC-SHA1</ex></ph>). + The connection to this site uses <ph name="PROTOCOL">$1<ex>TLS 1.0</ex></ph> (<ph name="A_PROTOCOL">$2<ex>an obsolete protocol</ex></ph>), <ph name="KEY_EXCHANGE">$3<ex>ECDHE_RSA</ex></ph> (<ph name="A_KEY_EXCHANGE">$4<ex>an obsolete key exchange</ex></ph>), and <ph name="CIPHER">$5<ex>AES_256_CBC with HMAC-SHA1</ex></ph> (<ph name="A_CIPHER">$6<ex>an obsolete cipher</ex></ph>). </message> <message name="IDS_CIPHER_WITH_MAC" desc="Description of an SSL cipher that contains a separate (bulk) cipher and MAC." translateable="false"> <ph name="CIPHER">$1<ex>AES_256_CBC</ex></ph> with <ph name="MAC">$2<ex>HMAC-SHA1</ex></ph>
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc index 1bc06ebf9..d336f4a 100644 --- a/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc +++ b/ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.cc
@@ -193,7 +193,8 @@ request_context.get()), base::MakeUnique<RemoteSuggestionsDatabase>(database_dir, task_runner), base::MakeUnique<RemoteSuggestionsStatusService>(signin_manager, prefs, - std::string())); + std::string()), + /*prefetched_pages_tracker=*/nullptr); service->remote_suggestions_scheduler()->SetProvider(provider.get()); service->set_remote_suggestions_provider(provider.get());
diff --git a/media/cdm/cdm_adapter_factory.cc b/media/cdm/cdm_adapter_factory.cc index 6c9c085..b00a09f 100644 --- a/media/cdm/cdm_adapter_factory.cc +++ b/media/cdm/cdm_adapter_factory.cc
@@ -11,6 +11,7 @@ #include "base/path_service.h" #include "base/threading/thread_task_runner_handle.h" #include "media/base/cdm_factory.h" +#include "media/base/key_system_names.h" #include "media/base/key_systems.h" #include "media/cdm/cdm_adapter.h" #include "media/cdm/cdm_paths.h" @@ -49,15 +50,16 @@ return; } + // TODO(xhwang): We should have the CDM path forwarded from the browser + // already. See http://crbug.com/510604 base::FilePath cdm_path; +// TODO(xhwang): Remove key-system-specific logic. We should have the +// CDM path forwarded from the browser already. See http://crbug.com/510604 + #if defined(WIDEVINE_CDM_AVAILABLE) - // TODO(xhwang): Remove key-system-specific logic here. We should have the - // CDM path forwarded from the browser already. See http://crbug.com/510604 if (key_system == kWidevineKeySystem) { // Build the library path for Widevine CDM. - // TODO(xhwang): We should have the CDM path forwarded from the browser - // already. See http://crbug.com/510604 base::FilePath cdm_base_path; #if defined(OS_MACOSX) @@ -75,6 +77,19 @@ } #endif // defined(WIDEVINE_CDM_AVAILABLE) +// The hardcoded path for ClearKeyCdm does not work on Mac due to bundling. +// See http://crbug.com/736106 +#if !defined(OS_MACOSX) + if (cdm_path.empty() && IsExternalClearKey(key_system)) { + base::FilePath cdm_base_path; + base::PathService::Get(base::DIR_MODULE, &cdm_base_path); + cdm_base_path = cdm_base_path.Append( + GetPlatformSpecificDirectory(kClearKeyCdmBaseDirectory)); + cdm_path = cdm_base_path.AppendASCII( + base::GetNativeLibraryName(kClearKeyCdmLibraryName)); + } +#endif // !defined(OS_MACOSX) + if (cdm_path.empty()) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE,
diff --git a/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued/chain.pem b/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued/chain.pem index 1df6f70..7d2d449 100644 --- a/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued/chain.pem +++ b/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 2 intermediates. The first intermediate has a basic -constraints path length of 0. The second one is self-issued so does not count -against the path length. +Certificate chain where the intermediate sets pathlen=0, and is followed by +a self-issued intermediate. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued/generate-chains.py b/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued/generate-chains.py index 46b6b84..059620a 100755 --- a/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 2 intermediates. The first intermediate has a basic -constraints path length of 0. The second one is self-issued so does not count -against the path length.""" +"""Certificate chain where the intermediate sets pathlen=0, and is followed by +a self-issued intermediate.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate with pathlen 0
diff --git a/net/data/verify_certificate_chain_unittest/expired-intermediate/chain.pem b/net/data/verify_certificate_chain_unittest/expired-intermediate/chain.pem index 8b304a0..c1abbafb 100644 --- a/net/data/verify_certificate_chain_unittest/expired-intermediate/chain.pem +++ b/net/data/verify_certificate_chain_unittest/expired-intermediate/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with a root, intermediate and target. The intermediate has -a smaller validity range than the other certificates, making it easy to violate -just its validity. +Certificate chain where the intermediate has a smaller validity range +than the other certificates, making it easy to violate just its validity. Root: 2015/01/01 -> 2016/01/01 Intermediate: 2015/03/01 -> 2015/09/01
diff --git a/net/data/verify_certificate_chain_unittest/expired-intermediate/generate-chains.py b/net/data/verify_certificate_chain_unittest/expired-intermediate/generate-chains.py index 1387f9b..fa883e9f 100755 --- a/net/data/verify_certificate_chain_unittest/expired-intermediate/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/expired-intermediate/generate-chains.py
@@ -3,9 +3,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with a root, intermediate and target. The intermediate has -a smaller validity range than the other certificates, making it easy to violate -just its validity. +"""Certificate chain where the intermediate has a smaller validity range +than the other certificates, making it easy to violate just its validity. Root: 2015/01/01 -> 2016/01/01 Intermediate: 2015/03/01 -> 2015/09/01
diff --git a/net/data/verify_certificate_chain_unittest/expired-root/chain.pem b/net/data/verify_certificate_chain_unittest/expired-root/chain.pem index 45f1b7c..cf1f3b2 100644 --- a/net/data/verify_certificate_chain_unittest/expired-root/chain.pem +++ b/net/data/verify_certificate_chain_unittest/expired-root/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with a root, intermediate and target. The root has a -smaller validity range than the other certificates, making it easy to violate -just its validity. +Certificate chain where the root has a smaller validity range than the other +certificates, making it easy to violate just its validity. Root: 2015/03/01 -> 2015/09/01 Intermediate: 2015/01/01 -> 2016/01/01
diff --git a/net/data/verify_certificate_chain_unittest/expired-root/generate-chains.py b/net/data/verify_certificate_chain_unittest/expired-root/generate-chains.py index 93d5bb7..369dbe17 100755 --- a/net/data/verify_certificate_chain_unittest/expired-root/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/expired-root/generate-chains.py
@@ -3,9 +3,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with a root, intermediate and target. The root has a -smaller validity range than the other certificates, making it easy to violate -just its validity. +"""Certificate chain where the root has a smaller validity range than the other +certificates, making it easy to violate just its validity. Root: 2015/03/01 -> 2015/09/01 Intermediate: 2015/01/01 -> 2016/01/01
diff --git a/net/data/verify_certificate_chain_unittest/expired-target/chain.pem b/net/data/verify_certificate_chain_unittest/expired-target/chain.pem index fced9e6..d538892 100644 --- a/net/data/verify_certificate_chain_unittest/expired-target/chain.pem +++ b/net/data/verify_certificate_chain_unittest/expired-target/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with a root, intermediate and target. The target has a -smaller validity range than the other certificates, making it easy to violate -just its validity. +Certificate chain where the target certificate has a smaller validity range +than the other certificates, making it easy to violate just its validity. Root: 2015/01/01 -> 2016/01/01 Intermediate: 2015/01/01 -> 2016/01/01
diff --git a/net/data/verify_certificate_chain_unittest/expired-target/generate-chains.py b/net/data/verify_certificate_chain_unittest/expired-target/generate-chains.py index 8e548be..f75e499 100755 --- a/net/data/verify_certificate_chain_unittest/expired-target/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/expired-target/generate-chains.py
@@ -3,9 +3,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with a root, intermediate and target. The target has a -smaller validity range than the other certificates, making it easy to violate -just its validity. +"""Certificate chain where the target certificate has a smaller validity range +than the other certificates, making it easy to violate just its validity. Root: 2015/01/01 -> 2016/01/01 Intermediate: 2015/01/01 -> 2016/01/01
diff --git a/net/data/verify_certificate_chain_unittest/incorrect-trust-anchor/chain.pem b/net/data/verify_certificate_chain_unittest/incorrect-trust-anchor/chain.pem index d363a06..5c47cf6 100644 --- a/net/data/verify_certificate_chain_unittest/incorrect-trust-anchor/chain.pem +++ b/net/data/verify_certificate_chain_unittest/incorrect-trust-anchor/chain.pem
@@ -1,8 +1,10 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate, but the trust anchor used is -incorrect (neither subject nor signature matches). Verification is expected to -fail. +Certificate chain where the supposed root certificate is wrong: + + * The intermediate's "issuer" does not match the root's "subject" + * The intermediate's signature was not generated using the root's key + Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/incorrect-trust-anchor/generate-chains.py b/net/data/verify_certificate_chain_unittest/incorrect-trust-anchor/generate-chains.py index 3348296..a337dbb6 100755 --- a/net/data/verify_certificate_chain_unittest/incorrect-trust-anchor/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/incorrect-trust-anchor/generate-chains.py
@@ -3,16 +3,18 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate, but the trust anchor used is -incorrect (neither subject nor signature matches). Verification is expected to -fail.""" +"""Certificate chain where the supposed root certificate is wrong: + + * The intermediate's "issuer" does not match the root's "subject" + * The intermediate's signature was not generated using the root's key +""" import sys sys.path += ['..'] import common -# Self-signed root certificate, which is NOT saved as the trust anchor. +# Self-signed root certificate, which actually signed the intermediate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate. @@ -21,8 +23,8 @@ # Target certificate. target = common.create_end_entity_certificate('Target', intermediate) -# Self-signed root certificate, not part of chain, which is saved as trust -# anchor. +# Self-signed root certificate that has nothing to do with this chain, but will +# be saved as its root certificate. bogus_root = common.create_self_signed_root_certificate('BogusRoot') chain = [target, intermediate, bogus_root]
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false/chain.pem b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false/chain.pem index 3c33888..6ffe22fa 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false/chain.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The intermediate -has a basic constraints extension that indicates it is NOT a CA. Verification -is expected to fail. +Certificate chain where the intermediate has a basic constraints extension +that indicates it is NOT a CA. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false/generate-chains.py b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false/generate-chains.py index bd80f25c..5435ab1b 100755 --- a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The intermediate -has a basic constraints extension that indicates it is NOT a CA. Verification -is expected to fail.""" +"""Certificate chain where the intermediate has a basic constraints extension +that indicates it is NOT a CA.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate with incorrect basic constraints.
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical/chain.pem b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical/chain.pem index e4eda0b6..0e1da1c 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical/chain.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical/chain.pem
@@ -1,9 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The intermediate -has a basic constraints extension but does not mark it as critical. -Verification is expected to succeed, since although not critical, the -basicConstraints indicates CA=true as expected. +Certificate chain where the intermediate's Basic Constraints extension is +not marked as critical. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical/generate-chains.py b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical/generate-chains.py index a0f50e7..c83ecf5 100755 --- a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical/generate-chains.py
@@ -3,20 +3,18 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The intermediate -has a basic constraints extension but does not mark it as critical. -Verification is expected to succeed, since although not critical, the -basicConstraints indicates CA=true as expected.""" +"""Certificate chain where the intermediate's Basic Constraints extension is +not marked as critical.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') -# Intermediate with non-critical basic constarints. +# Intermediate with non-critical basic constraints. intermediate = common.create_intermediate_certificate('Intermediate', root) intermediate.get_extensions().set_property('basicConstraints', 'CA:true')
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/chain.pem b/net/data/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/chain.pem index 9d67a50..53dcebad 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/chain.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/chain.pem
@@ -1,9 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The intermediate -restricts the EKU to clientAuth + any, and the target has serverAuth + -clientAuth. Verification is expected to succeed because intermediate will match -the "any". +Certificate chain where the intermediate restricts the extended key usage to +clientAuth + any, and the target sets serverAuth + clientAuth. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/generate-chains.py b/net/data/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/generate-chains.py index 1a1460a9..83a5af09 100755 --- a/net/data/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/intermediate-eku-any-and-clientauth/generate-chains.py
@@ -3,17 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The intermediate -restricts the EKU to clientAuth + any, and the target has serverAuth + -clientAuth. Verification is expected to succeed because intermediate will match -the "any".""" +"""Certificate chain where the intermediate restricts the extended key usage to +clientAuth + any, and the target sets serverAuth + clientAuth.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-eku-clientauth/chain.pem b/net/data/verify_certificate_chain_unittest/intermediate-eku-clientauth/chain.pem index f51209a5..ec9cd15 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-eku-clientauth/chain.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-eku-clientauth/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The intermediate -restricts the EKU to clientAuth, and the target has serverAuth + -clientAuth. Verification is expected to fail when requesting serverAuth. +Certificate chain where the intermediate restricts the extended key usage to +clientAuth, and the target asserts serverAuth + clientAuth. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-eku-clientauth/generate-chains.py b/net/data/verify_certificate_chain_unittest/intermediate-eku-clientauth/generate-chains.py index 8f8eae7..5268f39 100755 --- a/net/data/verify_certificate_chain_unittest/intermediate-eku-clientauth/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/intermediate-eku-clientauth/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The intermediate -restricts the EKU to clientAuth, and the target has serverAuth + -clientAuth. Verification is expected to fail when requesting serverAuth.""" +"""Certificate chain where the intermediate restricts the extended key usage to +clientAuth, and the target asserts serverAuth + clientAuth.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints/chain.pem b/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints/chain.pem index 3941ad6..169249d 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints/chain.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The intermediate -lacks the basic constraints extension, and hence is expected to fail validation -(RFC 5280 requires v3 signing certificates have a BasicConstaints). +Certificate chain where the intermediate lacks a basic constraints +extension (yet is used to issue another certificate). Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints/generate-chains.py b/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints/generate-chains.py index b1219afa..c258acb2a 100755 --- a/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The intermediate -lacks the basic constraints extension, and hence is expected to fail validation -(RFC 5280 requires v3 signing certificates have a BasicConstaints).""" +"""Certificate chain where the intermediate lacks a basic constraints +extension (yet is used to issue another certificate).""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate that lacks basic constraints.
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage/chain.pem b/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage/chain.pem index e646cf6..04d5660 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage/chain.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage/chain.pem
@@ -1,8 +1,6 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The intermediate -contains a keyUsage extension, HOWEVER it does not contain the keyCertSign bit. -Hence validation is expected to fail. +Certificate chain where the intermediate lacks a keyUsage extension. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage/generate-chains.py b/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage/generate-chains.py index 42cb22f..657beab 100755 --- a/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage/generate-chains.py
@@ -3,16 +3,14 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The intermediate -contains a keyUsage extension, HOWEVER it does not contain the keyCertSign bit. -Hence validation is expected to fail.""" +"""Certificate chain where the intermediate lacks a keyUsage extension.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate that is missing keyCertSign.
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5/chain.pem b/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5/chain.pem index 55aae06..614fc6c 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5/chain.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The intermediate -however is signed using the MD5 hash. Verification is expected to fail because -MD5 is too weak. +Certificate chain where the intermediate has a valid signature, however uses +MD5 in the signature algorithm. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5/generate-chains.py b/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5/generate-chains.py index cfdbb1a5..518d5df 100755 --- a/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The intermediate -however is signed using the MD5 hash. Verification is expected to fail because -MD5 is too weak.""" +"""Certificate chain where the intermediate has a valid signature, however uses +MD5 in the signature algorithm.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate.
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension/chain.pem b/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension/chain.pem index 36aeef7b..4320fdb 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension/chain.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension/chain.pem
@@ -1,9 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The intermediate -has an unknown X.509v3 extension (OID=1.2.3.4) that is marked as critical. -Verifying this certificate chain is expected to fail because there is an -unrecognized critical extension. +Certificate chain where the intermediate has an unknown critical +extension. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension/generate-chains.py b/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension/generate-chains.py index f7863df..26cb4d4 100755 --- a/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension/generate-chains.py
@@ -3,17 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The intermediate -has an unknown X.509v3 extension (OID=1.2.3.4) that is marked as critical. -Verifying this certificate chain is expected to fail because there is an -unrecognized critical extension.""" +"""Certificate chain where the intermediate has an unknown critical +extension.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate that has an unknown critical extension.
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension/chain.pem b/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension/chain.pem index 9769849..deb636d 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension/chain.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension/chain.pem
@@ -1,9 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The intermediate -has an unknown X.509v3 extension that is marked as non-critical. Verification -is expected to succeed because although unrecognized, the extension is not -critical. +Certificate chain where the intermediate contains an unknown non-critical +extension. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension/generate-chains.py b/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension/generate-chains.py index 108c9196..4833c1b 100755 --- a/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension/generate-chains.py
@@ -3,17 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The intermediate -has an unknown X.509v3 extension that is marked as non-critical. Verification -is expected to succeed because although unrecognized, the extension is not -critical.""" +"""Certificate chain where the intermediate contains an unknown non-critical +extension.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') intermediate = common.create_intermediate_certificate('Intermediate', root)
diff --git a/net/data/verify_certificate_chain_unittest/non-self-signed-root/chain.pem b/net/data/verify_certificate_chain_unittest/non-self-signed-root/chain.pem index dd522984..55dc965 100644 --- a/net/data/verify_certificate_chain_unittest/non-self-signed-root/chain.pem +++ b/net/data/verify_certificate_chain_unittest/non-self-signed-root/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The trusted root -is NOT self signed, however its issuer is not included in the chain or root -store. Verification is expected to succeed since the root is trusted. +Certificate chain where the root certificate is not self-signed (or +self-issued for that matter). Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/non-self-signed-root/generate-chains.py b/net/data/verify_certificate_chain_unittest/non-self-signed-root/generate-chains.py index 858b18e3..7c6d6d8a 100755 --- a/net/data/verify_certificate_chain_unittest/non-self-signed-root/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/non-self-signed-root/generate-chains.py
@@ -3,9 +3,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The trusted root -is NOT self signed, however its issuer is not included in the chain or root -store. Verification is expected to succeed since the root is trusted.""" +"""Certificate chain where the root certificate is not self-signed (or +self-issued for that matter).""" import sys sys.path += ['..'] @@ -14,7 +13,7 @@ shadow_root = common.create_self_signed_root_certificate('ShadowRoot') -# Non-self-signed root (part of trust store). +# Non-self-signed root certificate. root = common.create_intermediate_certificate('Root', shadow_root) # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/root-basic-constraints-ca-false/chain.pem b/net/data/verify_certificate_chain_unittest/root-basic-constraints-ca-false/chain.pem index cf378a4f..9700061 100644 --- a/net/data/verify_certificate_chain_unittest/root-basic-constraints-ca-false/chain.pem +++ b/net/data/verify_certificate_chain_unittest/root-basic-constraints-ca-false/chain.pem
@@ -1,9 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trust anchor. The trust anchor -has a basic constraints extension that indicates it is NOT a CA. Verification -is expected to succeed even though the trust anchor enforces constraints, since -the CA part of basic constraints is not enforced. +Certificate chain where the root certificate contains a basic constraints +extension that indicates it is NOT a CA. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/root-basic-constraints-ca-false/generate-chains.py b/net/data/verify_certificate_chain_unittest/root-basic-constraints-ca-false/generate-chains.py index 4919d35..23a313c 100755 --- a/net/data/verify_certificate_chain_unittest/root-basic-constraints-ca-false/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/root-basic-constraints-ca-false/generate-chains.py
@@ -3,18 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trust anchor. The trust anchor -has a basic constraints extension that indicates it is NOT a CA. Verification -is expected to succeed even though the trust anchor enforces constraints, since -the CA part of basic constraints is not enforced.""" +"""Certificate chain where the root certificate contains a basic constraints +extension that indicates it is NOT a CA.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor) with non-CA basic -# constraints. +# Self-signed root certificate with non-CA basic constraints. root = common.create_self_signed_root_certificate('Root') root.get_extensions().set_property('basicConstraints', 'critical,CA:false')
diff --git a/net/data/verify_certificate_chain_unittest/root-eku-clientauth/chain.pem b/net/data/verify_certificate_chain_unittest/root-eku-clientauth/chain.pem index 6985faf..ac8fc31 100644 --- a/net/data/verify_certificate_chain_unittest/root-eku-clientauth/chain.pem +++ b/net/data/verify_certificate_chain_unittest/root-eku-clientauth/chain.pem
@@ -1,9 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trust anchor. The trust anchor -has an EKU that restricts it to clientAuth. Verification is expected to fail as -the end-entity is verified for serverAuth, and the trust anchor enforces -constraints. +Certificate chain where the root certificate restricts the extended key +usage to clientAuth. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/root-eku-clientauth/generate-chains.py b/net/data/verify_certificate_chain_unittest/root-eku-clientauth/generate-chains.py index e58cd0a..e7490fb 100755 --- a/net/data/verify_certificate_chain_unittest/root-eku-clientauth/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/root-eku-clientauth/generate-chains.py
@@ -3,18 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trust anchor. The trust anchor -has an EKU that restricts it to clientAuth. Verification is expected to fail as -the end-entity is verified for serverAuth, and the trust anchor enforces -constraints.""" +"""Certificate chain where the root certificate restricts the extended key +usage to clientAuth.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor) with non-CA basic -# constraints. +# Self-signed root certificate with extended key usage of clientAuth. root = common.create_self_signed_root_certificate('Root') root.get_extensions().set_property('extendedKeyUsage', 'clientAuth')
diff --git a/net/data/verify_certificate_chain_unittest/root-lacks-basic-constraints/chain.pem b/net/data/verify_certificate_chain_unittest/root-lacks-basic-constraints/chain.pem index 13eb9fc3..1e7b4ff4 100644 --- a/net/data/verify_certificate_chain_unittest/root-lacks-basic-constraints/chain.pem +++ b/net/data/verify_certificate_chain_unittest/root-lacks-basic-constraints/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trust anchor. The trust anchor -lacks the basic constraints extension. This is not a problem and verification -should succeed. +Certificate chain where the root certificate lacks a basic constraints +extension. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/root-lacks-basic-constraints/generate-chains.py b/net/data/verify_certificate_chain_unittest/root-lacks-basic-constraints/generate-chains.py index 268cc1e2..dbd5619 100755 --- a/net/data/verify_certificate_chain_unittest/root-lacks-basic-constraints/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/root-lacks-basic-constraints/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trust anchor. The trust anchor -lacks the basic constraints extension. This is not a problem and verification -should succeed.""" +"""Certificate chain where the root certificate lacks a basic constraints +extension.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') root.get_extensions().remove_property('basicConstraints')
diff --git a/net/data/verify_certificate_chain_unittest/target-and-intermediate/chain.pem b/net/data/verify_certificate_chain_unittest/target-and-intermediate/chain.pem index 975f4fc5..55225b6 100644 --- a/net/data/verify_certificate_chain_unittest/target-and-intermediate/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-and-intermediate/chain.pem
@@ -1,7 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. Verification is -expected to succeed. +Simple certificate chain for a serverAuth which is comprised of a root, +intermediate, and leaf certificate. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-and-intermediate/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-and-intermediate/generate-chains.py index d118a7c..5cb2b46 100755 --- a/net/data/verify_certificate_chain_unittest/target-and-intermediate/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-and-intermediate/generate-chains.py
@@ -3,15 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. Verification is -expected to succeed.""" +"""Simple certificate chain for a serverAuth which is comprised of a root, +intermediate, and leaf certificate.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/target-eku-clientauth/chain.pem b/net/data/verify_certificate_chain_unittest/target-eku-clientauth/chain.pem index 713555460..ae578583 100644 --- a/net/data/verify_certificate_chain_unittest/target-eku-clientauth/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-eku-clientauth/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The target -certificate has only clientAuth EKU, so is expected to fail when verifying for -serverAuth. +Certificate chain where the target certificate sets the extended key usage +to clientAuth. Neither the root nor the intermediate have an EKU. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-eku-clientauth/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-eku-clientauth/generate-chains.py index fa5256c..12d04738 100755 --- a/net/data/verify_certificate_chain_unittest/target-eku-clientauth/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-eku-clientauth/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The target -certificate has only clientAuth EKU, so is expected to fail when verifying for -serverAuth.""" +"""Certificate chain where the target certificate sets the extended key usage +to clientAuth. Neither the root nor the intermediate have an EKU.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/target-eku-none/chain.pem b/net/data/verify_certificate_chain_unittest/target-eku-none/chain.pem index 3d9fd070..cbfacfc 100644 --- a/net/data/verify_certificate_chain_unittest/target-eku-none/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-eku-none/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The target has no -Extended Key Usage extension (meaning it is unrestricted). Verification is -expected to succeed. +Certificate chain where the leaf certificate lacks an extended key usage +extension. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-eku-none/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-eku-none/generate-chains.py index 666b1c3..bed26f3 100755 --- a/net/data/verify_certificate_chain_unittest/target-eku-none/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-eku-none/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The target has no -Extended Key Usage extension (meaning it is unrestricted). Verification is -expected to succeed.""" +"""Certificate chain where the leaf certificate lacks an extended key usage +extension.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca/chain.pem b/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca/chain.pem index 6ddc5ff..b168de17 100644 --- a/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca/chain.pem
@@ -1,9 +1,8 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate, a trusted root, and a target -certificate that is not a CA, and yet has the keyCertSign bit set. Verification -is expected to fail, since keyCertSign should only be asserted when CA is -true. +Certificate chain where the leaf certificate asserts the keyCertSign key +usage, however does not have CA=true in the basic constraints extension to +indicate it is a CA. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca/generate-chains.py index 01f4509d2..8be0639d 100755 --- a/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca/generate-chains.py
@@ -3,17 +3,16 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate, a trusted root, and a target -certificate that is not a CA, and yet has the keyCertSign bit set. Verification -is expected to fail, since keyCertSign should only be asserted when CA is -true.""" +"""Certificate chain where the leaf certificate asserts the keyCertSign key +usage, however does not have CA=true in the basic constraints extension to +indicate it is a CA.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca/chain.pem b/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca/chain.pem index a9755a0..d30730c 100644 --- a/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate, a trusted root, and a target -certificate that is not a CA, and yet has a pathlen set. Verification is -expected to fail, since pathlen should only be set for CAs. +Certificate chain where the leaf has a basic constraints extension with +CA=false, however specifies the optional pathlen. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca/generate-chains.py index 44405c9..ee76922 100755 --- a/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate, a trusted root, and a target -certificate that is not a CA, and yet has a pathlen set. Verification is -expected to fail, since pathlen should only be set for CAs.""" +"""Certificate chain where the leaf has a basic constraints extension with +CA=false, however specifies the optional pathlen.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/target-not-end-entity/chain.pem b/net/data/verify_certificate_chain_unittest/target-not-end-entity/chain.pem index 25b2680e..71b7cdb 100644 --- a/net/data/verify_certificate_chain_unittest/target-not-end-entity/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-not-end-entity/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate, a trusted root, and a target -certificate that is also a CA. Verification is expected to succeed, as the test -code accepts any target certificate. +Certificate chain where the target certificate is a CA rather than an +end-entity certificate (based on the basic constraints extension). Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-not-end-entity/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-not-end-entity/generate-chains.py index d1c8b493..2ddb84e 100755 --- a/net/data/verify_certificate_chain_unittest/target-not-end-entity/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-not-end-entity/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate, a trusted root, and a target -certificate that is also a CA. Verification is expected to succeed, as the test -code accepts any target certificate.""" +"""Certificate chain where the target certificate is a CA rather than an +end-entity certificate (based on the basic constraints extension).""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-decipherOnly.pem b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-decipherOnly.pem index 801b997..bd3a9a8 100644 --- a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-decipherOnly.pem +++ b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-decipherOnly.pem
@@ -1,6 +1,6 @@ [Created by: generate-chains.py] -Certificate chain where the target uses a EC key and has the single key usage decipherOnly +Certificate chain where the target certificate uses a EC key and has the single key usage decipherOnly Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-digitalSignature.pem b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-digitalSignature.pem index 4dcaeaf..fd83e03 100644 --- a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-digitalSignature.pem +++ b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-digitalSignature.pem
@@ -1,6 +1,6 @@ [Created by: generate-chains.py] -Certificate chain where the target uses a EC key and has the single key usage digitalSignature +Certificate chain where the target certificate uses a EC key and has the single key usage digitalSignature Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-keyAgreement.pem b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-keyAgreement.pem index 99c9740..f788b98 100644 --- a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-keyAgreement.pem +++ b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-keyAgreement.pem
@@ -1,6 +1,6 @@ [Created by: generate-chains.py] -Certificate chain where the target uses a EC key and has the single key usage keyAgreement +Certificate chain where the target certificate uses a EC key and has the single key usage keyAgreement Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-keyEncipherment.pem b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-keyEncipherment.pem index 39717eb..cfc277c 100644 --- a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-keyEncipherment.pem +++ b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/ec-keyEncipherment.pem
@@ -1,6 +1,6 @@ [Created by: generate-chains.py] -Certificate chain where the target uses a EC key and has the single key usage keyEncipherment +Certificate chain where the target certificate uses a EC key and has the single key usage keyEncipherment Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/generate-chains.py index 6b81970..ce07591 100755 --- a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/generate-chains.py
@@ -47,6 +47,7 @@ # Write the chain. chain = [target, intermediate, root] - description = ('Certificate chain where the target uses a %s key and has ' - 'the single key usage %s') % (key_type.upper(), key_usage) + description = ('Certificate chain where the target certificate uses a %s ' + 'key and has the single key usage %s') % (key_type.upper(), + key_usage) common.write_chain(description, chain, '%s-%s.pem' % (key_type, key_usage))
diff --git a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-decipherOnly.pem b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-decipherOnly.pem index 0b4b507..06e2f1c 100644 --- a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-decipherOnly.pem +++ b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-decipherOnly.pem
@@ -1,6 +1,6 @@ [Created by: generate-chains.py] -Certificate chain where the target uses a RSA key and has the single key usage decipherOnly +Certificate chain where the target certificate uses a RSA key and has the single key usage decipherOnly Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-digitalSignature.pem b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-digitalSignature.pem index 2aa08ea..2be07a26 100644 --- a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-digitalSignature.pem +++ b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-digitalSignature.pem
@@ -1,6 +1,6 @@ [Created by: generate-chains.py] -Certificate chain where the target uses a RSA key and has the single key usage digitalSignature +Certificate chain where the target certificate uses a RSA key and has the single key usage digitalSignature Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-keyAgreement.pem b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-keyAgreement.pem index e32e6d2..190afc5 100644 --- a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-keyAgreement.pem +++ b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-keyAgreement.pem
@@ -1,6 +1,6 @@ [Created by: generate-chains.py] -Certificate chain where the target uses a RSA key and has the single key usage keyAgreement +Certificate chain where the target certificate uses a RSA key and has the single key usage keyAgreement Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-keyEncipherment.pem b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-keyEncipherment.pem index 9ae0468b..b4caac3 100644 --- a/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-keyEncipherment.pem +++ b/net/data/verify_certificate_chain_unittest/target-serverauth-various-keyusages/rsa-keyEncipherment.pem
@@ -1,6 +1,6 @@ [Created by: generate-chains.py] -Certificate chain where the target uses a RSA key and has the single key usage keyEncipherment +Certificate chain where the target certificate uses a RSA key and has the single key usage keyEncipherment Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa/chain.pem b/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa/chain.pem index dd509cd..4b702e0 100644 --- a/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The target -certificate is signed using a weak RSA key (512-bit modulus), and so -verification is expected to fail. +Certificate chain where the target certificate is signed using a weak RSA +key (512-bit modulus). Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa/generate-chains.py index 411a831..066fb60e 100755 --- a/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The target -certificate is signed using a weak RSA key (512-bit modulus), and so -verification is expected to fail.""" +"""Certificate chain where the target certificate is signed using a weak RSA +key (512-bit modulus).""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate with a very weak key size (512-bit RSA).
diff --git a/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa/chain.pem b/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa/chain.pem index 86a472a..e53f710 100644 --- a/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa/chain.pem
@@ -1,7 +1,8 @@ [Created by: generate-chains.py] -Certificate chain with a trusted root using RSA, and intermediate using EC, -and a target certificate using RSA. Verification is expected to succeed. +Certificate chain where the root certificate holds an RSA key, intermediate +certificate holds an EC key, and target certificate holds an RSA key. The +target certificate has a valid signature using ECDSA. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa/generate-chains.py index b852f3f..ed8fd7ad8 100755 --- a/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa/generate-chains.py
@@ -3,15 +3,16 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with a trusted root using RSA, and intermediate using EC, -and a target certificate using RSA. Verification is expected to succeed.""" +"""Certificate chain where the root certificate holds an RSA key, intermediate +certificate holds an EC key, and target certificate holds an RSA key. The +target certificate has a valid signature using ECDSA.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). using RSA. +# Self-signed root certificate using an RSA key. root = common.create_self_signed_root_certificate('Root') # Intermediate using an EC key for the P-384 curve.
diff --git a/net/data/verify_certificate_chain_unittest/target-signed-with-md5/chain.pem b/net/data/verify_certificate_chain_unittest/target-signed-with-md5/chain.pem index 88bbc11..bc74388 100644 --- a/net/data/verify_certificate_chain_unittest/target-signed-with-md5/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-signed-with-md5/chain.pem
@@ -1,7 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with an intermediate that uses MD5 to sign the target -certificate. This is expected to fail because MD5 is too weak. +Certificate chain where the intermediate used MD5 to sign the target +certificate. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-signed-with-md5/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-signed-with-md5/generate-chains.py index 0a4d747..7ca93f4 100755 --- a/net/data/verify_certificate_chain_unittest/target-signed-with-md5/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-signed-with-md5/generate-chains.py
@@ -3,15 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with an intermediate that uses MD5 to sign the target -certificate. This is expected to fail because MD5 is too weak.""" +"""Certificate chain where the intermediate used MD5 to sign the target +certificate.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate.
diff --git a/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension/chain.pem b/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension/chain.pem index 465b565..15273d3 100644 --- a/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension/chain.pem
@@ -1,9 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 1 intermediate and a trusted root. The target -certificate has an unknown X.509v3 extension (OID=1.2.3.4) that is marked as -critical. Verifying this certificate chain is expected to fail because there is -an unrecognized critical extension. +Certificate chain where the target certificate contains an unknown X.509v3 +extension (OID=1.2.3.4) that is marked as critical. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension/generate-chains.py index f1d43a4..ce94161 100755 --- a/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension/generate-chains.py
@@ -3,17 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 1 intermediate and a trusted root. The target -certificate has an unknown X.509v3 extension (OID=1.2.3.4) that is marked as -critical. Verifying this certificate chain is expected to fail because there is -an unrecognized critical extension.""" +"""Certificate chain where the target certificate contains an unknown X.509v3 +extension (OID=1.2.3.4) that is marked as critical.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate.
diff --git a/net/data/verify_certificate_chain_unittest/target-wrong-signature/chain.pem b/net/data/verify_certificate_chain_unittest/target-wrong-signature/chain.pem index 56a5c00..181dee0 100644 --- a/net/data/verify_certificate_chain_unittest/target-wrong-signature/chain.pem +++ b/net/data/verify_certificate_chain_unittest/target-wrong-signature/chain.pem
@@ -1,8 +1,6 @@ [Created by: generate-chains.py] -Certificate chain where the target has an incorrect signature. Everything -else should check out, however the digital signature contained in the target -certificate is wrong. +Certificate chain where the target certificate has an incorrect signature. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/target-wrong-signature/generate-chains.py b/net/data/verify_certificate_chain_unittest/target-wrong-signature/generate-chains.py index 55c7e16..b29ef964b 100755 --- a/net/data/verify_certificate_chain_unittest/target-wrong-signature/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/target-wrong-signature/generate-chains.py
@@ -3,16 +3,14 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain where the target has an incorrect signature. Everything -else should check out, however the digital signature contained in the target -certificate is wrong.""" +"""Certificate chain where the target certificate has an incorrect signature.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate to include in the certificate chain.
diff --git a/net/data/verify_certificate_chain_unittest/unknown-critical-policy-qualifier/chain.pem b/net/data/verify_certificate_chain_unittest/unknown-critical-policy-qualifier/chain.pem index 496fafca..8795e03 100644 --- a/net/data/verify_certificate_chain_unittest/unknown-critical-policy-qualifier/chain.pem +++ b/net/data/verify_certificate_chain_unittest/unknown-critical-policy-qualifier/chain.pem
@@ -1,7 +1,7 @@ [Created by: generate-chains.py] -The intermediate has a policies extension marked as critical, which contains -an unknown qualifer (1.2.3.4). +Certificate chain where the intermediate has a policies extension marked as +critical, and contains an unknown policy qualifer (1.2.3.4). Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/unknown-critical-policy-qualifier/generate-chains.py b/net/data/verify_certificate_chain_unittest/unknown-critical-policy-qualifier/generate-chains.py index caad547..0cde86e 100755 --- a/net/data/verify_certificate_chain_unittest/unknown-critical-policy-qualifier/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/unknown-critical-policy-qualifier/generate-chains.py
@@ -3,15 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""The intermediate has a policies extension marked as critical, which contains -an unknown qualifer (1.2.3.4).""" +"""Certificate chain where the intermediate has a policies extension marked as +critical, and contains an unknown policy qualifer (1.2.3.4).""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate that has a critical policies extension containing an unknown
diff --git a/net/data/verify_certificate_chain_unittest/unknown-non-critical-policy-qualifier/chain.pem b/net/data/verify_certificate_chain_unittest/unknown-non-critical-policy-qualifier/chain.pem index f890d68..a7747b91 100644 --- a/net/data/verify_certificate_chain_unittest/unknown-non-critical-policy-qualifier/chain.pem +++ b/net/data/verify_certificate_chain_unittest/unknown-non-critical-policy-qualifier/chain.pem
@@ -1,7 +1,7 @@ [Created by: generate-chains.py] -The intermediate has a policies extension (not marked as critical), -which contains an unknown qualifer (1.2.3.4). +Certificate chain where the intermediate has a policies extension (not +marked as critical) which contains an unknown policy qualifer (1.2.3.4). Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/unknown-non-critical-policy-qualifier/generate-chains.py b/net/data/verify_certificate_chain_unittest/unknown-non-critical-policy-qualifier/generate-chains.py index 32dd793a..7fe6b22 100755 --- a/net/data/verify_certificate_chain_unittest/unknown-non-critical-policy-qualifier/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/unknown-non-critical-policy-qualifier/generate-chains.py
@@ -3,15 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""The intermediate has a policies extension (not marked as critical), -which contains an unknown qualifer (1.2.3.4).""" +"""Certificate chain where the intermediate has a policies extension (not +marked as critical) which contains an unknown policy qualifer (1.2.3.4).""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate that has a non-critical policies extension containing an unknown
diff --git a/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0/chain.pem b/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0/chain.pem index 9502729..cf5fa027 100644 --- a/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0/chain.pem +++ b/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0/chain.pem
@@ -1,8 +1,7 @@ [Created by: generate-chains.py] -Certificate chain with 2 intermediates. The first intermediate has a basic -constraints path length of 0, so it is a violation for it to have a subordinate -intermediate. +Certificate chain where the intermediate sets pathlen=0, however +violates this by issuing another (non-self-issued) intermediate. Certificate: Data:
diff --git a/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0/generate-chains.py b/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0/generate-chains.py index e8092f7a..a13bbdf 100755 --- a/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0/generate-chains.py +++ b/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0/generate-chains.py
@@ -3,16 +3,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Certificate chain with 2 intermediates. The first intermediate has a basic -constraints path length of 0, so it is a violation for it to have a subordinate -intermediate.""" +"""Certificate chain where the intermediate sets pathlen=0, however +violates this by issuing another (non-self-issued) intermediate.""" import sys sys.path += ['..'] import common -# Self-signed root certificate (used as trust anchor). +# Self-signed root certificate. root = common.create_self_signed_root_certificate('Root') # Intermediate with pathlen 0
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 400d73d8..4e30c10 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -797,7 +797,7 @@ crbug.com/521858 [ Win7 ] http/tests/security/media-element-audio-source-node-same-origin.html [ Failure Pass ] crbug.com/521858 [ Win7 ] virtual/mojo-loading/http/tests/security/media-element-audio-source-node-same-origin.html [ Failure Pass ] crbug.com/521853 [ Win ] http/tests/inspector/search/sources-search-scope.html [ Failure Pass ] -crbug.com/520170 [ Win ] fast/dom/timer-throttling-hidden-page.html [ Failure Pass ] +crbug.com/520170 fast/dom/timer-throttling-hidden-page.html [ Failure Pass ] crbug.com/652536 fast/events/mouse-cursor-change-after-image-load.html [ Failure Pass ] crbug.com/520188 [ Win ] http/tests/local/fileapi/file-last-modified-after-delete.html [ Failure Pass ] crbug.com/520188 [ Win ] virtual/mojo-loading/http/tests/local/fileapi/file-last-modified-after-delete.html [ Failure Pass ] @@ -2466,7 +2466,10 @@ crbug.com/595993 external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] crbug.com/595993 virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] -crbug.com/735883 [ Win10 ] external/wpt/service-workers/service-worker/fetch-canvas-tainting-cache.https.html [ Pass Failure ] +crbug.com/735883 external/wpt/service-workers/service-worker/fetch-canvas-tainting.https.html [ Pass Failure ] +crbug.com/735883 virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting.https.html [ Pass Failure ] +crbug.com/735883 external/wpt/service-workers/service-worker/fetch-canvas-tainting-cache.https.html [ Pass Failure ] +crbug.com/735883 virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-canvas-tainting-cache.https.html [ Pass Failure ] crbug.com/619427 [ Mac Linux ] fast/overflow/overflow-height-float-not-removed-crash3.html [ Pass Failure ] @@ -2764,3 +2767,67 @@ # Rebaselining a newly-passing test fixed by v8 crbug.com/v8/6504 fast/js/mozilla/strict/B.1.2.html [ NeedsManualRebaseline ] + +# These tests are failing on Mac-10.12 when using an Intel GPU. +crbug.com/736177 [ Mac ] css2.1/t1202-counter-04-b.html [ Failure Pass ] +crbug.com/736177 [ Mac ] css2.1/t1202-counters-04-b.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/block/basic/001.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/block/float/intruding-painted-twice.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/borders/inline-mask-overlay-image-outset.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/css-generated-content/012.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/css-generated-content/014.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/css/acid2-pixel.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/css/clip-zooming.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/css/h1-in-section-elements.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/css/rem-calc-dynamic-scaling.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/css/rem-dynamic-scaling.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/dom/HTMLMeterElement/meter-optimums.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/dynamic/012.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/forms/form-element-geometry.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/inline/absolute-positioned-inline-in-centred-block.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/lists/ordered-list-with-no-ol-tag.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/selectors/166.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/text/color-emoji.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/text/emoticons.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/text/fallback-traits-fixup.html [ Failure Pass ] +crbug.com/736177 [ Mac ] fast/text/unicode-fallback-font.html [ Failure Pass ] +crbug.com/736177 [ Mac ] html/details_summary/details-marker-style.html [ Failure Pass ] +crbug.com/736177 [ Mac ] http/tests/misc/acid2-pixel.html [ Failure Pass ] +crbug.com/736177 [ Mac ] media/video-zoom-controls.html [ Failure Pass ] +crbug.com/736177 [ Mac ] paint/spellmarkers/document-markers-zoom-150.html [ Failure Pass ] +crbug.com/736177 [ Mac ] scrollbars/custom-scrollbar-with-incomplete-style.html [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/W3C-SVG-1.1/script-handle-02-b.svg [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/W3C-SVG-1.1/script-handle-03-b.svg [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/W3C-SVG-1.1/script-handle-04-b.svg [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/W3C-SVG-1.1/struct-use-05-b.svg [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/W3C-SVG-1.1/text-fonts-01-t.svg [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/as-border-image/svg-as-border-image-2.html [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/as-border-image/svg-as-border-image.html [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/batik/text/textLayout.svg [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/custom/focus-ring-text.svg [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/text/surrogate-pair-queries.html [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/text/text-path-middle-align.svg [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/transforms/svg-css-transforms-clip-path.xhtml [ Failure Pass ] +crbug.com/736177 [ Mac ] svg/transforms/svg-css-transforms.xhtml [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/bugs/bug18359.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/bugs/bug2479-3.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/bugs/bug2479-4.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/bugs/bug46480-1.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/bugs/bug46480-2.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/bugs/bug8032-1.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/bugs/bug8858.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/other/test3.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/other/test6.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/other/wa_table_thtd_rowspan.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla/other/wa_table_tr_align.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla_expected_failures/bugs/bug1128.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla_expected_failures/bugs/bug2479-5.html [ Failure Pass ] +crbug.com/736177 [ Mac ] tables/mozilla_expected_failures/bugs/bug91057.html [ Failure Pass ] +crbug.com/736177 [ Mac ] transforms/svg-vs-css.xhtml [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/disable-spinvalidation/paint/spellmarkers/document-markers-zoom-150.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/layout_ng/fast/block/basic/001.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/mojo-loading/http/tests/misc/acid2-pixel.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/off-main-thread-fetch/http/tests/misc/acid2-pixel.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/prefer_compositing_to_lcd_text/scrollbars/custom-scrollbar-with-incomplete-style.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style.html [ Failure Pass ]
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp index 595aebb..b790cb0 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -655,9 +655,9 @@ << position << ' ' << highest_root; // position falls before highestRoot. if (position.CompareTo(PositionTemplate<Strategy>::FirstPositionInNode( - &highest_root)) == -1 && + highest_root)) == -1 && HasEditableStyle(highest_root)) - return PositionTemplate<Strategy>::FirstPositionInNode(&highest_root); + return PositionTemplate<Strategy>::FirstPositionInNode(highest_root); PositionTemplate<Strategy> editable_position = position; @@ -1907,7 +1907,7 @@ else scope = document.documentElement(); - EphemeralRange range(Position::FirstPositionInNode(scope), + EphemeralRange range(Position::FirstPositionInNode(*scope), p.ParentAnchoredEquivalent()); return TextIterator::RangeLength(
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp b/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp index eb00000..aeae254 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp
@@ -55,7 +55,7 @@ .DeepEquivalent()); EXPECT_EQ( - Position::FirstPositionInNode(host), + Position::FirstPositionInNode(*host), FirstEditablePositionAfterPositionInRoot(Position(three, 0), *host)); EXPECT_EQ( Position(one->firstChild(), 0), @@ -184,13 +184,13 @@ .DeepEquivalent()); EXPECT_EQ( - Position::FirstPositionInNode(host), + Position::FirstPositionInNode(*host), LastEditablePositionBeforePositionInRoot(Position(three, 0), *host)); EXPECT_EQ( Position(one->firstChild(), 0), LastEditableVisiblePositionBeforePositionInRoot(Position(three, 0), *host) .DeepEquivalent()); - EXPECT_EQ(PositionInFlatTree::FirstPositionInNode(host), + EXPECT_EQ(PositionInFlatTree::FirstPositionInNode(*host), LastEditablePositionBeforePositionInRoot( PositionInFlatTree(three, 0), *host)); EXPECT_EQ(PositionInFlatTree(two->firstChild(), 0),
diff --git a/third_party/WebKit/Source/core/editing/EphemeralRange.cpp b/third_party/WebKit/Source/core/editing/EphemeralRange.cpp index 574ddb6..019ac2a 100644 --- a/third_party/WebKit/Source/core/editing/EphemeralRange.cpp +++ b/third_party/WebKit/Source/core/editing/EphemeralRange.cpp
@@ -143,7 +143,7 @@ EphemeralRangeTemplate<Strategy> EphemeralRangeTemplate<Strategy>::RangeOfContents(const Node& node) { return EphemeralRangeTemplate<Strategy>( - PositionTemplate<Strategy>::FirstPositionInNode(&const_cast<Node&>(node)), + PositionTemplate<Strategy>::FirstPositionInNode(node), PositionTemplate<Strategy>::LastPositionInNode(&const_cast<Node&>(node))); }
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp index 7e42e9c..0c0c9718 100644 --- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp +++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -448,7 +448,7 @@ // Selection has focus if it contains the focused element. const PositionInFlatTree& focused_position = - PositionInFlatTree::FirstPositionInNode(focused_element); + PositionInFlatTree::FirstPositionInNode(*focused_element); if (ComputeVisibleSelectionInFlatTree().Start() <= focused_position && ComputeVisibleSelectionInFlatTree().End() >= focused_position) return true;
diff --git a/third_party/WebKit/Source/core/editing/Position.cpp b/third_party/WebKit/Source/core/editing/Position.cpp index 6b58eb4..9647826 100644 --- a/third_party/WebKit/Source/core/editing/Position.cpp +++ b/third_party/WebKit/Source/core/editing/Position.cpp
@@ -490,10 +490,10 @@ // static template <typename Strategy> PositionTemplate<Strategy> PositionTemplate<Strategy>::FirstPositionInNode( - Node* anchor_node) { - if (anchor_node->IsTextNode()) + const Node& anchor_node) { + if (anchor_node.IsTextNode()) return PositionTemplate<Strategy>(anchor_node, 0); - return PositionTemplate<Strategy>(anchor_node, + return PositionTemplate<Strategy>(&anchor_node, PositionAnchorType::kBeforeChildren); } @@ -515,7 +515,7 @@ if (!node) return PositionTemplate<Strategy>(); return EditingIgnoresContent(*node) ? BeforeNode(*node) - : FirstPositionInNode(node); + : FirstPositionInNode(*node); } // static
diff --git a/third_party/WebKit/Source/core/editing/Position.h b/third_party/WebKit/Source/core/editing/Position.h index 11ed856..0e97aae 100644 --- a/third_party/WebKit/Source/core/editing/Position.h +++ b/third_party/WebKit/Source/core/editing/Position.h
@@ -193,7 +193,8 @@ static PositionTemplate<Strategy> InParentBeforeNode(const Node& anchor_node); static PositionTemplate<Strategy> InParentAfterNode(const Node& anchor_node); static int LastOffsetInNode(Node* anchor_node); - static PositionTemplate<Strategy> FirstPositionInNode(Node* anchor_node); + static PositionTemplate<Strategy> FirstPositionInNode( + const Node& anchor_node); static PositionTemplate<Strategy> LastPositionInNode(Node* anchor_node); static PositionTemplate<Strategy> FirstPositionInOrBeforeNode( Node* anchor_node);
diff --git a/third_party/WebKit/Source/core/editing/PositionIteratorTest.cpp b/third_party/WebKit/Source/core/editing/PositionIteratorTest.cpp index 615d2ae..b609a02 100644 --- a/third_party/WebKit/Source/core/editing/PositionIteratorTest.cpp +++ b/third_party/WebKit/Source/core/editing/PositionIteratorTest.cpp
@@ -141,7 +141,7 @@ // Increment until start of "123" from INPUT on DOM tree PositionIterator dom_iterator( - Position::FirstPositionInNode(GetDocument().body())); + Position::FirstPositionInNode(*GetDocument().body())); EXPECT_EQ(Position(GetDocument().body(), 0), dom_iterator.ComputePosition()); dom_iterator.Increment(); EXPECT_EQ(Position::BeforeNode(*input), dom_iterator.ComputePosition()); @@ -154,7 +154,7 @@ // Increment until start of "123" from INPUT on flat tree PositionIteratorInFlatTree flat_iterator( - PositionInFlatTree::FirstPositionInNode(GetDocument().body())); + PositionInFlatTree::FirstPositionInNode(*GetDocument().body())); EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 0), flat_iterator.ComputePosition()); flat_iterator.Increment(); @@ -177,7 +177,7 @@ // Increment until start of "123" from SELECT on DOM tree PositionIterator dom_iterator( - Position::FirstPositionInNode(GetDocument().body())); + Position::FirstPositionInNode(*GetDocument().body())); EXPECT_EQ(Position(GetDocument().body(), 0), dom_iterator.ComputePosition()); dom_iterator.Increment(); EXPECT_EQ(Position::BeforeNode(*select), dom_iterator.ComputePosition()); @@ -194,7 +194,7 @@ // Increment until start of "123" from SELECT on flat tree PositionIteratorInFlatTree flat_iterator( - PositionInFlatTree::FirstPositionInNode(GetDocument().body())); + PositionInFlatTree::FirstPositionInNode(*GetDocument().body())); EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 0), flat_iterator.ComputePosition()); flat_iterator.Increment(); @@ -223,7 +223,7 @@ // Increment until start of "123" from TEXTAREA on DOM tree PositionIterator dom_iterator( - Position::FirstPositionInNode(GetDocument().body())); + Position::FirstPositionInNode(*GetDocument().body())); EXPECT_EQ(Position(GetDocument().body(), 0), dom_iterator.ComputePosition()); dom_iterator.Increment(); EXPECT_EQ(Position::BeforeNode(*textarea), dom_iterator.ComputePosition()); @@ -236,7 +236,7 @@ // Increment until start of "123" from TEXTAREA on flat tree PositionIteratorInFlatTree flat_iterator( - PositionInFlatTree::FirstPositionInNode(GetDocument().body())); + PositionInFlatTree::FirstPositionInNode(*GetDocument().body())); EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 0), flat_iterator.ComputePosition()); // TODO(yosin): We should not traverse inside TEXTAREA
diff --git a/third_party/WebKit/Source/core/editing/PositionTest.cpp b/third_party/WebKit/Source/core/editing/PositionTest.cpp index 96b11dc..63532a6 100644 --- a/third_party/WebKit/Source/core/editing/PositionTest.cpp +++ b/third_party/WebKit/Source/core/editing/PositionTest.cpp
@@ -18,7 +18,7 @@ EXPECT_TRUE(Position(sample, 0).IsEquivalent(Position(sample, 0))); EXPECT_TRUE( - Position(sample, 0).IsEquivalent(Position::FirstPositionInNode(sample))); + Position(sample, 0).IsEquivalent(Position::FirstPositionInNode(*sample))); EXPECT_TRUE(Position(sample, 0).IsEquivalent( Position::BeforeNode(*sample->firstChild()))); EXPECT_TRUE(Position(sample, 1).IsEquivalent(
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp index fdf7cea..e17c6ee55 100644 --- a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp +++ b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
@@ -177,7 +177,7 @@ ContainerNode& container) { Node* node = position.ComputeContainerNode(); if (container.ContainsIncludingHostElements(*node)) - return Position::FirstPositionInNode(&container); + return Position::FirstPositionInNode(container); return position; }
diff --git a/third_party/WebKit/Source/core/editing/SurroundingText.cpp b/third_party/WebKit/Source/core/editing/SurroundingText.cpp index 68e561e..7e9926d 100644 --- a/third_party/WebKit/Source/core/editing/SurroundingText.cpp +++ b/third_party/WebKit/Source/core/editing/SurroundingText.cpp
@@ -92,7 +92,7 @@ // starts at the document's or input element's start and ends at the selection // start and will be updated. BackwardsCharacterIterator backwards_iterator( - Position::FirstPositionInNode(root_element).ParentAnchoredEquivalent(), + Position::FirstPositionInNode(*root_element).ParentAnchoredEquivalent(), start_position, TextIteratorBehavior::Builder().SetStopsOnFormControls(true).Build()); if (!backwards_iterator.AtEnd())
diff --git a/third_party/WebKit/Source/core/editing/TextFinder.cpp b/third_party/WebKit/Source/core/editing/TextFinder.cpp index 5bb2ca8..0cc5628 100644 --- a/third_party/WebKit/Source/core/editing/TextFinder.cpp +++ b/third_party/WebKit/Source/core/editing/TextFinder.cpp
@@ -395,7 +395,7 @@ } PositionInFlatTree search_start = PositionInFlatTree::FirstPositionInNode( - OwnerFrame().GetFrame()->GetDocument()); + *OwnerFrame().GetFrame()->GetDocument()); PositionInFlatTree search_end = PositionInFlatTree::LastPositionInNode( OwnerFrame().GetFrame()->GetDocument()); DCHECK_EQ(search_start.GetDocument(), search_end.GetDocument());
diff --git a/third_party/WebKit/Source/core/editing/VisiblePosition.cpp b/third_party/WebKit/Source/core/editing/VisiblePosition.cpp index 80b34b7..63daef9 100644 --- a/third_party/WebKit/Source/core/editing/VisiblePosition.cpp +++ b/third_party/WebKit/Source/core/editing/VisiblePosition.cpp
@@ -118,7 +118,7 @@ VisiblePositionTemplate<Strategy> VisiblePositionTemplate<Strategy>::FirstPositionInNode(Node* node) { return Create(PositionWithAffinityTemplate<Strategy>( - PositionTemplate<Strategy>::FirstPositionInNode(node))); + PositionTemplate<Strategy>::FirstPositionInNode(*node))); } template <typename Strategy>
diff --git a/third_party/WebKit/Source/core/editing/VisibleSelectionTest.cpp b/third_party/WebKit/Source/core/editing/VisibleSelectionTest.cpp index 868b1b216..1fa4edd 100644 --- a/third_party/WebKit/Source/core/editing/VisibleSelectionTest.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleSelectionTest.cpp
@@ -253,7 +253,7 @@ const VisibleSelection& visible_selectin_in_dom_tree = CreateVisibleSelection( SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(html_element)) + .Collapse(Position::FirstPositionInNode(*html_element)) .Extend(Position::LastPositionInNode(html_element)) .Build()); EXPECT_EQ(SelectionInDOMTree::Builder() @@ -265,7 +265,7 @@ const VisibleSelectionInFlatTree& visible_selectin_in_flat_tree = CreateVisibleSelection( SelectionInFlatTree::Builder() - .Collapse(PositionInFlatTree::FirstPositionInNode(html_element)) + .Collapse(PositionInFlatTree::FirstPositionInNode(*html_element)) .Extend(PositionInFlatTree::LastPositionInNode(html_element)) .Build()); EXPECT_EQ(SelectionInFlatTree::Builder() @@ -292,12 +292,12 @@ VisibleSelection selection = CreateVisibleSelection( SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(one)) + .Collapse(Position::FirstPositionInNode(*one)) .Extend(Position::LastPositionInNode(shadow_root)) .Build()); VisibleSelectionInFlatTree selection_in_flat_tree = CreateVisibleSelection( SelectionInFlatTree::Builder() - .Collapse(PositionInFlatTree::FirstPositionInNode(one)) + .Collapse(PositionInFlatTree::FirstPositionInNode(*one)) .Extend(PositionInFlatTree::LastPositionInNode(host)) .Build()); @@ -327,12 +327,12 @@ VisibleSelection selection = CreateVisibleSelection(SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(one)) + .Collapse(Position::FirstPositionInNode(*one)) .Extend(Position::LastPositionInNode(two)) .Build()); VisibleSelectionInFlatTree selection_in_flat_tree = CreateVisibleSelection( SelectionInFlatTree::Builder() - .Collapse(PositionInFlatTree::FirstPositionInNode(one)) + .Collapse(PositionInFlatTree::FirstPositionInNode(*one)) .Extend(PositionInFlatTree::LastPositionInNode(two)) .Build()); @@ -373,12 +373,12 @@ VisibleSelection selection = CreateVisibleSelection( SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(one)) + .Collapse(Position::FirstPositionInNode(*one)) .Extend(Position::LastPositionInNode(shadow_root2)) .Build()); VisibleSelectionInFlatTree selection_in_flat_tree = CreateVisibleSelection( SelectionInFlatTree::Builder() - .Collapse(PositionInFlatTree::FirstPositionInNode(one)) + .Collapse(PositionInFlatTree::FirstPositionInNode(*one)) .Extend(PositionInFlatTree::AfterNode(*eight)) .Build());
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp index 8c81961..868deaa 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -418,7 +418,7 @@ BackwardsTextBuffer prefix_string; if (RequiresContextForWordBoundary(CharacterAfter(c))) { SimplifiedBackwardsTextIteratorAlgorithm<Strategy> backwards_iterator( - PositionTemplate<Strategy>::FirstPositionInNode(&d), start); + PositionTemplate<Strategy>::FirstPositionInNode(d), start); while (!backwards_iterator.AtEnd()) { backwards_iterator.CopyTextTo(&prefix_string); int context_start_index = StartOfLastWordBoundaryContext( @@ -590,7 +590,7 @@ return VisiblePositionTemplate<Strategy>(); return CreateVisiblePosition(PositionTemplate<Strategy>::FirstPositionInNode( - node->GetDocument().documentElement())); + *node->GetDocument().documentElement())); } VisiblePosition StartOfDocument(const VisiblePosition& c) {
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsLine.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsLine.cpp index 2bb61c8..37ed8d25 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnitsLine.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnitsLine.cpp
@@ -359,7 +359,7 @@ if (!editable_root->contains( vis_pos.GetPosition().ComputeContainerNode())) { return PositionWithAffinityTemplate<Strategy>( - PositionTemplate<Strategy>::FirstPositionInNode(editable_root)); + PositionTemplate<Strategy>::FirstPositionInNode(*editable_root)); } }
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp index a5c92fe5..741a73e8 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp
@@ -246,11 +246,11 @@ EXPECT_EQ(Position::BeforeNode(*input), CanonicalPositionOf(Position::FirstPositionInNode( - GetDocument().documentElement()))); + *GetDocument().documentElement()))); EXPECT_EQ(PositionInFlatTree::BeforeNode(*input), CanonicalPositionOf(PositionInFlatTree::FirstPositionInNode( - GetDocument().documentElement()))); + *GetDocument().documentElement()))); } TEST_F(VisibleUnitsTest, characterBefore) { @@ -1338,13 +1338,13 @@ EXPECT_EQ(Position(GetDocument().body(), 0), MostForwardCaretPosition( - Position::FirstPositionInNode(GetDocument().body()))); + Position::FirstPositionInNode(*GetDocument().body()))); EXPECT_EQ( Position(sample, 1), MostForwardCaretPosition(Position::BeforeNode(*sample->parentNode()))); EXPECT_EQ(Position(sample, 1), MostForwardCaretPosition( - Position::FirstPositionInNode(sample->parentNode()))); + Position::FirstPositionInNode(*sample->parentNode()))); EXPECT_EQ(Position(sample, 1), MostForwardCaretPosition(Position(sample, 0))); EXPECT_EQ(Position(sample, 1), MostForwardCaretPosition(Position(sample, 1))); EXPECT_EQ(Position(sample, 2), MostForwardCaretPosition(Position(sample, 2)));
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp index a1c3139e..a2d4f00 100644 --- a/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp
@@ -279,7 +279,7 @@ SplitTextNode(start_text, start_offset); GetDocument().UpdateStyleAndLayoutTree(); - start = Position::FirstPositionInNode(start_text); + start = Position::FirstPositionInNode(*start_text); if (is_start_and_end_on_same_node) { DCHECK_GE(end.OffsetInContainerNode(), start_offset); end = Position(start_text, end.OffsetInContainerNode() - start_offset); @@ -360,7 +360,7 @@ if (!style->PreserveNewline() || !end_of_next_paragraph_position.OffsetInContainerNode() || !IsNewLineAtPosition( - Position::FirstPositionInNode(end_of_next_paragraph_text))) + Position::FirstPositionInNode(*end_of_next_paragraph_text))) return end_of_next_paragraph; // \n at the beginning of the text node immediately following the current
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp index 19b8a96..8682b1f 100644 --- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
@@ -263,10 +263,10 @@ Node& scope = NodeTraversal::HighestAncestorOrSelf( *visible_start.DeepEquivalent().AnchorNode()); Range* start_range = - Range::Create(GetDocument(), Position::FirstPositionInNode(&scope), + Range::Create(GetDocument(), Position::FirstPositionInNode(scope), visible_start.DeepEquivalent().ParentAnchoredEquivalent()); Range* end_range = - Range::Create(GetDocument(), Position::FirstPositionInNode(&scope), + Range::Create(GetDocument(), Position::FirstPositionInNode(scope), visible_end.DeepEquivalent().ParentAnchoredEquivalent()); const TextIteratorBehavior behavior = @@ -303,8 +303,8 @@ block = new_block; if (paragraph_start.IsOrphan()) { GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); - paragraph_start = - CreateVisiblePosition(Position::FirstPositionInNode(new_block)); + paragraph_start = CreateVisiblePosition( + Position::FirstPositionInNode(*new_block)); } } DCHECK(!paragraph_start.IsOrphan()) << paragraph_start; @@ -1552,7 +1552,7 @@ Text* text = ToText(start.ComputeContainerNode()); SplitTextNode(text, start.OffsetInContainerNode()); - UpdateStartEnd(Position::FirstPositionInNode(text), new_end); + UpdateStartEnd(Position::FirstPositionInNode(*text), new_end); } void ApplyStyleCommand::SplitTextAtEnd(const Position& start,
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp index 253830d2..21d0a7b 100644 --- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -1504,7 +1504,7 @@ GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); destination_index = TextIterator::RangeLength( - Position::FirstPositionInNode(GetDocument().documentElement()), + Position::FirstPositionInNode(*GetDocument().documentElement()), destination.ToParentAnchoredPosition(), TextIteratorBehavior::AllVisiblePositionsRangeLengthBehavior()); @@ -1678,7 +1678,7 @@ return false; SetEndingSelection(SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(new_block)) + .Collapse(Position::FirstPositionInNode(*new_block)) .SetIsDirectional(EndingSelection().IsDirectional()) .Build());
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp index 7ab8a9f6..4d8630f 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp
@@ -169,7 +169,7 @@ InsertNodeBefore(node_to_insert, text_node, editing_state); if (editing_state->IsAborted()) return; - Position ending_position = Position::FirstPositionInNode(text_node); + Position ending_position = Position::FirstPositionInNode(*text_node); // Handle whitespace that occurs after the split GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); @@ -190,7 +190,7 @@ InsertNodeAt(nbsp_node, position_before_text_node, editing_state); if (editing_state->IsAborted()) return; - ending_position = Position::FirstPositionInNode(nbsp_node); + ending_position = Position::FirstPositionInNode(*nbsp_node); } }
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp index e89026a..3635296f 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp
@@ -426,7 +426,7 @@ } SetEndingSelection(SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(new_list)) + .Collapse(Position::FirstPositionInNode(*new_list)) .Build()); return true;
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp index 7e2d71e..760d55c 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp
@@ -337,7 +337,7 @@ return; SetEndingSelection(SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(parent)) + .Collapse(Position::FirstPositionInNode(*parent)) .SetIsDirectional(EndingSelection().IsDirectional()) .Build()); return; @@ -496,7 +496,7 @@ SplitTextNode(text_node, text_offset); GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets(); - position_after_split = Position::FirstPositionInNode(text_node); + position_after_split = Position::FirstPositionInNode(*text_node); insertion_position = Position(text_node->previousSibling(), text_offset); } } @@ -590,7 +590,7 @@ SetEndingSelection( SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(block_to_insert)) + .Collapse(Position::FirstPositionInNode(*block_to_insert)) .SetIsDirectional(EndingSelection().IsDirectional()) .Build()); ApplyStyleAfterInsertion(start_block, editing_state);
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp index 0d7f811..cdafbfa8 100644 --- a/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp
@@ -58,7 +58,7 @@ InsertNodeAtTabSpanPosition(text_node, pos, editing_state); if (editing_state->IsAborted()) return Position(); - return Position::FirstPositionInNode(text_node); + return Position::FirstPositionInNode(*text_node); } // Prepare for text input by looking at the specified position. @@ -68,7 +68,7 @@ InsertNodeAt(text_node, pos, editing_state); if (editing_state->IsAborted()) return Position(); - return Position::FirstPositionInNode(text_node); + return Position::FirstPositionInNode(*text_node); } return pos;
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp index f7b3793..e44d9d4f 100644 --- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -592,7 +592,7 @@ !context ? ToHTMLQuoteElement(context) : ToHTMLQuoteElement(EnclosingNodeOfType( - Position::FirstPositionInNode(context), + Position::FirstPositionInNode(*context), IsMailHTMLBlockquoteElement, kCanCrossEditingBoundary)); // EditingStyle::removeStyleFromRulesAndContext() uses StyleResolver, @@ -1254,7 +1254,7 @@ SplitTextNode(ToText(insertion_pos.ComputeContainerNode()), insertion_pos.OffsetInContainerNode()); insertion_pos = - Position::FirstPositionInNode(insertion_pos.ComputeContainerNode()); + Position::FirstPositionInNode(*insertion_pos.ComputeContainerNode()); } if (HTMLElement* element_to_split_to = @@ -1543,7 +1543,7 @@ return; SetEndingSelection( SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(new_list_item)) + .Collapse(Position::FirstPositionInNode(*new_list_item)) .Build()); } else { // Use a default paragraph element (a plain div) for the empty @@ -1714,7 +1714,7 @@ InsertNodeBefore(node, start_node, editing_state); if (editing_state->IsAborted()) return; - start_of_inserted_content_ = Position::FirstPositionInNode(node); + start_of_inserted_content_ = Position::FirstPositionInNode(*node); } } }
diff --git a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp index a43633b..3dbbedfd 100644 --- a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
@@ -685,7 +685,7 @@ if (editing_state->IsAborted()) return false; SetEndingSelection(SelectionInDOMTree::Builder() - .Collapse(Position::FirstPositionInNode(root)) + .Collapse(Position::FirstPositionInNode(*root)) .SetIsDirectional(EndingSelection().IsDirectional()) .Build());
diff --git a/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp b/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp index 3322d03..47369b2c 100644 --- a/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/SearchBuffer.cpp
@@ -332,7 +332,7 @@ if (buffer.NeedsMoreContext()) { for (SimplifiedBackwardsTextIteratorAlgorithm<Strategy> backwards_iterator( PositionTemplate<Strategy>::FirstPositionInNode( - it.OwnerDocument()), + *it.OwnerDocument()), PositionTemplate<Strategy>(it.CurrentContainer(), it.StartOffset())); !backwards_iterator.AtEnd(); backwards_iterator.Advance()) {
diff --git a/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp b/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp index 3f628d2..9040767 100644 --- a/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp +++ b/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp
@@ -209,7 +209,7 @@ if (check_ancestor->GetLayoutObject()) { HTMLElement* new_special_common_ancestor = ToHTMLElement(HighestEnclosingNodeOfType( - Position::FirstPositionInNode(check_ancestor), + Position::FirstPositionInNode(*check_ancestor), &IsPresentationalHTMLElement, kCanCrossEditingBoundary, constraining_ancestor)); if (new_special_common_ancestor) @@ -229,8 +229,8 @@ if (HTMLAnchorElement* enclosing_anchor = toHTMLAnchorElement(EnclosingElementWithTag( Position::FirstPositionInNode(special_common_ancestor - ? special_common_ancestor - : common_ancestor), + ? *special_common_ancestor + : *common_ancestor), aTag))) special_common_ancestor = enclosing_anchor;
diff --git a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupAccumulator.cpp b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupAccumulator.cpp index 09ba1ab6..a073148 100644 --- a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupAccumulator.cpp +++ b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupAccumulator.cpp
@@ -115,7 +115,7 @@ AppendText(text); } else { const bool use_rendered_text = !EnclosingElementWithTag( - Position::FirstPositionInNode(&text), selectTag); + Position::FirstPositionInNode(text), selectTag); String content = use_rendered_text ? RenderedText(text) : StringValueForRange(text); StringBuilder buffer;
diff --git a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp index 5b47b20..accb117 100644 --- a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp +++ b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp
@@ -231,7 +231,7 @@ *start_.ComputeContainerNode(), *end_.ComputeContainerNode()); DCHECK(common_ancestor); HTMLBodyElement* body = toHTMLBodyElement(EnclosingElementWithTag( - Position::FirstPositionInNode(common_ancestor), bodyTag)); + Position::FirstPositionInNode(*common_ancestor), bodyTag)); HTMLBodyElement* fully_selected_root = nullptr; // FIXME: Do this for all fully selected blocks, not just the body. if (body && AreSameRanges(body, start_, end_))
diff --git a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializerTest.cpp b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializerTest.cpp index 3531094..d1d5a15 100644 --- a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializerTest.cpp +++ b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializerTest.cpp
@@ -283,10 +283,11 @@ SetBodyContent(body_content); Element* span1 = GetDocument().getElementById("span1"); Element* span2 = GetDocument().getElementById("span2"); - Position start_dom = Position::FirstPositionInNode(span1); + Position start_dom = Position::FirstPositionInNode(*span1); Position end_dom = Position::LastPositionInNode(span2); EXPECT_EQ("", SerializePart<EditingStrategy>(start_dom, end_dom)); - PositionInFlatTree start_ict = PositionInFlatTree::FirstPositionInNode(span1); + PositionInFlatTree start_ict = + PositionInFlatTree::FirstPositionInNode(*span1); PositionInFlatTree end_ict = PositionInFlatTree::LastPositionInNode(span2); EXPECT_EQ("", SerializePart<EditingInFlatTreeStrategy>(start_ict, end_ict)); }
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/ColdModeSpellCheckRequester.cpp b/third_party/WebKit/Source/core/editing/spellcheck/ColdModeSpellCheckRequester.cpp index f172052..5d5ebb66 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/ColdModeSpellCheckRequester.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/ColdModeSpellCheckRequester.cpp
@@ -26,8 +26,7 @@ if (!node.IsElementNode()) return false; // TODO(editing-dev): Make |Position| constructors take const parameters. - const Position& position = - Position::FirstPositionInNode(const_cast<Node*>(&node)); + const Position& position = Position::FirstPositionInNode(node); if (!IsEditablePosition(position)) return false; return SpellChecker::IsSpellCheckingEnabledAt(position);
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp index 4dda54c..5103772 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
@@ -212,7 +212,7 @@ TextControlElement* enclosing_text_control_element = nullptr; if (!IsTextControlElement(*element)) { enclosing_text_control_element = - EnclosingTextControl(Position::FirstPositionInNode(element)); + EnclosingTextControl(Position::FirstPositionInNode(*element)); } element = enclosing_text_control_element ? enclosing_text_control_element : element; @@ -537,7 +537,7 @@ if (!node) return; - EphemeralRange paragraph_range(Position::FirstPositionInNode(node), + EphemeralRange paragraph_range(Position::FirstPositionInNode(*node), Position::LastPositionInNode(node)); TextCheckingParagraph text_to_check(inserted_range, paragraph_range); ChunkAndMarkAllMisspellings(text_to_check);
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp index 9a010b9c..edda6f9f 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -69,7 +69,6 @@ #include "core/layout/LayoutMedia.h" #include "core/layout/api/LayoutViewItem.h" #include "core/layout/compositing/PaintLayerCompositor.h" -#include "core/loader/FrameLoader.h" #include "core/page/ChromeClient.h" #include "platform/Histogram.h" #include "platform/LayoutTestSupport.h" @@ -528,7 +527,7 @@ LocalFrame* frame = document.GetFrame(); if (frame) { remote_playback_client_ = - frame->Loader().Client()->CreateWebRemotePlaybackClient(*this); + frame->Client()->CreateWebRemotePlaybackClient(*this); } SetHasCustomStyleCallbacks(); @@ -1252,7 +1251,7 @@ } web_media_player_ = - frame->Loader().Client()->CreateWebMediaPlayer(*this, source, this); + frame->Client()->CreateWebMediaPlayer(*this, source, this); if (!web_media_player_) { MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError, BuildElementErrorMessage(
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.cpp b/third_party/WebKit/Source/core/loader/EmptyClients.cpp index 4ba46e8..ecb3c5d 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.cpp +++ b/third_party/WebKit/Source/core/loader/EmptyClients.cpp
@@ -71,6 +71,8 @@ class EmptyFrameScheduler : public WebFrameScheduler { public: EmptyFrameScheduler() { DCHECK(IsMainThread()); } + void AddThrottlingObserver(ObserverType, Observer*) override {} + void RemoveThrottlingObserver(ObserverType, Observer*) override {} void SetFrameVisible(bool) override {} RefPtr<WebTaskRunner> LoadingTaskRunner() override; RefPtr<WebTaskRunner> TimerTaskRunner() override;
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp index 32f1f5f2a..e15549c 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
@@ -173,7 +173,23 @@ void OfflineAudioDestinationHandler::DoOfflineRendering() { DCHECK(!IsMainThread()); - unsigned number_of_channels = render_target_->numberOfChannels(); + unsigned number_of_channels; + Vector<float*> destinations; + { + // Main thread GCs cannot happen while we're reading out channel + // data. Detect that condition by trying to take the cross-thread + // persistent lock which is held while a GC runs. If the lock is + // already held, simply delay rendering until the next quantum. + CrossThreadPersistentRegion::LockScope gc_lock( + ProcessHeap::GetCrossThreadPersistentRegion(), true); + if (!gc_lock.HasLock()) + return; + + number_of_channels = render_target_->numberOfChannels(); + destinations.ReserveInitialCapacity(number_of_channels); + for (unsigned i = 0; i < number_of_channels; ++i) + destinations.push_back(render_target_->getChannelData(i).View()->Data()); + } // Reset the suspend flag. should_suspend_ = false; @@ -198,9 +214,7 @@ for (unsigned channel_index = 0; channel_index < number_of_channels; ++channel_index) { const float* source = render_bus_->Channel(channel_index)->Data(); - float* destination = - render_target_->getChannelData(channel_index).View()->Data(); - memcpy(destination + frames_processed_, source, + memcpy(destinations[channel_index] + frames_processed_, source, sizeof(float) * frames_available_to_copy); }
diff --git a/third_party/WebKit/Source/platform/WebFrameScheduler.h b/third_party/WebKit/Source/platform/WebFrameScheduler.h index 83ca660..42ffbda9 100644 --- a/third_party/WebKit/Source/platform/WebFrameScheduler.h +++ b/third_party/WebKit/Source/platform/WebFrameScheduler.h
@@ -18,6 +18,15 @@ public: virtual ~WebFrameScheduler() {} + // Observer type that regulates conditions to invoke callbacks. + enum class ObserverType { kLoader }; + + // Represents throttling state. + enum class ThrottlingState { + kThrottled, + kNotThrottled, + }; + class ActiveConnectionHandle { public: ActiveConnectionHandle() {} @@ -27,6 +36,21 @@ DISALLOW_COPY_AND_ASSIGN(ActiveConnectionHandle); }; + // Observer interface to receive scheduling policy change events. + class Observer { + public: + // Notified when throttling state is changed. + virtual void OnThrottlingStateChanged(ThrottlingState) = 0; + }; + + // Adds an Observer instance to be notified on scheduling policy changed. + // When an Observer is added, the initial state will be notified synchronously + // through the Observer interface. + virtual void AddThrottlingObserver(ObserverType, Observer*) = 0; + + // Removes an Observer instance. + virtual void RemoveThrottlingObserver(ObserverType, Observer*) = 0; + // The scheduler may throttle tasks associated with offscreen frames. virtual void SetFrameVisible(bool) {}
diff --git a/third_party/WebKit/Source/platform/heap/PersistentNode.h b/third_party/WebKit/Source/platform/heap/PersistentNode.h index 9ed41b0..60d179c6 100644 --- a/third_party/WebKit/Source/platform/heap/PersistentNode.h +++ b/third_party/WebKit/Source/platform/heap/PersistentNode.h
@@ -202,14 +202,27 @@ STACK_ALLOCATED(); public: - LockScope(CrossThreadPersistentRegion& persistent_region) - : persistent_region_(persistent_region) { - persistent_region_.lock(); + LockScope(CrossThreadPersistentRegion& persistent_region, + bool try_lock = false) + : persistent_region_(persistent_region), locked_(true) { + if (try_lock) + locked_ = persistent_region_.TryLock(); + else + persistent_region_.lock(); } - ~LockScope() { persistent_region_.unlock(); } + ~LockScope() { + if (locked_) + persistent_region_.unlock(); + } + + // If the lock scope is set up with |try_lock| set to |true|, caller/user + // is responsible for checking whether the GC lock was taken via + // |HasLock()|. + bool HasLock() const { return locked_; } private: CrossThreadPersistentRegion& persistent_region_; + bool locked_; }; void TracePersistentNodes(Visitor* visitor) { @@ -237,6 +250,8 @@ void unlock() { mutex_.unlock(); } + bool TryLock() { return mutex_.TryLock(); } + // We don't make CrossThreadPersistentRegion inherit from PersistentRegion // because we don't want to virtualize performance-sensitive methods // such as PersistentRegion::allocate/freePersistentNode.
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp index 2c2b263..a8716456 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp +++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -1453,9 +1453,11 @@ GCForbiddenScope gc_forbidden_scope(this); { - // Access to the CrossThreadPersistentRegion has to be prevented while in - // the marking phase because otherwise other threads may allocate or free - // PersistentNodes and we can't handle that. + // Access to the CrossThreadPersistentRegion has to be prevented + // while in the marking phase because otherwise other threads may + // allocate or free PersistentNodes and we can't handle + // that. Grabbing this lock also prevents non-attached threads + // from accessing any GCed heap while a GC runs. CrossThreadPersistentRegion::LockScope persistent_lock( ProcessHeap::GetCrossThreadPersistentRegion()); {
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc index d1100e3..29f57db 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
@@ -106,6 +106,25 @@ timer_task_queue_.get()); } +void WebFrameSchedulerImpl::AddThrottlingObserver(ObserverType type, + Observer* observer) { + DCHECK_EQ(ObserverType::kLoader, type); + DCHECK(observer); + observer->OnThrottlingStateChanged(page_visible_ + ? ThrottlingState::kNotThrottled + : ThrottlingState::kThrottled); + loader_observers_.insert(observer); +} + +void WebFrameSchedulerImpl::RemoveThrottlingObserver(ObserverType type, + Observer* observer) { + DCHECK_EQ(ObserverType::kLoader, type); + DCHECK(observer); + const auto found = loader_observers_.find(observer); + DCHECK(loader_observers_.end() != found); + loader_observers_.erase(found); +} + void WebFrameSchedulerImpl::SetFrameVisible(bool frame_visible) { DCHECK(parent_web_view_scheduler_); if (frame_visible_ == frame_visible) @@ -301,6 +320,12 @@ bool was_throttled = ShouldThrottleTimers(); page_visible_ = page_visible; UpdateTimerThrottling(was_throttled); + + for (auto observer : loader_observers_) { + observer->OnThrottlingStateChanged(page_visible_ + ? ThrottlingState::kNotThrottled + : ThrottlingState::kThrottled); + } } void WebFrameSchedulerImpl::SetSuspended(bool frame_suspended) {
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h index f66523a..6f4b58d6 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_RENDERER_WEB_FRAME_SCHEDULER_IMPL_H_ #include <memory> +#include <set> #include "base/macros.h" #include "base/memory/ref_counted.h" @@ -39,6 +40,8 @@ ~WebFrameSchedulerImpl() override; // WebFrameScheduler implementation: + void AddThrottlingObserver(ObserverType, Observer*) override; + void RemoveThrottlingObserver(ObserverType, Observer*) override; void SetFrameVisible(bool frame_visible) override; void SetPageVisible(bool page_visible) override; void SetSuspended(bool frame_suspended) override; @@ -60,7 +63,6 @@ void SetDocumentParsingInBackground(bool background_parser_active) override; void OnFirstMeaningfulPaint() override; std::unique_ptr<ActiveConnectionHandle> OnActiveConnectionCreated() override; - void AsValueInto(base::trace_event::TracedValue* state) const; bool has_active_connection() const { return active_connection_count_; } @@ -107,6 +109,7 @@ RendererSchedulerImpl* renderer_scheduler_; // NOT OWNED WebViewSchedulerImpl* parent_web_view_scheduler_; // NOT OWNED base::trace_event::BlameContext* blame_context_; // NOT OWNED + std::set<Observer*> loader_observers_; // NOT OWNED bool frame_visible_; bool page_visible_; bool frame_suspended_;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc index 1d5a787..b0d55fbd 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
@@ -58,6 +58,35 @@ namespace { +class MockThrottlingObserver : public WebFrameScheduler::Observer { + public: + MockThrottlingObserver() : throttled_count_(0u), not_throttled_count_(0u) {} + + void CheckObserverState(size_t throttled_count_expectation, + size_t not_throttled_count_expectation) { + EXPECT_EQ(throttled_count_expectation, throttled_count_); + EXPECT_EQ(not_throttled_count_expectation, not_throttled_count_); + } + + // WebFrameScheduler::Observer. + void OnThrottlingStateChanged( + WebFrameScheduler::ThrottlingState state) override { + switch (state) { + case WebFrameScheduler::ThrottlingState::kThrottled: + throttled_count_++; + break; + case WebFrameScheduler::ThrottlingState::kNotThrottled: + not_throttled_count_++; + break; + // We should not have another state, and compiler checks it. + } + } + + private: + size_t throttled_count_; + size_t not_throttled_count_; +}; + void RunRepeatingTask(RefPtr<WebTaskRunner> task_runner, int* run_count); std::unique_ptr<WTF::Closure> MakeRepeatingTask( @@ -209,5 +238,46 @@ EXPECT_EQ(5, counter); } +// Tests if throttling observer interfaces work. +TEST_F(WebFrameSchedulerImplTest, ThrottlingObserver) { + std::unique_ptr<MockThrottlingObserver> observer = + base::MakeUnique<MockThrottlingObserver>(); + + size_t throttled_count = 0u; + size_t not_throttled_count = 0u; + + observer->CheckObserverState(throttled_count, not_throttled_count); + + web_frame_scheduler_->AddThrottlingObserver( + WebFrameScheduler::ObserverType::kLoader, observer.get()); + + // Initial state should be synchronously notified here. + // We assume kNotThrottled is notified as an initial state, but it could + // depend on implementation details and can be changed. + observer->CheckObserverState(throttled_count, ++not_throttled_count); + + // Once the page gets to be invisible, it should notify the observer of + // kThrottled synchronously. + web_view_scheduler_->SetPageVisible(false); + observer->CheckObserverState(++throttled_count, not_throttled_count); + + // Going back to visible state should notify the observer of kNotThrottled + // synchronously. + web_view_scheduler_->SetPageVisible(true); + observer->CheckObserverState(throttled_count, ++not_throttled_count); + + // Remove from the observer list, and see if any other callback should not be + // invoked when the condition is changed. + web_frame_scheduler_->RemoveThrottlingObserver( + WebFrameScheduler::ObserverType::kLoader, observer.get()); + web_view_scheduler_->SetPageVisible(false); + + // Wait 100 secs virtually and run pending tasks just in case. + clock_->Advance(base::TimeDelta::FromSeconds(100)); + mock_task_runner_->RunUntilIdle(); + + observer->CheckObserverState(throttled_count, not_throttled_count); +} + } // namespace scheduler } // namespace blink
diff --git a/tools/win/DebugVisualizers/BUILD.gn b/tools/win/DebugVisualizers/BUILD.gn index d858fe2..d85b8d3d 100644 --- a/tools/win/DebugVisualizers/BUILD.gn +++ b/tools/win/DebugVisualizers/BUILD.gn
@@ -16,7 +16,7 @@ # Since these only add ldflags, the targets themselves are not rebuilt when the # natvis files are updated. To debug, erase the .pdb file and build to re-link. -import("//build/toolchain/toolchain.gni") +import("//build/config/compiler/compiler.gni") assert(is_win)