diff --git a/chrome/app/mash/mash_runner.cc b/chrome/app/mash/mash_runner.cc index 9c14e73..d5086ec61 100644 --- a/chrome/app/mash/mash_runner.cc +++ b/chrome/app/mash/mash_runner.cc
@@ -237,8 +237,8 @@ service_manager::ServiceContext context( base::MakeUnique<mash::MashPackagedService>(), std::move(service_request)); - // Quit the child process if it loses its connection to service manager. - context.SetConnectionLostClosure(run_loop.QuitClosure()); + // Quit the child process when the service quits. + context.SetQuitClosure(run_loop.QuitClosure()); run_loop.Run(); // |context| must be destroyed before |message_loop|. }
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index c491cf46..b5c99f9 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -48,6 +48,7 @@ "+sandbox/win/src", # The path doesn't say it, but this is the Windows sandbox. "+services/image_decoder/public/cpp", "+services/image_decoder/public/interfaces", + "+services/preferences/public/cpp", "+services/preferences/public/interfaces", "+services/service_manager", "+services/shape_detection/public/interfaces",
diff --git a/chrome/browser/chromeos/preferences_chromeos_browsertest.cc b/chrome/browser/chromeos/preferences_chromeos_browsertest.cc index 93812b0..aa3234bf 100644 --- a/chrome/browser/chromeos/preferences_chromeos_browsertest.cc +++ b/chrome/browser/chromeos/preferences_chromeos_browsertest.cc
@@ -5,10 +5,16 @@ #include <stddef.h> #include <sys/types.h> +#include <set> +#include <string> + #include "ash/shell.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/run_loop.h" +#include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" #include "chrome/browser/chromeos/login/login_manager_test.h" @@ -20,12 +26,20 @@ #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h" #include "chrome/browser/chromeos/system/fake_input_device_settings.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" +#include "chrome/browser/ui/browser.h" #include "chrome/common/pref_names.h" +#include "chrome/test/base/in_process_browser_test.h" #include "chromeos/chromeos_switches.h" #include "components/feedback/tracing_manager.h" #include "components/prefs/pref_service.h" +#include "components/prefs/pref_store.h" +#include "components/prefs/writeable_pref_store.h" #include "components/user_manager/user_manager.h" +#include "content/public/common/service_manager_connection.h" #include "content/public/test/test_utils.h" +#include "services/preferences/public/cpp/pref_client_store.h" +#include "services/preferences/public/interfaces/preferences.mojom.h" +#include "services/service_manager/public/cpp/connector.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/chromeos/fake_ime_keyboard.h" #include "ui/events/event_utils.h" @@ -141,6 +155,61 @@ DISALLOW_COPY_AND_ASSIGN(PreferencesTest); }; +class PreferencesServiceBrowserTest : public InProcessBrowserTest { + public: + PreferencesServiceBrowserTest() {} + + protected: + static service_manager::Connector* connector() { + return content::ServiceManagerConnection::GetForProcess()->GetConnector(); + } + + void WaitForPrefChange(PrefStore* store, const std::string& key) { + base::RunLoop run_loop; + TestPrefObserver observer(key, run_loop.QuitClosure()); + store->AddObserver(&observer); + run_loop.Run(); + store->RemoveObserver(&observer); + } + + bool GetIntegerPrefValue(PrefStore* store, + const std::string& key, + int* out_value) { + const base::Value* value = nullptr; + if (!store->GetValue(key, &value)) + return false; + return value->GetAsInteger(out_value); + } + + private: + class TestPrefObserver : public PrefStore::Observer { + public: + TestPrefObserver(const std::string& pref_name, + const base::Closure& callback) + : pref_name_(pref_name), callback_(callback) {} + + ~TestPrefObserver() override {} + + // PrefStore::Observer: + void OnPrefValueChanged(const std::string& key) override { + if (key == pref_name_) + callback_.Run(); + } + + void OnInitializationCompleted(bool success) override { + ASSERT_TRUE(success); + } + + private: + const std::string pref_name_; + const base::Closure callback_; + + DISALLOW_COPY_AND_ASSIGN(TestPrefObserver); + }; + + DISALLOW_COPY_AND_ASSIGN(PreferencesServiceBrowserTest); +}; + IN_PROC_BROWSER_TEST_F(PreferencesTest, PRE_MultiProfiles) { RegisterUser(test_users_[0].GetUserEmail()); RegisterUser(test_users_[1].GetUserEmail()); @@ -214,4 +283,43 @@ CheckLocalStateCorrespondsToPrefs(prefs1); } +IN_PROC_BROWSER_TEST_F(PreferencesServiceBrowserTest, Basic) { + constexpr int kInitialValue = 1; + PrefService* pref_service = browser()->profile()->GetPrefs(); + pref_service->SetInteger(prefs::kMouseSensitivity, kInitialValue); + + prefs::mojom::PreferencesServiceFactoryPtr factory_a; + connector()->BindInterface(prefs::mojom::kServiceName, &factory_a); + scoped_refptr<preferences::PrefClientStore> pref_store_a = + new preferences::PrefClientStore(std::move(factory_a)); + pref_store_a->Subscribe({prefs::kMouseSensitivity}); + WaitForPrefChange(pref_store_a.get(), prefs::kMouseSensitivity); + + prefs::mojom::PreferencesServiceFactoryPtr factory_b; + connector()->BindInterface(prefs::mojom::kServiceName, &factory_b); + scoped_refptr<preferences::PrefClientStore> pref_store_b = + new preferences::PrefClientStore(std::move(factory_b)); + pref_store_b->Subscribe({prefs::kMouseSensitivity}); + WaitForPrefChange(pref_store_b.get(), prefs::kMouseSensitivity); + + int value_a = 0; + ASSERT_TRUE(GetIntegerPrefValue(pref_store_a.get(), prefs::kMouseSensitivity, + &value_a)); + EXPECT_EQ(kInitialValue, value_a); + + int value_b = 0; + ASSERT_TRUE(GetIntegerPrefValue(pref_store_b.get(), prefs::kMouseSensitivity, + &value_b)); + EXPECT_EQ(kInitialValue, value_b); + + const int kTestValue = 42; + pref_store_a->SetValue(prefs::kMouseSensitivity, + base::MakeUnique<base::FundamentalValue>(kTestValue), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + WaitForPrefChange(pref_store_b.get(), prefs::kMouseSensitivity); + ASSERT_TRUE(GetIntegerPrefValue(pref_store_b.get(), prefs::kMouseSensitivity, + &value_b)); + EXPECT_EQ(kTestValue, value_b); +} + } // namespace chromeos
diff --git a/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc b/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc index 4c619e38..0ea2aea2 100644 --- a/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc +++ b/chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h" #include "base/files/file_util.h" #include "chrome/browser/extensions/api/image_writer_private/error_messages.h" #include "chrome/browser/extensions/api/image_writer_private/operation_manager.h" -#include "chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h" #include "content/public/browser/browser_thread.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" namespace extensions { @@ -83,9 +84,37 @@ SetStage(image_writer_api::STAGE_DOWNLOAD); + // Create traffic annotation tag. + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("cros_recovery_image_download", R"( + semantics { + sender: "Chrome OS Recovery Utility" + description: + "The Google Chrome OS recovery utility downloads the recovery " + "image from Google Download Server." + trigger: + "User uses the Chrome OS Recovery Utility app/extension, selects " + "a Chrome OS recovery image, and clicks the Create button to write " + "the image to a USB or SD card." + data: + "URL of the image file to be downloaded. No other data or user " + "identifier is sent." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: true + cookies_store: "user" + setting: + "This feature cannot be disabled by settings, it can only be used " + "by whitelisted apps/extension." + policy_exception_justification: + "Not implemented, considered not useful." + })"); + // Store the URL fetcher on this object so that it is destroyed before this // object is. - url_fetcher_ = net::URLFetcher::Create(url_, net::URLFetcher::GET, this); + url_fetcher_ = net::URLFetcher::Create(url_, net::URLFetcher::GET, this, + traffic_annotation); url_fetcher_->SetRequestContext(request_context_); url_fetcher_->SaveResponseToFileAtPath(
diff --git a/chrome/browser/prefs/preferences_manifest.json b/chrome/browser/prefs/preferences_manifest.json index 0ce32ca..bb498c20 100644 --- a/chrome/browser/prefs/preferences_manifest.json +++ b/chrome/browser/prefs/preferences_manifest.json
@@ -4,7 +4,7 @@ "interface_provider_specs": { "service_manager:connector": { "provides": { - "preferences_manager": [ "prefs::mojom::PreferencesFactory" ] + "preferences_manager": [ "prefs::mojom::PreferencesServiceFactory" ] }, "requires": { }
diff --git a/chrome/browser/prefs/preferences_service.cc b/chrome/browser/prefs/preferences_service.cc index 5494965..85b9c2a 100644 --- a/chrome/browser/prefs/preferences_service.cc +++ b/chrome/browser/prefs/preferences_service.cc
@@ -33,7 +33,8 @@ service_->FindPreference(preference_name); std::unique_ptr<base::DictionaryValue> dictionary = base::MakeUnique<base::DictionaryValue>(); - dictionary->Set(preference_name, pref->GetValue()->CreateDeepCopy()); + dictionary->SetWithoutPathExpansion(preference_name, + pref->GetValue()->CreateDeepCopy()); client_->OnPreferencesChanged(std::move(dictionary)); } @@ -73,7 +74,7 @@ preferences_change_registrar_->Add( it, base::Bind(&PreferencesService::PreferenceChanged, base::Unretained(this))); - dictionary->Set(it, pref->GetValue()->CreateDeepCopy()); + dictionary->SetWithoutPathExpansion(it, pref->GetValue()->CreateDeepCopy()); } if (dictionary->empty())
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 4bab94b..849eb3a 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2384,7 +2384,11 @@ "//chrome/browser/chromeos:arc_test_support", "//chromeos/ime:gencode", "//components/arc:arc_test_support", + "//components/prefs", "//components/user_manager:test_support", + "//services/preferences/public/cpp", + "//services/preferences/public/interfaces", + "//services/service_manager/public/cpp", "//ui/login:resources", ]
diff --git a/chrome/test/base/mash_browser_tests_main.cc b/chrome/test/base/mash_browser_tests_main.cc index 5f44d7fc..7e011882 100644 --- a/chrome/test/base/mash_browser_tests_main.cc +++ b/chrome/test/base/mash_browser_tests_main.cc
@@ -162,7 +162,7 @@ service_manager::ServiceContext context( base::MakeUnique<mash::MashPackagedService>(), std::move(service_request)); - context.SetConnectionLostClosure(run_loop.QuitClosure()); + context.SetQuitClosure(run_loop.QuitClosure()); run_loop.Run(); }
diff --git a/content/browser/renderer_host/render_view_host_delegate.cc b/content/browser/renderer_host/render_view_host_delegate.cc index 3d5853c..dfd91f0 100644 --- a/content/browser/renderer_host/render_view_host_delegate.cc +++ b/content/browser/renderer_host/render_view_host_delegate.cc
@@ -61,4 +61,8 @@ return false; } +bool RenderViewHostDelegate::HasPersistentVideo() const { + return false; +} + } // namespace content
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h index 7dc40c3..3059773 100644 --- a/content/browser/renderer_host/render_view_host_delegate.h +++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -185,6 +185,9 @@ // Whether download UI should be hidden. virtual bool HideDownloadUI() const; + // Whether the WebContents as a persistent video. + virtual bool HasPersistentVideo() const; + protected: virtual ~RenderViewHostDelegate() {} };
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index e16766a..8388af1b 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -532,6 +532,10 @@ if (delegate_ && delegate_->HideDownloadUI()) prefs.hide_download_ui = true; + // `media_controls_enabled` is `true` by default. + if (delegate_ && delegate_->HasPersistentVideo()) + prefs.media_controls_enabled = false; + prefs.background_video_track_optimization_enabled = base::FeatureList::IsEnabled(media::kBackgroundVideoTrackOptimization);
diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc index 52c4520..f8225d5 100644 --- a/content/browser/web_contents/web_contents_android.cc +++ b/content/browser/web_contents/web_contents_android.cc
@@ -703,6 +703,13 @@ view->DismissTextHandles(); } +void WebContentsAndroid::SetHasPersistentVideo( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jboolean value) { + web_contents_->SetHasPersistentVideo(value); +} + void WebContentsAndroid::OnFinishGetContentBitmap( const JavaRef<jobject>& obj, const JavaRef<jobject>& callback,
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h index d31ba28..93fc028 100644 --- a/content/browser/web_contents/web_contents_android.h +++ b/content/browser/web_contents/web_contents_android.h
@@ -193,6 +193,9 @@ const base::android::JavaParamRef<jobject>& jcallback); void DismissTextHandles(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + void SetHasPersistentVideo(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jboolean value); void SetMediaSession( const base::android::ScopedJavaLocalRef<jobject>& j_media_session);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 7b92187..87b9b7b 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4252,6 +4252,10 @@ return is_overlay_content_; } +bool WebContentsImpl::HasPersistentVideo() const { + return has_persistent_video_; +} + bool WebContentsImpl::IsFocusedElementEditable() { RenderFrameHostImpl* frame = GetFocusedFrame(); return frame && frame->has_focused_editable_element(); @@ -5280,6 +5284,14 @@ } } +void WebContentsImpl::SetHasPersistentVideo(bool value) { + if (has_persistent_video_ == value) + return; + + has_persistent_video_ = value; + NotifyPreferencesChanged(); +} + #if defined(OS_ANDROID) void WebContentsImpl::NotifyFindMatchRectsReply( int version, @@ -5344,19 +5356,7 @@ } void WebContentsImpl::UpdateOverridingUserAgent() { - std::set<RenderViewHost*> render_view_host_set; - for (FrameTreeNode* node : frame_tree_.Nodes()) { - RenderWidgetHost* render_widget_host = - node->current_frame_host()->GetRenderWidgetHost(); - if (!render_widget_host) - continue; - RenderViewHost* render_view_host = RenderViewHost::From(render_widget_host); - if (!render_view_host) - continue; - render_view_host_set.insert(render_view_host); - } - for (RenderViewHost* render_view_host : render_view_host_set) - render_view_host->OnWebkitPreferencesChanged(); + NotifyPreferencesChanged(); } void WebContentsImpl::SetJavaScriptDialogManagerForTesting( @@ -5417,4 +5417,20 @@ " releasing your website to the public.")); } +void WebContentsImpl::NotifyPreferencesChanged() { + std::set<RenderViewHost*> render_view_host_set; + for (FrameTreeNode* node : frame_tree_.Nodes()) { + RenderWidgetHost* render_widget_host = + node->current_frame_host()->GetRenderWidgetHost(); + if (!render_widget_host) + continue; + RenderViewHost* render_view_host = RenderViewHost::From(render_widget_host); + if (!render_view_host) + continue; + render_view_host_set.insert(render_view_host); + } + for (RenderViewHost* render_view_host : render_view_host_set) + render_view_host->OnWebkitPreferencesChanged(); +} + } // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index cf9f25f..c325f5a 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -572,6 +572,7 @@ bool IsOverridingUserAgent() override; bool IsJavaScriptDialogShowing() const override; bool HideDownloadUI() const override; + bool HasPersistentVideo() const override; // NavigatorDelegate --------------------------------------------------------- @@ -791,6 +792,9 @@ void IncrementBluetoothConnectedDeviceCount(); void DecrementBluetoothConnectedDeviceCount(); + // Called when the WebContents gains or loses a persistent video. + void SetHasPersistentVideo(bool value); + #if defined(OS_ANDROID) // Called by FindRequestManager when all of the find match rects are in. void NotifyFindMatchRectsReply(int version, @@ -1172,6 +1176,10 @@ // certificate via --allow-insecure-localhost. void ShowInsecureLocalhostWarningIfNeeded(); + // Notify this WebContents that the preferences have changed. This will send + // an IPC to all the renderer process associated with this WebContents. + void NotifyPreferencesChanged(); + // Data for core operation --------------------------------------------------- // Delegate for notifying our owner about stuff. Not owned by us. @@ -1502,6 +1510,8 @@ int currently_playing_video_count_ = 0; + bool has_persistent_video_ = false; + base::WeakPtrFactory<WebContentsImpl> loading_weak_factory_; base::WeakPtrFactory<WebContentsImpl> weak_factory_;
diff --git a/content/common/service_manager/embedded_service_runner.cc b/content/common/service_manager/embedded_service_runner.cc index 0c7c4589..665a6e3 100644 --- a/content/common/service_manager/embedded_service_runner.cc +++ b/content/common/service_manager/embedded_service_runner.cc
@@ -87,7 +87,7 @@ factory_callback_.Run(), std::move(request)); service_manager::ServiceContext* raw_context = context.get(); - context->SetConnectionLostClosure( + context->SetQuitClosure( base::Bind(&InstanceManager::OnInstanceLost, this, instance_id)); contexts_.insert(std::make_pair(raw_context, std::move(context))); id_to_context_map_.insert(std::make_pair(instance_id, raw_context));
diff --git a/content/common/service_manager/service_manager_connection_impl.cc b/content/common/service_manager/service_manager_connection_impl.cc index 8be6e76b..83a4d11 100644 --- a/content/common/service_manager/service_manager_connection_impl.cc +++ b/content/common/service_manager/service_manager_connection_impl.cc
@@ -273,7 +273,7 @@ return accept; } - bool OnStop() override { + bool OnServiceManagerConnectionLost() override { ClearConnectionFiltersOnIOThread(); callback_task_runner_->PostTask(FROM_HERE, stop_callback_); return true;
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java index 657c9a0..322d072 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -517,6 +517,11 @@ nativeDismissTextHandles(mNativeWebContentsAndroid); } + @Override + public void setHasPersistentVideo(boolean value) { + nativeSetHasPersistentVideo(mNativeWebContentsAndroid, value); + } + @CalledByNative private final void setMediaSession(MediaSessionImpl mediaSession) { mMediaSession = mediaSession; @@ -604,4 +609,5 @@ String url, boolean isFavicon, int maxBitmapSize, boolean bypassCache, ImageDownloadCallback callback); private native void nativeDismissTextHandles(long nativeWebContentsAndroid); + private native void nativeSetHasPersistentVideo(long nativeWebContentsAndroid, boolean value); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java index 3e5332e..dd74c514 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
@@ -372,4 +372,12 @@ * (e.g. renderer for the currently selected tab) */ public void simulateRendererKilledForTesting(boolean wasOomProtected); + + /** + * Notifies the WebContents about the new persistent video status. It should be called whenever + * the value changes. + * + * @param value Whether there is a persistent video associated with this WebContents. + */ + public void setHasPersistentVideo(boolean value); }
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index 8d53c17..bf638a5 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -251,6 +251,7 @@ IPC_STRUCT_TRAITS_MEMBER(max_keyframe_distance_to_disable_background_video) IPC_STRUCT_TRAITS_MEMBER(enable_instant_source_buffer_gc) IPC_STRUCT_TRAITS_MEMBER(presentation_receiver) + IPC_STRUCT_TRAITS_MEMBER(media_controls_enabled) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(blink::mojom::WindowFeatures)
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index 2034641d..ba85d1b0 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc
@@ -227,7 +227,8 @@ max_keyframe_distance_to_disable_background_video( base::TimeDelta::FromSeconds(10)), enable_instant_source_buffer_gc(false), - presentation_receiver(false) { + presentation_receiver(false), + media_controls_enabled(true) { standard_font_family_map[kCommonScript] = base::ASCIIToUTF16("Times New Roman"); fixed_font_family_map[kCommonScript] = base::ASCIIToUTF16("Courier New");
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index ccabaec..71ea3098 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h
@@ -284,6 +284,9 @@ // Whether it is a presentation receiver. bool presentation_receiver; + // If disabled, media controls should never be used. + bool media_controls_enabled; + // We try to keep the default values the same as the default values in // chrome, except for the cases where it would require lots of extra work for // the embedder to use the same default value.
diff --git a/content/public/test/test_download_request_handler.cc b/content/public/test/test_download_request_handler.cc index c0f9525..180f37f 100644 --- a/content/public/test/test_download_request_handler.cc +++ b/content/public/test/test_download_request_handler.cc
@@ -24,6 +24,7 @@ #include "net/base/io_buffer.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" +#include "net/http/http_util.h" #include "net/url_request/url_request_filter.h" #include "net/url_request/url_request_interceptor.h" @@ -477,8 +478,9 @@ void TestDownloadRequestHandler::PartialResponseJob:: NotifyHeadersCompleteAndPrepareToRead() { - std::string normalized_headers; - response_info_.headers->GetNormalizedHeaders(&normalized_headers); + std::string normalized_headers = + net::HttpUtil::ConvertHeadersBackToHTTPResponse( + response_info_.headers->raw_headers()); DVLOG(1) << "Notify ready with headers:\n" << normalized_headers; offset_of_next_read_ = requested_range_begin_;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index e3ea8995..65b2fdc5 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1101,6 +1101,8 @@ settings->setPresentationReceiver(prefs.presentation_receiver); + settings->setMediaControlsEnabled(prefs.media_controls_enabled); + #if defined(OS_MACOSX) settings->setDoubleTapToZoomEnabled(true); web_view->setMaximumLegibleScale(prefs.default_maximum_page_scale_factor);
diff --git a/google_apis/drive/base_requests.cc b/google_apis/drive/base_requests.cc index d1aa60d..39492d0 100644 --- a/google_apis/drive/base_requests.cc +++ b/google_apis/drive/base_requests.cc
@@ -95,18 +95,14 @@ // Returns response headers as a string. Returns a warning message if // |url_fetcher| does not contain a valid response. Used only for debugging. std::string GetResponseHeadersAsString(const URLFetcher* url_fetcher) { - // net::HttpResponseHeaders::raw_headers(), as the name implies, stores - // all headers in their raw format, i.e each header is null-terminated. - // So logging raw_headers() only shows the first header, which is probably - // the status line. GetNormalizedHeaders, on the other hand, will show all - // the headers, one per line, which is probably what we want. std::string headers; // Check that response code indicates response headers are valid (i.e. not // malformed) before we retrieve the headers. if (url_fetcher->GetResponseCode() == URLFetcher::RESPONSE_CODE_INVALID) { headers.assign("Response headers are malformed!!"); } else { - url_fetcher->GetResponseHeaders()->GetNormalizedHeaders(&headers); + headers = net::HttpUtil::ConvertHeadersBackToHTTPResponse( + url_fetcher->GetResponseHeaders()->raw_headers()); } return headers; }
diff --git a/google_apis/gaia/gaia_auth_fetcher.cc b/google_apis/gaia/gaia_auth_fetcher.cc index 789fa47..03bd8a45 100644 --- a/google_apis/gaia/gaia_auth_fetcher.cc +++ b/google_apis/gaia/gaia_auth_fetcher.cc
@@ -25,6 +25,7 @@ #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" +#include "net/http/http_util.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_status.h" @@ -953,7 +954,8 @@ #ifndef NDEBUG std::string headers; if (source->GetResponseHeaders()) - source->GetResponseHeaders()->GetNormalizedHeaders(&headers); + headers = net::HttpUtil::ConvertHeadersBackToHTTPResponse( + source->GetResponseHeaders()->raw_headers()); DVLOG(2) << "Response " << url.spec() << ", code = " << response_code << "\n" << headers << "\n"; DVLOG(2) << "data: " << data << "\n";
diff --git a/media/mojo/services/media_service.cc b/media/mojo/services/media_service.cc index 72df120..43eace8 100644 --- a/media/mojo/services/media_service.cc +++ b/media/mojo/services/media_service.cc
@@ -39,7 +39,7 @@ return true; } -bool MediaService::OnStop() { +bool MediaService::OnServiceManagerConnectionLost() { mojo_media_client_.reset(); return true; }
diff --git a/media/mojo/services/media_service.h b/media/mojo/services/media_service.h index de2b0da..08c4885 100644 --- a/media/mojo/services/media_service.h +++ b/media/mojo/services/media_service.h
@@ -41,7 +41,7 @@ void OnStart() final; bool OnConnect(const service_manager::ServiceInfo& remote_info, service_manager::InterfaceRegistry* registry) final; - bool OnStop() final; + bool OnServiceManagerConnectionLost() final; // service_manager::InterfaceFactory<mojom::MediaService> implementation. void Create(const service_manager::Identity& remote_identity,
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index 635c15ca..868570b0 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc
@@ -70,6 +70,34 @@ namespace { +// Returns a simple text serialization of the given +// |HttpResponseHeaders|. This is used by tests to verify that an +// |HttpResponseHeaders| matches an expectation string. +// +// * One line per header, written as: +// HEADER_NAME: HEADER_VALUE\n +// * The original case of header names is preserved. +// * Whitespace around head names/values is stripped. +// * Repeated headers are not aggregated. +// * Headers are listed in their original order. +// TODO(tfarina): this is a duplicate function from +// http_response_headers_unittest.cc:ToSimpleString(). Figure out how to merge +// them. crbug.com/488593 +std::string ToSimpleString(const scoped_refptr<HttpResponseHeaders>& parsed) { + std::string result = parsed->GetStatusLine() + "\n"; + + size_t iter = 0; + std::string name; + std::string value; + while (parsed->EnumerateHeaderLines(&iter, &name, &value)) { + std::string new_line = name + ": " + value + "\n"; + + result += new_line; + } + + return result; +} + // Tests the load timing values of a request that goes through a // MockNetworkTransaction. void TestLoadTimingNetworkRequest(const LoadTimingInfo& load_timing_info) { @@ -262,7 +290,7 @@ std::string* response_headers) { HttpResponseInfo response; RunTransactionTestWithResponseInfo(cache, trans_info, &response); - response.headers->GetNormalizedHeaders(response_headers); + *response_headers = ToSimpleString(response.headers); } void RunTransactionTestWithResponseAndGetTiming( @@ -275,7 +303,7 @@ RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info), &response, log, load_timing_info, nullptr, nullptr, nullptr); - response.headers->GetNormalizedHeaders(response_headers); + *response_headers = ToSimpleString(response.headers); } // This class provides a handler for kFastNoStoreGET_Transaction so that the @@ -6734,13 +6762,10 @@ EXPECT_EQ(response_time.ToInternalValue(), response.response_time.ToInternalValue()); - std::string headers; - response.headers->GetNormalizedHeaders(&headers); - EXPECT_EQ("HTTP/1.1 200 OK\n" "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", - headers); + ToSimpleString(response.headers)); RemoveMockTransaction(&mock_network_response); }
diff --git a/net/http/http_response_headers.cc b/net/http/http_response_headers.cc index d5ab1e8..d0b2fc1 100644 --- a/net/http/http_response_headers.cc +++ b/net/http/http_response_headers.cc
@@ -460,60 +460,6 @@ DCHECK_EQ('\0', raw_headers_[raw_headers_.size() - 1]); } -// Append all of our headers to the final output string. -void HttpResponseHeaders::GetNormalizedHeaders(std::string* output) const { - // copy up to the null byte. this just copies the status line. - output->assign(raw_headers_.c_str()); - - // headers may appear multiple times (not necessarily in succession) in the - // header data, so we build a map from header name to generated header lines. - // to preserve the order of the original headers, the actual values are kept - // in a separate list. finally, the list of headers is flattened to form - // the normalized block of headers. - // - // NOTE: We take special care to preserve the whitespace around any commas - // that may occur in the original response headers. Because our consumer may - // be a web app, we cannot be certain of the semantics of commas despite the - // fact that RFC 2616 says that they should be regarded as value separators. - // - using HeadersMap = std::unordered_map<std::string, size_t>; - HeadersMap headers_map; - HeadersMap::iterator iter = headers_map.end(); - - std::vector<std::string> headers; - - for (size_t i = 0; i < parsed_.size(); ++i) { - DCHECK(!parsed_[i].is_continuation()); - - std::string name(parsed_[i].name_begin, parsed_[i].name_end); - std::string lower_name = base::ToLowerASCII(name); - - iter = headers_map.find(lower_name); - if (iter == headers_map.end()) { - iter = headers_map.insert( - HeadersMap::value_type(lower_name, headers.size())).first; - headers.push_back(name + ": "); - } else { - headers[iter->second].append(", "); - } - - std::string::const_iterator value_begin = parsed_[i].value_begin; - std::string::const_iterator value_end = parsed_[i].value_end; - while (++i < parsed_.size() && parsed_[i].is_continuation()) - value_end = parsed_[i].value_end; - --i; - - headers[iter->second].append(value_begin, value_end); - } - - for (size_t i = 0; i < headers.size(); ++i) { - output->push_back('\n'); - output->append(headers[i]); - } - - output->push_back('\n'); -} - bool HttpResponseHeaders::GetNormalizedHeader(const std::string& name, std::string* value) const { // If you hit this assertion, please use EnumerateHeader instead!
diff --git a/net/http/http_response_headers.h b/net/http/http_response_headers.h index e45fe05..167980d 100644 --- a/net/http/http_response_headers.h +++ b/net/http/http_response_headers.h
@@ -119,30 +119,6 @@ int64_t resource_size, bool replace_status_line); - // Creates a normalized header string. The output will be formatted exactly - // like so: - // HTTP/<version> <status_code>[ <status_text>]\n - // [<header-name>: <header-values>\n]* - // meaning, each line is \n-terminated, and there is no extra whitespace - // beyond the single space separators shown (of course, values can contain - // whitespace within them). If a given header-name appears more than once - // in the set of headers, they are combined into a single line like so: - // <header-name>: <header-value1>, <header-value2>, ...<header-valueN>\n - // - // DANGER: For some headers (e.g., "Set-Cookie"), the normalized form can be - // a lossy format. This is due to the fact that some servers generate - // Set-Cookie headers that contain unquoted commas (usually as part of the - // value of an "expires" attribute). So, use this function with caution. Do - // not expect to be able to re-parse Set-Cookie headers from this output. - // - // NOTE: Do not make any assumptions about the encoding of this output - // string. It may be non-ASCII, and the encoding used by the server is not - // necessarily known to us. Do not assume that this output is UTF-8! - // - // TODO(darin): remove this method - // - void GetNormalizedHeaders(std::string* output) const; - // Fetch the "normalized" value of a single header, where all values for the // header name are separated by commas. See the GetNormalizedHeaders for // format details. Returns false if this header wasn't found.
diff --git a/services/image_decoder/image_decoder_service.cc b/services/image_decoder/image_decoder_service.cc index 4226e9fe..4ad2a0b 100644 --- a/services/image_decoder/image_decoder_service.cc +++ b/services/image_decoder/image_decoder_service.cc
@@ -62,10 +62,6 @@ return true; } -bool ImageDecoderService::OnStop() { - return true; -} - void ImageDecoderService::MaybeRequestQuitDelayed() { base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE,
diff --git a/services/image_decoder/image_decoder_service.h b/services/image_decoder/image_decoder_service.h index 643a130..a41006e 100644 --- a/services/image_decoder/image_decoder_service.h +++ b/services/image_decoder/image_decoder_service.h
@@ -27,7 +27,6 @@ void OnStart() override; bool OnConnect(const service_manager::ServiceInfo& remote_info, service_manager::InterfaceRegistry* registry) override; - bool OnStop() override; private: void MaybeRequestQuitDelayed();
diff --git a/services/preferences/public/cpp/pref_client_store.cc b/services/preferences/public/cpp/pref_client_store.cc index 2ca8134..289aaaa 100644 --- a/services/preferences/public/cpp/pref_client_store.cc +++ b/services/preferences/public/cpp/pref_client_store.cc
@@ -82,7 +82,7 @@ return; auto prefs = base::MakeUnique<base::DictionaryValue>(); - prefs->Set(key, value.CreateDeepCopy()); + prefs->SetWithoutPathExpansion(key, value.CreateDeepCopy()); prefs_service_ptr_->SetPreferences(std::move(prefs)); }
diff --git a/services/service_manager/background/tests/test_service.cc b/services/service_manager/background/tests/test_service.cc index 18de6bd..96fd1522 100644 --- a/services/service_manager/background/tests/test_service.cc +++ b/services/service_manager/background/tests/test_service.cc
@@ -28,9 +28,6 @@ registry->AddInterface(this); return true; } - bool OnStop() override { - return true; - } // InterfaceFactory<mojom::TestService>: void Create(const Identity& remote_identity,
diff --git a/services/service_manager/public/cpp/lib/service.cc b/services/service_manager/public/cpp/lib/service.cc index 72222ef..2b40a6c 100644 --- a/services/service_manager/public/cpp/lib/service.cc +++ b/services/service_manager/public/cpp/lib/service.cc
@@ -42,20 +42,25 @@ interface_provider->GetInterface(interface_name, std::move(interface_pipe)); } -bool Service::OnStop() { return true; } +bool Service::OnServiceManagerConnectionLost() { + return true; +} ServiceContext* Service::context() const { DCHECK(service_context_) - << "Service::context() may only be called during or after OnStart()."; + << "Service::context() may only be called after the Service constructor."; return service_context_; } +void Service::SetContext(ServiceContext* context) { + service_context_ = context; +} + ForwardingService::ForwardingService(Service* target) : target_(target) {} ForwardingService::~ForwardingService() {} void ForwardingService::OnStart() { - target_->set_context(context()); target_->OnStart(); } @@ -64,6 +69,20 @@ return target_->OnConnect(remote_info, registry); } -bool ForwardingService::OnStop() { return target_->OnStop(); } +void ForwardingService::OnBindInterface( + const ServiceInfo& remote_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + target_->OnBindInterface(remote_info, interface_name, + std::move(interface_pipe)); +} + +bool ForwardingService::OnServiceManagerConnectionLost() { + return target_->OnServiceManagerConnectionLost(); +} + +void ForwardingService::SetContext(ServiceContext* context) { + target_->SetContext(context); +} } // namespace service_manager
diff --git a/services/service_manager/public/cpp/lib/service_context.cc b/services/service_manager/public/cpp/lib/service_context.cc index f45202e..6459459 100644 --- a/services/service_manager/public/cpp/lib/service_context.cc +++ b/services/service_manager/public/cpp/lib/service_context.cc
@@ -42,14 +42,18 @@ } else { DCHECK(pending_connector_request_.is_pending()); } + service_->SetContext(this); } ServiceContext::~ServiceContext() {} -void ServiceContext::SetConnectionLostClosure(const base::Closure& closure) { - connection_lost_closure_ = closure; - if (service_quit_) - QuitNow(); +void ServiceContext::SetQuitClosure(const base::Closure& closure) { + if (service_quit_) { + // CAUTION: May delete |this|. + closure.Run(); + } else { + quit_closure_ = closure; + } } void ServiceContext::RequestQuit() { @@ -64,15 +68,13 @@ } void ServiceContext::QuitNow() { + service_quit_ = true; if (binding_.is_bound()) binding_.Close(); - if (!connection_lost_closure_.is_null()) - base::ResetAndReturn(&connection_lost_closure_).Run(); -} - -void ServiceContext::DestroyService() { - QuitNow(); - service_.reset(); + if (!quit_closure_.is_null()) { + // CAUTION: May delete |this|. + base::ResetAndReturn(&quit_closure_).Run(); + } } //////////////////////////////////////////////////////////////////////////////// @@ -83,8 +85,6 @@ local_info_ = info; callback.Run(std::move(pending_connector_request_), mojo::MakeRequest(&service_control_)); - - service_->set_context(this); service_->OnStart(); } @@ -140,19 +140,10 @@ } void ServiceContext::OnConnectionError() { - // Note that the Service doesn't technically have to quit now, it may live - // on to service existing connections. All existing Connectors however are - // invalid. - service_quit_ = service_->OnStop(); - if (service_quit_) { + if (service_->OnServiceManagerConnectionLost()) { + // CAUTION: May delete |this|. QuitNow(); - // NOTE: This call may delete |this|, so don't access any ServiceContext - // state beyond this point. - return; } - - // We don't reset the connector as clients may have taken a raw pointer to it. - // Connect() will return nullptr if they try to connect to anything. } void ServiceContext::OnRegistryConnectionError(InterfaceRegistry* registry) {
diff --git a/services/service_manager/public/cpp/lib/service_runner.cc b/services/service_manager/public/cpp/lib/service_runner.cc index 374a948..4ba2f58 100644 --- a/services/service_manager/public/cpp/lib/service_runner.cc +++ b/services/service_manager/public/cpp/lib/service_runner.cc
@@ -57,7 +57,7 @@ mojo::MakeRequest<mojom::Service>(mojo::MakeScopedHandle( mojo::MessagePipeHandle(service_request_handle))))); base::RunLoop run_loop; - context_->SetConnectionLostClosure(run_loop.QuitClosure()); + context_->SetQuitClosure(run_loop.QuitClosure()); run_loop.Run(); context_.reset(); }
diff --git a/services/service_manager/public/cpp/service.h b/services/service_manager/public/cpp/service.h index 250b8ab..db5ad50 100644 --- a/services/service_manager/public/cpp/service.h +++ b/services/service_manager/public/cpp/service.h
@@ -23,9 +23,9 @@ Service(); virtual ~Service(); - // Called exactly once, when a bidirectional connection with the Service - // Manager has been established. No calls to OnConnect() will be received - // before this. + // Called exactly once when a bidirectional connection with the Service + // Manager has been established. No calls to OnConnect() or OnBindInterface() + // will be made before this. virtual void OnStart(); // Called each time a connection to this service is brokered by the Service @@ -51,32 +51,28 @@ // service should use this as a signal to shut down, and in fact its process // may be reaped shortly afterward if applicable. // - // Return true from this method to tell the ServiceContext to signal its - // shutdown externally (i.e. to invoke its "connection lost" closure if set), - // or return false to defer the signal. If deferred, the Service should - // explicitly call QuitNow() on the ServiceContext when it's ready to be - // torn down. + // If this returns |true| then QuitNow() will be invoked immediately upon + // return to the ServiceContext. Otherwise the Service is responsible for + // eventually calling QuitNow(). // - // The default implementation returns true. + // The default implementation returns |true|. // - // While it's possible for this to be invoked before either OnStart() or - // OnConnect() is invoked, neither will be invoked at any point after this - // OnStop(). - virtual bool OnStop(); + // NOTE: This may be called at any time, and once it's been called, none of + // the other public Service methods will be invoked by the ServiceContext. + virtual bool OnServiceManagerConnectionLost(); protected: - // Access the ServiceContext associated with this Service. Note that this is - // only valid to call during or after OnStart(), but never before! As such, - // it's always safe to call in OnStart() and OnConnect(), but should generally - // be avoided in OnStop(). + // Accesses the ServiceContext associated with this Service. Note that this is + // only valid AFTER the Service's constructor has run. ServiceContext* context() const; private: friend class ForwardingService; friend class ServiceContext; - // NOTE: This is guaranteed to be called before OnStart(). - void set_context(ServiceContext* context) { service_context_ = context; } + // NOTE: This MUST be called before any public Service methods. ServiceContext + // satisfies this guarantee for any Service instance it owns. + virtual void SetContext(ServiceContext* context); ServiceContext* service_context_ = nullptr; @@ -95,9 +91,14 @@ void OnStart() override; bool OnConnect(const ServiceInfo& remote_info, InterfaceRegistry* registry) override; - bool OnStop() override; + void OnBindInterface(const ServiceInfo& remote_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override; + bool OnServiceManagerConnectionLost() override; private: + void SetContext(ServiceContext* context) override; + Service* const target_ = nullptr; DISALLOW_COPY_AND_ASSIGN(ForwardingService);
diff --git a/services/service_manager/public/cpp/service_context.h b/services/service_manager/public/cpp/service_context.h index a1af32c..f843462 100644 --- a/services/service_manager/public/cpp/service_context.h +++ b/services/service_manager/public/cpp/service_context.h
@@ -22,9 +22,11 @@ namespace service_manager { // Encapsulates a connection to the Service Manager in two parts: +// // - a bound InterfacePtr to mojom::Connector, the primary mechanism // by which the instantiating service connects to other services, // brokered by the Service Manager. +// // - a bound InterfaceRequest of mojom::Service, an interface used by the // Service Manager to inform this service of lifecycle events and // inbound connections brokered by it. @@ -62,12 +64,14 @@ const ServiceInfo& local_info() const { return local_info_; } const Identity& identity() const { return local_info_.identity; } - // Specify a function to be called when the connection to the service manager - // is lost. Note that if connection has already been lost, then |closure| is - // called immediately. + // Specify a closure to be run when the Service calls QuitNow(), typically + // in response to Service::OnServiceManagerConnectionLost(). // - // It is acceptable for |closure| to delete this ServiceContext. - void SetConnectionLostClosure(const base::Closure& closure); + // Note that if the Service has already called QuitNow(), |closure| is run + // immediately from this method. + // + // NOTE: It is acceptable for |closure| to delete this ServiceContext. + void SetQuitClosure(const base::Closure& closure); // Informs the Service Manager that this instance is ready to terminate. If // the Service Manager has any outstanding connection requests for this @@ -75,33 +79,32 @@ // the pending request(s) and can then appropriately decide whether or not // it still wants to quit. // - // If the request is granted, the Service Manager will service the connection - // to this ServiceContext and Service::OnStop() will eventually be invoked. + // If the request is granted, the Service Manager will soon sever the + // connection to this ServiceContext, and + // Service::OnServiceManagerConnectionLost() will be invoked at that time. void RequestQuit(); // Immediately severs the connection to the Service Manager. // - // Note that calling this before the Service receives OnStop() can lead to - // unpredictable behavior, specifically because clients may have inbound - // connections in transit which may have already been brokered by the Service - // Manager and thus will be irreparably broken on the client side. + // Note that calling this before the Service receives + // OnServiceManagerConnectionLost() can lead to unpredictable behavior, as the + // Service Manager may have already brokered new inbound connections from + // other services to this Service instance, and those connections will be + // abruptly terminated as they can no longer result in OnConnect() or + // OnBindInterface() calls on the Service. // - // Use of this call before OnStop() should be reserved for exceptional cases. + // To put it another way: unless you want flaky connections to be a normal + // experience for consumers of your service, avoid calling this before + // receiving Service::OnServiceManagerConnectionLost(). void DisconnectFromServiceManager(); - // Immediately severs the connection to the Service Manager. - // - // If a connection-lost closure was set, it is immediately invoked. Note that - // it is never necessary or meaningful to call this after the Service - // has received OnStop(). + // Immediately severs the connection to the Service Manager and invokes the + // quit closure (see SetQuitClosure() above) if one has been set. // // See comments on DisconnectFromServiceManager() regarding abrupt // disconnection from the Service Manager. void QuitNow(); - // Simliar to QuitNow() above but also destroys the Service instance. - void DestroyService(); - private: friend class service_manager::Service; @@ -146,9 +149,16 @@ // is unbound and therefore invalid until OnStart() is called. mojom::ServiceControlAssociatedPtr service_control_; + // The Service may call QuitNow() before SetConnectionLostClosure(), and the + // latter is expected to invoke the closure immediately in that case. This is + // used to track that condition. + // + // TODO(rockot): Figure out who depends on this behavior and make them stop. + // It's weird and shouldn't be necessary. bool service_quit_ = false; - base::Closure connection_lost_closure_; + // The closure to run when QuitNow() is invoked. May delete |this|. + base::Closure quit_closure_; base::WeakPtrFactory<ServiceContext> weak_factory_;
diff --git a/services/service_manager/tests/connect/connect_test_package.cc b/services/service_manager/tests/connect/connect_test_package.cc index 596774e1..974e387 100644 --- a/services/service_manager/tests/connect/connect_test_package.cc +++ b/services/service_manager/tests/connect/connect_test_package.cc
@@ -181,7 +181,7 @@ return true; } - bool OnStop() override { + bool OnServiceManagerConnectionLost() override { provided_services_.clear(); return true; }
diff --git a/services/service_manager/tests/lifecycle/app_client.cc b/services/service_manager/tests/lifecycle/app_client.cc index 9ada68b..5e9467e 100644 --- a/services/service_manager/tests/lifecycle/app_client.cc +++ b/services/service_manager/tests/lifecycle/app_client.cc
@@ -21,7 +21,7 @@ return true; } -bool AppClient::OnStop() { +bool AppClient::OnServiceManagerConnectionLost() { base::MessageLoop::current()->QuitWhenIdle(); return true; } @@ -54,7 +54,7 @@ void AppClient::BindingLost() { if (bindings_.empty()) - OnStop(); + OnServiceManagerConnectionLost(); } } // namespace test
diff --git a/services/service_manager/tests/lifecycle/app_client.h b/services/service_manager/tests/lifecycle/app_client.h index 2c31a3f..9d8baad 100644 --- a/services/service_manager/tests/lifecycle/app_client.h +++ b/services/service_manager/tests/lifecycle/app_client.h
@@ -31,7 +31,7 @@ // Service: bool OnConnect(const ServiceInfo& remote_info, InterfaceRegistry* registry) override; - bool OnStop() override; + bool OnServiceManagerConnectionLost() override; // InterfaceFactory<LifecycleControl>: void Create(const Identity& remote_identity,
diff --git a/services/service_manager/tests/service_manager/embedder.cc b/services/service_manager/tests/service_manager/embedder.cc index 9cabede..dceb8f3 100644 --- a/services/service_manager/tests/service_manager/embedder.cc +++ b/services/service_manager/tests/service_manager/embedder.cc
@@ -52,7 +52,7 @@ return true; } - bool OnStop() override { + bool OnServiceManagerConnectionLost() override { base::MessageLoop::current()->QuitWhenIdle(); return true; }
diff --git a/services/shape_detection/shape_detection_service.cc b/services/shape_detection/shape_detection_service.cc index e0105629..c2375168 100644 --- a/services/shape_detection/shape_detection_service.cc +++ b/services/shape_detection/shape_detection_service.cc
@@ -48,8 +48,4 @@ return true; } -bool ShapeDetectionService::OnStop() { - return true; -} - } // namespace shape_detection
diff --git a/services/shape_detection/shape_detection_service.h b/services/shape_detection/shape_detection_service.h index b84125f..ab79456 100644 --- a/services/shape_detection/shape_detection_service.h +++ b/services/shape_detection/shape_detection_service.h
@@ -25,7 +25,6 @@ void OnStart() override; bool OnConnect(const service_manager::ServiceInfo& remote_info, service_manager::InterfaceRegistry* registry) override; - bool OnStop() override; private: std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_;
diff --git a/services/tracing/service.cc b/services/tracing/service.cc index 31cfcde..f2a6c3b 100644 --- a/services/tracing/service.cc +++ b/services/tracing/service.cc
@@ -28,7 +28,7 @@ return true; } -bool Service::OnStop() { +bool Service::OnServiceManagerConnectionLost() { // TODO(beng): This is only required because Service isn't run by // ServiceRunner - instead it's launched automatically by the standalone // service manager. It shouldn't be.
diff --git a/services/tracing/service.h b/services/tracing/service.h index 5938b07f..b45d54c 100644 --- a/services/tracing/service.h +++ b/services/tracing/service.h
@@ -38,7 +38,7 @@ // service_manager::Service implementation. bool OnConnect(const service_manager::ServiceInfo& remote_info, service_manager::InterfaceRegistry* registry) override; - bool OnStop() override; + bool OnServiceManagerConnectionLost() override; // service_manager::InterfaceFactory<mojom::Factory>: void Create(const service_manager::Identity& remote_identity,
diff --git a/third_party/WebKit/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-expected.html b/third_party/WebKit/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-expected.html index 1e3c7f2..5f4d437 100644 --- a/third_party/WebKit/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-expected.html +++ b/third_party/WebKit/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-expected.html
@@ -28,10 +28,9 @@ </div> </div> -<!-- crbug.com/690087: We use 99px instead of 100px because we end up discarding 1px when trying - to allocate the spare pixels to the table. --> -<div class="table container" style="display: block; float: left; height: 99px;"> - <div class="td" style="height: 91px;" style="display: block;"> + +<div class="table container" style="display: block; float: left; height: 98px;"> + <div class="td" style="height: 90px;" style="display: block;"> <div class="item"></div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/media/controls/settings-disable-controls.html b/third_party/WebKit/LayoutTests/media/controls/settings-disable-controls.html new file mode 100644 index 0000000..5bd7c115 --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/controls/settings-disable-controls.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<title>Test that 'mediaControlsEnabled' properly toggles the native controls</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../media-file.js"></script> +<script src="../media-controls.js"></script> +<video controls></video> +<script> +async_test(t => { + var video = document.querySelector('video'); + + internals.mediaPlayerRemoteRouteAvailabilityChanged(video, true); + t.add_cleanup(() => { + internals.mediaPlayerRemoteRouteAvailabilityChanged(video, false); + }); + + video.addEventListener('canplaythrough', t.step_func(e => { + assert_equals(overlayCastButton(video).style.display, "none"); + assert_not_equals(mediaControlsButton(video, "panel").style.display, "none"); + + internals.settings.setMediaControlsEnabled(false); + testRunner.layoutAndPaintAsyncThen(t.step_func(() => { + assert_equals(mediaControlsButton(video, "panel").style.display, "none"); + assert_equals(overlayCastButton(video).style.display, "none"); + + internals.settings.setMediaControlsEnabled(true); + testRunner.layoutAndPaintAsyncThen(t.step_func_done(() => { + assert_not_equals(mediaControlsButton(video, "panel").style.display, "none"); + assert_equals(overlayCastButton(video).style.display, "none"); + })); + })); + })); + + video.src = findMediaFile('video', '../content/test'); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table-two-pass-layout-overpaint-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/table-two-pass-layout-overpaint-expected.html index 6c8da19..013c379 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/table-two-pass-layout-overpaint-expected.html +++ b/third_party/WebKit/LayoutTests/paint/invalidation/table-two-pass-layout-overpaint-expected.html
@@ -11,14 +11,8 @@ <tr> <td> <div id="target"></div> - <div id="dummy"></div> </td> </tr> </table> </body> </html> -<!-- crbug.com/690087: We do this to force a two-pass layout so that we get the same height on the table as the reference. --> -<script> - document.body.offsetTop; - document.getElementById("dummy").style.display = "none"; -</script>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table-two-pass-layout-overpaint-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table-two-pass-layout-overpaint-expected.txt index f4575e4d..a3de9dc 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/table-two-pass-layout-overpaint-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/table-two-pass-layout-overpaint-expected.txt
@@ -7,40 +7,17 @@ "drawsContent": true, "paintInvalidations": [ { - "object": "LayoutTable TABLE", - "rect": [8, 106, 106, 1], - "reason": "incremental" - }, - { - "object": "LayoutTableCell TD", - "rect": [10, 104, 102, 1], - "reason": "incremental" - }, - { "object": "LayoutBlockFlow DIV id='target'", - "rect": [11, 45, 100, 25], - "reason": "bounds change" - }, - { - "object": "LayoutBlockFlow DIV id='target'", - "rect": [11, 44, 50, 25], - "reason": "bounds change" + "rect": [61, 44, 50, 25], + "reason": "incremental" } ] } ], "objectPaintInvalidations": [ { - "object": "LayoutTable TABLE", - "reason": "incremental" - }, - { - "object": "LayoutTableCell TD", - "reason": "incremental" - }, - { "object": "LayoutBlockFlow DIV id='target'", - "reason": "bounds change" + "reason": "incremental" } ] }
diff --git a/third_party/WebKit/PerformanceTests/Layout/nested-percent-height-tables.html b/third_party/WebKit/PerformanceTests/Layout/nested-percent-height-tables.html deleted file mode 100644 index 934ed15..0000000 --- a/third_party/WebKit/PerformanceTests/Layout/nested-percent-height-tables.html +++ /dev/null
@@ -1,94 +0,0 @@ -<!DOCTYPE HTML> -<style> -.body { margin:0; } -.maxHeight { width:100%; height:100%; } -.overflowDiv { overflow:hidden; display:inline-block } -.overflowAuto { overflow:auto; } -</style> -<html id="top"> - <body class="body" style="height:100%;"> - <table class="maxHeight"> - <tr> - <td style="height:100%;"> - <div class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td style="height:100%;"> - <div class="maxHeight"> - <table id="top" class="maxHeight"> - <colgroup> - <col/> - <col /> - <col style="width:100%;"/> - </colgroup> - <tr style="height:100%;"> - <td style="height:100%;"> - <div class="overflowAuto maxHeight" style="position:relative;"> - </td> - <td rowspan="1"> - <div class="overflowDiv" > - </div> - </td> - <td style="height:100%;"> - <div class="overflowAuto maxHeight" style="position:relative;"> - <div class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td style="height:100%;"> - <table class="maxHeight"> - <tr> - <td colspan="2" class="maxHeight"> - <div class=" maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td style="height:100%;"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <div class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> - <table class="maxHeight"> - <tr> - <td class="maxHeight"> -<script src="../resources/runner.js"></script> -<script> -function test() { - PerfTestRunner.forceLayout(); - document.getElementById("top").style.height = "100%"; - PerfTestRunner.forceLayout(); - document.getElementById("top").style.height = "auto"; -} -PerfTestRunner.measureRunsPerSecond({ - description: "Measures performance of nested tables with percent height.", - run: test, -}); -</script>
diff --git a/third_party/WebKit/Source/core/frame/Settings.json5 b/third_party/WebKit/Source/core/frame/Settings.json5 index e5c0b05..f72c8b4 100644 --- a/third_party/WebKit/Source/core/frame/Settings.json5 +++ b/third_party/WebKit/Source/core/frame/Settings.json5
@@ -916,5 +916,12 @@ name: "presentationReceiver", initial: false, }, + + // Whether Blink should show media controls when `controls` attribute is used. + { + name: "mediaControlsEnabled", + initial: true, + invalidate: "MediaControls", + }, ], }
diff --git a/third_party/WebKit/Source/core/frame/SettingsDelegate.h b/third_party/WebKit/Source/core/frame/SettingsDelegate.h index 37edc88db..72041f8 100644 --- a/third_party/WebKit/Source/core/frame/SettingsDelegate.h +++ b/third_party/WebKit/Source/core/frame/SettingsDelegate.h
@@ -63,6 +63,7 @@ AccessibilityStateChange, TextTrackKindUserPreferenceChange, DOMWorldsChange, + MediaControlsChange, }; virtual void settingsChanged(ChangeType) = 0;
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp index dbbcdb2a..a3a195c2 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -134,6 +134,7 @@ MediaControlsShowFullscreen, MediaControlsShowNoScript, MediaControlsShowNotShown, + MediaControlsShowDisabledSettings, MediaControlsShowMax }; @@ -372,6 +373,18 @@ RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled(); } +void HTMLMediaElement::onMediaControlsEnabledChange(Document* document) { + auto it = documentToElementSetMap().find(document); + if (it == documentToElementSetMap().end()) + return; + DCHECK(it->value); + WeakMediaElementSet& elements = *it->value; + for (const auto& element : elements) { + element->updateControlsVisibility(); + element->mediaControls()->onMediaControlsEnabledChange(); + } +} + HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document) : HTMLElement(tagName, document), @@ -2386,6 +2399,13 @@ bool HTMLMediaElement::shouldShowControls( const RecordMetricsBehavior recordMetrics) const { + Settings* settings = document().settings(); + if (settings && !settings->getMediaControlsEnabled()) { + if (recordMetrics == RecordMetricsBehavior::DoRecord) + showControlsHistogram().count(MediaControlsShowDisabledSettings); + return false; + } + if (fastHasAttribute(controlsAttr)) { if (recordMetrics == RecordMetricsBehavior::DoRecord) showControlsHistogram().count(MediaControlsShowAttribute);
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/HTMLMediaElement.h index 1b3a7d9..fa05bccdfa 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.h +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -98,6 +98,10 @@ // by the page). static bool mediaTracksEnabledInternally(); + // Notify the HTMLMediaElement that the media controls settings have changed + // for the given document. + static void onMediaControlsEnabledChange(Document*); + DECLARE_VIRTUAL_TRACE(); DECLARE_VIRTUAL_TRACE_WRAPPERS();
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp index ad9607ac..cefa6bb 100644 --- a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp +++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
@@ -71,8 +71,16 @@ } static bool shouldShowCastButton(HTMLMediaElement& mediaElement) { - return !mediaElement.fastHasAttribute(HTMLNames::disableremoteplaybackAttr) && - mediaElement.hasRemoteRoutes(); + if (mediaElement.fastHasAttribute(HTMLNames::disableremoteplaybackAttr)) + return false; + + // Explicitly do not show cast button when the mediaControlsEnabled setting is + // false to make sure the overlay does not appear. + Document& document = mediaElement.document(); + if (document.settings() && !document.settings()->getMediaControlsEnabled()) + return false; + + return mediaElement.hasRemoteRoutes(); } static bool preferHiddenVolumeControls(const Document& document) {
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.h b/third_party/WebKit/Source/core/html/shadow/MediaControls.h index b2046b6..7480531 100644 --- a/third_party/WebKit/Source/core/html/shadow/MediaControls.h +++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.h
@@ -110,6 +110,13 @@ refreshCastButtonVisibility(); } + // TODO(mlamouri): this method is needed in order to notify the controls that + // the `mediaControlsEnabled` setting has changed. + void onMediaControlsEnabledChange() { + // There is no update because only the overlay is expected to change. + refreshCastButtonVisibilityWithoutUpdate(); + } + DECLARE_VIRTUAL_TRACE(); private:
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp index 685b14c..7084123c 100644 --- a/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp +++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp
@@ -293,6 +293,22 @@ ASSERT_TRUE(isElementVisible(*castOverlayButton)); } +TEST_F(MediaControlsTest, CastOverlayMediaControlsDisabled) { + Element* castOverlayButton = getElementByShadowPseudoId( + mediaControls(), "-internal-media-controls-overlay-cast-button"); + ASSERT_NE(nullptr, castOverlayButton); + + EXPECT_FALSE(isElementVisible(*castOverlayButton)); + simulateRouteAvailabe(); + EXPECT_TRUE(isElementVisible(*castOverlayButton)); + + document().settings()->setMediaControlsEnabled(false); + EXPECT_FALSE(isElementVisible(*castOverlayButton)); + + document().settings()->setMediaControlsEnabled(true); + EXPECT_TRUE(isElementVisible(*castOverlayButton)); +} + TEST_F(MediaControlsTest, KeepControlsVisibleIfOverflowListVisible) { Element* overflowList = getElementByShadowPseudoId( mediaControls(), "-internal-media-controls-overflow-menu-list");
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp index 8fe7915e..c497b9f0 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -451,13 +451,12 @@ layouter.setChildNeedsLayout(§ion); if (!section.needsLayout()) markChildForPaginationRelayoutIfNeeded(section, layouter); - if (section.needsLayout()) { - section.layout(); - section.setLogicalHeight(LayoutUnit(section.calcRowLogicalHeight())); - } + section.layoutIfNeeded(); + int sectionLogicalHeight = section.calcRowLogicalHeight(); + section.setLogicalHeight(LayoutUnit(sectionLogicalHeight)); if (view()->layoutState()->isPaginated()) updateFragmentationInfoForChild(section); - setLogicalHeight(logicalHeight() + section.logicalHeight()); + setLogicalHeight(logicalHeight() + sectionLogicalHeight); } LayoutUnit LayoutTable::logicalHeightFromStyle() const { @@ -502,8 +501,8 @@ extraLogicalHeight -= section->distributeExtraLogicalHeightToRows(extraLogicalHeight); - // crbug.com/690087: We really would like to enable this ASSERT to ensure that - // all the extra space has been distributed. + // FIXME: We really would like to enable this ASSERT to ensure that all the + // extra space has been distributed. // However our current distribution algorithm does not round properly and thus // we can have some remaining height. // ASSERT(!topSection() || !extraLogicalHeight);
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.h b/third_party/WebKit/Source/core/layout/LayoutTableSection.h index 0254244..f7d6d1d 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableSection.h +++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.h
@@ -329,8 +329,6 @@ bool isRepeatingHeaderGroup() const; - void layout() override; - protected: void styleDidChange(StyleDifference, const ComputedStyle* oldStyle) override; bool nodeAtPoint(HitTestResult&, @@ -345,6 +343,8 @@ void willBeRemovedFromTree() override; + void layout() override; + int borderSpacingForRow(unsigned row) const { return m_grid[row].rowLayoutObject ? table()->vBorderSpacing() : 0; }
diff --git a/third_party/WebKit/Source/core/page/Page.cpp b/third_party/WebKit/Source/core/page/Page.cpp index d5771fbc..6f484137 100644 --- a/third_party/WebKit/Source/core/page/Page.cpp +++ b/third_party/WebKit/Source/core/page/Page.cpp
@@ -437,6 +437,16 @@ } } } break; + case SettingsDelegate::MediaControlsChange: + for (Frame* frame = mainFrame(); frame; + frame = frame->tree().traverseNext()) { + if (!frame->isLocalFrame()) + continue; + Document* doc = toLocalFrame(frame)->document(); + if (doc) + HTMLMediaElement::onMediaControlsEnabledChange(doc); + } + break; } }
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp index 97ce826..e0b5cb8 100644 --- a/third_party/WebKit/Source/platform/heap/Heap.cpp +++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -145,8 +145,9 @@ ProcessHeap::decreaseTotalAllocatedSpace(delta); } -ThreadHeap::ThreadHeap() - : m_regionTree(WTF::makeUnique<RegionTree>()), +ThreadHeap::ThreadHeap(ThreadState* threadState) + : m_threadState(threadState), + m_regionTree(WTF::makeUnique<RegionTree>()), m_heapDoesNotContainCache(WTF::wrapUnique(new HeapDoesNotContainCache)), m_freePagePool(WTF::wrapUnique(new PagePool)), m_markingStack(CallbackStack::create()), @@ -160,41 +161,9 @@ ThreadHeap::~ThreadHeap() { } -void ThreadHeap::attach(ThreadState* thread) { - MutexLocker locker(m_threadAttachMutex); - m_threads.insert(thread); -} - -void ThreadHeap::detach(ThreadState* thread) { - ASSERT(ThreadState::current() == thread); - bool isLastThread = false; - { - // Grab the threadAttachMutex to ensure only one thread can shutdown at - // a time and that no other thread can do a global GC. It also allows - // safe iteration of the m_threads set which happens as part of - // thread local GC asserts. We enter a safepoint while waiting for the - // lock to avoid a dead-lock where another thread has already requested - // GC. - MutexLocker locker(m_threadAttachMutex); - thread->runTerminationGC(); - ASSERT(m_threads.contains(thread)); - m_threads.erase(thread); - isLastThread = m_threads.isEmpty(); - } - if (thread->isMainThread()) - DCHECK_EQ(heapStats().allocatedSpace(), 0u); - if (isLastThread) - delete this; -} - #if DCHECK_IS_ON() BasePage* ThreadHeap::findPageFromAddress(Address address) { - MutexLocker locker(m_threadAttachMutex); - for (ThreadState* state : m_threads) { - if (BasePage* page = state->findPageFromAddress(address)) - return page; - } - return nullptr; + return m_threadState->findPageFromAddress(address); } #endif @@ -346,19 +315,16 @@ void ThreadHeap::preGC() { ASSERT(!ThreadState::current()->isInGC()); - for (ThreadState* state : m_threads) - state->preGC(); + m_threadState->preGC(); } void ThreadHeap::postGC(BlinkGC::GCType gcType) { ASSERT(ThreadState::current()->isInGC()); - for (ThreadState* state : m_threads) - state->postGC(gcType); + m_threadState->postGC(gcType); } void ThreadHeap::preSweep(BlinkGC::GCType gcType) { - for (ThreadState* state : m_threads) - state->preSweep(gcType); + m_threadState->preSweep(gcType); } void ThreadHeap::processMarkingStack(Visitor* visitor) { @@ -510,15 +476,12 @@ } size_t ThreadHeap::objectPayloadSizeForTesting() { - // MEMO: is threadAttachMutex locked? size_t objectPayloadSize = 0; - for (ThreadState* state : m_threads) { - state->setGCState(ThreadState::GCRunning); - state->makeConsistentForGC(); - objectPayloadSize += state->objectPayloadSizeForTesting(); - state->setGCState(ThreadState::Sweeping); - state->setGCState(ThreadState::NoGCScheduled); - } + m_threadState->setGCState(ThreadState::GCRunning); + m_threadState->makeConsistentForGC(); + objectPayloadSize += m_threadState->objectPayloadSizeForTesting(); + m_threadState->setGCState(ThreadState::Sweeping); + m_threadState->setGCState(ThreadState::NoGCScheduled); return objectPayloadSize; } @@ -527,15 +490,13 @@ TRACE_EVENT0("blink_gc", "ThreadHeap::visitPersistentRoots"); ProcessHeap::crossThreadPersistentRegion().tracePersistentNodes(visitor); - for (ThreadState* state : m_threads) - state->visitPersistents(visitor); + m_threadState->visitPersistents(visitor); } void ThreadHeap::visitStackRoots(Visitor* visitor) { ASSERT(ThreadState::current()->isInGC()); TRACE_EVENT0("blink_gc", "ThreadHeap::visitStackRoots"); - for (ThreadState* state : m_threads) - state->visitStack(visitor); + m_threadState->visitStack(visitor); } BasePage* ThreadHeap::lookupPageForAddress(Address address) { @@ -555,8 +516,7 @@ ProcessHeap::decreaseTotalMarkedObjectSize(m_stats.markedObjectSize()); m_stats.reset(); - for (ThreadState* state : m_threads) - state->resetHeapCounters(); + m_threadState->resetHeapCounters(); } ThreadHeap* ThreadHeap::s_mainThreadHeap = nullptr;
diff --git a/third_party/WebKit/Source/platform/heap/Heap.h b/third_party/WebKit/Source/platform/heap/Heap.h index e9b3b880..bf5ebe7 100644 --- a/third_party/WebKit/Source/platform/heap/Heap.h +++ b/third_party/WebKit/Source/platform/heap/Heap.h
@@ -220,11 +220,9 @@ double m_estimatedMarkingTimePerByte; }; -using ThreadStateSet = HashSet<ThreadState*>; - class PLATFORM_EXPORT ThreadHeap { public: - ThreadHeap(); + explicit ThreadHeap(ThreadState*); ~ThreadHeap(); // Returns true for main thread's heap. @@ -270,8 +268,6 @@ StackFrameDepth& stackFrameDepth() { return m_stackFrameDepth; } - RecursiveMutex& threadAttachMutex() { return m_threadAttachMutex; } - const ThreadStateSet& threads() const { return m_threads; } ThreadHeapStats& heapStats() { return m_stats; } CallbackStack* markingStack() const { return m_markingStack.get(); } CallbackStack* postMarkingCallbackStack() const { @@ -282,11 +278,6 @@ } CallbackStack* ephemeronStack() const { return m_ephemeronStack.get(); } - void attach(ThreadState*); - void detach(ThreadState*); - void lockThreadAttachMutex(); - void unlockThreadAttachMutex(); - void visitPersistentRoots(Visitor*); void visitStackRoots(Visitor*); void enterSafePoint(ThreadState*); @@ -454,8 +445,7 @@ void commitCallbackStacks(); void decommitCallbackStacks(); - RecursiveMutex m_threadAttachMutex; - ThreadStateSet m_threads; + ThreadState* m_threadState; ThreadHeapStats m_stats; std::unique_ptr<RegionTree> m_regionTree; std::unique_ptr<HeapDoesNotContainCache> m_heapDoesNotContainCache;
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp index 0dfd5f4..9b8d8098 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp +++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -131,9 +131,7 @@ ASSERT(!**s_threadSpecific); **s_threadSpecific = this; - m_heap = new ThreadHeap(); - ASSERT(m_heap); - m_heap->attach(this); + m_heap = WTF::wrapUnique(new ThreadHeap(this)); for (int arenaIndex = 0; arenaIndex < BlinkGC::LargeObjectArenaIndex; arenaIndex++) @@ -148,6 +146,10 @@ ThreadState::~ThreadState() { ASSERT(checkThread()); + if (isMainThread()) + DCHECK_EQ(heap().heapStats().allocatedSpace(), 0u); + CHECK(gcState() == ThreadState::NoGCScheduled); + for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) delete m_arenas[i]; @@ -163,6 +165,12 @@ new ThreadState(); } +void ThreadState::detachCurrentThread() { + ThreadState* state = current(); + state->runTerminationGC(); + delete state; +} + void ThreadState::removeAllPages() { ASSERT(checkThread()); for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) @@ -208,13 +216,6 @@ removeAllPages(); } -void ThreadState::detachCurrentThread() { - ThreadState* state = current(); - state->heap().detach(state); - RELEASE_ASSERT(state->gcState() == ThreadState::NoGCScheduled); - delete state; -} - NO_SANITIZE_ADDRESS void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr) { #if defined(ADDRESS_SANITIZER) @@ -1256,14 +1257,6 @@ } #endif -void ThreadState::lockThreadAttachMutex() { - m_heap->threadAttachMutex().lock(); -} - -void ThreadState::unlockThreadAttachMutex() { - m_heap->threadAttachMutex().unlock(); -} - void ThreadState::invokePreFinalizers() { ASSERT(checkThread()); ASSERT(!sweepForbidden());
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.h b/third_party/WebKit/Source/platform/heap/ThreadState.h index 69b00073..522977f 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadState.h +++ b/third_party/WebKit/Source/platform/heap/ThreadState.h
@@ -158,9 +158,6 @@ ThreadState* m_state; }; - void lockThreadAttachMutex(); - void unlockThreadAttachMutex(); - static void attachMainThread(); // Associate ThreadState object with the current thread. After this @@ -613,7 +610,7 @@ // and lazily construct ThreadState in it using placement new. static uint8_t s_mainThreadStateStorage[]; - ThreadHeap* m_heap; + std::unique_ptr<ThreadHeap> m_heap; ThreadIdentifier m_thread; std::unique_ptr<PersistentRegion> m_persistentRegion; BlinkGC::StackState m_stackState;
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.cpp b/third_party/WebKit/Source/web/WebSettingsImpl.cpp index 0d18192e..8843e8c 100644 --- a/third_party/WebKit/Source/web/WebSettingsImpl.cpp +++ b/third_party/WebKit/Source/web/WebSettingsImpl.cpp
@@ -724,4 +724,8 @@ m_expensiveBackgroundThrottlingMaxDelay = maxDelay; } +void WebSettingsImpl::setMediaControlsEnabled(bool enabled) { + m_settings->setMediaControlsEnabled(enabled); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.h b/third_party/WebKit/Source/web/WebSettingsImpl.h index a6eae28f..0c4ec8c0 100644 --- a/third_party/WebKit/Source/web/WebSettingsImpl.h +++ b/third_party/WebKit/Source/web/WebSettingsImpl.h
@@ -208,6 +208,7 @@ void setExpensiveBackgroundThrottlingInitialBudget(float) override; void setExpensiveBackgroundThrottlingMaxBudget(float) override; void setExpensiveBackgroundThrottlingMaxDelay(float) override; + void setMediaControlsEnabled(bool) override; bool showFPSCounter() const { return m_showFPSCounter; } bool showPaintRects() const { return m_showPaintRects; }
diff --git a/third_party/WebKit/public/web/WebSettings.h b/third_party/WebKit/public/web/WebSettings.h index 64a661a..ef8014e4 100644 --- a/third_party/WebKit/public/web/WebSettings.h +++ b/third_party/WebKit/public/web/WebSettings.h
@@ -295,6 +295,7 @@ virtual void setExpensiveBackgroundThrottlingInitialBudget(float) = 0; virtual void setExpensiveBackgroundThrottlingMaxBudget(float) = 0; virtual void setExpensiveBackgroundThrottlingMaxDelay(float) = 0; + virtual void setMediaControlsEnabled(bool) = 0; protected: ~WebSettings() {}
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 9c9f420..2026b258 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -10301,15 +10301,13 @@ </histogram> <histogram name="DevTools.ActionTaken" enum="DevToolsAction"> - <owner>sergeyv@chromium.org</owner> - <owner>vsevik@chromium.org</owner> + <owner>alph@chromium.org</owner> <owner>pfeldman@chromium.org</owner> <summary>Specified DevTools action has been taken.</summary> </histogram> <histogram name="DevTools.InspectElement" units="ms"> - <owner>sergeyv@chromium.org</owner> - <owner>vsevik@chromium.org</owner> + <owner>alph@chromium.org</owner> <owner>pfeldman@chromium.org</owner> <summary> Time to load Developer Tools when user clicks Inspect Element in the context @@ -10318,15 +10316,13 @@ </histogram> <histogram name="DevTools.PanelShown" enum="DevToolsPanel"> - <owner>sergeyv@chromium.org</owner> - <owner>vsevik@chromium.org</owner> + <owner>alph@chromium.org</owner> <owner>pfeldman@chromium.org</owner> <summary>Specified DevTools panel was shown.</summary> </histogram> <histogram name="DevTools.SettingChanged" enum="DevToolsSetting"> - <owner>sergeyv@chromium.org</owner> - <owner>vsevik@chromium.org</owner> + <owner>alph@chromium.org</owner> <owner>pfeldman@chromium.org</owner> <summary>Specified DevTools setting was changed.</summary> </histogram> @@ -98927,6 +98923,7 @@ <int value="1" label="Fullscreen"/> <int value="2" label="No scripts allowed"/> <int value="3" label="Not shown"/> + <int value="4" label="Disabled by settings"/> </enum> <enum name="MediaDocumentDownloadButtonType" type="int">