diff --git a/DEPS b/DEPS index 9283bd6..0408441 100644 --- a/DEPS +++ b/DEPS
@@ -130,7 +130,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '3ac7c0f0224ef18ba45d6cb1017a48ac1d73c5ec', + 'catapult_revision': 'dc9404644cac587e0bdc26f4430498f00e8ba3a2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/chrome/browser/apps/guest_view/app_view_browsertest.cc b/chrome/browser/apps/guest_view/app_view_browsertest.cc index ecf0bcc..41fa83c 100644 --- a/chrome/browser/apps/guest_view/app_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/app_view_browsertest.cc
@@ -196,7 +196,13 @@ } // Tests that <appview> correctly handles multiple successive connects. -IN_PROC_BROWSER_TEST_P(AppViewTest, TestAppViewMultipleConnects) { +// TODO(crbug.com/794490) Reenable after fixing timeout issues. +#if defined(OS_LINUX) && defined(ADDRESS_SANITIZER) +#define MAYBE_TestAppViewMultipleConnects DISABLED_TestAppViewMultipleConnects +#else +#define MAYBE_TestAppViewMultipleConnects TestAppViewMultipleConnects +#endif +IN_PROC_BROWSER_TEST_P(AppViewTest, MAYBE_TestAppViewMultipleConnects) { const extensions::Extension* skeleton_app = InstallPlatformApp("app_view/shim/skeleton"); TestHelper("testAppViewMultipleConnects",
diff --git a/chrome/browser/media/media_engagement_autoplay_browsertest.cc b/chrome/browser/media/media_engagement_autoplay_browsertest.cc index 26f91432..a0b1539 100644 --- a/chrome/browser/media/media_engagement_autoplay_browsertest.cc +++ b/chrome/browser/media/media_engagement_autoplay_browsertest.cc
@@ -3,10 +3,17 @@ // found in the LICENSE file. #include "base/command_line.h" +#include "base/files/file_util.h" +#include "base/json/json_writer.h" +#include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" +#include "base/threading/thread_restrictions.h" +#include "base/values.h" +#include "build/build_config.h" #include "chrome/browser/content_settings/chrome_content_settings_utils.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/media/media_engagement_preloaded_list.h" #include "chrome/browser/media/media_engagement_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -19,12 +26,32 @@ namespace { +base::FilePath GetPythonPath() { +#if defined(OS_WIN) + // Windows bots do not have python installed and available on the PATH. + // Please see infra/doc/users/python.md + base::FilePath bot_path = + base::FilePath(FILE_PATH_LITERAL("c:/infra-system/bin/python.exe")); + + if (base::PathExists(bot_path)) + return bot_path; + return base::FilePath(FILE_PATH_LITERAL("python.exe")); +#else + return base::FilePath(FILE_PATH_LITERAL("python")); +#endif +} + +const base::FilePath kTestDataPath = base::FilePath( + FILE_PATH_LITERAL("chrome/test/data/media/engagement/preload")); + const char kMediaEngagementTestDataPath[] = "chrome/test/data/media/engagement"; const base::string16 kAllowedTitle = base::ASCIIToUTF16("Allowed"); const base::string16 kDeniedTitle = base::ASCIIToUTF16("Denied"); +const base::FilePath kEmptyDataPath = kTestDataPath.AppendASCII("empty.pb"); + } // namespace // Class used to test that origins with a high Media Engagement score @@ -51,10 +78,14 @@ scoped_feature_list_.InitWithFeatures( {media::kRecordMediaEngagementScores, - media::kMediaEngagementBypassAutoplayPolicies}, + media::kMediaEngagementBypassAutoplayPolicies, + media::kPreloadMediaEngagementData}, {}); InProcessBrowserTest::SetUp(); + + // Clear any preloaded MEI data. + ApplyEmptyPreloadedList(); }; void LoadTestPage(const std::string& page) { @@ -88,6 +119,50 @@ void ExpectAutoplayDenied() { EXPECT_EQ(kDeniedTitle, WaitAndGetTitle()); } + void ApplyPreloadedOrigin(GURL url) { + base::ScopedAllowBlockingForTesting allow_blocking; + + // Get two temporary files. + base::FilePath input_path; + base::FilePath output_path; + EXPECT_TRUE(base::CreateTemporaryFile(&input_path)); + EXPECT_TRUE(base::CreateTemporaryFile(&output_path)); + + // Write JSON file with the server origin in it. + base::ListValue list; + list.AppendString(url::Origin::Create(url).Serialize()); + std::string json_data; + base::JSONWriter::Write(list, &json_data); + EXPECT_TRUE( + base::WriteFile(input_path, json_data.c_str(), json_data.size())); + + // Get the path to the "generator" binary in the module path. + base::FilePath module_dir; + EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &module_dir)); + + // Launch the generator and wait for it to finish. + base::CommandLine cmd(GetPythonPath()); + cmd.AppendArg("tools/media_engagement_preload/make_dafsa.py"); + cmd.AppendArgPath(input_path); + cmd.AppendArgPath(output_path); + base::Process process = base::LaunchProcess(cmd, base::LaunchOptions()); + EXPECT_TRUE(process.WaitForExit(0)); + + // Load the preloaded list. + EXPECT_TRUE( + MediaEngagementPreloadedList::GetInstance()->LoadFromFile(output_path)); + } + + void ApplyEmptyPreloadedList() { + // Get the path relative to the source root. + base::FilePath source_root; + EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_root)); + + base::ScopedAllowBlockingForTesting allow_blocking; + EXPECT_TRUE(MediaEngagementPreloadedList::GetInstance()->LoadFromFile( + source_root.Append(kEmptyDataPath))); + } + private: base::string16 WaitAndGetTitle() { content::TitleWatcher title_watcher(GetWebContents(), kAllowedTitle); @@ -177,3 +252,64 @@ LoadTestPage("engagement_autoplay_test.html"); ExpectAutoplayAllowed(); } + +IN_PROC_BROWSER_TEST_F(MediaEngagementAutoplayBrowserTest, + UsePreloadedData_Allowed) { + // Autoplay should be blocked by default if we have a bad score. + SetScores(PrimaryOrigin(), 0, 0); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayDenied(); + + // Load the preloaded data and we should now be able to autoplay. + ApplyPreloadedOrigin(PrimaryOrigin()); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayAllowed(); + + // If we now have a high MEI score we should still be allowed to autoplay. + SetScores(PrimaryOrigin(), 10, 10); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayAllowed(); + + // If we clear the preloaded data we should still be allowed to autoplay. + ApplyEmptyPreloadedList(); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayAllowed(); +} + +IN_PROC_BROWSER_TEST_F(MediaEngagementAutoplayBrowserTest, + UsePreloadedData_Denied) { + // Autoplay should be blocked by default if we have a bad score. + SetScores(PrimaryOrigin(), 0, 0); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayDenied(); + + // Load the preloaded data but we are not in that dataset so we should not be + // allowed to autoplay. + ApplyPreloadedOrigin(SecondaryOrigin()); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayDenied(); + + // If we now have a high MEI score we should now be allowed to autoplay. + SetScores(PrimaryOrigin(), 10, 10); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayAllowed(); + + // If we clear the preloaded data we should still be allowed to autoplay. + ApplyEmptyPreloadedList(); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayAllowed(); +} + +IN_PROC_BROWSER_TEST_F(MediaEngagementAutoplayBrowserTest, + PreloadedDataAndHighVisits) { + // Autoplay should be denied due to a low score. + SetScores(PrimaryOrigin(), 10, 0); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayDenied(); + + // Load the preloaded data and even though we are in the dataset we should not + // be allowed to play. + ApplyPreloadedOrigin(PrimaryOrigin()); + LoadTestPage("engagement_autoplay_test.html"); + ExpectAutoplayDenied(); +}
diff --git a/chrome/browser/media/media_engagement_contents_observer.cc b/chrome/browser/media/media_engagement_contents_observer.cc index c9acba8d..41173e0f 100644 --- a/chrome/browser/media/media_engagement_contents_observer.cc +++ b/chrome/browser/media/media_engagement_contents_observer.cc
@@ -6,13 +6,14 @@ #include "base/metrics/histogram.h" #include "base/metrics/histogram_macros.h" -#include "build/build_config.h" +#include "chrome/browser/media/media_engagement_preloaded_list.h" #include "chrome/browser/media/media_engagement_service.h" #include "chrome/browser/media/media_engagement_session.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "media/base/media_switches.h" #include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h" #include "third_party/WebKit/public/platform/media_engagement.mojom.h" @@ -490,7 +491,22 @@ content::NavigationHandle* handle) { // TODO(beccahughes): Convert MEI API to using origin. GURL url = handle->GetWebContents()->GetURL(); - if (service_->HasHighEngagement(url)) { + MediaEngagementScore score = service_->CreateEngagementScore(url); + bool has_high_engagement = score.high_score(); + + // If the preloaded feature flag is enabled and the number of visits is less + // than the number of visits required to have an MEI score we should check the + // global data. + if (!has_high_engagement && + score.visits() < MediaEngagementScore::GetScoreMinVisits() && + base::FeatureList::IsEnabled(media::kPreloadMediaEngagementData)) { + has_high_engagement = + MediaEngagementPreloadedList::GetInstance()->CheckOriginIsPresent( + url::Origin::Create(url)); + } + + // If we have high media engagement then we should send that to Blink. + if (has_high_engagement) { SendEngagementLevelToFrame(url::Origin::Create(handle->GetURL()), handle->GetRenderFrameHost()); }
diff --git a/chrome/browser/media/media_engagement_preloaded_list.cc b/chrome/browser/media/media_engagement_preloaded_list.cc index a552e08a..3fcf426 100644 --- a/chrome/browser/media/media_engagement_preloaded_list.cc +++ b/chrome/browser/media/media_engagement_preloaded_list.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/media/media_engagement_preloaded_list.h" #include "base/files/file_util.h" +#include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" @@ -20,11 +21,34 @@ const char MediaEngagementPreloadedList::kHistogramLoadResultName[] = "Media.Engagement.PreloadedList.LoadResult"; -MediaEngagementPreloadedList::MediaEngagementPreloadedList() = default; +// static +MediaEngagementPreloadedList* MediaEngagementPreloadedList::GetInstance() { + CR_DEFINE_STATIC_LOCAL(MediaEngagementPreloadedList, instance, ()); + return &instance; +} -MediaEngagementPreloadedList::~MediaEngagementPreloadedList() = default; +MediaEngagementPreloadedList::MediaEngagementPreloadedList() { + // This class is allowed to be instantiated on any thread. + DETACH_FROM_SEQUENCE(sequence_checker_); +} + +MediaEngagementPreloadedList::~MediaEngagementPreloadedList() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +bool MediaEngagementPreloadedList::loaded() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return is_loaded_; +} + +bool MediaEngagementPreloadedList::empty() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return dafsa_.empty(); +} bool MediaEngagementPreloadedList::LoadFromFile(const base::FilePath& path) { + DETACH_FROM_SEQUENCE(sequence_checker_); + // Check the file exists. if (!base::PathExists(path)) { RecordLoadResult(LoadResult::kFileNotFound); @@ -57,6 +81,8 @@ bool MediaEngagementPreloadedList::CheckOriginIsPresent( const url::Origin& origin) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Check if we have loaded the data. if (!loaded()) { RecordCheckResult(CheckResult::kListNotLoaded);
diff --git a/chrome/browser/media/media_engagement_preloaded_list.h b/chrome/browser/media/media_engagement_preloaded_list.h index 23e74fc..7e78ffb 100644 --- a/chrome/browser/media/media_engagement_preloaded_list.h +++ b/chrome/browser/media/media_engagement_preloaded_list.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/macros.h" +#include "base/sequence_checker.h" namespace base { class FilePath; @@ -20,6 +21,8 @@ class MediaEngagementPreloadedList { public: + static MediaEngagementPreloadedList* GetInstance(); + MediaEngagementPreloadedList(); ~MediaEngagementPreloadedList(); @@ -31,10 +34,10 @@ bool CheckOriginIsPresent(const url::Origin& origin) const; // Check whether we have loaded a list. - bool loaded() const { return is_loaded_; } + bool loaded() const; // Check whether the list we have loaded is empty. - bool empty() const { return dafsa_.empty(); } + bool empty() const; protected: friend class MediaEngagementPreloadedListTest; @@ -115,6 +118,8 @@ // If a list has been successfully loaded. bool is_loaded_ = false; + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(MediaEngagementPreloadedList); };
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index b4a2f1db..9abb57ea 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -355,6 +355,7 @@ data_deps = [ "//testing/buildbot/filters:browser_tests_filters", + "//tools/media_engagement_preload:generator", ] data = []
diff --git a/content/renderer/cache_storage/cache_storage_dispatcher.cc b/content/renderer/cache_storage/cache_storage_dispatcher.cc index 8fb3a23..0504423 100644 --- a/content/renderer/cache_storage/cache_storage_dispatcher.cc +++ b/content/renderer/cache_storage/cache_storage_dispatcher.cc
@@ -42,7 +42,7 @@ namespace { -CacheStorageDispatcher* const kHasBeenDeleted = +CacheStorageDispatcher* const kDeletedCacheStorageDispatcherMarker = reinterpret_cast<CacheStorageDispatcher*>(0x1); ServiceWorkerFetchRequest FetchRequestFromWebRequest( @@ -200,12 +200,14 @@ ClearCallbacksMapWithErrors(&cache_keys_callbacks_); ClearCallbacksMapWithErrors(&cache_batch_callbacks_); - g_cache_storage_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); + g_cache_storage_dispatcher_tls.Pointer()->Set( + kDeletedCacheStorageDispatcherMarker); } CacheStorageDispatcher* CacheStorageDispatcher::ThreadSpecificInstance( ThreadSafeSender* thread_safe_sender) { - if (g_cache_storage_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { + if (g_cache_storage_dispatcher_tls.Pointer()->Get() == + kDeletedCacheStorageDispatcherMarker) { NOTREACHED() << "Re-instantiating TLS CacheStorageDispatcher."; g_cache_storage_dispatcher_tls.Pointer()->Set(nullptr); }
diff --git a/content/renderer/indexed_db/indexed_db_dispatcher.cc b/content/renderer/indexed_db/indexed_db_dispatcher.cc index 3e2acce..2beba1d 100644 --- a/content/renderer/indexed_db/indexed_db_dispatcher.cc +++ b/content/renderer/indexed_db/indexed_db_dispatcher.cc
@@ -25,7 +25,7 @@ namespace { -IndexedDBDispatcher* const kHasBeenDeleted = +IndexedDBDispatcher* const kDeletedIndexedDBDispatcherMarker = reinterpret_cast<IndexedDBDispatcher*>(0x1); } // unnamed namespace @@ -39,11 +39,12 @@ mojo_owned_callback_state_.clear(); mojo_owned_database_callback_state_.clear(); - g_idb_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); + g_idb_dispatcher_tls.Pointer()->Set(kDeletedIndexedDBDispatcherMarker); } IndexedDBDispatcher* IndexedDBDispatcher::ThreadSpecificInstance() { - if (g_idb_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { + if (g_idb_dispatcher_tls.Pointer()->Get() == + kDeletedIndexedDBDispatcherMarker) { NOTREACHED() << "Re-instantiating TLS IndexedDBDispatcher."; g_idb_dispatcher_tls.Pointer()->Set(nullptr); }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 99ad0c11..c7cc232 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3029,13 +3029,6 @@ // blink::mojom::MediaEngagementClient implementation -------------------------- void RenderFrameImpl::SetHasHighMediaEngagement(const url::Origin& origin) { - // Set the HasHighMediaEngagement bit on |frame| if the origin matches - // the one we were provided. - if (frame_ && url::Origin(frame_->GetSecurityOrigin()) == origin) { - frame_->SetHasHighMediaEngagement(true); - return; - } - high_media_engagement_origin_ = origin; }
diff --git a/content/renderer/service_worker/service_worker_dispatcher.cc b/content/renderer/service_worker/service_worker_dispatcher.cc index d4ce0f10..a38b326 100644 --- a/content/renderer/service_worker/service_worker_dispatcher.cc +++ b/content/renderer/service_worker/service_worker_dispatcher.cc
@@ -38,7 +38,8 @@ base::LazyInstance<ThreadLocalPointer<void>>::Leaky g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER; -void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1); +void* const kDeletedServiceWorkerDispatcherMarker = + reinterpret_cast<void*>(0x1); } // namespace @@ -55,7 +56,7 @@ g_dispatcher_tls.Pointer()->Set(nullptr); return; } - g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); + g_dispatcher_tls.Pointer()->Set(kDeletedServiceWorkerDispatcherMarker); } void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) { @@ -76,7 +77,8 @@ ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( scoped_refptr<ThreadSafeSender> thread_safe_sender, scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) { - if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { + if (g_dispatcher_tls.Pointer()->Get() == + kDeletedServiceWorkerDispatcherMarker) { NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher."; g_dispatcher_tls.Pointer()->Set(nullptr); } @@ -92,7 +94,8 @@ } ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() { - if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) + if (g_dispatcher_tls.Pointer()->Get() == + kDeletedServiceWorkerDispatcherMarker) return nullptr; return static_cast<ServiceWorkerDispatcher*>( g_dispatcher_tls.Pointer()->Get());
diff --git a/content/renderer/service_worker/web_service_worker_impl.cc b/content/renderer/service_worker/web_service_worker_impl.cc index 0f7907b..4b6b93f3 100644 --- a/content/renderer/service_worker/web_service_worker_impl.cc +++ b/content/renderer/service_worker/web_service_worker_impl.cc
@@ -26,18 +26,19 @@ namespace { -class HandleImpl : public blink::WebServiceWorker::Handle { +class ServiceWorkerHandleImpl : public blink::WebServiceWorker::Handle { public: - explicit HandleImpl(const scoped_refptr<WebServiceWorkerImpl>& worker) + explicit ServiceWorkerHandleImpl( + const scoped_refptr<WebServiceWorkerImpl>& worker) : worker_(worker) {} - ~HandleImpl() override {} + ~ServiceWorkerHandleImpl() override {} blink::WebServiceWorker* ServiceWorker() override { return worker_.get(); } private: scoped_refptr<WebServiceWorkerImpl> worker_; - DISALLOW_COPY_AND_ASSIGN(HandleImpl); + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandleImpl); }; } // namespace @@ -105,7 +106,7 @@ const scoped_refptr<WebServiceWorkerImpl>& worker) { if (!worker) return nullptr; - return std::make_unique<HandleImpl>(worker); + return std::make_unique<ServiceWorkerHandleImpl>(worker); } WebServiceWorkerImpl::~WebServiceWorkerImpl() {
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.cc b/content/renderer/service_worker/web_service_worker_registration_impl.cc index bf5efd7..55b1cb704 100644 --- a/content/renderer/service_worker/web_service_worker_registration_impl.cc +++ b/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -24,12 +24,13 @@ namespace { -class HandleImpl : public blink::WebServiceWorkerRegistration::Handle { +class ServiceWorkerRegistrationHandleImpl + : public blink::WebServiceWorkerRegistration::Handle { public: - explicit HandleImpl( + explicit ServiceWorkerRegistrationHandleImpl( scoped_refptr<WebServiceWorkerRegistrationImpl> registration) : registration_(std::move(registration)) {} - ~HandleImpl() override {} + ~ServiceWorkerRegistrationHandleImpl() override {} blink::WebServiceWorkerRegistration* Registration() override { return registration_.get(); @@ -38,7 +39,7 @@ private: scoped_refptr<WebServiceWorkerRegistrationImpl> registration_; - DISALLOW_COPY_AND_ASSIGN(HandleImpl); + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegistrationHandleImpl); }; } // namespace @@ -380,7 +381,8 @@ scoped_refptr<WebServiceWorkerRegistrationImpl> registration) { if (!registration) return nullptr; - return std::make_unique<HandleImpl>(std::move(registration)); + return std::make_unique<ServiceWorkerRegistrationHandleImpl>( + std::move(registration)); } // static
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 2c281bb..ee8f223 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -3295,7 +3295,8 @@ // TODO(crbug.com/778822): This can be cleaned up when the new fullscreen // is enabled. if (IsSafeAreaCompatibleToolbarEnabled() && - header.view == _toolbarCoordinator.toolbarViewController.view) { + header.view == _toolbarCoordinator.toolbarViewController.view && + !IsIPadIdiom()) { self.toolbarOffsetConstraint.constant = yOrigin; } CGRect frame = [header.view frame];
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm index c8c9b94..8460aa1 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
@@ -938,6 +938,7 @@ [_locationBarView setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal]; + _locationBarView.clipsToBounds = YES; } return _locationBarView; }
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm index 75825ac..ca69e6a 100644 --- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm +++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -252,6 +252,7 @@ font:[MDCTypography subheadFont] textColor:textColor tintColor:tintColor]; + _locationBarView.clipsToBounds = YES; _keyboardDelegate = [[ToolbarAssistiveKeyboardDelegateImpl alloc] init]; _keyboardDelegate.dispatcher = dispatcher; _keyboardDelegate.omniboxTextField = _locationBarView.textField;
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 5b41ef3..e207069 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -366,4 +366,9 @@ const base::Feature kUseModernMediaControls{"UseModernMediaControls", base::FEATURE_DISABLED_BY_DEFAULT}; +// Allows Media Engagement to use preloaded data to decide whether an origin has +// a high media engagement. +const base::Feature kPreloadMediaEngagementData{ + "PreloadMediaEngagementData", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace media
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index b5481ef..0586dfe 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -121,6 +121,7 @@ MEDIA_EXPORT extern const base::Feature kNewRemotePlaybackPipeline; MEDIA_EXPORT extern const base::Feature kOverflowIconsForMediaControls; MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo; +MEDIA_EXPORT extern const base::Feature kPreloadMediaEngagementData; MEDIA_EXPORT extern const base::Feature kResumeBackgroundVideo; MEDIA_EXPORT extern const base::Feature kSpecCompliantCanPlayThrough; MEDIA_EXPORT extern const base::Feature kSupportExperimentalCdmInterface;
diff --git a/third_party/WebKit/Source/core/streams/ReadableStream.js b/third_party/WebKit/Source/core/streams/ReadableStream.js index e23e893..02c8dc0f 100644 --- a/third_party/WebKit/Source/core/streams/ReadableStream.js +++ b/third_party/WebKit/Source/core/streams/ReadableStream.js
@@ -427,6 +427,348 @@ return promise; } + // + // Readable stream abstract operations + // + + function AcquireReadableStreamDefaultReader(stream) { + return new ReadableStreamDefaultReader(stream); + } + + function IsReadableStream(x) { + return hasOwnPropertyNoThrow(x, _controller); + } + + function IsReadableStreamDisturbed(stream) { + return stream[_readableStreamBits] & DISTURBED; + } + + function IsReadableStreamLocked(stream) { + return stream[_reader] !== undefined; + } + + // Potential future optimization: use class instances for the underlying + // sources, so that we don't re-create + // closures every time. + + // TODO(domenic): shouldClone argument from spec not supported yet + function ReadableStreamTee(stream) { + const reader = AcquireReadableStreamDefaultReader(stream); + + let closedOrErrored = false; + let canceled1 = false; + let canceled2 = false; + let reason1; + let reason2; + const promise = v8.createPromise(); + + const branch1Stream = new ReadableStream({pull, cancel: cancel1}); + + const branch2Stream = new ReadableStream({pull, cancel: cancel2}); + + const branch1 = branch1Stream[_controller]; + const branch2 = branch2Stream[_controller]; + + thenPromise(reader[_closedPromise], undefined, function(r) { + if (closedOrErrored === true) { + return; + } + + ReadableStreamDefaultControllerError(branch1, r); + ReadableStreamDefaultControllerError(branch2, r); + closedOrErrored = true; + }); + + return [branch1Stream, branch2Stream]; + + function pull() { + return thenPromise( + ReadableStreamDefaultReaderRead(reader), function(result) { + const value = result.value; + const done = result.done; + + if (done === true && closedOrErrored === false) { + if (canceled1 === false) { + ReadableStreamDefaultControllerClose(branch1); + } + if (canceled2 === false) { + ReadableStreamDefaultControllerClose(branch2); + } + closedOrErrored = true; + } + + if (closedOrErrored === true) { + return; + } + + if (canceled1 === false) { + ReadableStreamDefaultControllerEnqueue(branch1, value); + } + + if (canceled2 === false) { + ReadableStreamDefaultControllerEnqueue(branch2, value); + } + }); + } + + function cancel1(reason) { + canceled1 = true; + reason1 = reason; + + if (canceled2 === true) { + const compositeReason = [reason1, reason2]; + const cancelResult = ReadableStreamCancel(stream, compositeReason); + resolvePromise(promise, cancelResult); + } + + return promise; + } + + function cancel2(reason) { + canceled2 = true; + reason2 = reason; + + if (canceled1 === true) { + const compositeReason = [reason1, reason2]; + const cancelResult = ReadableStreamCancel(stream, compositeReason); + resolvePromise(promise, cancelResult); + } + + return promise; + } + } + + // + // Abstract Operations Used By Controllers + // + + function ReadableStreamAddReadRequest(stream) { + const promise = v8.createPromise(); + stream[_reader][_readRequests].push(promise); + return promise; + } + + function ReadableStreamCancel(stream, reason) { + stream[_readableStreamBits] |= DISTURBED; + + const state = ReadableStreamGetState(stream); + if (state === STATE_CLOSED) { + return Promise_resolve(undefined); + } + if (state === STATE_ERRORED) { + return Promise_reject(stream[_storedError]); + } + + ReadableStreamClose(stream); + + const sourceCancelPromise = + ReadableStreamDefaultControllerCancel(stream[_controller], reason); + return thenPromise(sourceCancelPromise, () => undefined); + } + + function ReadableStreamClose(stream) { + ReadableStreamSetState(stream, STATE_CLOSED); + + const reader = stream[_reader]; + if (reader === undefined) { + return undefined; + } + + if (IsReadableStreamDefaultReader(reader) === true) { + reader[_readRequests].forEach( + request => + resolvePromise(request, CreateIterResultObject(undefined, true))); + reader[_readRequests] = new binding.SimpleQueue(); + } + + resolvePromise(reader[_closedPromise], undefined); + } + + function ReadableStreamError(stream, e) { + stream[_storedError] = e; + ReadableStreamSetState(stream, STATE_ERRORED); + + const reader = stream[_reader]; + if (reader === undefined) { + return undefined; + } + + if (IsReadableStreamDefaultReader(reader) === true) { + reader[_readRequests].forEach(request => rejectPromise(request, e)); + reader[_readRequests] = new binding.SimpleQueue(); + } + + rejectPromise(reader[_closedPromise], e); + markPromiseAsHandled(reader[_closedPromise]); + } + + function ReadableStreamFulfillReadRequest(stream, chunk, done) { + const readRequest = stream[_reader][_readRequests].shift(); + resolvePromise(readRequest, CreateIterResultObject(chunk, done)); + } + + function ReadableStreamGetNumReadRequests(stream) { + const reader = stream[_reader]; + const readRequests = reader[_readRequests]; + return readRequests.length; + } + + // + // Class ReadableStreamDefaultReader + // + + class ReadableStreamDefaultReader { + constructor(stream) { + if (IsReadableStream(stream) === false) { + throw new TypeError(errReaderConstructorBadArgument); + } + if (IsReadableStreamLocked(stream) === true) { + throw new TypeError(errReaderConstructorStreamAlreadyLocked); + } + + ReadableStreamReaderGenericInitialize(this, stream); + + this[_readRequests] = new binding.SimpleQueue(); + } + + get closed() { + if (IsReadableStreamDefaultReader(this) === false) { + return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + } + + return this[_closedPromise]; + } + + cancel(reason) { + if (IsReadableStreamDefaultReader(this) === false) { + return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + } + + const stream = this[_ownerReadableStream]; + if (stream === undefined) { + return Promise_reject(new TypeError(errCancelReleasedReader)); + } + + return ReadableStreamReaderGenericCancel(this, reason); + } + + read() { + if (IsReadableStreamDefaultReader(this) === false) { + return Promise_reject(new TypeError(streamErrors.illegalInvocation)); + } + + if (this[_ownerReadableStream] === undefined) { + return Promise_reject(new TypeError(errReadReleasedReader)); + } + + return ReadableStreamDefaultReaderRead(this); + } + + releaseLock() { + if (IsReadableStreamDefaultReader(this) === false) { + throw new TypeError(streamErrors.illegalInvocation); + } + + const stream = this[_ownerReadableStream]; + if (stream === undefined) { + return undefined; + } + + if (this[_readRequests].length > 0) { + throw new TypeError(errReleaseReaderWithPendingRead); + } + + ReadableStreamReaderGenericRelease(this); + } + } + + // + // Readable Stream Reader Abstract Operations + // + + function IsReadableStreamDefaultReader(x) { + return hasOwnPropertyNoThrow(x, _readRequests); + } + + function ReadableStreamReaderGenericCancel(reader, reason) { + return ReadableStreamCancel(reader[_ownerReadableStream], reason); + } + + function ReadableStreamReaderGenericInitialize(reader, stream) { + // TODO(yhirano): Remove this when we don't need hasPendingActivity in + // blink::UnderlyingSourceBase. + const controller = stream[_controller]; + if (controller[_readableStreamDefaultControllerBits] & + EXTERNALLY_CONTROLLED) { + // The stream is created with an external controller (i.e. made in + // Blink). + const underlyingSource = controller[_underlyingSource]; + callFunction(underlyingSource.notifyLockAcquired, underlyingSource); + } + + reader[_ownerReadableStream] = stream; + stream[_reader] = reader; + + switch (ReadableStreamGetState(stream)) { + case STATE_READABLE: + reader[_closedPromise] = v8.createPromise(); + break; + case STATE_CLOSED: + reader[_closedPromise] = Promise_resolve(undefined); + break; + case STATE_ERRORED: + reader[_closedPromise] = Promise_reject(stream[_storedError]); + markPromiseAsHandled(reader[_closedPromise]); + break; + } + } + + function ReadableStreamReaderGenericRelease(reader) { + // TODO(yhirano): Remove this when we don't need hasPendingActivity in + // blink::UnderlyingSourceBase. + const controller = reader[_ownerReadableStream][_controller]; + if (controller[_readableStreamDefaultControllerBits] & + EXTERNALLY_CONTROLLED) { + // The stream is created with an external controller (i.e. made in + // Blink). + const underlyingSource = controller[_underlyingSource]; + callFunction(underlyingSource.notifyLockReleased, underlyingSource); + } + + if (ReadableStreamGetState(reader[_ownerReadableStream]) === + STATE_READABLE) { + rejectPromise( + reader[_closedPromise], + new TypeError(errReleasedReaderClosedPromise)); + } else { + reader[_closedPromise] = + Promise_reject(new TypeError(errReleasedReaderClosedPromise)); + } + markPromiseAsHandled(reader[_closedPromise]); + + reader[_ownerReadableStream][_reader] = undefined; + reader[_ownerReadableStream] = undefined; + } + + function ReadableStreamDefaultReaderRead(reader) { + const stream = reader[_ownerReadableStream]; + stream[_readableStreamBits] |= DISTURBED; + + if (ReadableStreamGetState(stream) === STATE_CLOSED) { + return Promise_resolve(CreateIterResultObject(undefined, true)); + } + + if (ReadableStreamGetState(stream) === STATE_ERRORED) { + return Promise_reject(stream[_storedError]); + } + + return ReadableStreamDefaultControllerPull(stream[_controller]); + } + + // + // Class ReadableStreamDefaultController + // + class ReadableStreamDefaultController { constructor( stream, underlyingSource, size, highWaterMark, isExternallyControlled) { @@ -534,6 +876,7 @@ } } + // [[CancelSteps]] in the standard. function ReadableStreamDefaultControllerCancel(controller, reason) { controller[_queue] = new binding.SimpleQueue(); @@ -542,6 +885,7 @@ underlyingSource, 'cancel', reason, 'underlyingSource.cancel'); } + // [[PullSteps]] in the standard. function ReadableStreamDefaultControllerPull(controller) { const stream = controller[_controlledReadableStream]; @@ -564,340 +908,14 @@ return pendingPromise; } - function ReadableStreamAddReadRequest(stream) { - const promise = v8.createPromise(); - stream[_reader][_readRequests].push(promise); - return promise; - } - - class ReadableStreamDefaultReader { - constructor(stream) { - if (IsReadableStream(stream) === false) { - throw new TypeError(errReaderConstructorBadArgument); - } - if (IsReadableStreamLocked(stream) === true) { - throw new TypeError(errReaderConstructorStreamAlreadyLocked); - } - - ReadableStreamReaderGenericInitialize(this, stream); - - this[_readRequests] = new binding.SimpleQueue(); - } - - get closed() { - if (IsReadableStreamDefaultReader(this) === false) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); - } - - return this[_closedPromise]; - } - - cancel(reason) { - if (IsReadableStreamDefaultReader(this) === false) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); - } - - const stream = this[_ownerReadableStream]; - if (stream === undefined) { - return Promise_reject(new TypeError(errCancelReleasedReader)); - } - - return ReadableStreamReaderGenericCancel(this, reason); - } - - read() { - if (IsReadableStreamDefaultReader(this) === false) { - return Promise_reject(new TypeError(streamErrors.illegalInvocation)); - } - - if (this[_ownerReadableStream] === undefined) { - return Promise_reject(new TypeError(errReadReleasedReader)); - } - - return ReadableStreamDefaultReaderRead(this); - } - - releaseLock() { - if (IsReadableStreamDefaultReader(this) === false) { - throw new TypeError(streamErrors.illegalInvocation); - } - - const stream = this[_ownerReadableStream]; - if (stream === undefined) { - return undefined; - } - - if (this[_readRequests].length > 0) { - throw new TypeError(errReleaseReaderWithPendingRead); - } - - ReadableStreamReaderGenericRelease(this); - } - } - - function ReadableStreamReaderGenericCancel(reader, reason) { - return ReadableStreamCancel(reader[_ownerReadableStream], reason); - } - // - // Readable stream abstract operations + // Readable Stream Default Controller Abstract Operations // - function AcquireReadableStreamDefaultReader(stream) { - return new ReadableStreamDefaultReader(stream); - } - - function ReadableStreamCancel(stream, reason) { - stream[_readableStreamBits] |= DISTURBED; - - const state = ReadableStreamGetState(stream); - if (state === STATE_CLOSED) { - return Promise_resolve(undefined); - } - if (state === STATE_ERRORED) { - return Promise_reject(stream[_storedError]); - } - - ReadableStreamClose(stream); - - const sourceCancelPromise = - ReadableStreamDefaultControllerCancel(stream[_controller], reason); - return thenPromise(sourceCancelPromise, () => undefined); - } - - function ReadableStreamDefaultControllerClose(controller) { - const stream = controller[_controlledReadableStream]; - - controller[_readableStreamDefaultControllerBits] |= CLOSE_REQUESTED; - - if (controller[_queue].length === 0) { - ReadableStreamClose(stream); - } - } - - function ReadableStreamFulfillReadRequest(stream, chunk, done) { - const readRequest = stream[_reader][_readRequests].shift(); - resolvePromise(readRequest, CreateIterResultObject(chunk, done)); - } - - function ReadableStreamDefaultControllerEnqueue(controller, chunk) { - const stream = controller[_controlledReadableStream]; - - if (IsReadableStreamLocked(stream) === true && - ReadableStreamGetNumReadRequests(stream) > 0) { - ReadableStreamFulfillReadRequest(stream, chunk, false); - } else { - let chunkSize = 1; - - const strategySize = controller[_strategySize]; - if (strategySize !== undefined) { - try { - chunkSize = strategySize(chunk); - } catch (chunkSizeE) { - if (ReadableStreamGetState(stream) === STATE_READABLE) { - ReadableStreamDefaultControllerError(controller, chunkSizeE); - } - throw chunkSizeE; - } - } - - try { - EnqueueValueWithSize(controller, chunk, chunkSize); - } catch (enqueueE) { - if (ReadableStreamGetState(stream) === STATE_READABLE) { - ReadableStreamDefaultControllerError(controller, enqueueE); - } - throw enqueueE; - } - } - - ReadableStreamDefaultControllerCallPullIfNeeded(controller); - } - - function ReadableStreamGetState(stream) { - return (stream[_readableStreamBits] & STATE_MASK) >> STATE_BITS_OFFSET; - } - - function ReadableStreamSetState(stream, state) { - stream[_readableStreamBits] = (stream[_readableStreamBits] & ~STATE_MASK) | - (state << STATE_BITS_OFFSET); - } - - function ReadableStreamDefaultControllerError(controller, e) { - controller[_queue] = new binding.SimpleQueue(); - const stream = controller[_controlledReadableStream]; - ReadableStreamError(stream, e); - } - - function ReadableStreamError(stream, e) { - stream[_storedError] = e; - ReadableStreamSetState(stream, STATE_ERRORED); - - const reader = stream[_reader]; - if (reader === undefined) { - return undefined; - } - - if (IsReadableStreamDefaultReader(reader) === true) { - reader[_readRequests].forEach(request => rejectPromise(request, e)); - reader[_readRequests] = new binding.SimpleQueue(); - } - - rejectPromise(reader[_closedPromise], e); - markPromiseAsHandled(reader[_closedPromise]); - } - - function ReadableStreamClose(stream) { - ReadableStreamSetState(stream, STATE_CLOSED); - - const reader = stream[_reader]; - if (reader === undefined) { - return undefined; - } - - if (IsReadableStreamDefaultReader(reader) === true) { - reader[_readRequests].forEach( - request => - resolvePromise(request, CreateIterResultObject(undefined, true))); - reader[_readRequests] = new binding.SimpleQueue(); - } - - resolvePromise(reader[_closedPromise], undefined); - } - - function ReadableStreamDefaultControllerGetDesiredSize(controller) { - return controller[_strategyHWM] - controller[_queueTotalSize]; - } - - function ReadableStreamDefaultControllerHasBackpressure(controller) { - return !ReadableStreamDefaultControllerShouldCallPull(controller); - } - - function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) { - if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { - return false; - } - const state = ReadableStreamGetState(controller[_controlledReadableStream]); - return state === STATE_READABLE; - } - - function IsReadableStream(x) { - return hasOwnPropertyNoThrow(x, _controller); - } - - function IsReadableStreamDisturbed(stream) { - return stream[_readableStreamBits] & DISTURBED; - } - - function IsReadableStreamLocked(stream) { - return stream[_reader] !== undefined; - } - function IsReadableStreamDefaultController(x) { return hasOwnPropertyNoThrow(x, _controlledReadableStream); } - function IsReadableStreamDefaultReader(x) { - return hasOwnPropertyNoThrow(x, _readRequests); - } - - function IsReadableStreamReadable(stream) { - return ReadableStreamGetState(stream) === STATE_READABLE; - } - - function IsReadableStreamClosed(stream) { - return ReadableStreamGetState(stream) === STATE_CLOSED; - } - - function IsReadableStreamErrored(stream) { - return ReadableStreamGetState(stream) === STATE_ERRORED; - } - - // Used internally by enqueue() and also by TransformStream. - function getReadableStreamEnqueueError(stream, controller) { - if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { - return new TypeError(errEnqueueCloseRequestedStream); - } - - const state = ReadableStreamGetState(stream); - if (state === STATE_ERRORED) { - return new TypeError(errEnqueueErroredStream); - } - // assert(state === STATE_CLOSED, 'state is "closed"'); - return new TypeError(errEnqueueClosedStream); - } - - function ReadableStreamReaderGenericInitialize(reader, stream) { - // TODO(yhirano): Remove this when we don't need hasPendingActivity in - // blink::UnderlyingSourceBase. - const controller = stream[_controller]; - if (controller[_readableStreamDefaultControllerBits] & - EXTERNALLY_CONTROLLED) { - // The stream is created with an external controller (i.e. made in - // Blink). - const underlyingSource = controller[_underlyingSource]; - callFunction(underlyingSource.notifyLockAcquired, underlyingSource); - } - - reader[_ownerReadableStream] = stream; - stream[_reader] = reader; - - switch (ReadableStreamGetState(stream)) { - case STATE_READABLE: - reader[_closedPromise] = v8.createPromise(); - break; - case STATE_CLOSED: - reader[_closedPromise] = Promise_resolve(undefined); - break; - case STATE_ERRORED: - reader[_closedPromise] = Promise_reject(stream[_storedError]); - markPromiseAsHandled(reader[_closedPromise]); - break; - } - } - - function ReadableStreamReaderGenericRelease(reader) { - // TODO(yhirano): Remove this when we don't need hasPendingActivity in - // blink::UnderlyingSourceBase. - const controller = reader[_ownerReadableStream][_controller]; - if (controller[_readableStreamDefaultControllerBits] & - EXTERNALLY_CONTROLLED) { - // The stream is created with an external controller (i.e. made in - // Blink). - const underlyingSource = controller[_underlyingSource]; - callFunction(underlyingSource.notifyLockReleased, underlyingSource); - } - - if (ReadableStreamGetState(reader[_ownerReadableStream]) === - STATE_READABLE) { - rejectPromise( - reader[_closedPromise], - new TypeError(errReleasedReaderClosedPromise)); - } else { - reader[_closedPromise] = - Promise_reject(new TypeError(errReleasedReaderClosedPromise)); - } - markPromiseAsHandled(reader[_closedPromise]); - - reader[_ownerReadableStream][_reader] = undefined; - reader[_ownerReadableStream] = undefined; - } - - function ReadableStreamDefaultReaderRead(reader) { - const stream = reader[_ownerReadableStream]; - stream[_readableStreamBits] |= DISTURBED; - - if (ReadableStreamGetState(stream) === STATE_CLOSED) { - return Promise_resolve(CreateIterResultObject(undefined, true)); - } - - if (ReadableStreamGetState(stream) === STATE_ERRORED) { - return Promise_reject(stream[_storedError]); - } - - return ReadableStreamDefaultControllerPull(stream[_controller]); - } - function ReadableStreamDefaultControllerCallPullIfNeeded(controller) { const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller); @@ -964,101 +982,113 @@ return false; } - function ReadableStreamGetNumReadRequests(stream) { - const reader = stream[_reader]; - const readRequests = reader[_readRequests]; - return readRequests.length; + function ReadableStreamDefaultControllerClose(controller) { + const stream = controller[_controlledReadableStream]; + + controller[_readableStreamDefaultControllerBits] |= CLOSE_REQUESTED; + + if (controller[_queue].length === 0) { + ReadableStreamClose(stream); + } } - // Potential future optimization: use class instances for the underlying - // sources, so that we don't re-create - // closures every time. + function ReadableStreamDefaultControllerEnqueue(controller, chunk) { + const stream = controller[_controlledReadableStream]; - // TODO(domenic): shouldClone argument from spec not supported yet - function ReadableStreamTee(stream) { - const reader = AcquireReadableStreamDefaultReader(stream); + if (IsReadableStreamLocked(stream) === true && + ReadableStreamGetNumReadRequests(stream) > 0) { + ReadableStreamFulfillReadRequest(stream, chunk, false); + } else { + let chunkSize = 1; - let closedOrErrored = false; - let canceled1 = false; - let canceled2 = false; - let reason1; - let reason2; - const promise = v8.createPromise(); - - const branch1Stream = new ReadableStream({pull, cancel: cancel1}); - - const branch2Stream = new ReadableStream({pull, cancel: cancel2}); - - const branch1 = branch1Stream[_controller]; - const branch2 = branch2Stream[_controller]; - - thenPromise(reader[_closedPromise], undefined, function(r) { - if (closedOrErrored === true) { - return; + const strategySize = controller[_strategySize]; + if (strategySize !== undefined) { + try { + chunkSize = strategySize(chunk); + } catch (chunkSizeE) { + if (ReadableStreamGetState(stream) === STATE_READABLE) { + ReadableStreamDefaultControllerError(controller, chunkSizeE); + } + throw chunkSizeE; + } } - ReadableStreamDefaultControllerError(branch1, r); - ReadableStreamDefaultControllerError(branch2, r); - closedOrErrored = true; - }); - - return [branch1Stream, branch2Stream]; - - function pull() { - return thenPromise( - ReadableStreamDefaultReaderRead(reader), function(result) { - const value = result.value; - const done = result.done; - - if (done === true && closedOrErrored === false) { - if (canceled1 === false) { - ReadableStreamDefaultControllerClose(branch1); - } - if (canceled2 === false) { - ReadableStreamDefaultControllerClose(branch2); - } - closedOrErrored = true; - } - - if (closedOrErrored === true) { - return; - } - - if (canceled1 === false) { - ReadableStreamDefaultControllerEnqueue(branch1, value); - } - - if (canceled2 === false) { - ReadableStreamDefaultControllerEnqueue(branch2, value); - } - }); - } - - function cancel1(reason) { - canceled1 = true; - reason1 = reason; - - if (canceled2 === true) { - const compositeReason = [reason1, reason2]; - const cancelResult = ReadableStreamCancel(stream, compositeReason); - resolvePromise(promise, cancelResult); + try { + EnqueueValueWithSize(controller, chunk, chunkSize); + } catch (enqueueE) { + if (ReadableStreamGetState(stream) === STATE_READABLE) { + ReadableStreamDefaultControllerError(controller, enqueueE); + } + throw enqueueE; } - - return promise; } - function cancel2(reason) { - canceled2 = true; - reason2 = reason; + ReadableStreamDefaultControllerCallPullIfNeeded(controller); + } - if (canceled1 === true) { - const compositeReason = [reason1, reason2]; - const cancelResult = ReadableStreamCancel(stream, compositeReason); - resolvePromise(promise, cancelResult); - } + function ReadableStreamDefaultControllerError(controller, e) { + controller[_queue] = new binding.SimpleQueue(); + const stream = controller[_controlledReadableStream]; + ReadableStreamError(stream, e); + } - return promise; + function ReadableStreamDefaultControllerGetDesiredSize(controller) { + return controller[_strategyHWM] - controller[_queueTotalSize]; + } + + function ReadableStreamDefaultControllerHasBackpressure(controller) { + return !ReadableStreamDefaultControllerShouldCallPull(controller); + } + + function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) { + if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { + return false; } + const state = ReadableStreamGetState(controller[_controlledReadableStream]); + return state === STATE_READABLE; + } + + // + // Internal functions. Not part of the standard. + // + + function ReadableStreamGetState(stream) { + return (stream[_readableStreamBits] & STATE_MASK) >> STATE_BITS_OFFSET; + } + + function ReadableStreamSetState(stream, state) { + stream[_readableStreamBits] = (stream[_readableStreamBits] & ~STATE_MASK) | + (state << STATE_BITS_OFFSET); + } + + // + // Functions exported for use by TransformStream. Not part of the standard. + // + + function IsReadableStreamReadable(stream) { + return ReadableStreamGetState(stream) === STATE_READABLE; + } + + function IsReadableStreamClosed(stream) { + return ReadableStreamGetState(stream) === STATE_CLOSED; + } + + function IsReadableStreamErrored(stream) { + return ReadableStreamGetState(stream) === STATE_ERRORED; + } + + // Used internally by enqueue() and also by TransformStream. + function getReadableStreamEnqueueError(stream, controller) { + if (controller[_readableStreamDefaultControllerBits] & CLOSE_REQUESTED) { + return new TypeError(errEnqueueCloseRequestedStream); + } + + const state = ReadableStreamGetState(stream); + if (state === STATE_ERRORED) { + return new TypeError(errEnqueueErroredStream); + } + // assert(state === STATE_CLOSED, 'state is "closed"'); + return new TypeError(errEnqueueClosedStream); } //
diff --git a/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp b/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp index b8120eaa..32a666f 100644 --- a/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp +++ b/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp
@@ -45,15 +45,6 @@ return WebSecurityOrigin(SecurityOrigin::Create(url)); } -WebSecurityOrigin WebSecurityOrigin::CreateFromTupleWithSuborigin( - const WebString& protocol, - const WebString& host, - int port, - const WebString& suborigin) { - return WebSecurityOrigin( - SecurityOrigin::Create(protocol, host, port, suborigin)); -} - WebSecurityOrigin WebSecurityOrigin::CreateUnique() { return WebSecurityOrigin(SecurityOrigin::CreateUnique()); }
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp index 90d25f8..33e4f70b 100644 --- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp +++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp
@@ -28,7 +28,9 @@ #include "platform/weborigin/SecurityOrigin.h" +#include <stdint.h> #include <memory> + #include "net/base/url_util.h" #include "platform/runtime_enabled_features.h" #include "platform/weborigin/KURL.h" @@ -48,8 +50,7 @@ namespace blink { -const int kInvalidPort = 0; -const int kMaxAllowedPort = 65535; +const uint16_t kInvalidPort = 0; static URLSecurityOriginMap* g_url_origin_map = nullptr; @@ -535,10 +536,7 @@ scoped_refptr<SecurityOrigin> SecurityOrigin::Create(const String& protocol, const String& host, - int port) { - if (port < 0 || port > kMaxAllowedPort) - return CreateUnique(); - + uint16_t port) { DCHECK_EQ(host, DecodeURLEscapeSequences(host)); String port_part = port ? ":" + String::Number(port) : String(); @@ -547,7 +545,7 @@ scoped_refptr<SecurityOrigin> SecurityOrigin::Create(const String& protocol, const String& host, - int port, + uint16_t port, const String& suborigin) { scoped_refptr<SecurityOrigin> origin = Create(protocol, host, port); if (!suborigin.IsEmpty())
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h index 6dbe401..685e5fec 100644 --- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h +++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h
@@ -29,7 +29,9 @@ #ifndef SecurityOrigin_h #define SecurityOrigin_h +#include <stdint.h> #include <memory> + #include "base/gtest_prod_util.h" #include "platform/PlatformExport.h" #include "platform/weborigin/Suborigin.h" @@ -53,10 +55,10 @@ static scoped_refptr<SecurityOrigin> CreateFromString(const String&); static scoped_refptr<SecurityOrigin> Create(const String& protocol, const String& host, - int port); + uint16_t port); static scoped_refptr<SecurityOrigin> Create(const String& protocol, const String& host, - int port, + uint16_t port, const String& suborigin); static scoped_refptr<SecurityOrigin> CreateFromUrlOrigin(const url::Origin&); url::Origin ToUrlOrigin() const; @@ -92,10 +94,10 @@ // Returns 0 if the effective port of this origin is the default for its // scheme. - unsigned short Port() const { return port_; } + uint16_t Port() const { return port_; } // Returns the effective port, even if it is the default port for the // scheme (e.g. "http" => 80). - unsigned short EffectivePort() const { return effective_port_; } + uint16_t EffectivePort() const { return effective_port_; } // Returns true if a given URL is secure, based either directly on its // own protocol, or, when relevant, on the protocol of its "inner URL" @@ -313,8 +315,8 @@ String host_; String domain_; Suborigin suborigin_; - unsigned short port_; - unsigned short effective_port_; + uint16_t port_; + uint16_t effective_port_; const bool is_unique_; bool universal_access_; bool domain_was_set_in_dom_;
diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp index d007dd2..aa1b679 100644 --- a/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp +++ b/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp
@@ -30,6 +30,8 @@ #include "platform/weborigin/SecurityOrigin.h" +#include <stdint.h> + #include "platform/blob/BlobURL.h" #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" #include "platform/weborigin/KURL.h" @@ -43,7 +45,7 @@ namespace blink { -const int kMaxAllowedPort = 65535; +const uint16_t kMaxAllowedPort = UINT16_MAX; class SecurityOriginTest : public ::testing::Test { public: @@ -53,19 +55,8 @@ } }; -TEST_F(SecurityOriginTest, InvalidPortsCreateUniqueOrigins) { - int ports[] = {-100, -1, kMaxAllowedPort + 1, 1000000}; - - for (size_t i = 0; i < WTF_ARRAY_LENGTH(ports); ++i) { - scoped_refptr<const SecurityOrigin> origin = - SecurityOrigin::Create("http", "example.com", ports[i]); - EXPECT_TRUE(origin->IsUnique()) - << "Port " << ports[i] << " should have generated a unique origin."; - } -} - TEST_F(SecurityOriginTest, ValidPortsCreateNonUniqueOrigins) { - int ports[] = {0, 80, 443, 5000, kMaxAllowedPort}; + uint16_t ports[] = {0, 80, 443, 5000, kMaxAllowedPort}; for (size_t i = 0; i < WTF_ARRAY_LENGTH(ports); ++i) { scoped_refptr<const SecurityOrigin> origin = @@ -436,7 +427,7 @@ struct TestCase { const char* scheme; const char* host; - unsigned short port; + uint16_t port; const char* origin; } cases[] = { {"http", "example.com", 80, "http://example.com"}, @@ -561,7 +552,7 @@ const char* const url; const char* const scheme; const char* const host; - unsigned short port; + uint16_t port; } cases[] = { // IP Addresses {"http://192.168.9.1/", "http", "192.168.9.1", 80},
diff --git a/third_party/WebKit/public/platform/WebSecurityOrigin.h b/third_party/WebKit/public/platform/WebSecurityOrigin.h index 891a5a6..7307a78 100644 --- a/third_party/WebKit/public/platform/WebSecurityOrigin.h +++ b/third_party/WebKit/public/platform/WebSecurityOrigin.h
@@ -124,14 +124,6 @@ #endif private: - // Present only to facilitate conversion from 'url::Origin'; this constructor - // shouldn't be used anywhere else. - BLINK_PLATFORM_EXPORT static WebSecurityOrigin CreateFromTupleWithSuborigin( - const WebString& protocol, - const WebString& host, - int port, - const WebString& suborigin); - WebPrivatePtr<const SecurityOrigin> private_; };
diff --git a/tools/media_engagement_preload/BUILD.gn b/tools/media_engagement_preload/BUILD.gn new file mode 100644 index 0000000..e59e693a --- /dev/null +++ b/tools/media_engagement_preload/BUILD.gn
@@ -0,0 +1,58 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +generator_sources = [ + "make_dafsa.py", + "media_engagement_preload_pb2.py", + + # protobuf dependency + "../../third_party/protobuf/python/google/protobuf/descriptor_pb2.py", + "../../third_party/protobuf/python/google/protobuf/json_format.py", + "../../third_party/protobuf/python/google/protobuf/service.py", + "../../third_party/protobuf/python/google/protobuf/message.py", + "../../third_party/protobuf/python/google/protobuf/service_reflection.py", + "../../third_party/protobuf/python/google/protobuf/text_encoding.py", + "../../third_party/protobuf/python/google/protobuf/proto_builder.py", + "../../third_party/protobuf/python/google/protobuf/python_protobuf.h", + "../../third_party/protobuf/python/google/protobuf/descriptor.py", + "../../third_party/protobuf/python/google/protobuf/descriptor_database.py", + "../../third_party/protobuf/python/google/protobuf/message_factory.py", + "../../third_party/protobuf/python/google/protobuf/symbol_database.py", + "../../third_party/protobuf/python/google/protobuf/text_format.py", + "../../third_party/protobuf/python/google/protobuf/descriptor_pool.py", + "../../third_party/protobuf/python/google/protobuf/internal/more_extensions.proto", + "../../third_party/protobuf/python/google/protobuf/internal/wire_format.py", + "../../third_party/protobuf/python/google/protobuf/internal/testing_refleaks.py", + "../../third_party/protobuf/python/google/protobuf/internal/type_checkers.py", + "../../third_party/protobuf/python/google/protobuf/internal/missing_enum_values.proto", + "../../third_party/protobuf/python/google/protobuf/internal/more_messages.proto", + "../../third_party/protobuf/python/google/protobuf/internal/containers.py", + "../../third_party/protobuf/python/google/protobuf/internal/test_bad_identifiers.proto", + "../../third_party/protobuf/python/google/protobuf/internal/_parameterized.py", + "../../third_party/protobuf/python/google/protobuf/internal/message_listener.py", + "../../third_party/protobuf/python/google/protobuf/internal/enum_type_wrapper.py", + "../../third_party/protobuf/python/google/protobuf/internal/api_implementation.py", + "../../third_party/protobuf/python/google/protobuf/internal/encoder.py", + "../../third_party/protobuf/python/google/protobuf/internal/test_util.py", + "../../third_party/protobuf/python/google/protobuf/internal/well_known_types.py", + "../../third_party/protobuf/python/google/protobuf/internal/decoder.py", + "../../third_party/protobuf/python/google/protobuf/internal/api_implementation.cc", + "../../third_party/protobuf/python/google/protobuf/internal/python_message.py", + "../../third_party/protobuf/python/google/protobuf/internal/message_set_extensions.proto", + "../../third_party/protobuf/python/google/protobuf/internal/python_protobuf.cc", + "../../third_party/protobuf/python/google/protobuf/internal/more_extensions_dynamic.proto", + "../../third_party/protobuf/python/google/protobuf/internal/__init__.py", + "../../third_party/protobuf/python/google/protobuf/reflection.py", + "../../third_party/protobuf/python/google/protobuf/__init__.py", + "../../third_party/protobuf/python/google/__init__.py", + "../../third_party/protobuf/third_party/six/six.py", +] + +copy("generator") { + sources = generator_sources + + outputs = [ + "$root_out_dir/{{source_root_relative_dir}}/{{source_file_part}}", + ] +}
diff --git a/url/scheme_host_port.cc b/url/scheme_host_port.cc index eb2905d..b9298bc 100644 --- a/url/scheme_host_port.cc +++ b/url/scheme_host_port.cc
@@ -140,8 +140,12 @@ // A valid GURL never returns PORT_INVALID. int port = url.EffectiveIntPort(); - if (port == PORT_UNSPECIFIED) + if (port == PORT_UNSPECIFIED) { port = 0; + } else { + DCHECK_GE(port, 0); + DCHECK_LE(port, 65535); + } if (!IsValidInput(scheme, host, port, ALREADY_CANONICALIZED)) return;