diff --git a/DEPS b/DEPS index f81fc5eb..93366c3 100644 --- a/DEPS +++ b/DEPS
@@ -94,7 +94,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '3e2b10936c5304477fdadfa233671738008fe154', + 'swiftshader_revision': 'a0aa5fdeee12bc42616fe13ef3ea62edb1b9f166', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -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': '9252115c46302971355d1d5fcbe1512f32d30a70', + 'catapult_revision': '43a5c4971235ed78db5c8e2df5eb5c2e0dbff2d6', # 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/ash/window_manager.cc b/ash/window_manager.cc index f76a2fe..905577e 100644 --- a/ash/window_manager.cc +++ b/ash/window_manager.cc
@@ -55,6 +55,7 @@ #include "ui/aura/mus/window_tree_client.h" #include "ui/aura/mus/window_tree_host_mus.h" #include "ui/aura/window.h" +#include "ui/aura/window_event_dispatcher.h" #include "ui/base/class_property.h" #include "ui/base/hit_test.h" #include "ui/display/display_observer.h" @@ -308,7 +309,20 @@ void WindowManager::OnPointerEventObserved(const ui::PointerEvent& event, aura::Window* target) { - pointer_watcher_event_router_->OnPointerEventObserved(event, target); + DCHECK_EQ(Config::MASH, Shell::GetAshConfig()); + // We have received a pointer event on |target|. However, we need to fixup + // |target| first. WindowManager's WindowTree is the entire root tree and + // we must adjust |target| from being the root to the aura::Window which + // would handle |event|. + std::unique_ptr<ui::Event> event_copy = ui::Event::Clone(event); + ui::EventTarget* e_target = + target->GetHost() + ->dispatcher() + ->GetDefaultEventTargeter() + ->FindTargetForEvent(target, event_copy.get()); + + pointer_watcher_event_router_->OnPointerEventObserved( + event, static_cast<aura::Window*>(e_target)); } aura::PropertyConverter* WindowManager::GetPropertyConverter() {
diff --git a/base/process/launch_fuchsia.cc b/base/process/launch_fuchsia.cc index b79210f..7292bdc 100644 --- a/base/process/launch_fuchsia.cc +++ b/base/process/launch_fuchsia.cc
@@ -193,4 +193,8 @@ return GetAppOutputInternal(cl, false, output, exit_code); } +void RaiseProcessToHighPriority() { + // Fuchsia doesn't provide an API to change process priority. +} + } // namespace base
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java index 17ad8b9..80b2110ce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java
@@ -407,12 +407,12 @@ * requirement for launch. We also need the web->app verification which will be checked after * the Activity has launched async. * @param session The session attempting to launch the TrustedWebActivity. - * @param origin The origin that will load on the TrustedWebActivity. + * @param url The url that will load on the TrustedWebActivity. * @return Whether the client for the session passes the initial requirements to launch a * TrustedWebActivity in the given origin. */ public synchronized boolean canSessionLaunchInTrustedWebActivity( - CustomTabsSessionToken session, Uri origin) { + CustomTabsSessionToken session, Uri url) { if (!ChromeFeatureList.isEnabled(ChromeFeatureList.TRUSTED_WEB_ACTIVITY)) return false; if (ChromeVersionInfo.isBetaBuild() || ChromeVersionInfo.isStableBuild()) return false; @@ -420,8 +420,11 @@ if (params == null) return false; String packageName = params.getPackageName(); if (TextUtils.isEmpty(packageName)) return false; - boolean isAppAssociatedWithOrigin = params.mLinkedUrls.contains(origin); + boolean isAppAssociatedWithOrigin = params.mLinkedUrls.contains(url); if (!isAppAssociatedWithOrigin) return false; + + // Split path from the given Uri to get only the origin before web->native verification. + Uri origin = new Uri.Builder().scheme(url.getScheme()).authority(url.getHost()).build(); if (OriginVerifier.isValidOrigin( packageName, origin, CustomTabsService.RELATION_HANDLE_ALL_URLS)) { return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index ab7a37d..56fd836 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -122,6 +122,7 @@ private static boolean sRegisteredDaydreamHook; private static boolean sAddedBlackOverlayView; private static boolean sRegisteredVrAssetsComponent = false; + private static boolean sChromeStarted = false; private ChromeActivity mActivity; @@ -334,6 +335,10 @@ public static void maybeRegisterVrEntryHook(final ChromeActivity activity) { // Daydream is not supported on pre-N devices. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return; + if (!sChromeStarted) { + nativeOnChromeStarted(); + sChromeStarted = true; + } if (sInstance != null) return; // Will be handled in onResume. if (!activitySupportsVrBrowsing(activity) && sRegisteredVrAssetsComponent) return; @@ -1776,4 +1781,5 @@ private native boolean nativeIsClearActivatePending(long nativeVrShellDelegate); private native void nativeDestroy(long nativeVrShellDelegate); private static native void nativeRegisterVrAssetsComponent(); + private static native void nativeOnChromeStarted(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index 72d7b22..26bb763 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -163,7 +163,12 @@ void verifyRelationship() { mOriginVerifier = new OriginVerifier(mTrustedWebContentProvider, getNativeClientPackageName(), CustomTabsService.RELATION_HANDLE_ALL_URLS); - mOriginVerifier.start(mWebappInfo.uri()); + // Split path from the url to get only the origin. + Uri origin = new Uri.Builder() + .scheme(mWebappInfo.uri().getScheme()) + .authority(mWebappInfo.uri().getHost()) + .build(); + mOriginVerifier.start(origin); } @Override
diff --git a/chrome/browser/android/vr_shell/vr_shell_delegate.cc b/chrome/browser/android/vr_shell/vr_shell_delegate.cc index a4a47d51..c773955 100644 --- a/chrome/browser/android/vr_shell/vr_shell_delegate.cc +++ b/chrome/browser/android/vr_shell/vr_shell_delegate.cc
@@ -12,6 +12,8 @@ #include "chrome/browser/android/vr_shell/vr_shell.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/component_updater/vr_assets_component_installer.h" +#include "chrome/browser/vr/assets.h" +#include "chrome/browser/vr/metrics_helper.h" #include "chrome/browser/vr/service/vr_device_manager.h" #include "chrome/browser/vr/service/vr_service_impl.h" #include "content/public/browser/webvr_service_provider.h" @@ -284,4 +286,10 @@ g_browser_process->component_updater()); } +static void JNI_VrShellDelegate_OnChromeStarted( + JNIEnv* env, + const JavaParamRef<jclass>& clazz) { + vr::Assets::GetInstance()->GetMetricsHelper()->OnChromeStarted(); +} + } // namespace vr_shell
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc index 72d28cc..bdd1ff749 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc
@@ -96,7 +96,7 @@ std::unique_ptr<data_reduction_proxy::DataReductionProxyIOData> data_reduction_proxy_io_data( new data_reduction_proxy::DataReductionProxyIOData( - DataReductionProxyChromeSettings::GetClient(), net_log, + DataReductionProxyChromeSettings::GetClient(), prefs, net_log, io_task_runner, ui_task_runner, enabled, GetUserAgent(), version_info::GetChannelString(chrome::GetChannel())));
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 10adea7..ef083f1 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -465,6 +465,11 @@ prefs::kWebRTCUDPPortRange, base::Value::Type::STRING }, #endif // BUILDFLAG(ENABLE_WEBRTC) +#if BUILDFLAG(ENABLE_EXTENSIONS) + { key::kSecurityKeyPermitAttestation, + prefs::kSecurityKeyPermitAttestation, + base::Value::Type::LIST }, +#endif // BUILDFLAG(ENABLE_EXTENSIONS) #if !defined(OS_MACOSX) { key::kFullscreenAllowed, prefs::kFullscreenAllowed, @@ -473,9 +478,6 @@ { key::kFullscreenAllowed, extensions::pref_names::kAppFullscreenAllowed, base::Value::Type::BOOLEAN }, - { key::kSecurityKeyPermitAttestation, - prefs::kSecurityKeyPermitAttestation, - base::Value::Type::LIST }, #endif // BUILDFLAG(ENABLE_EXTENSIONS) #endif // !defined(OS_MACOSX)
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc index 3d83b26..5242890 100644 --- a/chrome/browser/process_singleton_win.cc +++ b/chrome/browser/process_singleton_win.cc
@@ -220,7 +220,7 @@ DPLOG(ERROR) << "Unable to terminate process"; } UMA_HISTOGRAM_SPARSE_SLOWLY( - "Chrome.ProcessSingleton.ProcessTerminateErrorCode.Windows", + "Chrome.ProcessSingleton.TerminateProcessErrorCode.Windows", terminate_error); }
diff --git a/chrome/browser/process_singleton_win_unittest.cc b/chrome/browser/process_singleton_win_unittest.cc index 482197f..5106f885 100644 --- a/chrome/browser/process_singleton_win_unittest.cc +++ b/chrome/browser/process_singleton_win_unittest.cc
@@ -287,7 +287,7 @@ histogram_tester().ExpectTotalCount( "Chrome.ProcessSingleton.TerminateProcessTime", 1u); histogram_tester().ExpectUniqueSample( - "Chrome.ProcessSingleton.ProcessTerminateErrorCode.Windows", 0, 1u); + "Chrome.ProcessSingleton.TerminateProcessErrorCode.Windows", 0, 1u); histogram_tester().ExpectUniqueSample( "Chrome.ProcessSingleton.TerminationWaitErrorCode.Windows", 0, 1u); histogram_tester().ExpectUniqueSample( @@ -346,7 +346,7 @@ histogram_tester().ExpectTotalCount( "Chrome.ProcessSingleton.TerminateProcessTime", 1u); histogram_tester().ExpectUniqueSample( - "Chrome.ProcessSingleton.ProcessTerminateErrorCode.Windows", 0, 1u); + "Chrome.ProcessSingleton.TerminateProcessErrorCode.Windows", 0, 1u); histogram_tester().ExpectUniqueSample( "Chrome.ProcessSingleton.TerminationWaitErrorCode.Windows", 0, 1u); histogram_tester().ExpectUniqueSample(
diff --git a/chrome/browser/ui/tabs/tab_data_experimental.cc b/chrome/browser/ui/tabs/tab_data_experimental.cc index 6c43d3ef..3d398d9 100644 --- a/chrome/browser/ui/tabs/tab_data_experimental.cc +++ b/chrome/browser/ui/tabs/tab_data_experimental.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/ui/tabs/tab_data_experimental.h" #include "base/memory/ptr_util.h" +#include "base/strings/string_util.h" +#include "chrome/browser/ui/tab_ui_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model_experimental.h" #include "content/public/browser/web_contents.h" @@ -58,11 +60,43 @@ TabDataExperimental& TabDataExperimental::operator=(TabDataExperimental&&) = default; -base::string16 TabDataExperimental::GetTitle() const { +const GURL& TabDataExperimental::GetURL() const { + if (contents_) + return contents_->GetURL(); + return GURL::EmptyGURL(); +} + +const base::string16& TabDataExperimental::GetTitle() const { // TODO(brettw) this will need to use TabUIHelper. if (contents_) return contents_->GetTitle(); - return base::string16(); + return base::EmptyString16(); +} + +gfx::ImageSkia TabDataExperimental::GetFavicon() const { + TabUIHelper* tab_ui_helper = TabUIHelper::FromWebContents(contents_); + return tab_ui_helper->GetFavicon().AsImageSkia(); +} + +TabNetworkState TabDataExperimental::GetNetworkState() const { + if (contents_) + return TabNetworkStateForWebContents(contents_); + return TabNetworkState::kNone; +} + +bool TabDataExperimental::IsCrashed() const { + if (!contents_) + return false; + + auto crashed_status = contents_->GetCrashedStatus(); + return (crashed_status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED || +#if defined(OS_CHROMEOS) + crashed_status == + base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM || +#endif + crashed_status == base::TERMINATION_STATUS_PROCESS_CRASHED || + crashed_status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION || + crashed_status == base::TERMINATION_STATUS_LAUNCH_FAILED); } bool TabDataExperimental::CountsAsViewIndex() const {
diff --git a/chrome/browser/ui/tabs/tab_data_experimental.h b/chrome/browser/ui/tabs/tab_data_experimental.h index b270cd9d..50aacbc 100644 --- a/chrome/browser/ui/tabs/tab_data_experimental.h +++ b/chrome/browser/ui/tabs/tab_data_experimental.h
@@ -10,6 +10,10 @@ #include "base/macros.h" #include "base/strings/string16.h" +#include "chrome/browser/ui/tabs/tab_network_state.h" +#include "ui/gfx/image/image_skia.h" + +class GURL; namespace content { class WebContents; @@ -55,7 +59,11 @@ content::WebContents* contents() { return contents_; } - base::string16 GetTitle() const; + const GURL& GetURL() const; + const base::string16& GetTitle() const; + gfx::ImageSkia GetFavicon() const; + TabNetworkState GetNetworkState() const; + bool IsCrashed() const; // Returns true if this tab data itself is counted as a enumerable item when // going through the view.
diff --git a/chrome/browser/ui/tabs/tab_strip_model_experimental.cc b/chrome/browser/ui/tabs/tab_strip_model_experimental.cc index 59dcfdf..7a2b328 100644 --- a/chrome/browser/ui/tabs/tab_strip_model_experimental.cc +++ b/chrome/browser/ui/tabs/tab_strip_model_experimental.cc
@@ -295,8 +295,8 @@ if (parent->type() == TabDataExperimental::Type::kSingle) { // Promote parent to hub-and-spoke. parent->set_type(TabDataExperimental::Type::kHubAndSpoke); - for (auto& observer : exp_observers_) - observer.TabChanged(parent, TabChangeType::kAll); + for (auto& exp_observer : exp_observers_) + exp_observer.TabChanged(parent, TabChangeType::kAll); } parent->children_.push_back(std::make_unique<TabDataExperimental>( @@ -316,8 +316,8 @@ // Need to do this if we start insering in the middle. // selection_model_.IncrementFrom(index); - for (auto& observer : exp_observers_) - observer.TabInserted(data, active); + for (auto& exp_observer : exp_observers_) + exp_observer.TabInserted(data, active); for (auto& observer : observers()) observer.TabInsertedAt(this, contents, index, active); @@ -520,8 +520,12 @@ TabChangeType change_type) { ViewIterator found = FindViewIndex(view_index); DCHECK(found != end()); - for (auto& observer : exp_observers_) - observer.TabChanged(&*found, change_type); + + TabDataExperimental* data = &*found; + for (auto& observer : observers()) + observer.TabChangedAt(data->contents(), view_index, change_type); + for (auto& exp_observer : exp_observers_) + exp_observer.TabChanged(data, change_type); } void TabStripModelExperimental::SetTabNeedsAttentionAt(int index, @@ -545,7 +549,10 @@ } bool TabStripModelExperimental::TabsAreLoading() const { - NOTIMPLEMENTED(); + for (const auto& data : tabs_) { + if (data->contents() && data->contents()->IsLoading()) + return true; + } return false; } @@ -701,8 +708,8 @@ uint32_t close_types) { TabDataExperimental* data = GetDataForWebContents(contents); DCHECK(data); - for (auto& observer : exp_observers_) - observer.TabClosing(data); + for (auto& exp_observer : exp_observers_) + exp_observer.TabClosing(data); } void TabStripModelExperimental::DetachWebContents( @@ -738,8 +745,8 @@ // Erasing the last child of a hub and spoke one converts it back to // a single. parent->set_type(TabDataExperimental::Type::kSingle); - for (auto& observer : exp_observers_) - observer.TabChanged(parent, TabChangeType::kAll); + for (auto& exp_observer : exp_observers_) + exp_observer.TabChanged(parent, TabChangeType::kAll); } else { DCHECK(parent->type() == TabDataExperimental::Type::kGroup); // TODO(brettw) remove group. Notifications might be tricky. @@ -751,8 +758,8 @@ data->set_type(TabDataExperimental::Type::kGroup); data->contents_ = nullptr; // TODO(brettw) does this delete things properly? - for (auto& observer : exp_observers_) - observer.TabChanged(data, TabChangeType::kAll); + for (auto& exp_observer : exp_observers_) + exp_observer.TabChanged(data, TabChangeType::kAll); } else { // Just remove from tabs. tabs_.erase(tabs_.begin() + found.toplevel_index_); @@ -868,8 +875,8 @@ TabDataExperimental* old_data = GetDataForViewIndex(old_model.active()); TabDataExperimental* new_data = GetDataForViewIndex(selection_model_.active()); - for (auto& observer : exp_observers_) - observer.TabSelectionChanged(old_data, new_data); + for (auto& exp_observer : exp_observers_) + exp_observer.TabSelectionChanged(old_data, new_data); for (auto& observer : observers()) observer.TabSelectionChanged(this, old_model);
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 6117f50..c5560c2 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/ash_util.h" +#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_features.h" @@ -1535,7 +1536,11 @@ if (was_source_fullscreen_) { // In fullscreen mode it is only possible to get here if the source // was in "immersive fullscreen" mode, so toggle it back on. - GetAttachedBrowserWidget()->SetFullscreen(true); + BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( + GetAttachedBrowserWidget()->GetNativeWindow()); + DCHECK(browser_view); + if (!browser_view->IsFullscreen()) + chrome::ToggleFullscreenMode(browser_view->browser()); } #endif }
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index c8ece54..dc7ac813 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -1026,6 +1026,70 @@ EXPECT_TRUE(new_browser->window()->IsMaximized()); } +#if defined(OS_CHROMEOS) + +// This test makes sense only on Chrome OS where we have the immersive +// fullscreen mode. The detached tab to a new browser window should remain in +// immersive fullscreen mode. +IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, + DetachToOwnWindowWhileInImmersiveFullscreenMode) { + // Toggle the immersive fullscreen mode for the initial browser. + chrome::ToggleFullscreenMode(browser()); + ASSERT_TRUE(BrowserView::GetBrowserViewForBrowser(browser()) + ->immersive_mode_controller() + ->IsEnabled()); + + // Add another tab. + AddTabAndResetBrowser(browser()); + TabStripImpl* tab_strip = GetTabStripForBrowser(browser()); + + // Move to the first tab and drag it enough so that it detaches. + gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0))); + ASSERT_TRUE(PressInput(tab_0_center)); + ASSERT_TRUE(DragInputToNotifyWhenDone( + tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip), + base::Bind(&DetachToOwnWindowStep2, this))); + if (input_source() == INPUT_SOURCE_MOUSE) { + ASSERT_TRUE(ReleaseMouseAsync()); + QuitWhenNotDragging(); + } + + // Should no longer be dragging. + ASSERT_FALSE(tab_strip->IsDragSessionActive()); + ASSERT_FALSE(TabDragController::IsActive()); + + // There should now be another browser. + ASSERT_EQ(2u, browser_list->size()); + Browser* new_browser = browser_list->get(1); + ASSERT_TRUE(new_browser->window()->IsActive()); + TabStripImpl* tab_strip2 = GetTabStripForBrowser(new_browser); + ASSERT_FALSE(tab_strip2->IsDragSessionActive()); + + EXPECT_EQ("0", IDString(new_browser->tab_strip_model())); + EXPECT_EQ("1", IDString(browser()->tab_strip_model())); + + // The bounds of the initial window should not have changed. + EXPECT_TRUE(browser()->window()->IsFullscreen()); + ASSERT_TRUE(BrowserView::GetBrowserViewForBrowser(browser()) + ->immersive_mode_controller() + ->IsEnabled()); + + EXPECT_FALSE(GetIsDragged(browser())); + EXPECT_FALSE(GetIsDragged(new_browser)); + // After this both windows should still be manageable. + EXPECT_TRUE(IsWindowPositionManaged(browser()->window()->GetNativeWindow())); + EXPECT_TRUE( + IsWindowPositionManaged(new_browser->window()->GetNativeWindow())); + + // The new browser should be in immersive fullscreen mode. + ASSERT_TRUE(BrowserView::GetBrowserViewForBrowser(new_browser) + ->immersive_mode_controller() + ->IsEnabled()); + EXPECT_TRUE(new_browser->window()->IsFullscreen()); +} + +#endif + // Deletes a tab being dragged before the user moved enough to start a drag. IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, DeleteBeforeStartedDragging) {
diff --git a/chrome/browser/ui/views/tabs/tab_experimental.cc b/chrome/browser/ui/views/tabs/tab_experimental.cc index 9724eeb..1ae3388 100644 --- a/chrome/browser/ui/views/tabs/tab_experimental.cc +++ b/chrome/browser/ui/views/tabs/tab_experimental.cc
@@ -5,12 +5,18 @@ #include "chrome/browser/ui/views/tabs/tab_experimental.h" #include "chrome/browser/themes/theme_properties.h" +#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/tab_contents/core_tab_helper.h" #include "chrome/browser/ui/tabs/tab_strip_model_experimental.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/tabs/tab_close_button.h" +#include "chrome/browser/ui/views/tabs/tab_icon.h" +#include "chrome/grit/generated_resources.h" +#include "components/grit/components_scaled_resources.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/theme_provider.h" +#include "ui/gfx/favicon_size.h" #include "ui/views/border.h" #include "ui/views/controls/label.h" #include "ui/views/masked_targeter_delegate.h" @@ -18,6 +24,7 @@ namespace { +constexpr int kExtraLeftPaddingToBalanceCloseButtonPadding = 2; constexpr int kAfterTitleSpacing = 4; // Returns the width of the tab endcap in DIP. More precisely, this is the @@ -43,7 +50,10 @@ model_(model), data_(data), type_(data->type()), + icon_(new TabIcon), title_(new views::Label), + close_button_( + new TabCloseButton(this, base::BindRepeating(&OnMouseEventInTab))), hover_controller_(this), paint_(this) { title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); @@ -51,12 +61,9 @@ title_->SetHandlesTooltips(false); title_->SetAutoColorReadabilityEnabled(false); title_->SetText(CoreTabHelper::GetDefaultTitle()); - AddChildView(title_); - // Unretained is safe here because this class outlives its close button, and - // the controller outlives this Tab. - close_button_ = - new TabCloseButton(this, base::BindRepeating(&OnMouseEventInTab)); + AddChildView(icon_); + AddChildView(title_); AddChildView(close_button_); SetEventTargeter(std::make_unique<views::ViewTargeter>(this)); @@ -94,17 +101,39 @@ } void TabExperimental::DataUpdated(TabChangeType change_type) { + // Need to do network state first since the tab title depends on it. + // TODO(brettw) should_hide_throbber param. + icon_->SetNetworkState(data_->GetNetworkState(), false); + // TODO(brettw) icon layer painting. if (change_type == TabChangeType::kLoadingOnly) - return; // TODO(brettw) need to add throbber support. + return; + // Tab title. + base::string16 title = data_->GetTitle(); + if (title.empty()) { + title = icon_->ShowingLoadingAnimation() + ? l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) + : CoreTabHelper::GetDefaultTitle(); + } else { + Browser::FormatTitleForDisplay(&title); + } title_->SetText(data_->GetTitle()); + // TODO(brettw) attention indicators when title not loading changes. if (change_type == TabChangeType::kTitleNotLoading) return; // Don't need to update anything else. + icon_->SetIcon(data_->GetURL(), data_->GetFavicon()); + icon_->SetIsCrashed(data_->IsCrashed()); type_ = data_->type(); + SchedulePaint(); } +void TabExperimental::StepLoadingAnimation() { + icon_->StepLoadingAnimation(); + // TODO(brettw) throbber layer for faster painting. +} + void TabExperimental::SetGroupLayoutParams(int first_child_begin_x) { first_child_begin_x_ = first_child_begin_x; } @@ -147,7 +176,14 @@ constexpr int kTitleSpacing = 6; const gfx::Rect bounds = GetContentsBounds(); - int title_left = bounds.x() + kTitleSpacing; + // Icon. + int favicon_y = bounds.y() + (bounds.height() - gfx::kFaviconSize + 1) / 2; + gfx::Rect favicon_bounds( + bounds.x() + kExtraLeftPaddingToBalanceCloseButtonPadding, favicon_y, + icon_->GetPreferredSize().width(), bounds.height() - favicon_y); + icon_->SetBoundsRect(favicon_bounds); + + int title_left = favicon_bounds.right() + kTitleSpacing; int title_right; if (first_child_begin_x_ >= 0) title_right = first_child_begin_x_; @@ -175,8 +211,6 @@ void TabExperimental::OnThemeChanged() { OnButtonColorMaybeChanged(); - // TODO(brettw) favicons. - // favicon_ = gfx::ImageSkia(); } bool TabExperimental::OnMousePressed(const ui::MouseEvent& event) {
diff --git a/chrome/browser/ui/views/tabs/tab_experimental.h b/chrome/browser/ui/views/tabs/tab_experimental.h index 76f9b2f..dc69aa1 100644 --- a/chrome/browser/ui/views/tabs/tab_experimental.h +++ b/chrome/browser/ui/views/tabs/tab_experimental.h
@@ -16,6 +16,7 @@ class TabCloseButton; class TabDataExperimental; +class TabIcon; class TabStripModelExperimental; namespace views { @@ -62,6 +63,9 @@ void SetSelected(bool selected); void DataUpdated(TabChangeType change_type); + // Redraws the loading animation if one is visible. Otherwise, no-op. + void StepLoadingAnimation(); + // Called for group types when layout is done to set the bounds of the // first tab. This is used to determine some painting parameters. void SetGroupLayoutParams(int first_child_begin_x); @@ -105,8 +109,9 @@ bool closing_ = false; // Non-owning child view pointers (owned by View hierarchy). + TabIcon* icon_; views::Label* title_; - TabCloseButton* close_button_ = nullptr; + TabCloseButton* close_button_; // Location of the first child tab. Negative indicates unused. int first_child_begin_x_ = -1;
diff --git a/chrome/browser/ui/views/tabs/tab_strip_experimental.cc b/chrome/browser/ui/views/tabs/tab_strip_experimental.cc index 355b5596..879cffb4 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_experimental.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_experimental.cc
@@ -353,7 +353,8 @@ } void TabStripExperimental::UpdateLoadingAnimations() { - // controller_->UpdateLoadingAnimations(); + for (const auto& tab : tabs_) + tab.second->StepLoadingAnimation(); } gfx::Rect TabStripExperimental::GetNewTabButtonBounds() {
diff --git a/chrome/browser/ui/views/tabs/tab_strip_impl.cc b/chrome/browser/ui/views/tabs/tab_strip_impl.cc index cb8add0..320e6184 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_impl.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_impl.cc
@@ -72,6 +72,7 @@ #include "ui/views/window/non_client_view.h" #if defined(OS_WIN) +#include "base/win/windows_version.h" #include "ui/display/win/screen_win.h" #include "ui/gfx/win/hwnd_util.h" #include "ui/views/win/hwnd_util.h" @@ -725,7 +726,7 @@ #else static const SkAlpha kInactiveTabAlphaGlass = 200; static const SkAlpha kInactiveTabAlphaOpaque = 255; - const SkAlpha base_alpha = GetWidget()->ShouldWindowContentsBeTransparent() + const SkAlpha base_alpha = TitlebarBackgroundIsTransparent() ? kInactiveTabAlphaGlass : kInactiveTabAlphaOpaque; #endif // OS_CHROMEOS @@ -1020,7 +1021,7 @@ int TabStripImpl::GetBackgroundResourceId(bool* custom_image) const { const ui::ThemeProvider* tp = GetThemeProvider(); - if (GetWidget()->ShouldWindowContentsBeTransparent()) { + if (TitlebarBackgroundIsTransparent()) { const int kBackgroundIdGlass = IDR_THEME_TAB_BACKGROUND_V; *custom_image = tp->HasCustomImage(kBackgroundIdGlass); return kBackgroundIdGlass; @@ -1411,6 +1412,16 @@ return in_tab_close_; } +bool TabStripImpl::TitlebarBackgroundIsTransparent() const { +#if defined(OS_WIN) + // Windows 8+ uses transparent window contents (because the titlebar area is + // drawn by the system and not Chrome), but the actual titlebar is opaque. + if (base::win::GetVersion() >= base::win::VERSION_WIN8) + return false; +#endif + return GetWidget()->ShouldWindowContentsBeTransparent(); +} + void TabStripImpl::DoLayout() { last_layout_size_ = size();
diff --git a/chrome/browser/ui/views/tabs/tab_strip_impl.h b/chrome/browser/ui/views/tabs/tab_strip_impl.h index b6db4c8..81f3fd4 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_impl.h +++ b/chrome/browser/ui/views/tabs/tab_strip_impl.h
@@ -316,6 +316,9 @@ // Returns whether the highlight button should be highlighted after a remove. bool ShouldHighlightCloseButtonAfterRemove(); + // Returns whether the window background behind the tabstrip is transparent. + bool TitlebarBackgroundIsTransparent() const; + // Invoked from Layout if the size changes or layout is really needed. void DoLayout();
diff --git a/chrome/browser/ui/webui/chromeos/internet_config_dialog.cc b/chrome/browser/ui/webui/chromeos/internet_config_dialog.cc index 0426dd3..085857acd 100644 --- a/chrome/browser/ui/webui/chromeos/internet_config_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/internet_config_dialog.cc
@@ -37,6 +37,7 @@ {"internetJoinType", IDS_SETTINGS_INTERNET_JOIN_TYPE}, {"networkButtonConnect", IDS_SETTINGS_INTERNET_BUTTON_CONNECT}, {"cancel", IDS_CANCEL}, + {"close", IDS_CANCEL}, {"save", IDS_SAVE}, }; for (const auto& entry : localized_strings)
diff --git a/chrome/browser/ui/webui/chromeos/internet_detail_dialog.cc b/chrome/browser/ui/webui/chromeos/internet_detail_dialog.cc index f5f6ed3..327acb5 100644 --- a/chrome/browser/ui/webui/chromeos/internet_detail_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/internet_detail_dialog.cc
@@ -37,6 +37,8 @@ const char* name; int id; } localized_strings[] = { + {"cancel", IDS_CANCEL}, + {"close", IDS_CLOSE}, {"networkButtonConnect", IDS_SETTINGS_INTERNET_BUTTON_CONNECT}, {"networkButtonDisconnect", IDS_SETTINGS_INTERNET_BUTTON_DISCONNECT}, {"networkIPAddress", IDS_SETTINGS_INTERNET_NETWORK_IP_ADDRESS},
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index 5927cd3..afadab0 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -82,6 +82,8 @@ "elements/text.h", "elements/text_input.cc", "elements/text_input.h", + "elements/text_texture.cc", + "elements/text_texture.h", "elements/textured_element.cc", "elements/textured_element.h", "elements/throbber.cc",
diff --git a/chrome/browser/vr/elements/text.cc b/chrome/browser/vr/elements/text.cc index 8795efed..a505f774 100644 --- a/chrome/browser/vr/elements/text.cc +++ b/chrome/browser/vr/elements/text.cc
@@ -6,7 +6,7 @@ #include "base/memory/ptr_util.h" #include "cc/paint/skia_paint_canvas.h" -#include "chrome/browser/vr/elements/ui_texture.h" +#include "chrome/browser/vr/elements/text_texture.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font_list.h" #include "ui/gfx/geometry/rect.h" @@ -15,49 +15,6 @@ namespace vr { -class TextTexture : public UiTexture { - public: - explicit TextTexture(float font_height) : font_height_(font_height) {} - ~TextTexture() override {} - - void SetText(const base::string16& text) { SetAndDirty(&text_, text); } - - void SetColor(SkColor color) { SetAndDirty(&color_, color); } - - void SetAlignment(TextAlignment alignment) { - SetAndDirty(&alignment_, alignment); - } - - void SetMultiLine(bool multiline) { SetAndDirty(&multiline_, multiline); } - - void SetTextWidth(float width) { SetAndDirty(&text_width_, width); } - - int rendered_lines() { return rendered_lines_; } - - private: - gfx::Size GetPreferredTextureSize(int width) const override { - return gfx::Size(width, width); - } - - gfx::SizeF GetDrawnSize() const override { return size_; } - - void Draw(SkCanvas* sk_canvas, const gfx::Size& texture_size) override; - - gfx::SizeF size_; - base::string16 text_; - // These dimensions are in meters. - float font_height_ = 0; - float text_width_ = 0; - TextAlignment alignment_ = kTextAlignmentCenter; - bool multiline_ = true; - SkColor color_ = SK_ColorBLACK; - - // The number of lines generated in the last draw operation. - int rendered_lines_ = 0; - - DISALLOW_COPY_AND_ASSIGN(TextTexture); -}; - Text::Text(int maximum_width_pixels, float font_height_meters) : TexturedElement(maximum_width_pixels), texture_(base::MakeUnique<TextTexture>(font_height_meters)) {} @@ -83,44 +40,11 @@ texture_->SetTextWidth(size.width()); } -int Text::NumRenderedLinesForTest() const { - return texture_->rendered_lines(); -} - -UiTexture* Text::GetTexture() const { +TextTexture* Text::GetTextureForTest() { return texture_.get(); } -void TextTexture::Draw(SkCanvas* sk_canvas, const gfx::Size& texture_size) { - cc::SkiaPaintCanvas paint_canvas(sk_canvas); - gfx::Canvas gfx_canvas(&paint_canvas, 1.0f); - gfx::Canvas* canvas = &gfx_canvas; - - gfx::FontList fonts; - float pixels_per_meter = texture_size.width() / text_width_; - int pixel_font_height = static_cast<int>(font_height_ * pixels_per_meter); - GetDefaultFontList(pixel_font_height, text_, &fonts); - gfx::Rect text_bounds(texture_size.width(), - multiline_ ? 0 : texture_size.height()); - - std::vector<std::unique_ptr<gfx::RenderText>> lines = - // TODO(vollick): if this subsumes all text, then we should probably move - // this function into this class. - PrepareDrawStringRect( - text_, fonts, color_, &text_bounds, alignment_, - multiline_ ? kWrappingBehaviorWrap : kWrappingBehaviorNoWrap); - - // Draw the text. - for (auto& render_text : lines) - render_text->Draw(canvas); - - // Note, there is no padding here whatsoever. - size_ = gfx::SizeF(text_bounds.size()); - - rendered_lines_ = lines.size(); -} - -UiTexture* Text::GetTextureForTest() const { +UiTexture* Text::GetTexture() const { return texture_.get(); }
diff --git a/chrome/browser/vr/elements/text.h b/chrome/browser/vr/elements/text.h index f8a3891..7eea71f4 100644 --- a/chrome/browser/vr/elements/text.h +++ b/chrome/browser/vr/elements/text.h
@@ -22,15 +22,12 @@ void SetText(const base::string16& text); void SetColor(SkColor color); - void SetTextAlignment(UiTexture::TextAlignment alignment); void SetMultiLine(bool multiline); void OnSetSize(gfx::SizeF size) override; - int NumRenderedLinesForTest() const; - - UiTexture* GetTextureForTest() const; + TextTexture* GetTextureForTest(); private: UiTexture* GetTexture() const override;
diff --git a/chrome/browser/vr/elements/text_texture.cc b/chrome/browser/vr/elements/text_texture.cc new file mode 100644 index 0000000..b3fad1d --- /dev/null +++ b/chrome/browser/vr/elements/text_texture.cc
@@ -0,0 +1,80 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/elements/text_texture.h" + +#include "base/memory/ptr_util.h" +#include "cc/paint/skia_paint_canvas.h" +#include "chrome/browser/vr/elements/ui_texture.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/font_list.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/render_text.h" + +namespace vr { + +TextTexture::TextTexture(float font_height) : font_height_(font_height) {} + +TextTexture::~TextTexture() {} + +void TextTexture::SetText(const base::string16& text) { + SetAndDirty(&text_, text); +} + +void TextTexture::SetColor(SkColor color) { + SetAndDirty(&color_, color); +} + +void TextTexture::SetAlignment(TextAlignment alignment) { + SetAndDirty(&alignment_, alignment); +} + +void TextTexture::SetMultiLine(bool multiline) { + SetAndDirty(&multiline_, multiline); +} + +void TextTexture::SetTextWidth(float width) { + SetAndDirty(&text_width_, width); +} + +gfx::SizeF TextTexture::GetDrawnSize() const { + return size_; +} + +std::vector<std::unique_ptr<gfx::RenderText>> TextTexture::LayOutText( + const gfx::Size& texture_size) { + gfx::FontList fonts; + float pixels_per_meter = texture_size.width() / text_width_; + int pixel_font_height = static_cast<int>(font_height_ * pixels_per_meter); + GetDefaultFontList(pixel_font_height, text_, &fonts); + gfx::Rect text_bounds(texture_size.width(), 0); + + std::vector<std::unique_ptr<gfx::RenderText>> lines = + // TODO(vollick): if this subsumes all text, then we should probably move + // this function into this class. + PrepareDrawStringRect( + text_, fonts, color_, &text_bounds, alignment_, + multiline_ ? kWrappingBehaviorWrap : kWrappingBehaviorNoWrap); + + // Note, there is no padding here whatsoever. + size_ = gfx::SizeF(text_bounds.size()); + + return lines; +} + +gfx::Size TextTexture::GetPreferredTextureSize(int width) const { + return gfx::Size(width, width); +} + +void TextTexture::Draw(SkCanvas* sk_canvas, const gfx::Size& texture_size) { + cc::SkiaPaintCanvas paint_canvas(sk_canvas); + gfx::Canvas gfx_canvas(&paint_canvas, 1.0f); + gfx::Canvas* canvas = &gfx_canvas; + + auto lines = LayOutText(texture_size); + for (auto& render_text : lines) + render_text->Draw(canvas); +} + +} // namespace vr
diff --git a/chrome/browser/vr/elements/text_texture.h b/chrome/browser/vr/elements/text_texture.h new file mode 100644 index 0000000..f0cdb50f --- /dev/null +++ b/chrome/browser/vr/elements/text_texture.h
@@ -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. + +#ifndef CHROME_BROWSER_VR_ELEMENTS_TEXT_TEXTURE_H_ +#define CHROME_BROWSER_VR_ELEMENTS_TEXT_TEXTURE_H_ + +#include <memory> + +#include "chrome/browser/vr/elements/textured_element.h" +#include "chrome/browser/vr/elements/ui_texture.h" +#include "third_party/skia/include/core/SkColor.h" + +namespace gfx { +class RenderText; +} + +namespace vr { + +class TextTexture : public UiTexture { + public: + explicit TextTexture(float font_height); + ~TextTexture() override; + + void SetText(const base::string16& text); + void SetColor(SkColor color); + void SetAlignment(TextAlignment alignment); + void SetMultiLine(bool multiline); + void SetTextWidth(float width); + + gfx::SizeF GetDrawnSize() const override; + + // This method does all text preparation for the element other than drawing to + // the texture. This allows for deeper unit testing of the Text element + // without having to mock canvases and simulate frame rendering. The state of + // the texture is modified here. + std::vector<std::unique_ptr<gfx::RenderText>> LayOutText( + const gfx::Size& texture_size); + + private: + gfx::Size GetPreferredTextureSize(int width) const override; + void Draw(SkCanvas* sk_canvas, const gfx::Size& texture_size) override; + + gfx::SizeF size_; + base::string16 text_; + // These dimensions are in meters. + float font_height_ = 0; + float text_width_ = 0; + TextAlignment alignment_ = kTextAlignmentCenter; + bool multiline_ = true; + SkColor color_ = SK_ColorBLACK; + + DISALLOW_COPY_AND_ASSIGN(TextTexture); +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_ELEMENTS_TEXT_TEXTURE_H_
diff --git a/chrome/browser/vr/elements/text_unittest.cc b/chrome/browser/vr/elements/text_unittest.cc index 475634cf..976cb8b 100644 --- a/chrome/browser/vr/elements/text_unittest.cc +++ b/chrome/browser/vr/elements/text_unittest.cc
@@ -6,48 +6,42 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" -#include "cc/test/test_skcanvas.h" -#include "chrome/browser/vr/ui_scene.h" +#include "chrome/browser/vr/elements/text_texture.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/render_text.h" namespace vr { TEST(Text, MultiLine) { - UiScene scene; - testing::NiceMock<cc::MockCanvas> canvas; - const float kInitialSize = 1.0f; - const int kPixelWidth = 512; + const gfx::Size texture_size({512, 512}); // Create an initialize a text element with a long string. - auto text_instance = base::MakeUnique<Text>(kPixelWidth, 0.020); - Text* text = text_instance.get(); + auto text = base::MakeUnique<Text>(texture_size.width(), 0.020); text->SetSize(kInitialSize, 0); text->SetText(base::UTF8ToUTF16(std::string(1000, 'x'))); - text->SetInitializedForTesting(); - scene.AddUiElement(kRoot, std::move(text_instance)); - // Grab a pointer to the underlying texture to inspect it directly. - UiTexture* texture = text->GetTextureForTest(); - auto texture_size = texture->GetPreferredTextureSize(kPixelWidth); + TextTexture* texture = text->GetTextureForTest(); // Make sure we get multiple lines of rendered text from the string. - scene.OnBeginFrame(base::TimeTicks(), {0, 0, 0}); - texture->DrawAndLayout(&canvas, texture_size); - int initial_num_lines = text->NumRenderedLinesForTest(); - EXPECT_GT(initial_num_lines, 1); + auto layout = texture->LayOutText(texture_size); + size_t initial_num_lines = layout.size(); + auto initial_size = texture->GetDrawnSize(); + EXPECT_GT(initial_num_lines, 1u); + EXPECT_GT(initial_size.height(), 0.f); - // Reduce the field width, and ensure that the number of lines increases. + // Reduce the field width, and ensure that the number of lines increases along + // with the texture height. text->SetSize(kInitialSize / 2, 0); - scene.OnBeginFrame(base::TimeTicks(), {0, 0, 0}); - texture->DrawAndLayout(&canvas, texture_size); - EXPECT_GT(text->NumRenderedLinesForTest(), initial_num_lines); + layout = texture->LayOutText(texture_size); + EXPECT_GT(layout.size(), initial_num_lines); + EXPECT_GT(texture->GetDrawnSize().height(), initial_size.height()); // Enforce single-line rendering. text->SetMultiLine(false); - scene.OnBeginFrame(base::TimeTicks(), {0, 0, 0}); - texture->DrawAndLayout(&canvas, texture_size); - EXPECT_EQ(1, text->NumRenderedLinesForTest()); + layout = texture->LayOutText(texture_size); + EXPECT_EQ(layout.size(), 1u); + EXPECT_LT(texture->GetDrawnSize().height(), initial_size.height()); } } // namespace vr
diff --git a/chrome/browser/vr/elements/ui_texture.cc b/chrome/browser/vr/elements/ui_texture.cc index fc05c24..8887357 100644 --- a/chrome/browser/vr/elements/ui_texture.cc +++ b/chrome/browser/vr/elements/ui_texture.cc
@@ -69,9 +69,9 @@ DCHECK(bounds); std::vector<std::unique_ptr<gfx::RenderText>> lines; - gfx::Rect rect(*bounds); if (wrapping_behavior == kWrappingBehaviorWrap) { + gfx::Rect rect(*bounds); std::vector<base::string16> strings; gfx::ElideRectangleText(text, font_list, bounds->width(), bounds->height() ? bounds->height() : INT_MAX, @@ -108,18 +108,13 @@ CreateConfiguredRenderText(text, font_list, color, text_alignment); if (bounds->width() != 0) render_text->SetElideBehavior(gfx::TRUNCATE); - else - rect.set_width(INT_MAX); - render_text->SetDisplayRect(rect); + if (bounds->width() == 0) + bounds->set_width(render_text->GetStringSize().width()); + if (bounds->height() == 0) + bounds->set_height(render_text->GetStringSize().height()); - if (bounds->width() == 0) { - int text_width = render_text->GetStringSize().width(); - bounds->set_width(text_width); - rect.set_width(text_width); - render_text->SetDisplayRect(rect); - } - + render_text->SetDisplayRect(*bounds); lines.push_back(std::move(render_text)); } return lines;
diff --git a/chrome/browser/vr/metrics_helper.cc b/chrome/browser/vr/metrics_helper.cc index a2b5fbd6..0fd8471a 100644 --- a/chrome/browser/vr/metrics_helper.cc +++ b/chrome/browser/vr/metrics_helper.cc
@@ -13,22 +13,31 @@ namespace { -constexpr char kStatusVr[] = "VR.AssetsComponent.Status.OnEnter.VR"; +constexpr char kStatusVr[] = "VR.Component.Assets.Status.OnEnter.AllVR"; constexpr char kStatusVrBrowsing[] = - "VR.AssetsComponent.Status.OnEnter.VRBrowsing"; -constexpr char kStatusWebVr[] = "VR.AssetsComponent.Status.OnEnter.WebVR"; + "VR.Component.Assets.Status.OnEnter.VRBrowsing"; +constexpr char kStatusWebVr[] = + "VR.Component.Assets.Status.OnEnter.WebVRPresentation"; constexpr char kLatencyVrBrowsing[] = - "VR.AssetsComponent.ReadyLatency.OnEnter.VRBrowsing"; + "VR.Component.Assets.DurationUntilReady.OnEnter.VRBrowsing"; constexpr char kLatencyWebVr[] = - "VR.AssetsComponent.ReadyLatency.OnEnter.WebVR"; -constexpr char kComponentUpdateStatus[] = "VR.AssetsComponent.UpdateStatus"; -constexpr char kAssetsLoadStatus[] = "VR.AssetsComponent.LoadStatus"; -constexpr char kDataConnectionRegisterComponent[] = - "VR.DataConnection.OnRegisterAssetsComponent"; -constexpr char kDataConnectionVr[] = "VR.DataConnection.OnEnter.VR"; -constexpr char kDataConnectionVrBrowsing[] = - "VR.DataConnection.OnEnter.VRBrowsing"; -constexpr char kDataConnectionWebVr[] = "VR.DataConnection.OnEnter.WebVR"; + "VR.Component.Assets.DurationUntilReady.OnEnter.WebVRPresentation"; +constexpr char kLatencyLaunchBrowser[] = + "VR.Component.Assets.DurationUntilReady.OnChromeStart"; +// TODO(tiborg): Rename VRAssetsComponentStatus and VRAssetsLoadStatus in +// enums.xml and consider merging them. +constexpr char kComponentUpdateStatus[] = + "VR.Component.Assets.VersionAndStatus.OnUpdate"; +constexpr char kAssetsLoadStatus[] = + "VR.Component.Assets.VersionAndStatus.OnLoad"; +constexpr char kNetworkConnectionTypeRegisterComponent[] = + "VR.NetworkConnectionType.OnRegisterComponent"; +constexpr char kNetworkConnectionTypeVr[] = + "VR.NetworkConnectionType.OnEnter.AllVR"; +constexpr char kNetworkConnectionTypeVrBrowsing[] = + "VR.NetworkConnectionType.OnEnter.VRBrowsing"; +constexpr char kNetworkConnectionTypeWebVr[] = + "VR.NetworkConnectionType.OnEnter.WebVRPresentation"; const auto kMinLatency = base::TimeDelta::FromMilliseconds(500); const auto kMaxLatency = base::TimeDelta::FromHours(1); @@ -85,17 +94,17 @@ switch (mode) { case Mode::kVr: UMA_HISTOGRAM_ENUMERATION( - kDataConnectionVr, type, + kNetworkConnectionTypeVr, type, net::NetworkChangeNotifier::ConnectionType::CONNECTION_LAST + 1); return; case Mode::kVrBrowsing: UMA_HISTOGRAM_ENUMERATION( - kDataConnectionVrBrowsing, type, + kNetworkConnectionTypeVrBrowsing, type, net::NetworkChangeNotifier::ConnectionType::CONNECTION_LAST + 1); return; case Mode::kWebVr: UMA_HISTOGRAM_ENUMERATION( - kDataConnectionWebVr, type, + kNetworkConnectionTypeWebVr, type, net::NetworkChangeNotifier::ConnectionType::CONNECTION_LAST + 1); return; default: @@ -132,6 +141,15 @@ LogLatencyIfWaited(Mode::kVrBrowsing, now); LogLatencyIfWaited(Mode::kWebVr, now); OnComponentUpdated(AssetsComponentUpdateStatus::kSuccess, version); + + if (logged_ready_duration_on_chrome_start_) { + return; + } + DCHECK(chrome_start_time_); + auto ready_duration = now - *chrome_start_time_; + UMA_HISTOGRAM_CUSTOM_TIMES(kLatencyLaunchBrowser, ready_duration, kMinLatency, + kMaxLatency, kLatencyBucketCount); + logged_ready_duration_on_chrome_start_ = true; } void MetricsHelper::OnEnter(Mode mode) { @@ -153,7 +171,7 @@ void MetricsHelper::OnRegisteredComponent() { UMA_HISTOGRAM_ENUMERATION( - kDataConnectionRegisterComponent, + kNetworkConnectionTypeRegisterComponent, net::NetworkChangeNotifier::GetConnectionType(), net::NetworkChangeNotifier::ConnectionType::CONNECTION_LAST + 1); } @@ -175,6 +193,12 @@ EncodeVersionStatus(component_version, static_cast<int>(status))); } +void MetricsHelper::OnChromeStarted() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!chrome_start_time_); + chrome_start_time_ = base::Time::Now(); +} + base::Optional<base::Time>& MetricsHelper::GetEnterTime(Mode mode) { switch (mode) { case Mode::kVr:
diff --git a/chrome/browser/vr/metrics_helper.h b/chrome/browser/vr/metrics_helper.h index c27f1a88..3a23309 100644 --- a/chrome/browser/vr/metrics_helper.h +++ b/chrome/browser/vr/metrics_helper.h
@@ -35,6 +35,7 @@ const base::Optional<base::Version>& version); void OnAssetsLoaded(AssetsLoadStatus status, const base::Version& component_version); + void OnChromeStarted(); private: base::Optional<base::Time>& GetEnterTime(Mode mode); @@ -43,6 +44,8 @@ base::Optional<base::Time> enter_vr_time_; base::Optional<base::Time> enter_vr_browsing_time_; base::Optional<base::Time> enter_web_vr_time_; + base::Optional<base::Time> chrome_start_time_; + bool logged_ready_duration_on_chrome_start_ = false; bool component_ready_ = false; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index fb5fc44..4a9ff34 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -33,7 +33,7 @@ "UnsafelyTreatInsecureOriginAsSecure": { "os": ["win", "linux", "max", "chromeos", "android"], "test_policy": { "UnsafelyTreatInsecureOriginAsSecure": ["http://example.com/"] }, - "pref_mappings": [ { "pref": "unsafely_treat_insecure_origin_as_securex" } ] + "pref_mappings": [ { "pref": "unsafely_treat_insecure_origin_as_secure" } ] }, "HomepageLocation": {
diff --git a/components/arc/connection_holder.h b/components/arc/connection_holder.h index 72cd647..4c6fb0d 100644 --- a/components/arc/connection_holder.h +++ b/components/arc/connection_holder.h
@@ -107,8 +107,10 @@ explicit ConnectionHolderImpl(ConnectionNotifier* connection_notifier) : connection_notifier_(connection_notifier), weak_ptr_factory_(this) {} - InstanceType* instance() { return instance_; } - uint32_t instance_version() const { return instance_version_; } + InstanceType* instance() { return IsConnected() ? instance_ : nullptr; } + uint32_t instance_version() const { + return IsConnected() ? instance_version_ : 0; + } // Returns true if |binding_| is set. bool IsConnected() const { return binding_.get(); } @@ -130,8 +132,6 @@ // Sets (or resets if |instance| is nullptr) the instance. void SetInstance(InstanceType* instance, uint32_t version = InstanceType::version_) { - DCHECK(instance == nullptr || instance_ == nullptr); - // Note: This can be called with nullptr even if |instance_| is still // nullptr for just in case clean up purpose. No-op in such a case. if (instance == instance_) @@ -143,29 +143,31 @@ } private: - // Called when |instance_| or |host_| is updated from null to non-null or - // from non-null to null. + // Called when |instance_| or |host_| are updated. void OnChanged() { - if (instance_ && host_) { - // When both get ready, start connection. - // TODO(crbug.com/750563): Fix the race issue. - binding_ = std::make_unique<mojo::Binding<HostType>>(host_); - mojo::InterfacePtr<HostType> host_proxy; - binding_->Bind(mojo::MakeRequest(&host_proxy)); - // Note: because the callback will be destroyed with |binding_|, - // base::Unretained() can be safely used. - binding_->set_connection_error_handler(base::BindOnce( - &mojo::Binding<HostType>::Close, base::Unretained(binding_.get()))); - - // Call the appropriate version of Init(). - CallInstanceInit<InstanceType>(std::move(host_proxy), - HasInitDeprecated<InstanceType>()); - } else if (binding_.get()) { - // Otherwise, the connection is closed. If it was connected, - // reset the host binding and notify. - binding_.reset(); - connection_notifier_->NotifyConnectionClosed(); + // Cancel any in-flight connection requests. This also prevents Observers + // from being notified of a spurious OnConnectionClosed() before an + // OnConnectionReady() event. + weak_ptr_factory_.InvalidateWeakPtrs(); + if (binding_.get()) { + // Regardless of what has changed, the old connection is now stale. Reset + // the current binding and notify any listeners. Since |binding_| is set + // just before the OnConnectionReady() event, we never notify observers of + // OnConnectionClosed() without seeing the former event first. + if (instance_ && host_) + LOG(ERROR) << "Unbinding instance of a stale connection"; + OnConnectionClosed(); } + if (!instance_ || !host_) + return; + // When both the instance and host are ready, start connection. + // TODO(crbug.com/750563): Fix the race issue. + auto binding = std::make_unique<mojo::Binding<HostType>>(host_); + mojo::InterfacePtr<HostType> host_proxy; + binding->Bind(mojo::MakeRequest(&host_proxy)); + // Call the appropriate version of Init(). + CallInstanceInit<InstanceType>(std::move(host_proxy), std::move(binding), + HasInitDeprecated<InstanceType>()); } // Dispatches the correct version of Init(). The template type is needed @@ -174,52 +176,84 @@ // std::false_type) refers to whether InstanceType::DeprecatedInit() exists. template <class T> typename std::enable_if<CountInitArgs<T>::value == 2, void>::type - CallInstanceInit(mojo::InterfacePtr<HostType> host_proxy, std::true_type) { + CallInstanceInit(mojo::InterfacePtr<HostType> host_proxy, + std::unique_ptr<mojo::Binding<HostType>> binding, + std::true_type) { if (instance_version_ < InstanceType::kInitMinVersion) { // The instance is too old to know about the new Init() version. For now, // call the deprecated version for backwards-compatibility. // TODO(crbug.com/750563): Deprecate this version. - CallInstanceInitDeprecated(std::move(host_proxy), + CallInstanceInitDeprecated(std::move(host_proxy), std::move(binding), HasInitDeprecated<InstanceType>()); return; } - instance_->Init(std::move(host_proxy), - base::BindOnce(&ConnectionHolderImpl::OnConnectionReady, - weak_ptr_factory_.GetWeakPtr())); + instance_->Init( + std::move(host_proxy), + base::BindOnce(&ConnectionHolderImpl::OnConnectionReady, + weak_ptr_factory_.GetWeakPtr(), std::move(binding))); } template <class T> typename std::enable_if<CountInitArgs<T>::value == 2, void>::type - CallInstanceInit(mojo::InterfacePtr<HostType> host_proxy, std::false_type) { - instance_->Init(std::move(host_proxy), - base::BindOnce(&ConnectionHolderImpl::OnConnectionReady, - weak_ptr_factory_.GetWeakPtr())); + CallInstanceInit(mojo::InterfacePtr<HostType> host_proxy, + std::unique_ptr<mojo::Binding<HostType>> binding, + std::false_type) { + instance_->Init( + std::move(host_proxy), + base::BindOnce(&ConnectionHolderImpl::OnConnectionReady, + weak_ptr_factory_.GetWeakPtr(), std::move(binding))); } // TODO(crbug.com/750563): Deprecate this version. template <class T> typename std::enable_if<CountInitArgs<T>::value == 1, void>::type - CallInstanceInit(mojo::InterfacePtr<HostType> host_proxy, ...) { + CallInstanceInit(mojo::InterfacePtr<HostType> host_proxy, + std::unique_ptr<mojo::Binding<HostType>> binding, + ...) { instance_->Init(std::move(host_proxy)); - OnConnectionReady(); + OnConnectionReady(std::move(binding)); } - void CallInstanceInitDeprecated(mojo::InterfacePtr<HostType> host_proxy, - std::true_type) { + void CallInstanceInitDeprecated( + mojo::InterfacePtr<HostType> host_proxy, + std::unique_ptr<mojo::Binding<HostType>> binding, + std::true_type) { instance_->InitDeprecated(std::move(host_proxy)); - OnConnectionReady(); + OnConnectionReady(std::move(binding)); } - void CallInstanceInitDeprecated(mojo::InterfacePtr<HostType> host_proxy, - std::false_type) { + void CallInstanceInitDeprecated( + mojo::InterfacePtr<HostType> host_proxy, + std::unique_ptr<mojo::Binding<HostType>> binding, + std::false_type) { // If InitDeprecated does not exists, ARC container must support // Init() with callback, already. Thus, this should not be called. NOTREACHED(); } + // Resets the binding and notifies all the observers that the connection is + // closed. + void OnConnectionClosed() { + DCHECK(binding_); + binding_.reset(); + connection_notifier_->NotifyConnectionClosed(); + } + // Notifies all the observers that the connection is ready. - void OnConnectionReady() { connection_notifier_->NotifyConnectionReady(); } + void OnConnectionReady(std::unique_ptr<mojo::Binding<HostType>> binding) { + DCHECK(!binding_); + // Now that we can finally commit to this connection and will deliver the + // OnConnectionReady() event, set the connection error handler to notify + // Observers of connection closures. + // Note: because the callback will be destroyed with |binding_|, + // base::Unretained() can be safely used. + binding->set_connection_error_handler(base::BindOnce( + &ConnectionHolderImpl::OnConnectionClosed, base::Unretained(this))); + + binding_ = std::move(binding); + connection_notifier_->NotifyConnectionReady(); + } // This class does not have ownership. The pointers should be managed by the // caller.
diff --git a/components/arc/test/connection_holder_util.h b/components/arc/test/connection_holder_util.h index 53fa7a6..e7515c0 100644 --- a/components/arc/test/connection_holder_util.h +++ b/components/arc/test/connection_holder_util.h
@@ -21,8 +21,8 @@ class ReadinessObserver : public ConnectionHolder<InstanceType, HostType>::Observer { public: - explicit ReadinessObserver(ConnectionHolder<InstanceType, HostType>* holder, - base::OnceClosure closure) + ReadinessObserver(ConnectionHolder<InstanceType, HostType>* holder, + base::OnceClosure closure) : holder_(holder), closure_(std::move(closure)) { holder_->AddObserver(this); }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index 312d5bf..a1e29f1 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -25,7 +25,9 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/time/default_tick_clock.h" +#include "build/build_config.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h" +#include "components/data_reduction_proxy/core/browser/network_properties_manager.h" #include "components/data_reduction_proxy/core/browser/warmup_url_fetcher.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_config_values.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h" @@ -37,6 +39,7 @@ #include "net/base/host_port_pair.h" #include "net/base/load_flags.h" #include "net/base/network_change_notifier.h" +#include "net/base/network_interfaces.h" #include "net/log/net_log_source_type.h" #include "net/nqe/effective_connection_type.h" #include "net/proxy/proxy_server.h" @@ -72,7 +75,7 @@ // name in metrics/histograms/histograms.xml. enum DataReductionProxyNetworkChangeEvent { // The client IP address changed. - IP_CHANGED = 0, + DEPRECATED_IP_CHANGED = 0, // [Deprecated] Proxy is disabled because a VPN is running. DEPRECATED_DISABLED_ON_VPN = 1, // There was a network change. @@ -135,6 +138,7 @@ configurator_(configurator), event_creator_(event_creator), connection_type_(net::NetworkChangeNotifier::GetConnectionType()), + network_properties_manager_(nullptr), weak_factory_(this) { DCHECK(io_task_runner_); DCHECK(configurator); @@ -144,7 +148,6 @@ } DataReductionProxyConfig::~DataReductionProxyConfig() { - net::NetworkChangeNotifier::RemoveIPAddressObserver(this); net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); } @@ -152,8 +155,11 @@ const scoped_refptr<net::URLRequestContextGetter>& basic_url_request_context_getter, const scoped_refptr<net::URLRequestContextGetter>& - url_request_context_getter) { + url_request_context_getter, + NetworkPropertiesManager* manager) { DCHECK(thread_checker_.CalledOnValidThread()); + network_properties_manager_ = manager; + DCHECK(network_properties_manager_); secure_proxy_checker_.reset( new SecureProxyChecker(basic_url_request_context_getter)); @@ -161,7 +167,6 @@ if (ShouldAddDefaultProxyBypassRules()) AddDefaultProxyBypassRules(); - net::NetworkChangeNotifier::AddIPAddressObserver(this); net::NetworkChangeNotifier::AddNetworkChangeObserver(this); } @@ -181,9 +186,10 @@ if (enabled_by_user_ && !params::IsIncludedInHoldbackFieldTrial() && !config_values_->proxies_for_http().empty()) { - configurator_->Enable(!network_properties_manager_.IsSecureProxyAllowed(), - !network_properties_manager_.IsInsecureProxyAllowed(), - config_values_->proxies_for_http()); + configurator_->Enable( + !network_properties_manager_->IsSecureProxyAllowed(), + !network_properties_manager_->IsInsecureProxyAllowed(), + config_values_->proxies_for_http()); } else { configurator_->Disable(); } @@ -350,6 +356,8 @@ void DataReductionProxyConfig::SetProxyConfig(bool enabled, bool at_startup) { DCHECK(thread_checker_.CalledOnValidThread()); enabled_by_user_ = enabled; + network_properties_manager_->OnChangeInNetworkID(GetCurrentNetworkID()); + ReloadConfig(); if (enabled_by_user_) { @@ -372,9 +380,9 @@ bool is_captive_portal = GetIsCaptivePortal(); UMA_HISTOGRAM_BOOLEAN("DataReductionProxy.CaptivePortalDetected.Platform", is_captive_portal); - if (is_captive_portal == network_properties_manager_.IsCaptivePortal()) + if (is_captive_portal == network_properties_manager_->IsCaptivePortal()) return; - network_properties_manager_.SetIsCaptivePortal(is_captive_portal); + network_properties_manager_->SetIsCaptivePortal(is_captive_portal); ReloadConfig(); } @@ -392,12 +400,17 @@ bool secure_proxies_allowed, bool insecure_proxies_allowed) { enabled_by_user_ = enabled; - network_properties_manager_.SetIsSecureProxyDisallowedByCarrier( + network_properties_manager_->SetIsSecureProxyDisallowedByCarrier( !secure_proxies_allowed); - network_properties_manager_.SetHasWarmupURLProbeFailed( + network_properties_manager_->SetHasWarmupURLProbeFailed( false, !insecure_proxies_allowed); } +void DataReductionProxyConfig::SetNetworkPropertiesManagerForTesting( + NetworkPropertiesManager* manager) { + network_properties_manager_ = manager; +} + void DataReductionProxyConfig::HandleSecureProxyCheckResponse( const std::string& response, const net::URLRequestStatus& status, @@ -422,29 +435,29 @@ } bool secure_proxy_allowed_past = - !network_properties_manager_.IsSecureProxyDisallowedByCarrier(); - network_properties_manager_.SetIsSecureProxyDisallowedByCarrier( + !network_properties_manager_->IsSecureProxyDisallowedByCarrier(); + network_properties_manager_->SetIsSecureProxyDisallowedByCarrier( !success_response); if (!enabled_by_user_) return; - if (!network_properties_manager_.IsSecureProxyDisallowedByCarrier() != + if (!network_properties_manager_->IsSecureProxyDisallowedByCarrier() != secure_proxy_allowed_past) ReloadConfig(); // Record the result. if (secure_proxy_allowed_past && - !network_properties_manager_.IsSecureProxyDisallowedByCarrier()) { + !network_properties_manager_->IsSecureProxyDisallowedByCarrier()) { RecordSecureProxyCheckFetchResult(SUCCEEDED_PROXY_ALREADY_ENABLED); } else if (secure_proxy_allowed_past && - network_properties_manager_.IsSecureProxyDisallowedByCarrier()) { + network_properties_manager_->IsSecureProxyDisallowedByCarrier()) { RecordSecureProxyCheckFetchResult(FAILED_PROXY_DISABLED); } else if (!secure_proxy_allowed_past && - !network_properties_manager_.IsSecureProxyDisallowedByCarrier()) { + !network_properties_manager_->IsSecureProxyDisallowedByCarrier()) { RecordSecureProxyCheckFetchResult(SUCCEEDED_PROXY_ENABLED); } else { DCHECK(!secure_proxy_allowed_past && - network_properties_manager_.IsSecureProxyDisallowedByCarrier()); + network_properties_manager_->IsSecureProxyDisallowedByCarrier()); RecordSecureProxyCheckFetchResult(FAILED_PROXY_ALREADY_DISABLED); } } @@ -455,16 +468,13 @@ connection_type_ = type; RecordNetworkChangeEvent(NETWORK_CHANGED); + network_properties_manager_->OnChangeInNetworkID(GetCurrentNetworkID()); + + ReloadConfig(); FetchWarmupURL(); -} - -void DataReductionProxyConfig::OnIPAddressChanged() { - DCHECK(thread_checker_.CalledOnValidThread()); if (enabled_by_user_) { - RecordNetworkChangeEvent(IP_CHANGED); - HandleCaptivePortal(); // It is safe to use base::Unretained here, since it gets executed // synchronously on the IO thread, and |this| outlives @@ -626,11 +636,11 @@ void DataReductionProxyConfig::OnInsecureProxyWarmupURLProbeStatusChange( bool insecure_proxies_allowed) { DCHECK(thread_checker_.CalledOnValidThread()); - bool old_status = network_properties_manager_.IsInsecureProxyAllowed(); - network_properties_manager_.SetHasWarmupURLProbeFailed( + bool old_status = network_properties_manager_->IsInsecureProxyAllowed(); + network_properties_manager_->SetHasWarmupURLProbeFailed( false, !insecure_proxies_allowed); - if (old_status == network_properties_manager_.IsInsecureProxyAllowed()) + if (old_status == network_properties_manager_->IsInsecureProxyAllowed()) return; ReloadConfig(); } @@ -639,19 +649,19 @@ if (!enabled_by_user_ || config_values_->proxies_for_http().empty()) return net::ProxyConfig::CreateDirect(); return configurator_->CreateProxyConfig( - !network_properties_manager_.IsSecureProxyAllowed(), - !network_properties_manager_.IsInsecureProxyAllowed(), + !network_properties_manager_->IsSecureProxyAllowed(), + !network_properties_manager_->IsInsecureProxyAllowed(), config_values_->proxies_for_http()); } bool DataReductionProxyConfig::secure_proxy_allowed() const { DCHECK(thread_checker_.CalledOnValidThread()); - return network_properties_manager_.IsSecureProxyAllowed(); + return network_properties_manager_->IsSecureProxyAllowed(); } bool DataReductionProxyConfig::insecure_proxies_allowed() const { DCHECK(thread_checker_.CalledOnValidThread()); - return network_properties_manager_.IsInsecureProxyAllowed(); + return network_properties_manager_->IsInsecureProxyAllowed(); } std::vector<DataReductionProxyServer> @@ -664,4 +674,52 @@ return config_values_->proxies_for_http(); } +std::string DataReductionProxyConfig::GetCurrentNetworkID() const { + DCHECK(thread_checker_.CalledOnValidThread()); + + // It is possible that the connection type changed between when + // GetConnectionType() was called and when the API to determine the + // network name was called. Check if that happened and retry until the + // connection type stabilizes. This is an imperfect solution but should + // capture majority of cases, and should not significantly affect estimates + // (that are approximate to begin with). + + while (true) { + net::NetworkChangeNotifier::ConnectionType connection_type = + net::NetworkChangeNotifier::GetConnectionType(); + std::string ssid_mccmnc; + + switch (connection_type) { + case net::NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN: + case net::NetworkChangeNotifier::ConnectionType::CONNECTION_NONE: + case net::NetworkChangeNotifier::ConnectionType::CONNECTION_BLUETOOTH: + case net::NetworkChangeNotifier::ConnectionType::CONNECTION_ETHERNET: + break; + case net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI: +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_WIN) + ssid_mccmnc = net::GetWifiSSID(); +#endif + break; + case net::NetworkChangeNotifier::ConnectionType::CONNECTION_2G: + case net::NetworkChangeNotifier::ConnectionType::CONNECTION_3G: + case net::NetworkChangeNotifier::ConnectionType::CONNECTION_4G: +#if defined(OS_ANDROID) + ssid_mccmnc = net::android::GetTelephonyNetworkOperator(); +#endif + break; + } + + if (connection_type == net::NetworkChangeNotifier::GetConnectionType()) { + if (connection_type >= net::NetworkChangeNotifier::CONNECTION_2G && + connection_type <= net::NetworkChangeNotifier::CONNECTION_4G) { + // No need to differentiate cellular connections by the exact + // connection type. + return "cell," + ssid_mccmnc; + } + return base::IntToString(connection_type) + "," + ssid_mccmnc; + } + } + NOTREACHED(); +} + } // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h index 2a6d182..5a3f59e1 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -18,7 +18,6 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "base/time/time.h" -#include "components/data_reduction_proxy/core/browser/network_properties_manager.h" #include "components/data_reduction_proxy/core/browser/secure_proxy_checker.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h" #include "components/previews/core/previews_experiments.h" @@ -48,6 +47,7 @@ class DataReductionProxyConfigValues; class DataReductionProxyConfigurator; class DataReductionProxyEventCreator; +class NetworkPropertiesManager; class SecureProxyChecker; class WarmupURLFetcher; struct DataReductionProxyTypeInfo; @@ -84,8 +84,7 @@ // This object lives on the IO thread and all of its methods are expected to be // called from there. class DataReductionProxyConfig - : public net::NetworkChangeNotifier::IPAddressObserver, - public net::NetworkChangeNotifier::NetworkChangeObserver { + : public net::NetworkChangeNotifier::NetworkChangeObserver { public: // The caller must ensure that all parameters remain alive for the lifetime // of the |DataReductionProxyConfig| instance, with the exception of @@ -110,7 +109,8 @@ void InitializeOnIOThread(const scoped_refptr<net::URLRequestContextGetter>& basic_url_request_context_getter, const scoped_refptr<net::URLRequestContextGetter>& - url_request_context_getter); + url_request_context_getter, + NetworkPropertiesManager* manager); // Sets the proxy configs, enabling or disabling the proxy according to // the value of |enabled|. If |restricted| is true, only enable the fallback @@ -200,6 +200,8 @@ // Called when a new client config has been fetched. void OnNewClientConfigFetched(); + void SetNetworkPropertiesManagerForTesting(NetworkPropertiesManager* manager); + protected: // Should be called when there is a change in the status of the availability // of the insecure data saver proxies triggered due to warmup URL. @@ -216,6 +218,9 @@ // testing. virtual bool ShouldAddDefaultProxyBypassRules() const; + // Returns the ID of the current network by calling the platform APIs. + virtual std::string GetCurrentNetworkID() const; + private: friend class MockDataReductionProxyConfig; friend class TestDataReductionProxyConfig; @@ -243,9 +248,6 @@ // |configurator_|. Used by the Data Reduction Proxy config service client. void ReloadConfig(); - // NetworkChangeNotifier::IPAddressObserver implementation: - void OnIPAddressChanged() override; - // NetworkChangeNotifier::NetworkChangeObserver implementation: void OnNetworkChanged( net::NetworkChangeNotifier::ConnectionType type) override; @@ -336,7 +338,9 @@ // The current connection type. net::NetworkChangeNotifier::ConnectionType connection_type_; - NetworkPropertiesManager network_properties_manager_; + // Should be accessed only on the IO thread. Guaranteed to be non-null during + // the lifetime of |this| if accessed on the IO thread. + NetworkPropertiesManager* network_properties_manager_; base::WeakPtrFactory<DataReductionProxyConfig> weak_factory_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc index a78757a..f3ba9fa9 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
@@ -122,6 +122,18 @@ add_default_proxy_bypass_rules_ = add_default_proxy_bypass_rules; } +std::string TestDataReductionProxyConfig::GetCurrentNetworkID() const { + if (current_network_id_) { + return current_network_id_.value(); + } + return DataReductionProxyConfig::GetCurrentNetworkID(); +} + +void TestDataReductionProxyConfig::SetCurrentNetworkID( + const std::string& network_id) { + current_network_id_ = network_id; +} + MockDataReductionProxyConfig::MockDataReductionProxyConfig( std::unique_ptr<DataReductionProxyConfigValues> config_values, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h index a454696..ed0acfe8 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
@@ -102,6 +102,10 @@ void SetShouldAddDefaultProxyBypassRules(bool add_default_proxy_bypass_rules); + std::string GetCurrentNetworkID() const override; + + void SetCurrentNetworkID(const std::string& network_id); + using DataReductionProxyConfig::UpdateConfigForTesting; using DataReductionProxyConfig::OnInsecureProxyWarmupURLProbeStatusChange; @@ -113,6 +117,8 @@ base::Optional<bool> was_data_reduction_proxy_used_; base::Optional<int> proxy_index_; + base::Optional<std::string> current_network_id_; + // Set to true if the captive portal probe for the current network has been // blocked. bool is_captive_portal_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc index 1b5f58a3..500add8 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -35,6 +35,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h" +#include "components/data_reduction_proxy/core/browser/network_properties_manager.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h" @@ -162,7 +163,8 @@ int http_response_code; }; - void CheckSecureProxyCheckOnIPChange( + void CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::ConnectionType connection_type, const std::string& response, bool is_captive_portal, int response_code, @@ -170,6 +172,8 @@ SecureProxyCheckFetchResult expected_fetch_result, const std::vector<net::ProxyServer>& expected_proxies_for_http) { base::HistogramTester histogram_tester; + net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( + connection_type); TestResponder responder; responder.response = response; @@ -180,7 +184,6 @@ .WillRepeatedly(testing::WithArgs<0>( testing::Invoke(&responder, &TestResponder::ExecuteCallback))); mock_config()->SetIsCaptivePortal(is_captive_portal); - net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); test_context_->RunUntilIdle(); EXPECT_EQ(expected_proxies_for_http, GetConfiguredProxiesForHttp()); @@ -240,13 +243,15 @@ return test_context_->GetConfiguredProxiesForHttp(); } + base::MessageLoopForIO message_loop_; + + std::unique_ptr<DataReductionProxyTestContext> test_context_; + private: std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; - bool mock_config_used_; - - base::MessageLoopForIO message_loop_; - std::unique_ptr<DataReductionProxyTestContext> test_context_; std::unique_ptr<TestDataReductionProxyParams> expected_params_; + + bool mock_config_used_; }; TEST_F(DataReductionProxyConfigTest, TestReloadConfigHoldback) { @@ -316,7 +321,53 @@ GetConfiguredProxiesForHttp()); } -TEST_F(DataReductionProxyConfigTest, TestOnIPAddressChanged) { +TEST_F(DataReductionProxyConfigTest, TestOnConnectionChangePersistedData) { + base::FieldTrialList field_trial_list(nullptr); + + const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( + "https://secure_origin.net:443", net::ProxyServer::SCHEME_HTTP); + const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI( + "insecure_origin.net:80", net::ProxyServer::SCHEME_HTTP); + SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy}); + + ResetSettings(); + test_config()->SetProxyConfig(true, true); + + EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}), + GetConfiguredProxiesForHttp()); + + test_config()->SetCurrentNetworkID("wifi,test"); + net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( + net::NetworkChangeNotifier::CONNECTION_WIFI); + base::RunLoop().RunUntilIdle(); + test_config()->UpdateConfigForTesting(true /* enabled */, + false /* secure_proxies_allowed */, + true /* insecure_proxies_allowed */); + test_config()->OnNewClientConfigFetched(); + EXPECT_EQ(std::vector<net::ProxyServer>({kHttpProxy}), + GetConfiguredProxiesForHttp()); + base::RunLoop().RunUntilIdle(); + + test_config()->SetCurrentNetworkID("cell,test"); + net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( + net::NetworkChangeNotifier::CONNECTION_2G); + base::RunLoop().RunUntilIdle(); + test_config()->UpdateConfigForTesting(true /* enabled */, + false /* secure_proxies_allowed */, + false /* insecure_proxies_allowed */); + test_config()->OnNewClientConfigFetched(); + EXPECT_EQ(std::vector<net::ProxyServer>({}), GetConfiguredProxiesForHttp()); + + // On network change, persisted config should be read, and config reloaded. + test_config()->SetCurrentNetworkID("wifi,test"); + net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests( + net::NetworkChangeNotifier::CONNECTION_WIFI); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(std::vector<net::ProxyServer>({kHttpProxy}), + GetConfiguredProxiesForHttp()); +} + +TEST_F(DataReductionProxyConfigTest, TestOnNetworkChanged) { RecreateContextWithMockConfig(); const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( @@ -331,70 +382,77 @@ mock_config()->UpdateConfigForTesting(true, true, true); mock_config()->OnNewClientConfigFetched(); - // IP address change triggers a secure proxy check that succeeds. Proxy + // Connection change triggers a secure proxy check that succeeds. Proxy // remains unrestricted. - CheckSecureProxyCheckOnIPChange("OK", false, net::HTTP_OK, kSuccess, - SUCCEEDED_PROXY_ALREADY_ENABLED, - {kHttpsProxy, kHttpProxy}); + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, "OK", false, net::HTTP_OK, + kSuccess, SUCCEEDED_PROXY_ALREADY_ENABLED, {kHttpsProxy, kHttpProxy}); - // IP address change triggers a secure proxy check that succeeds but captive + // Connection change triggers a secure proxy check that succeeds but captive // portal fails. Proxy is restricted. - CheckSecureProxyCheckOnIPChange("OK", true, net::HTTP_OK, kSuccess, - SUCCEEDED_PROXY_ALREADY_ENABLED, - std::vector<net::ProxyServer>(1, kHttpProxy)); + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, "OK", true, net::HTTP_OK, + kSuccess, SUCCEEDED_PROXY_ALREADY_ENABLED, + std::vector<net::ProxyServer>(1, kHttpProxy)); - // IP address change triggers a secure proxy check that fails. Proxy is + // Connection change triggers a secure proxy check that fails. Proxy is // restricted. - CheckSecureProxyCheckOnIPChange("Bad", false, net::HTTP_OK, kSuccess, - FAILED_PROXY_DISABLED, - std::vector<net::ProxyServer>(1, kHttpProxy)); + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, "Bad", false, net::HTTP_OK, + kSuccess, FAILED_PROXY_DISABLED, + std::vector<net::ProxyServer>(1, kHttpProxy)); - // IP address change triggers a secure proxy check that succeeds. Proxies + // Connection change triggers a secure proxy check that succeeds. Proxies // are unrestricted. - CheckSecureProxyCheckOnIPChange("OK", false, net::HTTP_OK, kSuccess, - SUCCEEDED_PROXY_ENABLED, - {kHttpsProxy, kHttpProxy}); + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, "OK", false, net::HTTP_OK, + kSuccess, SUCCEEDED_PROXY_ENABLED, {kHttpsProxy, kHttpProxy}); - // IP address change triggers a secure proxy check that fails. Proxy is + // Connection change triggers a secure proxy check that fails. Proxy is // restricted. - CheckSecureProxyCheckOnIPChange("Bad", true, net::HTTP_OK, kSuccess, - FAILED_PROXY_DISABLED, - std::vector<net::ProxyServer>(1, kHttpProxy)); + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, "Bad", true, net::HTTP_OK, + kSuccess, FAILED_PROXY_DISABLED, + std::vector<net::ProxyServer>(1, kHttpProxy)); - // IP address change triggers a secure proxy check that fails due to the + // Connection change triggers a secure proxy check that fails due to the // network changing again. This should be ignored, so the proxy should remain // unrestricted. - CheckSecureProxyCheckOnIPChange( - std::string(), false, net::URLFetcher::RESPONSE_CODE_INVALID, + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, std::string(), false, + net::URLFetcher::RESPONSE_CODE_INVALID, net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_INTERNET_DISCONNECTED), INTERNET_DISCONNECTED, std::vector<net::ProxyServer>(1, kHttpProxy)); - // IP address change triggers a secure proxy check that fails. Proxy remains + // Connection change triggers a secure proxy check that fails. Proxy remains // restricted. - CheckSecureProxyCheckOnIPChange("Bad", false, net::HTTP_OK, kSuccess, - FAILED_PROXY_ALREADY_DISABLED, - std::vector<net::ProxyServer>(1, kHttpProxy)); + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, "Bad", false, net::HTTP_OK, + kSuccess, FAILED_PROXY_ALREADY_DISABLED, + std::vector<net::ProxyServer>(1, kHttpProxy)); - // IP address change triggers a secure proxy check that succeeds. Proxy is + // Connection change triggers a secure proxy check that succeeds. Proxy is // unrestricted. - CheckSecureProxyCheckOnIPChange("OK", false, net::HTTP_OK, kSuccess, - SUCCEEDED_PROXY_ENABLED, - {kHttpsProxy, kHttpProxy}); + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, "OK", false, net::HTTP_OK, + kSuccess, SUCCEEDED_PROXY_ENABLED, {kHttpsProxy, kHttpProxy}); - // IP address change triggers a secure proxy check that fails due to the + // Connection change triggers a secure proxy check that fails due to the // network changing again. This should be ignored, so the proxy should remain // unrestricted. - CheckSecureProxyCheckOnIPChange( - std::string(), false, net::URLFetcher::RESPONSE_CODE_INVALID, + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, std::string(), false, + net::URLFetcher::RESPONSE_CODE_INVALID, net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_INTERNET_DISCONNECTED), INTERNET_DISCONNECTED, {kHttpsProxy, kHttpProxy}); - // IP address change triggers a secure proxy check that fails because of a + // Connection change triggers a secure proxy check that fails because of a // redirect response, e.g. by a captive portal. Proxy is restricted. - CheckSecureProxyCheckOnIPChange( - "Bad", false, net::HTTP_FOUND, + CheckSecureProxyCheckOnNetworkChange( + net::NetworkChangeNotifier::CONNECTION_WIFI, "Bad", false, + net::HTTP_FOUND, net::URLRequestStatus(net::URLRequestStatus::CANCELED, net::ERR_ABORTED), FAILED_PROXY_DISABLED, std::vector<net::ProxyServer>(1, kHttpProxy)); } @@ -449,8 +507,12 @@ scoped_refptr<net::URLRequestContextGetter> request_context_getter_ = new net::TestURLRequestContextGetter(task_runner()); + + NetworkPropertiesManager network_properties_manager( + test_context_->pref_service(), test_context_->task_runner()); config.InitializeOnIOThread(request_context_getter_.get(), - request_context_getter_.get()); + request_context_getter_.get(), + &network_properties_manager); RunUntilIdle(); {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc index b55c538..98e55d4 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -24,6 +24,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h" +#include "components/data_reduction_proxy/core/browser/network_properties_manager.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_storage_delegate.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" @@ -93,6 +94,7 @@ DataReductionProxyIOData::DataReductionProxyIOData( Client client, + PrefService* prefs, net::NetLog* net_log, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, @@ -157,13 +159,25 @@ proxy_delegate_.reset(new DataReductionProxyDelegate( config_.get(), configurator_.get(), event_creator_.get(), bypass_stats_.get(), net_log_)); + network_properties_manager_.reset( + new NetworkPropertiesManager(prefs, ui_task_runner_)); } -DataReductionProxyIOData::DataReductionProxyIOData() +DataReductionProxyIOData::DataReductionProxyIOData( + PrefService* prefs, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) : client_(Client::UNKNOWN), net_log_(nullptr), + io_task_runner_(io_task_runner), + ui_task_runner_(ui_task_runner), url_request_context_getter_(nullptr), - weak_factory_(this) {} + weak_factory_(this) { + DCHECK(ui_task_runner_); + DCHECK(io_task_runner_); + network_properties_manager_.reset( + new NetworkPropertiesManager(prefs, ui_task_runner_)); +} DataReductionProxyIOData::~DataReductionProxyIOData() { // Guaranteed to be destroyed on IO thread if the IO thread is still @@ -173,6 +187,7 @@ void DataReductionProxyIOData::ShutdownOnUIThread() { DCHECK(ui_task_runner_->BelongsToCurrentThread()); + network_properties_manager_->ShutdownOnUIThread(); } void DataReductionProxyIOData::SetDataReductionProxyService( @@ -195,8 +210,10 @@ void DataReductionProxyIOData::InitializeOnIOThread() { DCHECK(io_task_runner_->BelongsToCurrentThread()); + DCHECK(network_properties_manager_); config_->InitializeOnIOThread(basic_url_request_context_getter_.get(), - url_request_context_getter_); + url_request_context_getter_, + network_properties_manager_.get()); bypass_stats_->InitializeOnIOThread(); proxy_delegate_->InitializeOnIOThread(this); if (config_client_.get()) @@ -225,6 +242,12 @@ service_, pingback_reporting_fraction)); } +void DataReductionProxyIOData::DeleteBrowsingHistory(const base::Time start, + const base::Time end) { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + network_properties_manager_->DeleteHistory(); +} + std::unique_ptr<net::URLRequestInterceptor> DataReductionProxyIOData::CreateInterceptor() { DCHECK(io_task_runner_->BelongsToCurrentThread());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h index 8a1e32a..ae80b3d 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
@@ -48,6 +48,7 @@ class DataReductionProxyConfigurator; class DataReductionProxyEventCreator; class DataReductionProxyService; +class NetworkPropertiesManager; // Contains and initializes all Data Reduction Proxy objects that operate on // the IO thread. @@ -57,6 +58,7 @@ // state of the Data Reduction Proxy. DataReductionProxyIOData( Client client, + PrefService* prefs, net::NetLog* net_log, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, @@ -136,6 +138,9 @@ // |pingback_reporting_fraction|. Overridden in testing. virtual void SetPingbackReportingFraction(float pingback_reporting_fraction); + // Called when the user clears the browsing history. + void DeleteBrowsingHistory(const base::Time start, const base::Time end); + // Various accessor methods. DataReductionProxyConfigurator* configurator() const { return configurator_.get(); @@ -214,7 +219,10 @@ TestResetBadProxyListOnDisableDataSaver); // Used for testing. - DataReductionProxyIOData(); + DataReductionProxyIOData( + PrefService* prefs, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); // Initializes the weak pointer to |this| on the IO thread. It must be done // on the IO thread, since it is used for posting tasks from the UI thread @@ -299,6 +307,11 @@ // The production channel of this build. const std::string channel_; + // Created on the UI thread. Guaranteed to be destroyed on IO thread if the + // IO thread is still available at the time of destruction. If the IO thread + // is unavailable, then the destruction will happen on the UI thread. + std::unique_ptr<NetworkPropertiesManager> network_properties_manager_; + base::WeakPtrFactory<DataReductionProxyIOData> weak_factory_; DISALLOW_COPY_AND_ASSIGN(DataReductionProxyIOData);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc index 58370dc2..70fcaae 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
@@ -106,7 +106,7 @@ TEST_F(DataReductionProxyIODataTest, TestConstruction) { std::unique_ptr<DataReductionProxyIOData> io_data( new DataReductionProxyIOData( - Client::UNKNOWN, net_log(), + Client::UNKNOWN, prefs(), net_log(), scoped_task_environment_.GetMainThreadTaskRunner(), scoped_task_environment_.GetMainThreadTaskRunner(), false /* enabled */, std::string() /* user_agent */,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc index a310830..d730066 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc
@@ -90,6 +90,7 @@ registry->RegisterStringPref(prefs::kDataReductionProxyConfig, std::string()); registry->RegisterInt64Pref(prefs::kDataReductionProxyLastConfigRetrievalTime, 0L); + registry->RegisterDictionaryPref(prefs::kNetworkProperties); } void RegisterSimpleProfilePrefs(PrefRegistrySimple* registry) { @@ -170,6 +171,7 @@ registry->RegisterStringPref(prefs::kDataReductionProxyConfig, std::string()); registry->RegisterInt64Pref(prefs::kDataReductionProxyLastConfigRetrievalTime, 0L); + registry->RegisterDictionaryPref(prefs::kNetworkProperties); } } // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc index 48f85903..77fe29f 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_service.cc
@@ -248,6 +248,10 @@ db_task_runner_->PostTask( FROM_HERE, base::Bind(&DBDataOwner::DeleteBrowsingHistory, db_data_owner_->GetWeakPtr(), start, end)); + + io_task_runner_->PostTask( + FROM_HERE, base::Bind(&DataReductionProxyIOData::DeleteBrowsingHistory, + io_data_, start, end)); } void DataReductionProxyService::AddObserver(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc index 2b2eeb0..e4d3204 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
@@ -24,6 +24,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h" +#include "components/data_reduction_proxy/core/browser/network_properties_manager.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h" @@ -63,6 +64,11 @@ TEST_F(DataReductionProxySettingsTest, TestIsProxyEnabledOrManaged) { InitPrefMembers(); + NetworkPropertiesManager network_properties_manager( + test_context_->pref_service(), test_context_->task_runner()); + test_context_->config()->SetNetworkPropertiesManagerForTesting( + &network_properties_manager); + // The proxy is disabled initially. test_context_->config()->UpdateConfigForTesting(false, true, true); @@ -82,6 +88,11 @@ TEST_F(DataReductionProxySettingsTest, TestCanUseDataReductionProxy) { InitPrefMembers(); + NetworkPropertiesManager network_properties_manager( + test_context_->pref_service(), test_context_->task_runner()); + test_context_->config()->SetNetworkPropertiesManagerForTesting( + &network_properties_manager); + // The proxy is disabled initially. test_context_->config()->UpdateConfigForTesting(false, true, true); @@ -248,6 +259,11 @@ .SkipSettingsInitialization() .Build(); + NetworkPropertiesManager network_properties_manager( + drp_test_context->pref_service(), drp_test_context->task_runner()); + drp_test_context->config()->SetNetworkPropertiesManagerForTesting( + &network_properties_manager); + // The proxy is enabled initially. drp_test_context->config()->UpdateConfigForTesting(true, true, true); drp_test_context->InitSettings(); @@ -269,6 +285,11 @@ // Initialize the pref member in |settings_| without the usual callback // so it won't trigger MaybeActivateDataReductionProxy when the pref value // is set. + NetworkPropertiesManager network_properties_manager( + test_context_->pref_service(), test_context_->task_runner()); + test_context_->config()->SetNetworkPropertiesManagerForTesting( + &network_properties_manager); + settings_->spdy_proxy_auth_enabled_.Init( test_context_->GetDataReductionProxyEnabledPrefName(), settings_->GetOriginalProfilePrefs());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc index cdb018b..8c9575f 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -249,6 +249,7 @@ } TestDataReductionProxyIOData::TestDataReductionProxyIOData( + PrefService* prefs, const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, std::unique_ptr<DataReductionProxyConfig> config, std::unique_ptr<DataReductionProxyEventCreator> event_creator, @@ -256,7 +257,7 @@ std::unique_ptr<DataReductionProxyConfigurator> configurator, net::NetLog* net_log, bool enabled) - : DataReductionProxyIOData(), + : DataReductionProxyIOData(prefs, task_runner, task_runner), service_set_(false), pingback_reporting_fraction_(0.0f), test_request_options_(request_options.get()) { @@ -496,9 +497,9 @@ std::unique_ptr<TestDataReductionProxyIOData> io_data( new TestDataReductionProxyIOData( - task_runner, std::move(config), std::move(event_creator), - std::move(request_options), std::move(configurator), net_log.get(), - true /* enabled */)); + pref_service.get(), task_runner, std::move(config), + std::move(event_creator), std::move(request_options), + std::move(configurator), net_log.get(), true /* enabled */)); io_data->SetSimpleURLRequestContextGetter(request_context_getter); if (use_test_config_client_) { @@ -596,6 +597,7 @@ // indirectly owned by |settings_|. if (settings_.get()) { settings_.reset(); + storage_delegate_->SetStorageDelegate(nullptr); RunUntilIdle(); } }
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h index 7d4b174..0adb3ffd 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
@@ -195,6 +195,7 @@ class TestDataReductionProxyIOData : public DataReductionProxyIOData { public: TestDataReductionProxyIOData( + PrefService* prefs, const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, std::unique_ptr<DataReductionProxyConfig> config, std::unique_ptr<DataReductionProxyEventCreator> event_creator,
diff --git a/components/data_reduction_proxy/core/browser/network_properties_manager.cc b/components/data_reduction_proxy/core/browser/network_properties_manager.cc index b7809bb..69cae91 100644 --- a/components/data_reduction_proxy/core/browser/network_properties_manager.cc +++ b/components/data_reduction_proxy/core/browser/network_properties_manager.cc
@@ -4,13 +4,229 @@ #include "components/data_reduction_proxy/core/browser/network_properties_manager.h" +#include "base/base64.h" +#include "base/bind.h" +#include "base/metrics/histogram_macros.h" +#include "base/optional.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/values.h" +#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h" +#include "components/prefs/scoped_user_pref_update.h" + namespace data_reduction_proxy { -NetworkPropertiesManager::NetworkPropertiesManager() {} +namespace { -NetworkPropertiesManager::~NetworkPropertiesManager() {} +constexpr size_t kMaxCacheSize = 10u; + +// Parses a base::Value to NetworkProperties struct. If the parsing is +// unsuccessful, a nullptr is returned. +base::Optional<NetworkProperties> GetParsedNetworkProperty( + const base::Value& value) { + if (!value.is_string()) + return base::nullopt; + + std::string base64_decoded; + if (!base::Base64Decode(value.GetString(), &base64_decoded)) + return base::nullopt; + + NetworkProperties network_properties; + if (!network_properties.ParseFromString(base64_decoded)) + return base::nullopt; + + return network_properties; +} + +} // namespace + +class NetworkPropertiesManager::PrefManager { + public: + explicit PrefManager(PrefService* pref_service) + : pref_service_(pref_service), ui_weak_ptr_factory_(this) {} + + ~PrefManager() {} + + base::WeakPtr<PrefManager> GetWeakPtr() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return ui_weak_ptr_factory_.GetWeakPtr(); + } + + void ShutdownOnUIThread() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + ui_weak_ptr_factory_.InvalidateWeakPtrs(); + } + + void OnChangeInNetworkPropertyOnUIThread( + const std::string& network_id, + const NetworkProperties& network_properties) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + std::string serialized_network_properties; + bool serialize_to_string_ok = + network_properties.SerializeToString(&serialized_network_properties); + if (!serialize_to_string_ok) + return; + + std::string base64_encoded; + base::Base64Encode(serialized_network_properties, &base64_encoded); + + DictionaryPrefUpdate update(pref_service_, prefs::kNetworkProperties); + base::DictionaryValue* properties_dict = update.Get(); + properties_dict->SetKey(network_id, base::Value(base64_encoded)); + + LimitPrefSize(properties_dict); + } + + void DeleteHistory() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + pref_service_->ClearPref(prefs::kNetworkProperties); + } + + private: + // Limits the pref size to kMaxCacheSize. + void LimitPrefSize(base::DictionaryValue* properties_dict) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (properties_dict->size() <= kMaxCacheSize) + return; + + // Delete the key that corresponds to the network with the earliest + // timestamp. + const std::string* key_to_delete = nullptr; + int64_t earliest_timestamp = std::numeric_limits<int64_t>::max(); + + for (const auto& it : properties_dict->DictItems()) { + base::Optional<NetworkProperties> network_properties = + GetParsedNetworkProperty(it.second); + if (!network_properties) { + // Delete the corrupted entry. No need to find the oldest entry. + key_to_delete = &it.first; + break; + } + + int64_t timestamp = network_properties.value().last_modified(); + + // TODO(tbansal): crbug.com/779219: Consider handling the case when the + // device clock is moved back. For example, if the clock is moved back + // by a year, then for the next year, those older entries will have + // timestamps that are later than any new entries from networks that the + // user browses. + if (timestamp < earliest_timestamp) { + earliest_timestamp = timestamp; + key_to_delete = &it.first; + } + } + if (key_to_delete == nullptr) + return; + properties_dict->RemoveKey(*key_to_delete); + } + + // Guaranteed to be non-null during the lifetime of |this|. + PrefService* pref_service_; + + SEQUENCE_CHECKER(sequence_checker_); + + // Used to get |weak_ptr_| to self on the UI thread. + base::WeakPtrFactory<PrefManager> ui_weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(PrefManager); +}; + +NetworkPropertiesManager::NetworkPropertiesManager( + PrefService* pref_service, + scoped_refptr<base::SequencedTaskRunner> ui_task_runner) + : ui_task_runner_(ui_task_runner), + network_properties_container_(ConvertDictionaryValueToParsedPrefs( + pref_service->GetDictionary(prefs::kNetworkProperties))) { + DCHECK(ui_task_runner_); + DCHECK(ui_task_runner_->RunsTasksInCurrentSequence()); + + pref_manager_.reset(new PrefManager(pref_service)); + pref_manager_weak_ptr_ = pref_manager_->GetWeakPtr(); + + DETACH_FROM_SEQUENCE(sequence_checker_); +} + +NetworkPropertiesManager::~NetworkPropertiesManager() { + if (ui_task_runner_->RunsTasksInCurrentSequence() && pref_manager_) { + pref_manager_->ShutdownOnUIThread(); + } +} + +void NetworkPropertiesManager::DeleteHistory() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + ui_task_runner_->PostTask( + FROM_HERE, + base::Bind(&NetworkPropertiesManager::PrefManager::DeleteHistory, + pref_manager_weak_ptr_)); +} + +void NetworkPropertiesManager::ShutdownOnUIThread() { + DCHECK(ui_task_runner_->RunsTasksInCurrentSequence()); + pref_manager_->ShutdownOnUIThread(); + pref_manager_.reset(); +} + +void NetworkPropertiesManager::OnChangeInNetworkID( + const std::string& network_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + network_id_ = network_id; + + bool cached_entry_found = false; + + NetworkPropertiesContainer::const_iterator it = + network_properties_container_.find(network_id_); + if (it != network_properties_container_.end()) { + network_properties_ = it->second; + cached_entry_found = true; + + } else { + // Reset to default state. + network_properties_.Clear(); + } + UMA_HISTOGRAM_BOOLEAN("DataReductionProxy.NetworkProperties.CacheHit", + cached_entry_found); +} + +void NetworkPropertiesManager::OnChangeInNetworkPropertyOnIOThread() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + network_properties_.set_last_modified(base::Time::Now().ToJavaTime()); + // Remove the entry from the map, if it is already present. + network_properties_container_.erase(network_id_); + network_properties_container_.emplace( + std::make_pair(network_id_, network_properties_)); + + ui_task_runner_->PostTask( + FROM_HERE, + base::Bind(&NetworkPropertiesManager::PrefManager:: + OnChangeInNetworkPropertyOnUIThread, + pref_manager_weak_ptr_, network_id_, network_properties_)); +} + +// static +NetworkPropertiesManager::NetworkPropertiesContainer +NetworkPropertiesManager::ConvertDictionaryValueToParsedPrefs( + const base::Value* value) { + NetworkPropertiesContainer read_prefs; + + for (const auto& it : value->DictItems()) { + base::Optional<NetworkProperties> network_properties = + GetParsedNetworkProperty(it.second); + if (!network_properties) + continue; + + read_prefs.emplace(std::make_pair(it.first, network_properties.value())); + } + + return read_prefs; +} bool NetworkPropertiesManager::IsSecureProxyAllowed() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return !network_properties_.secure_proxy_disallowed_by_carrier() && !network_properties_.has_captive_portal() && !network_properties_.secure_proxy_flags() @@ -18,30 +234,38 @@ } bool NetworkPropertiesManager::IsInsecureProxyAllowed() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return !network_properties_.insecure_proxy_flags() .disallowed_due_to_warmup_probe_failure(); } bool NetworkPropertiesManager::IsSecureProxyDisallowedByCarrier() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return network_properties_.secure_proxy_disallowed_by_carrier(); } void NetworkPropertiesManager::SetIsSecureProxyDisallowedByCarrier( bool disallowed_by_carrier) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); network_properties_.set_secure_proxy_disallowed_by_carrier( disallowed_by_carrier); + OnChangeInNetworkPropertyOnIOThread(); } bool NetworkPropertiesManager::IsCaptivePortal() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return network_properties_.has_captive_portal(); } void NetworkPropertiesManager::SetIsCaptivePortal(bool is_captive_portal) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); network_properties_.set_has_captive_portal(is_captive_portal); + OnChangeInNetworkPropertyOnIOThread(); } bool NetworkPropertiesManager::HasWarmupURLProbeFailed( bool secure_proxy) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return secure_proxy ? network_properties_.secure_proxy_flags() .disallowed_due_to_warmup_probe_failure() : network_properties_.insecure_proxy_flags() @@ -51,6 +275,7 @@ void NetworkPropertiesManager::SetHasWarmupURLProbeFailed( bool secure_proxy, bool warmup_url_probe_failed) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (secure_proxy) { network_properties_.mutable_secure_proxy_flags() ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed); @@ -58,6 +283,7 @@ network_properties_.mutable_insecure_proxy_flags() ->set_disallowed_due_to_warmup_probe_failure(warmup_url_probe_failed); } + OnChangeInNetworkPropertyOnIOThread(); } } // namespace data_reduction_proxy \ No newline at end of file
diff --git a/components/data_reduction_proxy/core/browser/network_properties_manager.h b/components/data_reduction_proxy/core/browser/network_properties_manager.h index 33032db..8a1dfd2 100644 --- a/components/data_reduction_proxy/core/browser/network_properties_manager.h +++ b/components/data_reduction_proxy/core/browser/network_properties_manager.h
@@ -5,17 +5,40 @@ #ifndef COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_NETWORK_PROPERTIES_MANAGER_H_ #define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_NETWORK_PROPERTIES_MANAGER_H_ +#include <map> +#include <memory> +#include <string> + #include "base/macros.h" +#include "base/sequence_checker.h" +#include "base/sequenced_task_runner.h" #include "components/data_reduction_proxy/proto/network_properties.pb.h" +#include "components/prefs/pref_service.h" + +namespace base { +class Value; +} namespace data_reduction_proxy { -// Stores the properties of a single network. +// Stores the properties of a single network. Created on the UI thread, but +// lives on the IO thread. Guaranteed to be destroyed on IO thread if the IO +// thread is still available at the time of destruction. If the IO thread is +// unavailable, then the destruction will happen on the UI thread. class NetworkPropertiesManager { public: - NetworkPropertiesManager(); + NetworkPropertiesManager( + PrefService* pref_service, + scoped_refptr<base::SequencedTaskRunner> ui_task_runner); - ~NetworkPropertiesManager(); + virtual ~NetworkPropertiesManager(); + + // Called when the user clears the browsing history. + void DeleteHistory(); + + void ShutdownOnUIThread(); + + void OnChangeInNetworkID(const std::string& network_id); // Returns true if usage of secure proxies are allowed on the current network. bool IsSecureProxyAllowed() const; @@ -52,9 +75,41 @@ bool warmup_url_probe_failed); private: + // Map from network IDs to network properties. + typedef std::map<std::string, NetworkProperties> NetworkPropertiesContainer; + + // PrefManager writes or updates the network properties prefs. Created on + // UI thread, and should be used on the UI thread. May be destroyed on UI + // or IO thread. + class PrefManager; + + // Called when there is a change in the network property of the current + // network. + void OnChangeInNetworkPropertyOnIOThread(); + + static NetworkPropertiesContainer ConvertDictionaryValueToParsedPrefs( + const base::Value* value); + + // Task runner on which prefs should be accessed. + scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; + + // Network properties of different networks. Should be accessed on the IO + // thread. + NetworkPropertiesContainer network_properties_container_; + + // ID of the current network. + std::string network_id_; + // State of the proxies on the current network. NetworkProperties network_properties_; + std::unique_ptr<PrefManager> pref_manager_; + + // Should be dereferenced only on the UI thread. + base::WeakPtr<PrefManager> pref_manager_weak_ptr_; + + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(NetworkPropertiesManager); };
diff --git a/components/data_reduction_proxy/core/browser/network_properties_manager_unittest.cc b/components/data_reduction_proxy/core/browser/network_properties_manager_unittest.cc index b45edc2..1b6a365 100644 --- a/components/data_reduction_proxy/core/browser/network_properties_manager_unittest.cc +++ b/components/data_reduction_proxy/core/browser/network_properties_manager_unittest.cc
@@ -5,14 +5,38 @@ #include "components/data_reduction_proxy/core/browser/network_properties_manager.h" #include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/histogram_tester.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h" namespace data_reduction_proxy { namespace { +class TestNetworkPropertiesManager : public NetworkPropertiesManager { + public: + TestNetworkPropertiesManager( + PrefService* pref_service, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) + : NetworkPropertiesManager(pref_service, ui_task_runner) {} + ~TestNetworkPropertiesManager() override {} +}; + TEST(NetworkPropertyTest, TestSetterGetterCaptivePortal) { - NetworkPropertiesManager network_properties_manager; + base::HistogramTester histogram_tester; + TestingPrefServiceSimple test_prefs; + test_prefs.registry()->RegisterDictionaryPref(prefs::kNetworkProperties); + base::MessageLoopForIO loop; + TestNetworkPropertiesManager network_properties_manager( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + + std::string network_id("test"); + network_properties_manager.OnChangeInNetworkID(network_id); EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); EXPECT_TRUE(network_properties_manager.IsSecureProxyAllowed()); @@ -24,6 +48,20 @@ EXPECT_TRUE(network_properties_manager.IsCaptivePortal()); EXPECT_FALSE(network_properties_manager.HasWarmupURLProbeFailed(false)); EXPECT_FALSE(network_properties_manager.HasWarmupURLProbeFailed(true)); + base::RunLoop().RunUntilIdle(); + + // Verify the prefs. + EXPECT_EQ(1u, test_prefs.GetDictionary(prefs::kNetworkProperties)->size()); + EXPECT_FALSE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey("mismatched_network_id")); + EXPECT_TRUE( + test_prefs.GetDictionary(prefs::kNetworkProperties)->HasKey(network_id)); + { + TestNetworkPropertiesManager network_properties_manager_2( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + network_properties_manager_2.OnChangeInNetworkID(network_id); + EXPECT_TRUE(network_properties_manager_2.IsCaptivePortal()); + } network_properties_manager.SetIsCaptivePortal(false); EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); @@ -32,10 +70,29 @@ EXPECT_FALSE(network_properties_manager.IsCaptivePortal()); EXPECT_FALSE(network_properties_manager.HasWarmupURLProbeFailed(false)); EXPECT_FALSE(network_properties_manager.HasWarmupURLProbeFailed(true)); + base::RunLoop().RunUntilIdle(); + + { + TestNetworkPropertiesManager network_properties_manager_2( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + network_properties_manager_2.OnChangeInNetworkID(network_id); + EXPECT_FALSE(network_properties_manager_2.IsCaptivePortal()); + } + + // Verify the prefs. + EXPECT_EQ(1u, test_prefs.GetDictionary(prefs::kNetworkProperties)->size()); + EXPECT_FALSE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey("mismatched_network_id")); + EXPECT_TRUE( + test_prefs.GetDictionary(prefs::kNetworkProperties)->HasKey(network_id)); } TEST(NetworkPropertyTest, TestSetterGetterDisallowedByCarrier) { - NetworkPropertiesManager network_properties_manager; + TestingPrefServiceSimple test_prefs; + test_prefs.registry()->RegisterDictionaryPref(prefs::kNetworkProperties); + base::MessageLoopForIO loop; + TestNetworkPropertiesManager network_properties_manager( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); EXPECT_TRUE(network_properties_manager.IsSecureProxyAllowed()); @@ -58,7 +115,11 @@ } TEST(NetworkPropertyTest, TestWarmupURLFailedOnSecureProxy) { - NetworkPropertiesManager network_properties_manager; + TestingPrefServiceSimple test_prefs; + test_prefs.registry()->RegisterDictionaryPref(prefs::kNetworkProperties); + base::MessageLoopForIO loop; + TestNetworkPropertiesManager network_properties_manager( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); EXPECT_TRUE(network_properties_manager.IsSecureProxyAllowed()); @@ -81,7 +142,11 @@ } TEST(NetworkPropertyTest, TestWarmupURLFailedOnInSecureProxy) { - NetworkPropertiesManager network_properties_manager; + TestingPrefServiceSimple test_prefs; + test_prefs.registry()->RegisterDictionaryPref(prefs::kNetworkProperties); + base::MessageLoopForIO loop; + TestNetworkPropertiesManager network_properties_manager( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); EXPECT_TRUE(network_properties_manager.IsSecureProxyAllowed()); @@ -103,6 +168,219 @@ EXPECT_FALSE(network_properties_manager.HasWarmupURLProbeFailed(true)); } +TEST(NetworkPropertyTest, TestLimitPrefSize) { + TestingPrefServiceSimple test_prefs; + test_prefs.registry()->RegisterDictionaryPref(prefs::kNetworkProperties); + base::MessageLoopForIO loop; + TestNetworkPropertiesManager network_properties_manager( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + + size_t num_network_ids = 100; + + for (size_t i = 0; i < num_network_ids; ++i) { + std::string network_id("test" + base::IntToString(i)); + network_properties_manager.OnChangeInNetworkID(network_id); + + // State should be reset when there is a change in the network ID. + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + EXPECT_TRUE(network_properties_manager.IsSecureProxyAllowed()); + + network_properties_manager.SetIsCaptivePortal(true); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + EXPECT_FALSE(network_properties_manager.IsSecureProxyAllowed()); + EXPECT_FALSE(network_properties_manager.IsSecureProxyDisallowedByCarrier()); + EXPECT_TRUE(network_properties_manager.IsCaptivePortal()); + EXPECT_FALSE(network_properties_manager.HasWarmupURLProbeFailed(false)); + EXPECT_FALSE(network_properties_manager.HasWarmupURLProbeFailed(true)); + + base::RunLoop().RunUntilIdle(); + } + + // Pref size should be bounded to 10. + EXPECT_EQ(10u, test_prefs.GetDictionary(prefs::kNetworkProperties)->size()); + EXPECT_FALSE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey("mismatched_network_id")); + + // The last 10 network IDs are guaranteed to be present in the prefs. + for (size_t i = num_network_ids - 10; i < num_network_ids; ++i) { + EXPECT_TRUE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey("test" + base::IntToString(i))); + } + + { + TestNetworkPropertiesManager network_properties_manager_2( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + for (size_t i = 0; i < num_network_ids; ++i) { + std::string network_id("test" + base::IntToString(i)); + network_properties_manager_2.OnChangeInNetworkID(network_id); + + EXPECT_EQ(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey(network_id), + network_properties_manager_2.IsCaptivePortal()); + EXPECT_FALSE( + network_properties_manager_2.IsSecureProxyDisallowedByCarrier()); + EXPECT_FALSE(network_properties_manager_2.HasWarmupURLProbeFailed(false)); + EXPECT_FALSE(network_properties_manager_2.HasWarmupURLProbeFailed(true)); + } + } +} + +TEST(NetworkPropertyTest, TestChangeNetworkIDBackAndForth) { + TestingPrefServiceSimple test_prefs; + test_prefs.registry()->RegisterDictionaryPref(prefs::kNetworkProperties); + base::MessageLoopForIO loop; + TestNetworkPropertiesManager network_properties_manager( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + + // First network ID has a captive portal. + std::string first_network_id("test1"); + network_properties_manager.OnChangeInNetworkID(first_network_id); + // State should be reset when there is a change in the network ID. + EXPECT_FALSE(network_properties_manager.IsCaptivePortal()); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + network_properties_manager.SetIsCaptivePortal(true); + EXPECT_TRUE(network_properties_manager.IsCaptivePortal()); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + base::RunLoop().RunUntilIdle(); + + // Warmup probe failed on the insecure proxy for the second network ID. + std::string second_network_id("test2"); + network_properties_manager.OnChangeInNetworkID(second_network_id); + // State should be reset when there is a change in the network ID. + EXPECT_FALSE(network_properties_manager.IsCaptivePortal()); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + network_properties_manager.SetHasWarmupURLProbeFailed(false, true); + EXPECT_FALSE(network_properties_manager.IsCaptivePortal()); + EXPECT_FALSE(network_properties_manager.IsInsecureProxyAllowed()); + base::RunLoop().RunUntilIdle(); + + // Change back to |first_network_id|. + network_properties_manager.OnChangeInNetworkID(first_network_id); + EXPECT_TRUE(network_properties_manager.IsCaptivePortal()); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + + // Change back to |second_network_id|. + network_properties_manager.OnChangeInNetworkID(second_network_id); + EXPECT_FALSE(network_properties_manager.IsCaptivePortal()); + EXPECT_FALSE(network_properties_manager.IsInsecureProxyAllowed()); + + // Verify the prefs. + EXPECT_EQ(2u, test_prefs.GetDictionary(prefs::kNetworkProperties)->size()); + EXPECT_FALSE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey("mismatched_network_id")); + EXPECT_TRUE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey(first_network_id)); + EXPECT_TRUE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey(second_network_id)); +} + +TEST(NetworkPropertyTest, TestNetworkQualitiesOverwrite) { + TestingPrefServiceSimple test_prefs; + test_prefs.registry()->RegisterDictionaryPref(prefs::kNetworkProperties); + base::MessageLoopForIO loop; + TestNetworkPropertiesManager network_properties_manager( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + + // First network ID has a captive portal. + std::string first_network_id("test1"); + network_properties_manager.OnChangeInNetworkID(first_network_id); + // State should be reset when there is a change in the network ID. + EXPECT_FALSE(network_properties_manager.IsCaptivePortal()); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + network_properties_manager.SetIsCaptivePortal(true); + EXPECT_TRUE(network_properties_manager.IsCaptivePortal()); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + base::RunLoop().RunUntilIdle(); + + // Warmup probe failed on the insecure proxy for the second network ID. + std::string second_network_id("test2"); + network_properties_manager.OnChangeInNetworkID(second_network_id); + // State should be reset when there is a change in the network ID. + EXPECT_FALSE(network_properties_manager.IsCaptivePortal()); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + network_properties_manager.SetHasWarmupURLProbeFailed(false, true); + EXPECT_FALSE(network_properties_manager.IsCaptivePortal()); + EXPECT_FALSE(network_properties_manager.IsInsecureProxyAllowed()); + base::RunLoop().RunUntilIdle(); + + // Change back to |first_network_id|. + network_properties_manager.OnChangeInNetworkID(first_network_id); + EXPECT_TRUE(network_properties_manager.IsCaptivePortal()); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + network_properties_manager.SetHasWarmupURLProbeFailed(false, true); + + // Change to |first_network_id|. + network_properties_manager.OnChangeInNetworkID(first_network_id); + EXPECT_TRUE(network_properties_manager.IsCaptivePortal()); + EXPECT_FALSE(network_properties_manager.IsInsecureProxyAllowed()); + + // Verify the prefs. + EXPECT_EQ(2u, test_prefs.GetDictionary(prefs::kNetworkProperties)->size()); + EXPECT_FALSE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey("mismatched_network_id")); + EXPECT_TRUE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey(first_network_id)); + EXPECT_TRUE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey(second_network_id)); +} + +TEST(NetworkPropertyTest, TestDeleteHistory) { + base::HistogramTester histogram_tester; + TestingPrefServiceSimple test_prefs; + test_prefs.registry()->RegisterDictionaryPref(prefs::kNetworkProperties); + base::MessageLoopForIO loop; + TestNetworkPropertiesManager network_properties_manager( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + + std::string network_id("test"); + network_properties_manager.OnChangeInNetworkID(network_id); + histogram_tester.ExpectUniqueSample( + "DataReductionProxy.NetworkProperties.CacheHit", false, 1); + + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + EXPECT_TRUE(network_properties_manager.IsSecureProxyAllowed()); + + network_properties_manager.SetIsCaptivePortal(true); + EXPECT_TRUE(network_properties_manager.IsInsecureProxyAllowed()); + EXPECT_FALSE(network_properties_manager.IsSecureProxyAllowed()); + EXPECT_FALSE(network_properties_manager.IsSecureProxyDisallowedByCarrier()); + EXPECT_TRUE(network_properties_manager.IsCaptivePortal()); + EXPECT_FALSE(network_properties_manager.HasWarmupURLProbeFailed(false)); + EXPECT_FALSE(network_properties_manager.HasWarmupURLProbeFailed(true)); + base::RunLoop().RunUntilIdle(); + + // Verify the prefs. + EXPECT_EQ(1u, test_prefs.GetDictionary(prefs::kNetworkProperties)->size()); + EXPECT_FALSE(test_prefs.GetDictionary(prefs::kNetworkProperties) + ->HasKey("mismatched_network_id")); + EXPECT_TRUE( + test_prefs.GetDictionary(prefs::kNetworkProperties)->HasKey(network_id)); + { + TestNetworkPropertiesManager network_properties_manager_2( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + network_properties_manager_2.OnChangeInNetworkID(network_id); + EXPECT_TRUE(network_properties_manager_2.IsCaptivePortal()); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.NetworkProperties.CacheHit", true, 1); + histogram_tester.ExpectTotalCount( + "DataReductionProxy.NetworkProperties.CacheHit", 2); + } + + // Pref should be cleared. + network_properties_manager.DeleteHistory(); + base::RunLoop().RunUntilIdle(); + { + TestNetworkPropertiesManager network_properties_manager_2( + &test_prefs, base::ThreadTaskRunnerHandle::Get()); + network_properties_manager_2.OnChangeInNetworkID(network_id); + EXPECT_FALSE(network_properties_manager_2.IsCaptivePortal()); + histogram_tester.ExpectBucketCount( + "DataReductionProxy.NetworkProperties.CacheHit", false, 2); + histogram_tester.ExpectTotalCount( + "DataReductionProxy.NetworkProperties.CacheHit", 3); + } +} + } // namespace } // namespace data_reduction_proxy \ No newline at end of file
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc index 7d2083e..0acc086 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc
@@ -209,5 +209,9 @@ const char kDataReductionProxyLastConfigRetrievalTime[] = "data_reduction.last_config_retrieval_time"; +// Pref to store the properties of the different networks. The pref stores the +// map of network IDs and their respective network properties. +const char kNetworkProperties[] = "data_reduction.network_properties"; + } // namespace prefs } // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h index 4bbff19..5738c30 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h
@@ -52,6 +52,7 @@ extern const char kHttpOriginalContentLength[]; extern const char kHttpReceivedContentLength[]; extern const char kDataReductionProxyLastConfigRetrievalTime[]; +extern const char kNetworkProperties[]; } // namespace prefs } // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/proto/network_properties.proto b/components/data_reduction_proxy/proto/network_properties.proto index aa82b45..0a381811 100644 --- a/components/data_reduction_proxy/proto/network_properties.proto +++ b/components/data_reduction_proxy/proto/network_properties.proto
@@ -19,4 +19,5 @@ optional bool has_captive_portal = 2; optional ProxyFlags secure_proxy_flags = 3; optional ProxyFlags insecure_proxy_flags = 4; + optional int64 last_modified = 5; } \ No newline at end of file
diff --git a/components/exo/wayland/aura-shell-client-protocol.h b/components/exo/wayland/aura-shell-client-protocol.h index 2792ac45..8131b8a 100644 --- a/components/exo/wayland/aura-shell-client-protocol.h +++ b/components/exo/wayland/aura-shell-client-protocol.h
@@ -16,6 +16,7 @@ * @section page_ifaces_aura_shell Interfaces * - @subpage page_iface_zaura_shell - aura_shell * - @subpage page_iface_zaura_surface - aura shell interface to a wl_surface + * - @subpage page_iface_zaura_output - aura shell interface to a wl_output * @section page_copyright_aura_shell Copyright * <pre> * @@ -41,7 +42,9 @@ * DEALINGS IN THE SOFTWARE. * </pre> */ +struct wl_output; struct wl_surface; +struct zaura_output; struct zaura_shell; struct zaura_surface; @@ -81,6 +84,22 @@ * client to access aura shell specific functionality for surface. */ extern const struct wl_interface zaura_surface_interface; +/** + * @page page_iface_zaura_output zaura_output + * @section page_iface_zaura_output_desc Description + * + * An additional interface to a wl_output object, which allows the + * client to access aura shell specific functionality for output. + * @section page_iface_zaura_output_api API + * See @ref iface_zaura_output. + */ +/** + * @defgroup iface_zaura_output The zaura_output interface + * + * An additional interface to a wl_output object, which allows the + * client to access aura shell specific functionality for output. + */ +extern const struct wl_interface zaura_output_interface; #ifndef ZAURA_SHELL_ERROR_ENUM #define ZAURA_SHELL_ERROR_ENUM @@ -89,16 +108,25 @@ * the surface already has an aura surface object associated */ ZAURA_SHELL_ERROR_AURA_SURFACE_EXISTS = 0, + /** + * the output already has an aura output object associated + */ + ZAURA_SHELL_ERROR_AURA_OUTPUT_EXISTS = 1, }; #endif /* ZAURA_SHELL_ERROR_ENUM */ #define ZAURA_SHELL_GET_AURA_SURFACE 0 +#define ZAURA_SHELL_GET_AURA_OUTPUT 1 /** * @ingroup iface_zaura_shell */ #define ZAURA_SHELL_GET_AURA_SURFACE_SINCE_VERSION 1 +/** + * @ingroup iface_zaura_shell + */ +#define ZAURA_SHELL_GET_AURA_OUTPUT_SINCE_VERSION 2 /** @ingroup iface_zaura_shell */ static inline void @@ -146,6 +174,23 @@ return (struct zaura_surface *) id; } +/** + * @ingroup iface_zaura_shell + * + * Instantiate an interface extension for the given wl_output to + * provide aura shell functionality. + */ +static inline struct zaura_output * +zaura_shell_get_aura_output(struct zaura_shell *zaura_shell, struct wl_output *output) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_constructor((struct wl_proxy *) zaura_shell, + ZAURA_SHELL_GET_AURA_OUTPUT, &zaura_output_interface, NULL, output); + + return (struct zaura_output *) id; +} + #ifndef ZAURA_SURFACE_FRAME_TYPE_ENUM #define ZAURA_SURFACE_FRAME_TYPE_ENUM /** @@ -171,12 +216,17 @@ #endif /* ZAURA_SURFACE_FRAME_TYPE_ENUM */ #define ZAURA_SURFACE_SET_FRAME 0 +#define ZAURA_SURFACE_SET_PARENT 1 /** * @ingroup iface_zaura_surface */ #define ZAURA_SURFACE_SET_FRAME_SINCE_VERSION 1 +/** + * @ingroup iface_zaura_surface + */ +#define ZAURA_SURFACE_SET_PARENT_SINCE_VERSION 2 /** @ingroup iface_zaura_surface */ static inline void @@ -217,6 +267,126 @@ ZAURA_SURFACE_SET_FRAME, type); } +/** + * @ingroup iface_zaura_surface + * + * Set the "parent" of this surface. "x" and "y" arguments specify the + * initial position for surface relative to parent. + */ +static inline void +zaura_surface_set_parent(struct zaura_surface *zaura_surface, struct zaura_surface *parent, int32_t x, int32_t y) +{ + wl_proxy_marshal((struct wl_proxy *) zaura_surface, + ZAURA_SURFACE_SET_PARENT, parent, x, y); +} + +#ifndef ZAURA_OUTPUT_SCALE_PROPERTY_ENUM +#define ZAURA_OUTPUT_SCALE_PROPERTY_ENUM +/** + * @ingroup iface_zaura_output + * scale information + * + * These flags describe properties of an output scale. + * They are used in the flags bitfield of the scale event. + */ +enum zaura_output_scale_property { + /** + * indicates this is the current scale + */ + ZAURA_OUTPUT_SCALE_PROPERTY_CURRENT = 0x1, + /** + * indicates this is the preferred scale + */ + ZAURA_OUTPUT_SCALE_PROPERTY_PREFERRED = 0x2, +}; +#endif /* ZAURA_OUTPUT_SCALE_PROPERTY_ENUM */ + +#ifndef ZAURA_OUTPUT_SCALE_FACTOR_ENUM +#define ZAURA_OUTPUT_SCALE_FACTOR_ENUM +enum zaura_output_scale_factor { + ZAURA_OUTPUT_SCALE_FACTOR_0500 = 500, + ZAURA_OUTPUT_SCALE_FACTOR_0600 = 600, + ZAURA_OUTPUT_SCALE_FACTOR_0625 = 625, + ZAURA_OUTPUT_SCALE_FACTOR_0750 = 750, + ZAURA_OUTPUT_SCALE_FACTOR_0800 = 800, + ZAURA_OUTPUT_SCALE_FACTOR_1000 = 1000, + ZAURA_OUTPUT_SCALE_FACTOR_1125 = 1125, + ZAURA_OUTPUT_SCALE_FACTOR_1200 = 1200, + ZAURA_OUTPUT_SCALE_FACTOR_1250 = 1250, + ZAURA_OUTPUT_SCALE_FACTOR_1500 = 1500, + ZAURA_OUTPUT_SCALE_FACTOR_1600 = 1600, + ZAURA_OUTPUT_SCALE_FACTOR_2000 = 2000, +}; +#endif /* ZAURA_OUTPUT_SCALE_FACTOR_ENUM */ + +/** + * @ingroup iface_zaura_output + * @struct zaura_output_listener + */ +struct zaura_output_listener { + /** + * advertise available scales for the output + * + * The scale event describes an available scale for the output. + * + * The event is sent when binding to the output object and there + * will always be one scale, the current scale. The event is sent + * again if an output changes scale, for the scale that is now + * current. In other words, the current scale is always the last + * scale that was received with the current flag set. + * @param flags bitfield of scale flags + * @param scale output scale + */ + void (*scale)(void *data, + struct zaura_output *zaura_output, + uint32_t flags, + uint32_t scale); +}; + +/** + * @ingroup iface_zaura_output + */ +static inline int +zaura_output_add_listener(struct zaura_output *zaura_output, + const struct zaura_output_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zaura_output, + (void (**)(void)) listener, data); +} + +/** + * @ingroup iface_zaura_output + */ +#define ZAURA_OUTPUT_SCALE_SINCE_VERSION 1 + + +/** @ingroup iface_zaura_output */ +static inline void +zaura_output_set_user_data(struct zaura_output *zaura_output, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zaura_output, user_data); +} + +/** @ingroup iface_zaura_output */ +static inline void * +zaura_output_get_user_data(struct zaura_output *zaura_output) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zaura_output); +} + +static inline uint32_t +zaura_output_get_version(struct zaura_output *zaura_output) +{ + return wl_proxy_get_version((struct wl_proxy *) zaura_output); +} + +/** @ingroup iface_zaura_output */ +static inline void +zaura_output_destroy(struct zaura_output *zaura_output) +{ + wl_proxy_destroy((struct wl_proxy *) zaura_output); +} + #ifdef __cplusplus } #endif
diff --git a/components/exo/wayland/aura-shell-protocol.c b/components/exo/wayland/aura-shell-protocol.c index 61bb7b5..8dc4341 100644 --- a/components/exo/wayland/aura-shell-protocol.c +++ b/components/exo/wayland/aura-shell-protocol.c
@@ -27,32 +27,52 @@ #include <stdint.h> #include "wayland-util.h" +extern const struct wl_interface wl_output_interface; extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface zaura_output_interface; extern const struct wl_interface zaura_surface_interface; static const struct wl_interface *types[] = { NULL, + NULL, &zaura_surface_interface, &wl_surface_interface, + &zaura_output_interface, + &wl_output_interface, + &zaura_surface_interface, + NULL, + NULL, }; static const struct wl_message zaura_shell_requests[] = { - { "get_aura_surface", "no", types + 1 }, + { "get_aura_surface", "no", types + 2 }, + { "get_aura_output", "2no", types + 4 }, }; WL_EXPORT const struct wl_interface zaura_shell_interface = { - "zaura_shell", 1, - 1, zaura_shell_requests, + "zaura_shell", 2, + 2, zaura_shell_requests, 0, NULL, }; static const struct wl_message zaura_surface_requests[] = { { "set_frame", "u", types + 0 }, + { "set_parent", "2?oii", types + 6 }, }; WL_EXPORT const struct wl_interface zaura_surface_interface = { - "zaura_surface", 1, - 1, zaura_surface_requests, + "zaura_surface", 2, + 2, zaura_surface_requests, 0, NULL, }; +static const struct wl_message zaura_output_events[] = { + { "scale", "uu", types + 0 }, +}; + +WL_EXPORT const struct wl_interface zaura_output_interface = { + "zaura_output", 2, + 0, NULL, + 1, zaura_output_events, +}; +
diff --git a/components/exo/wayland/aura-shell-server-protocol.h b/components/exo/wayland/aura-shell-server-protocol.h index 37b9a9e..9328c45 100644 --- a/components/exo/wayland/aura-shell-server-protocol.h +++ b/components/exo/wayland/aura-shell-server-protocol.h
@@ -19,6 +19,7 @@ * @section page_ifaces_aura_shell Interfaces * - @subpage page_iface_zaura_shell - aura_shell * - @subpage page_iface_zaura_surface - aura shell interface to a wl_surface + * - @subpage page_iface_zaura_output - aura shell interface to a wl_output * @section page_copyright_aura_shell Copyright * <pre> * @@ -44,7 +45,9 @@ * DEALINGS IN THE SOFTWARE. * </pre> */ +struct wl_output; struct wl_surface; +struct zaura_output; struct zaura_shell; struct zaura_surface; @@ -84,6 +87,22 @@ * client to access aura shell specific functionality for surface. */ extern const struct wl_interface zaura_surface_interface; +/** + * @page page_iface_zaura_output zaura_output + * @section page_iface_zaura_output_desc Description + * + * An additional interface to a wl_output object, which allows the + * client to access aura shell specific functionality for output. + * @section page_iface_zaura_output_api API + * See @ref iface_zaura_output. + */ +/** + * @defgroup iface_zaura_output The zaura_output interface + * + * An additional interface to a wl_output object, which allows the + * client to access aura shell specific functionality for output. + */ +extern const struct wl_interface zaura_output_interface; #ifndef ZAURA_SHELL_ERROR_ENUM #define ZAURA_SHELL_ERROR_ENUM @@ -92,6 +111,10 @@ * the surface already has an aura surface object associated */ ZAURA_SHELL_ERROR_AURA_SURFACE_EXISTS = 0, + /** + * the output already has an aura output object associated + */ + ZAURA_SHELL_ERROR_AURA_OUTPUT_EXISTS = 1, }; #endif /* ZAURA_SHELL_ERROR_ENUM */ @@ -114,6 +137,19 @@ struct wl_resource *resource, uint32_t id, struct wl_resource *surface); + /** + * extend output interface for aura shell + * + * Instantiate an interface extension for the given wl_output to + * provide aura shell functionality. + * @param id the new aura output interface id + * @param output the output + * @since 2 + */ + void (*get_aura_output)(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *output); }; @@ -121,6 +157,10 @@ * @ingroup iface_zaura_shell */ #define ZAURA_SHELL_GET_AURA_SURFACE_SINCE_VERSION 1 +/** + * @ingroup iface_zaura_shell + */ +#define ZAURA_SHELL_GET_AURA_OUTPUT_SINCE_VERSION 2 #ifndef ZAURA_SURFACE_FRAME_TYPE_ENUM #define ZAURA_SURFACE_FRAME_TYPE_ENUM @@ -160,6 +200,18 @@ void (*set_frame)(struct wl_client *client, struct wl_resource *resource, uint32_t type); + /** + * set the parent of this surface + * + * Set the "parent" of this surface. "x" and "y" arguments + * specify the initial position for surface relative to parent. + * @since 2 + */ + void (*set_parent)(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *parent, + int32_t x, + int32_t y); }; @@ -167,6 +219,70 @@ * @ingroup iface_zaura_surface */ #define ZAURA_SURFACE_SET_FRAME_SINCE_VERSION 1 +/** + * @ingroup iface_zaura_surface + */ +#define ZAURA_SURFACE_SET_PARENT_SINCE_VERSION 2 + +#ifndef ZAURA_OUTPUT_SCALE_PROPERTY_ENUM +#define ZAURA_OUTPUT_SCALE_PROPERTY_ENUM +/** + * @ingroup iface_zaura_output + * scale information + * + * These flags describe properties of an output scale. + * They are used in the flags bitfield of the scale event. + */ +enum zaura_output_scale_property { + /** + * indicates this is the current scale + */ + ZAURA_OUTPUT_SCALE_PROPERTY_CURRENT = 0x1, + /** + * indicates this is the preferred scale + */ + ZAURA_OUTPUT_SCALE_PROPERTY_PREFERRED = 0x2, +}; +#endif /* ZAURA_OUTPUT_SCALE_PROPERTY_ENUM */ + +#ifndef ZAURA_OUTPUT_SCALE_FACTOR_ENUM +#define ZAURA_OUTPUT_SCALE_FACTOR_ENUM +enum zaura_output_scale_factor { + ZAURA_OUTPUT_SCALE_FACTOR_0500 = 500, + ZAURA_OUTPUT_SCALE_FACTOR_0600 = 600, + ZAURA_OUTPUT_SCALE_FACTOR_0625 = 625, + ZAURA_OUTPUT_SCALE_FACTOR_0750 = 750, + ZAURA_OUTPUT_SCALE_FACTOR_0800 = 800, + ZAURA_OUTPUT_SCALE_FACTOR_1000 = 1000, + ZAURA_OUTPUT_SCALE_FACTOR_1125 = 1125, + ZAURA_OUTPUT_SCALE_FACTOR_1200 = 1200, + ZAURA_OUTPUT_SCALE_FACTOR_1250 = 1250, + ZAURA_OUTPUT_SCALE_FACTOR_1500 = 1500, + ZAURA_OUTPUT_SCALE_FACTOR_1600 = 1600, + ZAURA_OUTPUT_SCALE_FACTOR_2000 = 2000, +}; +#endif /* ZAURA_OUTPUT_SCALE_FACTOR_ENUM */ + +#define ZAURA_OUTPUT_SCALE 0 + +/** + * @ingroup iface_zaura_output + */ +#define ZAURA_OUTPUT_SCALE_SINCE_VERSION 1 + + +/** + * @ingroup iface_zaura_output + * Sends an scale event to the client owning the resource. + * @param resource_ The client's resource + * @param flags bitfield of scale flags + * @param scale output scale + */ +static inline void +zaura_output_send_scale(struct wl_resource *resource_, uint32_t flags, uint32_t scale) +{ + wl_resource_post_event(resource_, ZAURA_OUTPUT_SCALE, flags, scale); +} #ifdef __cplusplus }
diff --git a/components/exo/wayland/protocol/aura-shell.xml b/components/exo/wayland/protocol/aura-shell.xml index 01f8e33..f4d99e7 100644 --- a/components/exo/wayland/protocol/aura-shell.xml +++ b/components/exo/wayland/protocol/aura-shell.xml
@@ -24,7 +24,7 @@ DEALINGS IN THE SOFTWARE. </copyright> - <interface name="zaura_shell" version="1"> + <interface name="zaura_shell" version="2"> <description summary="aura_shell"> The global interface exposing aura shell capabilities is used to instantiate an interface extension for a wl_surface object. @@ -35,6 +35,8 @@ <enum name="error"> <entry name="aura_surface_exists" value="0" summary="the surface already has an aura surface object associated"/> + <entry name="aura_output_exists" value="1" + summary="the output already has an aura output object associated"/> </enum> <request name="get_aura_surface"> @@ -50,9 +52,23 @@ <arg name="surface" type="object" interface="wl_surface" summary="the surface"/> </request> + + <!-- Version 2 additions --> + + <request name="get_aura_output" since="2"> + <description summary="extend output interface for aura shell"> + Instantiate an interface extension for the given wl_output to + provide aura shell functionality. + </description> + + <arg name="id" type="new_id" interface="zaura_output" + summary="the new aura output interface id"/> + <arg name="output" type="object" interface="wl_output" + summary="the output"/> + </request> </interface> - <interface name="zaura_surface" version="1"> + <interface name="zaura_surface" version="2"> <description summary="aura shell interface to a wl_surface"> An additional interface to a wl_surface object, which allows the client to access aura shell specific functionality for surface. @@ -73,6 +89,67 @@ </description> <arg name="type" type="uint" summary="the new frame type"/> </request> + + <!-- Version 2 additions --> + + <request name="set_parent" since="2"> + <description summary="set the parent of this surface"> + Set the "parent" of this surface. "x" and "y" arguments specify the + initial position for surface relative to parent. + </description> + <arg name="parent" type="object" interface="zaura_surface" allow-null="true"/> + <arg name="x" type="int"/> + <arg name="y" type="int"/> + </request> </interface> + <interface name="zaura_output" version="2"> + <description summary="aura shell interface to a wl_output"> + An additional interface to a wl_output object, which allows the + client to access aura shell specific functionality for output. + </description> + + <!-- Version 2 additions --> + + <enum name="scale_property" bitfield="true"> + <description summary="scale information"> + These flags describe properties of an output scale. + They are used in the flags bitfield of the scale event. + </description> + <entry name="current" value="0x1" + summary="indicates this is the current scale"/> + <entry name="preferred" value="0x2" + summary="indicates this is the preferred scale"/> + </enum> + + <enum name="scale_factor"> + <entry name="0500" value="500"/> + <entry name="0600" value="600"/> + <entry name="0625" value="625"/> + <entry name="0750" value="750"/> + <entry name="0800" value="800"/> + <entry name="1000" value="1000"/> + <entry name="1125" value="1125"/> + <entry name="1200" value="1200"/> + <entry name="1250" value="1250"/> + <entry name="1500" value="1500"/> + <entry name="1600" value="1600"/> + <entry name="2000" value="2000"/> + </enum> + + <event name="scale"> + <description summary="advertise available scales for the output"> + The scale event describes an available scale for the output. + + The event is sent when binding to the output object and there + will always be one scale, the current scale. The event is sent + again if an output changes scale, for the scale that is now + current. In other words, the current scale is always the last + scale that was received with the current flag set. + </description> + <arg name="flags" type="uint" enum="scale_property" summary="bitfield of scale flags"/> + <arg name="scale" type="uint" enum="scale_factor" summary="output scale"/> + </event> + </interface> + </protocol>
diff --git a/components/viz/common/gpu/in_process_context_provider.cc b/components/viz/common/gpu/in_process_context_provider.cc index 7c94a6d..46c479fb 100644 --- a/components/viz/common/gpu/in_process_context_provider.cc +++ b/components/viz/common/gpu/in_process_context_provider.cc
@@ -30,7 +30,6 @@ #include "third_party/khronos/GLES2/gl2ext.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" -#include "ui/gfx/native_widget_types.h" namespace viz { @@ -52,7 +51,7 @@ InProcessContextProvider::InProcessContextProvider( scoped_refptr<gpu::InProcessCommandBuffer::Service> service, - gpu::SurfaceHandle widget, + gpu::SurfaceHandle surface_handle, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gpu::ImageFactory* image_factory, const gpu::SharedMemoryLimits& limits, @@ -62,8 +61,8 @@ context_result_(context_->Initialize( std::move(service), nullptr, - (widget == gpu::kNullSurfaceHandle), - widget, + (surface_handle == gpu::kNullSurfaceHandle), + surface_handle, (shared_context ? shared_context->context_.get() : nullptr), attributes_, limits,
diff --git a/components/viz/common/gpu/in_process_context_provider.h b/components/viz/common/gpu/in_process_context_provider.h index d73409c..eeef36d 100644 --- a/components/viz/common/gpu/in_process_context_provider.h +++ b/components/viz/common/gpu/in_process_context_provider.h
@@ -37,7 +37,7 @@ public: InProcessContextProvider( scoped_refptr<gpu::InProcessCommandBuffer::Service> service, - gpu::SurfaceHandle widget, + gpu::SurfaceHandle surface_handle, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gpu::ImageFactory* image_factory, const gpu::SharedMemoryLimits& limits,
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc index 17f812d7..ca1af0f 100644 --- a/components/viz/host/host_frame_sink_manager.cc +++ b/components/viz/host/host_frame_sink_manager.cc
@@ -97,6 +97,7 @@ void HostFrameSinkManager::CreateRootCompositorFrameSink( const FrameSinkId& frame_sink_id, gpu::SurfaceHandle surface_handle, + bool force_software_compositing, const RendererSettings& renderer_settings, mojom::CompositorFrameSinkAssociatedRequest request, mojom::CompositorFrameSinkClientPtr client, @@ -109,8 +110,9 @@ data.has_created_compositor_frame_sink = true; frame_sink_manager_->CreateRootCompositorFrameSink( - frame_sink_id, surface_handle, renderer_settings, std::move(request), - std::move(client), std::move(display_private_request)); + frame_sink_id, surface_handle, force_software_compositing, + renderer_settings, std::move(request), std::move(client), + std::move(display_private_request)); display_hit_test_query_[frame_sink_id] = base::MakeUnique<HitTestQuery>(); }
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h index 5e007f3..d91ed439 100644 --- a/components/viz/host/host_frame_sink_manager.h +++ b/components/viz/host/host_frame_sink_manager.h
@@ -93,6 +93,7 @@ void CreateRootCompositorFrameSink( const FrameSinkId& frame_sink_id, gpu::SurfaceHandle surface_handle, + bool force_software_compositing, const RendererSettings& renderer_settings, mojom::CompositorFrameSinkAssociatedRequest request, mojom::CompositorFrameSinkClientPtr client,
diff --git a/components/viz/host/host_frame_sink_manager_unittest.cc b/components/viz/host/host_frame_sink_manager_unittest.cc index a08db51..697c8b4 100644 --- a/components/viz/host/host_frame_sink_manager_unittest.cc +++ b/components/viz/host/host_frame_sink_manager_unittest.cc
@@ -74,6 +74,7 @@ void CreateRootCompositorFrameSink( const FrameSinkId& frame_sink_id, gpu::SurfaceHandle surface_handle, + bool force_software_compositor, const RendererSettings& renderer_settings, mojom::CompositorFrameSinkAssociatedRequest request, mojom::CompositorFrameSinkClientPtr client, @@ -520,6 +521,7 @@ EXPECT_FALSE(DisplayHitTestQueryExists(kFrameSinkChild1)); host().CreateRootCompositorFrameSink( kFrameSinkChild1, 0 /* surface_handle */, + false /* force_software_compositing */, RendererSettings() /* renderer_settings */, nullptr /* request */, nullptr /* client */, nullptr /* display_private_request */); EXPECT_TRUE(DisplayHitTestQueryExists(kFrameSinkChild1)); @@ -596,6 +598,7 @@ mojom::DisplayPrivateAssociatedPtr display_private; host().CreateRootCompositorFrameSink( kFrameSinkChild1, 0 /* surface_handle */, + false /* force_software_compositing */, RendererSettings() /* renderer_settings */, MakeRequest(&compositor_frame_sink_associated_info), compositor_frame_sink_client.BindInterfacePtr(),
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index 53fb4558..edb3cc78 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -79,9 +79,9 @@ "display_embedder/compositing_mode_reporter_impl.cc", "display_embedder/compositing_mode_reporter_impl.h", "display_embedder/compositor_overlay_candidate_validator.h", - "display_embedder/display_output_surface.cc", - "display_embedder/display_output_surface.h", "display_embedder/display_provider.h", + "display_embedder/gl_output_surface.cc", + "display_embedder/gl_output_surface.h", "display_embedder/gpu_display_provider.cc", "display_embedder/gpu_display_provider.h", "display_embedder/in_process_gpu_memory_buffer_manager.cc", @@ -90,6 +90,8 @@ "display_embedder/server_shared_bitmap_manager.h", "display_embedder/shared_bitmap_allocation_notifier_impl.cc", "display_embedder/shared_bitmap_allocation_notifier_impl.h", + "display_embedder/software_output_surface.cc", + "display_embedder/software_output_surface.h", "frame_sinks/compositor_frame_sink_impl.cc", "frame_sinks/compositor_frame_sink_impl.h", "frame_sinks/compositor_frame_sink_support.cc", @@ -219,8 +221,8 @@ sources += [ "display_embedder/compositor_overlay_candidate_validator_ozone.cc", "display_embedder/compositor_overlay_candidate_validator_ozone.h", - "display_embedder/display_output_surface_ozone.cc", - "display_embedder/display_output_surface_ozone.h", + "display_embedder/gl_output_surface_ozone.cc", + "display_embedder/gl_output_surface_ozone.h", "display_embedder/software_output_device_ozone.cc", "display_embedder/software_output_device_ozone.h", ]
diff --git a/components/viz/service/display_embedder/display_provider.h b/components/viz/service/display_embedder/display_provider.h index be728d87..4eabbb1 100644 --- a/components/viz/service/display_embedder/display_provider.h +++ b/components/viz/service/display_embedder/display_provider.h
@@ -23,9 +23,12 @@ // Creates a new Display for |surface_handle| with |frame_sink_id|. Will // also create BeginFrameSource and return it in |begin_frame_source|. + // If |force_software_compositing| is true, then the resulting display + // compositor will not use Gpu acceleration even if it would by default. virtual std::unique_ptr<Display> CreateDisplay( const FrameSinkId& frame_sink_id, gpu::SurfaceHandle surface_handle, + bool force_software_compositing, const RendererSettings& renderer_settings, std::unique_ptr<SyntheticBeginFrameSource>* out_begin_frame_source) = 0; };
diff --git a/components/viz/service/display_embedder/display_output_surface.cc b/components/viz/service/display_embedder/gl_output_surface.cc similarity index 63% rename from components/viz/service/display_embedder/display_output_surface.cc rename to components/viz/service/display_embedder/gl_output_surface.cc index d598c84..684ea912 100644 --- a/components/viz/service/display_embedder/display_output_surface.cc +++ b/components/viz/service/display_embedder/gl_output_surface.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/viz/service/display_embedder/display_output_surface.h" +#include "components/viz/service/display_embedder/gl_output_surface.h" #include <stdint.h> @@ -19,7 +19,7 @@ namespace viz { -DisplayOutputSurface::DisplayOutputSurface( +GLOutputSurface::GLOutputSurface( scoped_refptr<InProcessContextProvider> context_provider, SyntheticBeginFrameSource* synthetic_begin_frame_source) : OutputSurface(context_provider), @@ -32,34 +32,34 @@ capabilities_.supports_stencil = context_provider->ContextCapabilities().num_stencil_bits > 0; context_provider->SetSwapBuffersCompletionCallback( - base::Bind(&DisplayOutputSurface::OnGpuSwapBuffersCompleted, - weak_ptr_factory_.GetWeakPtr())); + base::BindRepeating(&GLOutputSurface::OnGpuSwapBuffersCompleted, + weak_ptr_factory_.GetWeakPtr())); context_provider->SetUpdateVSyncParametersCallback( - base::Bind(&DisplayOutputSurface::OnVSyncParametersUpdated, - weak_ptr_factory_.GetWeakPtr())); - context_provider->SetPresentationCallback(base::Bind( - &DisplayOutputSurface::OnPresentation, weak_ptr_factory_.GetWeakPtr())); + base::BindRepeating(&GLOutputSurface::OnVSyncParametersUpdated, + weak_ptr_factory_.GetWeakPtr())); + context_provider->SetPresentationCallback(base::BindRepeating( + &GLOutputSurface::OnPresentation, weak_ptr_factory_.GetWeakPtr())); } -DisplayOutputSurface::~DisplayOutputSurface() {} +GLOutputSurface::~GLOutputSurface() {} -void DisplayOutputSurface::BindToClient(OutputSurfaceClient* client) { +void GLOutputSurface::BindToClient(OutputSurfaceClient* client) { DCHECK(client); DCHECK(!client_); client_ = client; } -void DisplayOutputSurface::EnsureBackbuffer() {} +void GLOutputSurface::EnsureBackbuffer() {} -void DisplayOutputSurface::DiscardBackbuffer() { +void GLOutputSurface::DiscardBackbuffer() { context_provider()->ContextGL()->DiscardBackbufferCHROMIUM(); } -void DisplayOutputSurface::BindFramebuffer() { +void GLOutputSurface::BindFramebuffer() { context_provider()->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0); } -void DisplayOutputSurface::SetDrawRectangle(const gfx::Rect& rect) { +void GLOutputSurface::SetDrawRectangle(const gfx::Rect& rect) { if (set_draw_rectangle_for_frame_) return; DCHECK(gfx::Rect(size_).Contains(rect)); @@ -71,11 +71,11 @@ rect.x(), rect.y(), rect.width(), rect.height()); } -void DisplayOutputSurface::Reshape(const gfx::Size& size, - float device_scale_factor, - const gfx::ColorSpace& color_space, - bool has_alpha, - bool use_stencil) { +void GLOutputSurface::Reshape(const gfx::Size& size, + float device_scale_factor, + const gfx::ColorSpace& color_space, + bool has_alpha, + bool use_stencil) { size_ = size; has_set_draw_rectangle_since_last_resize_ = false; context_provider()->ContextGL()->ResizeCHROMIUM( @@ -83,7 +83,7 @@ gl::GetGLColorSpace(color_space), has_alpha); } -void DisplayOutputSurface::SwapBuffers(OutputSurfaceFrame frame) { +void GLOutputSurface::SwapBuffers(OutputSurfaceFrame frame) { DCHECK(context_provider_); if (latency_info_cache_.WillSwap(std::move(frame.latency_info))) @@ -98,68 +98,68 @@ } } -uint32_t DisplayOutputSurface::GetFramebufferCopyTextureFormat() { +uint32_t GLOutputSurface::GetFramebufferCopyTextureFormat() { // TODO(danakj): What attributes are used for the default framebuffer here? // Can it have alpha? InProcessContextProvider doesn't take any // attributes. return GL_RGB; } -OverlayCandidateValidator* DisplayOutputSurface::GetOverlayCandidateValidator() +OverlayCandidateValidator* GLOutputSurface::GetOverlayCandidateValidator() const { return nullptr; } -bool DisplayOutputSurface::IsDisplayedAsOverlayPlane() const { +bool GLOutputSurface::IsDisplayedAsOverlayPlane() const { return false; } -unsigned DisplayOutputSurface::GetOverlayTextureId() const { +unsigned GLOutputSurface::GetOverlayTextureId() const { return 0; } -gfx::BufferFormat DisplayOutputSurface::GetOverlayBufferFormat() const { +gfx::BufferFormat GLOutputSurface::GetOverlayBufferFormat() const { return gfx::BufferFormat::RGBX_8888; } -bool DisplayOutputSurface::SurfaceIsSuspendForRecycle() const { +bool GLOutputSurface::SurfaceIsSuspendForRecycle() const { return false; } -bool DisplayOutputSurface::HasExternalStencilTest() const { +bool GLOutputSurface::HasExternalStencilTest() const { return false; } -void DisplayOutputSurface::ApplyExternalStencil() {} +void GLOutputSurface::ApplyExternalStencil() {} -void DisplayOutputSurface::DidReceiveSwapBuffersAck(gfx::SwapResult result, - uint64_t swap_id) { +void GLOutputSurface::DidReceiveSwapBuffersAck(gfx::SwapResult result, + uint64_t swap_id) { client_->DidReceiveSwapBuffersAck(swap_id); } -void DisplayOutputSurface::OnGpuSwapBuffersCompleted( +void GLOutputSurface::OnGpuSwapBuffersCompleted( const gfx::SwapResponse& response, const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) { DidReceiveSwapBuffersAck(response.result, response.swap_id); latency_info_cache_.OnSwapBuffersCompleted(response); } -void DisplayOutputSurface::LatencyInfoCompleted( +void GLOutputSurface::LatencyInfoCompleted( const std::vector<ui::LatencyInfo>& latency_info) { for (const auto& latency : latency_info) { latency_tracker_.OnGpuSwapBuffersCompleted(latency); } } -void DisplayOutputSurface::OnVSyncParametersUpdated(base::TimeTicks timebase, - base::TimeDelta interval) { +void GLOutputSurface::OnVSyncParametersUpdated(base::TimeTicks timebase, + base::TimeDelta interval) { // TODO(brianderson): We should not be receiving 0 intervals. synthetic_begin_frame_source_->OnUpdateVSyncParameters( timebase, interval.is_zero() ? BeginFrameArgs::DefaultInterval() : interval); } -void DisplayOutputSurface::OnPresentation( +void GLOutputSurface::OnPresentation( uint64_t swap_id, const gfx::PresentationFeedback& feedback) { client_->DidReceivePresentationFeedback(swap_id, feedback);
diff --git a/components/viz/service/display_embedder/display_output_surface.h b/components/viz/service/display_embedder/gl_output_surface.h similarity index 81% rename from components/viz/service/display_embedder/display_output_surface.h rename to components/viz/service/display_embedder/gl_output_surface.h index 457b24c7..7f4769c 100644 --- a/components/viz/service/display_embedder/display_output_surface.h +++ b/components/viz/service/display_embedder/gl_output_surface.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_DISPLAY_OUTPUT_SURFACE_H_ -#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_DISPLAY_OUTPUT_SURFACE_H_ +#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_H_ #include <memory> @@ -17,12 +17,12 @@ // An OutputSurface implementation that directly draws and // swaps to an actual GL surface. -class DisplayOutputSurface : public OutputSurface, - public OutputSurface::LatencyInfoCache::Client { +class GLOutputSurface : public OutputSurface, + public OutputSurface::LatencyInfoCache::Client { public: - DisplayOutputSurface(scoped_refptr<InProcessContextProvider> context_provider, - SyntheticBeginFrameSource* synthetic_begin_frame_source); - ~DisplayOutputSurface() override; + GLOutputSurface(scoped_refptr<InProcessContextProvider> context_provider, + SyntheticBeginFrameSource* synthetic_begin_frame_source); + ~GLOutputSurface() override; // OutputSurface implementation void BindToClient(OutputSurfaceClient* client) override; @@ -76,9 +76,9 @@ gfx::Size size_; LatencyInfoCache latency_info_cache_; - base::WeakPtrFactory<DisplayOutputSurface> weak_ptr_factory_; + base::WeakPtrFactory<GLOutputSurface> weak_ptr_factory_; }; } // namespace viz -#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_DISPLAY_OUTPUT_SURFACE_H_ +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_H_
diff --git a/components/viz/service/display_embedder/display_output_surface_ozone.cc b/components/viz/service/display_embedder/gl_output_surface_ozone.cc similarity index 73% rename from components/viz/service/display_embedder/display_output_surface_ozone.cc rename to components/viz/service/display_embedder/gl_output_surface_ozone.cc index 6ddb997..197830e 100644 --- a/components/viz/service/display_embedder/display_output_surface_ozone.cc +++ b/components/viz/service/display_embedder/gl_output_surface_ozone.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/viz/service/display_embedder/display_output_surface_ozone.h" +#include "components/viz/service/display_embedder/gl_output_surface_ozone.h" #include <utility> @@ -19,14 +19,14 @@ namespace viz { -DisplayOutputSurfaceOzone::DisplayOutputSurfaceOzone( +GLOutputSurfaceOzone::GLOutputSurfaceOzone( scoped_refptr<InProcessContextProvider> context_provider, gfx::AcceleratedWidget widget, SyntheticBeginFrameSource* synthetic_begin_frame_source, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, uint32_t target, uint32_t internalformat) - : DisplayOutputSurface(context_provider, synthetic_begin_frame_source), + : GLOutputSurface(context_provider, synthetic_begin_frame_source), gl_helper_(context_provider->ContextGL(), context_provider->ContextSupport()) { capabilities_.uses_default_gl_framebuffer = false; @@ -47,11 +47,11 @@ buffer_queue_->Initialize(); } -DisplayOutputSurfaceOzone::~DisplayOutputSurfaceOzone() { +GLOutputSurfaceOzone::~GLOutputSurfaceOzone() { // TODO(rjkroege): Support cleanup. } -void DisplayOutputSurfaceOzone::BindFramebuffer() { +void GLOutputSurfaceOzone::BindFramebuffer() { DCHECK(buffer_queue_); buffer_queue_->BindFramebuffer(); } @@ -62,18 +62,18 @@ // implies that screen size changes need to be plumbed differently. In // particular, we must create the native window in the size that the hardware // reports. -void DisplayOutputSurfaceOzone::Reshape(const gfx::Size& size, - float device_scale_factor, - const gfx::ColorSpace& color_space, - bool has_alpha, - bool use_stencil) { +void GLOutputSurfaceOzone::Reshape(const gfx::Size& size, + float device_scale_factor, + const gfx::ColorSpace& color_space, + bool has_alpha, + bool use_stencil) { reshape_size_ = size; - DisplayOutputSurface::Reshape(size, device_scale_factor, color_space, - has_alpha, use_stencil); + GLOutputSurface::Reshape(size, device_scale_factor, color_space, has_alpha, + use_stencil); buffer_queue_->Reshape(size, device_scale_factor, color_space, use_stencil); } -void DisplayOutputSurfaceOzone::SwapBuffers(OutputSurfaceFrame frame) { +void GLOutputSurfaceOzone::SwapBuffers(OutputSurfaceFrame frame) { DCHECK(buffer_queue_); // TODO(rjkroege): What if swap happens again before DidReceiveSwapBuffersAck @@ -85,29 +85,29 @@ frame.sub_buffer_rect ? *frame.sub_buffer_rect : gfx::Rect(swap_size_); buffer_queue_->SwapBuffers(damage_rect); - DisplayOutputSurface::SwapBuffers(std::move(frame)); + GLOutputSurface::SwapBuffers(std::move(frame)); } -uint32_t DisplayOutputSurfaceOzone::GetFramebufferCopyTextureFormat() { +uint32_t GLOutputSurfaceOzone::GetFramebufferCopyTextureFormat() { return buffer_queue_->internal_format(); } -bool DisplayOutputSurfaceOzone::IsDisplayedAsOverlayPlane() const { +bool GLOutputSurfaceOzone::IsDisplayedAsOverlayPlane() const { // TODO(rjkroege): implement remaining overlay functionality. return true; } -unsigned DisplayOutputSurfaceOzone::GetOverlayTextureId() const { +unsigned GLOutputSurfaceOzone::GetOverlayTextureId() const { return buffer_queue_->GetCurrentTextureId(); } -gfx::BufferFormat DisplayOutputSurfaceOzone::GetOverlayBufferFormat() const { +gfx::BufferFormat GLOutputSurfaceOzone::GetOverlayBufferFormat() const { DCHECK(buffer_queue_); return buffer_queue_->buffer_format(); } -void DisplayOutputSurfaceOzone::DidReceiveSwapBuffersAck(gfx::SwapResult result, - uint64_t swap_id) { +void GLOutputSurfaceOzone::DidReceiveSwapBuffersAck(gfx::SwapResult result, + uint64_t swap_id) { bool force_swap = false; if (result == gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS) { // Even through the swap failed, this is a fixable error so we can pretend
diff --git a/components/viz/service/display_embedder/display_output_surface_ozone.h b/components/viz/service/display_embedder/gl_output_surface_ozone.h similarity index 68% rename from components/viz/service/display_embedder/display_output_surface_ozone.h rename to components/viz/service/display_embedder/gl_output_surface_ozone.h index 24d8970..251c124 100644 --- a/components/viz/service/display_embedder/display_output_surface_ozone.h +++ b/components/viz/service/display_embedder/gl_output_surface_ozone.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_DISPLAY_OUTPUT_SURFACE_OZONE_H_ -#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_DISPLAY_OUTPUT_SURFACE_OZONE_H_ +#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_OZONE_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_OZONE_H_ #include <memory> @@ -12,7 +12,7 @@ #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/gpu/in_process_context_provider.h" #include "components/viz/service/display/output_surface.h" -#include "components/viz/service/display_embedder/display_output_surface.h" +#include "components/viz/service/display_embedder/gl_output_surface.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/swap_result.h" @@ -31,17 +31,16 @@ // "surfaceless" surface (aka one backed by a buffer managed explicitly in // mus/ozone. This class is adapted from // GpuSurfacelessBrowserCompositorOutputSurface. -class DisplayOutputSurfaceOzone : public DisplayOutputSurface { +class GLOutputSurfaceOzone : public GLOutputSurface { public: - DisplayOutputSurfaceOzone( - scoped_refptr<InProcessContextProvider> context_provider, - gfx::AcceleratedWidget widget, - SyntheticBeginFrameSource* synthetic_begin_frame_source, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, - uint32_t target, - uint32_t internalformat); + GLOutputSurfaceOzone(scoped_refptr<InProcessContextProvider> context_provider, + gfx::AcceleratedWidget widget, + SyntheticBeginFrameSource* synthetic_begin_frame_source, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + uint32_t target, + uint32_t internalformat); - ~DisplayOutputSurfaceOzone() override; + ~GLOutputSurfaceOzone() override; // TODO(rjkroege): Implement the equivalent of Reflector. @@ -59,7 +58,7 @@ unsigned GetOverlayTextureId() const override; gfx::BufferFormat GetOverlayBufferFormat() const override; - // DisplayOutputSurface: + // GLOutputSurface: void DidReceiveSwapBuffersAck(gfx::SwapResult result, uint64_t swap_id) override; @@ -69,9 +68,9 @@ gfx::Size reshape_size_; gfx::Size swap_size_; - DISALLOW_COPY_AND_ASSIGN(DisplayOutputSurfaceOzone); + DISALLOW_COPY_AND_ASSIGN(GLOutputSurfaceOzone); }; } // namespace viz -#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_DISPLAY_OUTPUT_SURFACE_OZONE_H_ +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_OZONE_H_
diff --git a/components/viz/service/display_embedder/gpu_display_provider.cc b/components/viz/service/display_embedder/gpu_display_provider.cc index 20398b8d..b7184da3 100644 --- a/components/viz/service/display_embedder/gpu_display_provider.cc +++ b/components/viz/service/display_embedder/gpu_display_provider.cc
@@ -16,18 +16,36 @@ #include "components/viz/service/display/display.h" #include "components/viz/service/display/display_scheduler.h" #include "components/viz/service/display_embedder/compositing_mode_reporter_impl.h" -#include "components/viz/service/display_embedder/display_output_surface.h" +#include "components/viz/service/display_embedder/gl_output_surface.h" #include "components/viz/service/display_embedder/in_process_gpu_memory_buffer_manager.h" #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h" +#include "components/viz/service/display_embedder/software_output_surface.h" #include "gpu/command_buffer/client/shared_memory_limits.h" #include "gpu/command_buffer/service/image_factory.h" +#include "gpu/ipc/common/surface_handle.h" #include "gpu/ipc/service/gpu_channel_manager.h" #include "gpu/ipc/service/gpu_memory_buffer_factory.h" #include "ui/base/ui_base_switches.h" +#if defined(OS_WIN) +#include "components/viz/service/display_embedder/software_output_device_win.h" +#endif + +#if defined(OS_MACOSX) +#include "components/viz/service/display_embedder/software_output_device_mac.h" +#endif + +#if defined(USE_X11) +#include "components/viz/service/display_embedder/software_output_device_x11.h" +#endif + #if defined(USE_OZONE) -#include "components/viz/service/display_embedder/display_output_surface_ozone.h" +#include "components/viz/service/display_embedder/gl_output_surface_ozone.h" +#include "components/viz/service/display_embedder/software_output_device_ozone.h" #include "gpu/command_buffer/client/gles2_interface.h" +#include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/surface_factory_ozone.h" +#include "ui/ozone/public/surface_ozone_canvas.h" #endif namespace { @@ -62,6 +80,7 @@ std::unique_ptr<Display> GpuDisplayProvider::CreateDisplay( const FrameSinkId& frame_sink_id, gpu::SurfaceHandle surface_handle, + bool force_software_compositing, const RendererSettings& renderer_settings, std::unique_ptr<SyntheticBeginFrameSource>* out_begin_frame_source) { auto synthetic_begin_frame_source = @@ -70,37 +89,54 @@ restart_id_); // TODO(crbug.com/730660): Fallback to software if gpu doesn't work with - // compositing_mode_reporter_->SetUsingSoftwareCompositing(); + // compositing_mode_reporter_->SetUsingSoftwareCompositing(), and once that + // is done, always make software-based Displays only. + bool gpu_compositing = !force_software_compositing; (void)compositing_mode_reporter_; - scoped_refptr<InProcessContextProvider> context_provider = - new InProcessContextProvider(gpu_service_, surface_handle, - gpu_memory_buffer_manager_.get(), - image_factory_, gpu::SharedMemoryLimits(), - nullptr /* shared_context */); - - // TODO(rjkroege): If there is something better to do than CHECK, add it. - // TODO(danakj): Should retry if the result is kTransientFailure. - auto result = context_provider->BindToCurrentThread(); - CHECK_EQ(result, gpu::ContextResult::kSuccess); - - std::unique_ptr<OutputSurface> display_output_surface; - if (context_provider->ContextCapabilities().surfaceless) { -#if defined(USE_OZONE) - display_output_surface = base::MakeUnique<DisplayOutputSurfaceOzone>( - std::move(context_provider), surface_handle, - synthetic_begin_frame_source.get(), gpu_memory_buffer_manager_.get(), - GL_TEXTURE_2D, GL_RGB); +#if !defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW) + // TODO(crbug.com/730660): On Mac/Android the handle is not an + // AcceleratedWidget, and the widget is only available in the browser process + // via GpuSurfaceTracker (and maybe can't be used in the viz process??) + NOTIMPLEMENTED(); + gfx::AcceleratedWidget widget = 0; + (void)widget; #else - NOTREACHED(); + gfx::AcceleratedWidget widget = surface_handle; #endif + + std::unique_ptr<OutputSurface> output_surface; + + if (!gpu_compositing) { + output_surface = std::make_unique<SoftwareOutputSurface>( + CreateSoftwareOutputDeviceForPlatform(widget), task_runner_); } else { - display_output_surface = base::MakeUnique<DisplayOutputSurface>( - std::move(context_provider), synthetic_begin_frame_source.get()); + auto context_provider = base::MakeRefCounted<InProcessContextProvider>( + gpu_service_, surface_handle, gpu_memory_buffer_manager_.get(), + image_factory_, gpu::SharedMemoryLimits(), + nullptr /* shared_context */); + + // TODO(rjkroege): If there is something better to do than CHECK, add it. + // TODO(danakj): Should retry if the result is kTransientFailure. + auto result = context_provider->BindToCurrentThread(); + CHECK_EQ(result, gpu::ContextResult::kSuccess); + + if (context_provider->ContextCapabilities().surfaceless) { +#if defined(USE_OZONE) + output_surface = base::MakeUnique<GLOutputSurfaceOzone>( + std::move(context_provider), widget, + synthetic_begin_frame_source.get(), gpu_memory_buffer_manager_.get(), + GL_TEXTURE_2D, GL_RGB); +#else + NOTREACHED(); +#endif + } else { + output_surface = base::MakeUnique<GLOutputSurface>( + std::move(context_provider), synthetic_begin_frame_source.get()); + } } - int max_frames_pending = - display_output_surface->capabilities().max_frames_pending; + int max_frames_pending = output_surface->capabilities().max_frames_pending; DCHECK_GT(max_frames_pending, 0); auto scheduler = base::MakeUnique<DisplayScheduler>( @@ -112,8 +148,46 @@ return base::MakeUnique<Display>( ServerSharedBitmapManager::current(), gpu_memory_buffer_manager_.get(), - renderer_settings, frame_sink_id, std::move(display_output_surface), + renderer_settings, frame_sink_id, std::move(output_surface), std::move(scheduler), task_runner_); } +std::unique_ptr<SoftwareOutputDevice> +GpuDisplayProvider::CreateSoftwareOutputDeviceForPlatform( + gfx::AcceleratedWidget widget) { +#if defined(OS_WIN) + if (!output_device_backing_) + output_device_backing_ = std::make_unique<OutputDeviceBacking>(); + auto device = std::make_unique<SoftwareOutputDeviceWin>( + output_device_backing_.get(), widget); +#elif defined(OS_MACOSX) + // TODO(crbug.com/730660): We don't have a widget here, so what do we do to + // get something we can draw to? Can we use an IO surface? Can we use CA + // layers and overlays like we do for gpu compositing? + // See https://chromium-review.googlesource.com/c/chromium/src/+/792295 to + // no longer have GpuSurfaceTracker. + // Part of the SoftwareOutputDeviceMac::EndPaint probably needs to move to + // the browser process, and we need to set up transport of an IO surface to + // here? + // auto device = std::make_unique<SoftwareOutputDeviceMac>(widget); + std::unique_ptr<SoftwareOutputDevice> device; + NOTIMPLEMENTED(); +#elif defined(OS_ANDROID) + // Android does not do software compositing, so we can't get here. + std::unique_ptr<SoftwareOutputDevice> device; + NOTREACHED(); +#elif defined(USE_OZONE) + ui::SurfaceFactoryOzone* factory = + ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone(); + std::unique_ptr<ui::SurfaceOzoneCanvas> surface_ozone = + factory->CreateCanvasForWidget(widget); + CHECK(surface_ozone); + auto device = + std::make_unique<SoftwareOutputDeviceOzone>(std::move(surface_ozone)); +#elif defined(USE_X11) + auto device = std::make_unique<SoftwareOutputDeviceX11>(widget); +#endif + return device; +} + } // namespace viz
diff --git a/components/viz/service/display_embedder/gpu_display_provider.h b/components/viz/service/display_embedder/gpu_display_provider.h index c0ccb572..4a93727 100644 --- a/components/viz/service/display_embedder/gpu_display_provider.h +++ b/components/viz/service/display_embedder/gpu_display_provider.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "build/build_config.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/service/display_embedder/display_provider.h" #include "components/viz/service/viz_service_export.h" @@ -25,6 +26,8 @@ namespace viz { class CompositingModeReporterImpl; class Display; +class OutputDeviceBacking; +class SoftwareOutputDevice; // In-process implementation of DisplayProvider. class VIZ_SERVICE_EXPORT GpuDisplayProvider : public DisplayProvider { @@ -36,21 +39,30 @@ CompositingModeReporterImpl* compositing_mode_reporter); ~GpuDisplayProvider() override; - // DisplayProvider: + // DisplayProvider implementation. std::unique_ptr<Display> CreateDisplay( const FrameSinkId& frame_sink_id, gpu::SurfaceHandle surface_handle, + bool force_software_compositing, const RendererSettings& renderer_settings, std::unique_ptr<SyntheticBeginFrameSource>* out_begin_frame_source) override; private: + std::unique_ptr<SoftwareOutputDevice> CreateSoftwareOutputDeviceForPlatform( + gfx::AcceleratedWidget widget); + const uint32_t restart_id_; scoped_refptr<gpu::InProcessCommandBuffer::Service> gpu_service_; std::unique_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_; gpu::ImageFactory* const image_factory_; CompositingModeReporterImpl* const compositing_mode_reporter_; +#if defined(OS_WIN) + // Used for software compositing output on Windows. + std::unique_ptr<OutputDeviceBacking> output_device_backing_; +#endif + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; DISALLOW_COPY_AND_ASSIGN(GpuDisplayProvider);
diff --git a/components/viz/service/display_embedder/software_output_device_ozone.cc b/components/viz/service/display_embedder/software_output_device_ozone.cc index eed0d38..ea3c84f 100644 --- a/components/viz/service/display_embedder/software_output_device_ozone.cc +++ b/components/viz/service/display_embedder/software_output_device_ozone.cc
@@ -8,34 +8,13 @@ #include "ui/gfx/skia_util.h" #include "ui/gfx/vsync_provider.h" -#include "ui/ozone/public/ozone_platform.h" -#include "ui/ozone/public/surface_factory_ozone.h" #include "ui/ozone/public/surface_ozone_canvas.h" namespace viz { -// static -std::unique_ptr<SoftwareOutputDeviceOzone> SoftwareOutputDeviceOzone::Create( - gfx::AcceleratedWidget widget) { - std::unique_ptr<SoftwareOutputDeviceOzone> result( - new SoftwareOutputDeviceOzone(widget)); - if (!result->surface_ozone_) - return nullptr; - return result; -} - SoftwareOutputDeviceOzone::SoftwareOutputDeviceOzone( - gfx::AcceleratedWidget widget) { - ui::SurfaceFactoryOzone* factory = - ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone(); - - surface_ozone_ = factory->CreateCanvasForWidget(widget); - - if (!surface_ozone_) { - LOG(ERROR) << "Failed to initialize canvas"; - return; - } - + std::unique_ptr<ui::SurfaceOzoneCanvas> surface_ozone) + : surface_ozone_(std::move(surface_ozone)) { vsync_provider_ = surface_ozone_->CreateVSyncProvider(); }
diff --git a/components/viz/service/display_embedder/software_output_device_ozone.h b/components/viz/service/display_embedder/software_output_device_ozone.h index d4f3eb2..6565811 100644 --- a/components/viz/service/display_embedder/software_output_device_ozone.h +++ b/components/viz/service/display_embedder/software_output_device_ozone.h
@@ -24,8 +24,8 @@ class VIZ_SERVICE_EXPORT SoftwareOutputDeviceOzone : public SoftwareOutputDevice { public: - static std::unique_ptr<SoftwareOutputDeviceOzone> Create( - gfx::AcceleratedWidget widget); + explicit SoftwareOutputDeviceOzone( + std::unique_ptr<ui::SurfaceOzoneCanvas> surface_ozone); ~SoftwareOutputDeviceOzone() override; void Resize(const gfx::Size& viewport_pixel_size, @@ -34,8 +34,6 @@ void EndPaint() override; private: - explicit SoftwareOutputDeviceOzone(gfx::AcceleratedWidget widget); - std::unique_ptr<ui::SurfaceOzoneCanvas> surface_ozone_; DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzone);
diff --git a/components/viz/service/display_embedder/software_output_device_ozone_unittest.cc b/components/viz/service/display_embedder/software_output_device_ozone_unittest.cc index 5ce79b14a..225ae49 100644 --- a/components/viz/service/display_embedder/software_output_device_ozone_unittest.cc +++ b/components/viz/service/display_embedder/software_output_device_ozone_unittest.cc
@@ -18,10 +18,13 @@ #include "ui/gfx/vsync_provider.h" #include "ui/gl/gl_implementation.h" #include "ui/ozone/public/ozone_platform.h" +#include "ui/ozone/public/surface_factory_ozone.h" #include "ui/ozone/public/surface_ozone_canvas.h" #include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_delegate.h" +namespace viz { + namespace { class TestPlatformWindowDelegate : public ui::PlatformWindowDelegate { @@ -63,7 +66,7 @@ void TearDown() override; protected: - std::unique_ptr<viz::SoftwareOutputDeviceOzone> output_device_; + std::unique_ptr<SoftwareOutputDeviceOzone> output_device_; bool enable_pixel_output_ = false; private: @@ -73,8 +76,8 @@ DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceOzoneTest); }; -SoftwareOutputDeviceOzoneTest::SoftwareOutputDeviceOzoneTest() {} -SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() {} +SoftwareOutputDeviceOzoneTest::SoftwareOutputDeviceOzoneTest() = default; +SoftwareOutputDeviceOzoneTest::~SoftwareOutputDeviceOzoneTest() = default; void SoftwareOutputDeviceOzoneTest::SetUp() { ui::ContextFactory* context_factory = nullptr; @@ -83,16 +86,24 @@ &context_factory_private); const gfx::Size size(500, 400); - compositor_.reset( - new ui::Compositor(viz::FrameSinkId(1, 1), context_factory, nullptr, - base::ThreadTaskRunnerHandle::Get(), - false /* enable_surface_synchronization */, - false /* enable_pixel_canvas */)); + compositor_ = std::make_unique<ui::Compositor>( + FrameSinkId(1, 1), context_factory, nullptr, + base::ThreadTaskRunnerHandle::Get(), + false /* enable_surface_synchronization */, + false /* enable_pixel_canvas */); compositor_->SetAcceleratedWidget(window_delegate_.GetAcceleratedWidget()); compositor_->SetScaleAndSize(1.0f, size); - output_device_ = - viz::SoftwareOutputDeviceOzone::Create(compositor_->widget()); + ui::SurfaceFactoryOzone* factory = + ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone(); + std::unique_ptr<ui::SurfaceOzoneCanvas> surface_ozone = + factory->CreateCanvasForWidget(compositor_->widget()); + if (!surface_ozone) { + LOG(ERROR) << "SurfaceOzoneCanvas not constructible on this platform"; + } else { + output_device_ = + std::make_unique<SoftwareOutputDeviceOzone>(std::move(surface_ozone)); + } if (output_device_) output_device_->Resize(size, 1.f); } @@ -138,3 +149,5 @@ canvas->getBaseLayerSize().height()); EXPECT_EQ(size.ToString(), canvas_size.ToString()); } + +} // namespace viz
diff --git a/components/viz/service/display_embedder/software_output_device_x11.cc b/components/viz/service/display_embedder/software_output_device_x11.cc index 5662d3b..aba4cae 100644 --- a/components/viz/service/display_embedder/software_output_device_x11.cc +++ b/components/viz/service/display_embedder/software_output_device_x11.cc
@@ -19,7 +19,6 @@ SoftwareOutputDeviceX11::SoftwareOutputDeviceX11(gfx::AcceleratedWidget widget) : widget_(widget), display_(gfx::GetXDisplay()), gc_(nullptr) { - // TODO(skaslev) Remove this when crbug.com/180702 is fixed. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); gc_ = XCreateGC(display_, widget_, 0, nullptr);
diff --git a/components/viz/service/display_embedder/software_output_surface.cc b/components/viz/service/display_embedder/software_output_surface.cc new file mode 100644 index 0000000..b142ec28 --- /dev/null +++ b/components/viz/service/display_embedder/software_output_surface.cc
@@ -0,0 +1,131 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/viz/service/display_embedder/software_output_surface.h" + +#include <utility> + +#include "base/bind.h" +#include "base/location.h" +#include "base/memory/ref_counted.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "components/viz/service/display/output_surface_client.h" +#include "components/viz/service/display/output_surface_frame.h" +#include "components/viz/service/display/software_output_device.h" +#include "ui/gfx/presentation_feedback.h" +#include "ui/gfx/vsync_provider.h" +#include "ui/latency/latency_info.h" + +namespace viz { + +SoftwareOutputSurface::SoftwareOutputSurface( + std::unique_ptr<SoftwareOutputDevice> software_device, + scoped_refptr<base::SequencedTaskRunner> task_runner) + : OutputSurface(std::move(software_device)), + task_runner_(std::move(task_runner)), + weak_factory_(this) {} + +SoftwareOutputSurface::~SoftwareOutputSurface() = default; + +void SoftwareOutputSurface::BindToClient(OutputSurfaceClient* client) { + DCHECK(client); + DCHECK(!client_); + client_ = client; +} + +void SoftwareOutputSurface::EnsureBackbuffer() { + software_device()->EnsureBackbuffer(); +} + +void SoftwareOutputSurface::DiscardBackbuffer() { + software_device()->DiscardBackbuffer(); +} + +void SoftwareOutputSurface::BindFramebuffer() { + // Not used for software surfaces. + NOTREACHED(); +} + +void SoftwareOutputSurface::SetDrawRectangle(const gfx::Rect& draw_rectangle) { + NOTREACHED(); +} + +void SoftwareOutputSurface::Reshape(const gfx::Size& size, + float device_scale_factor, + const gfx::ColorSpace& color_space, + bool has_alpha, + bool use_stencil) { + software_device()->Resize(size, device_scale_factor); +} + +void SoftwareOutputSurface::SwapBuffers(OutputSurfaceFrame frame) { + DCHECK(client_); + base::TimeTicks swap_time = base::TimeTicks::Now(); + for (auto& latency : frame.latency_info) { + latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1); + latency.AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0, + swap_time, 1); + } + // TODO(danakj): Send frame.latency_info somewhere like + // RenderWidgetHostImpl::OnGpuSwapBuffersCompleted. It should go to the + // ui::LatencyTracker in the viz process. + + // TODO(danakj): Update vsync params. + // gfx::VSyncProvider* vsync_provider = software_device()->GetVSyncProvider(); + // if (vsync_provider) + // vsync_provider->GetVSyncParameters(update_vsync_parameters_callback_); + // Update refresh_interval_ as well. + + ++swap_id_; + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&SoftwareOutputSurface::SwapBuffersCallback, + weak_factory_.GetWeakPtr(), swap_id_)); +} + +bool SoftwareOutputSurface::IsDisplayedAsOverlayPlane() const { + return false; +} + +OverlayCandidateValidator* SoftwareOutputSurface::GetOverlayCandidateValidator() + const { + // No overlay support in software compositing. + return nullptr; +} + +unsigned SoftwareOutputSurface::GetOverlayTextureId() const { + return 0; +} + +gfx::BufferFormat SoftwareOutputSurface::GetOverlayBufferFormat() const { + return gfx::BufferFormat::RGBX_8888; +} + +bool SoftwareOutputSurface::HasExternalStencilTest() const { + return false; +} + +void SoftwareOutputSurface::ApplyExternalStencil() {} + +bool SoftwareOutputSurface::SurfaceIsSuspendForRecycle() const { + return false; +} + +uint32_t SoftwareOutputSurface::GetFramebufferCopyTextureFormat() { + // Not used for software surfaces. + NOTREACHED(); + return 0; +} + +void SoftwareOutputSurface::SwapBuffersCallback(uint64_t swap_id) { + client_->DidReceiveSwapBuffersAck(swap_id); + client_->DidReceivePresentationFeedback( + swap_id, + gfx::PresentationFeedback(base::TimeTicks::Now(), refresh_interval_, 0u)); +} + +} // namespace viz
diff --git a/components/viz/service/display_embedder/software_output_surface.h b/components/viz/service/display_embedder/software_output_surface.h new file mode 100644 index 0000000..a6660047 --- /dev/null +++ b/components/viz/service/display_embedder/software_output_surface.h
@@ -0,0 +1,57 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_SURFACE_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_SURFACE_H_ + +#include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" +#include "components/viz/service/display/output_surface.h" +#include "components/viz/service/viz_service_export.h" + +namespace viz { +class SoftwareOutputDevice; + +class VIZ_SERVICE_EXPORT SoftwareOutputSurface : public OutputSurface { + public: + SoftwareOutputSurface(std::unique_ptr<SoftwareOutputDevice> software_device, + scoped_refptr<base::SequencedTaskRunner> task_runner); + ~SoftwareOutputSurface() override; + + // OutputSurface implementation. + void BindToClient(OutputSurfaceClient* client) override; + void EnsureBackbuffer() override; + void DiscardBackbuffer() override; + void BindFramebuffer() override; + void SetDrawRectangle(const gfx::Rect& draw_rectangle) override; + void Reshape(const gfx::Size& size, + float device_scale_factor, + const gfx::ColorSpace& color_space, + bool has_alpha, + bool use_stencil) override; + void SwapBuffers(OutputSurfaceFrame frame) override; + bool IsDisplayedAsOverlayPlane() const override; + OverlayCandidateValidator* GetOverlayCandidateValidator() const override; + unsigned GetOverlayTextureId() const override; + gfx::BufferFormat GetOverlayBufferFormat() const override; + bool HasExternalStencilTest() const override; + void ApplyExternalStencil() override; + bool SurfaceIsSuspendForRecycle() const override; + uint32_t GetFramebufferCopyTextureFormat() override; + + private: + void SwapBuffersCallback(uint64_t swap_id); + + OutputSurfaceClient* client_ = nullptr; + scoped_refptr<base::SequencedTaskRunner> task_runner_; + base::TimeDelta refresh_interval_; + uint64_t swap_id_ = 0; + base::WeakPtrFactory<SoftwareOutputSurface> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(SoftwareOutputSurface); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_SURFACE_H_
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index eb7ed9c..fd50f6c 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -103,6 +103,7 @@ void FrameSinkManagerImpl::CreateRootCompositorFrameSink( const FrameSinkId& frame_sink_id, gpu::SurfaceHandle surface_handle, + bool force_software_compositing, const RendererSettings& renderer_settings, mojom::CompositorFrameSinkAssociatedRequest request, mojom::CompositorFrameSinkClientPtr client, @@ -114,7 +115,8 @@ std::unique_ptr<SyntheticBeginFrameSource> begin_frame_source; auto display = display_provider_->CreateDisplay( - frame_sink_id, surface_handle, renderer_settings, &begin_frame_source); + frame_sink_id, surface_handle, force_software_compositing, + renderer_settings, &begin_frame_source); auto frame_sink = std::make_unique<RootCompositorFrameSinkImpl>( this, frame_sink_id, std::move(display), std::move(begin_frame_source),
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h index 5b3c43c1..ecbebd8e 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -71,6 +71,7 @@ void CreateRootCompositorFrameSink( const FrameSinkId& frame_sink_id, gpu::SurfaceHandle surface_handle, + bool force_software_compositing, const RendererSettings& renderer_settings, mojom::CompositorFrameSinkAssociatedRequest request, mojom::CompositorFrameSinkClientPtr client,
diff --git a/components/viz/test/test_frame_sink_manager.h b/components/viz/test/test_frame_sink_manager.h index 205fca4..5d0bafb9 100644 --- a/components/viz/test/test_frame_sink_manager.h +++ b/components/viz/test/test_frame_sink_manager.h
@@ -27,6 +27,7 @@ void CreateRootCompositorFrameSink( const FrameSinkId& frame_sink_id, gpu::SurfaceHandle surface_handle, + bool force_software_compositor, const RendererSettings& renderer_settings, mojom::CompositorFrameSinkAssociatedRequest request, mojom::CompositorFrameSinkClientPtr client,
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index cddd17c..496990c 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -88,6 +88,8 @@ #include "ui/ozone/public/overlay_manager_ozone.h" #include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/ozone_switches.h" +#include "ui/ozone/public/surface_factory_ozone.h" +#include "ui/ozone/public/surface_ozone_canvas.h" #elif defined(USE_X11) #include "components/viz/service/display_embedder/software_output_device_x11.h" #elif defined(OS_MACOSX) @@ -254,7 +256,13 @@ return std::make_unique<viz::SoftwareOutputDeviceWin>(software_backing_.get(), widget); #elif defined(USE_OZONE) - return viz::SoftwareOutputDeviceOzone::Create(widget); + ui::SurfaceFactoryOzone* factory = + ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone(); + std::unique_ptr<ui::SurfaceOzoneCanvas> surface_ozone = + factory->CreateCanvasForWidget(widget); + CHECK(surface_ozone); + return std::make_unique<viz::SoftwareOutputDeviceOzone>( + std::move(surface_ozone)); #elif defined(USE_X11) return std::make_unique<viz::SoftwareOutputDeviceX11>(widget); #elif defined(OS_MACOSX)
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc index 7c85001..4c718787 100644 --- a/content/browser/compositor/viz_process_transport_factory.cc +++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -10,6 +10,7 @@ #include "base/single_thread_task_runner.h" #include "cc/raster/single_thread_task_graph_runner.h" #include "components/viz/client/client_layer_tree_frame_sink.h" +#include "components/viz/client/client_shared_bitmap_manager.h" #include "components/viz/client/local_surface_id_provider.h" #include "components/viz/common/features.h" #include "components/viz/common/gpu/context_provider.h" @@ -400,16 +401,17 @@ #endif // Creates the viz end of the root CompositorFrameSink. - // TODO(crbug.com/730660): If compositor->force_software_compositor() then - // make a software-based RootCompositorFrameSink. GetHostFrameSinkManager()->CreateRootCompositorFrameSink( - compositor->frame_sink_id(), surface_handle, renderer_settings_, + compositor->frame_sink_id(), surface_handle, + compositor->force_software_compositor(), renderer_settings_, std::move(sink_request), std::move(client), std::move(display_private_request)); // Create LayerTreeFrameSink with the browser end of CompositorFrameSink. viz::ClientLayerTreeFrameSink::InitParams params; params.gpu_memory_buffer_manager = GetGpuMemoryBufferManager(); + // TODO(crbug.com/730660): Make a ClientSharedBitmapManager to pass here. + params.shared_bitmap_manager = shared_bitmap_manager_.get(); params.pipes.compositor_frame_sink_associated_info = std::move(sink_info); params.pipes.client_request = std::move(client_request); params.local_surface_id_provider =
diff --git a/content/browser/compositor/viz_process_transport_factory.h b/content/browser/compositor/viz_process_transport_factory.h index 8a48b55..61e4cea 100644 --- a/content/browser/compositor/viz_process_transport_factory.h +++ b/content/browser/compositor/viz_process_transport_factory.h
@@ -36,6 +36,7 @@ } namespace viz { +class ClientSharedBitmapManager; class ForwardingCompositingModeReporterImpl; } @@ -154,6 +155,7 @@ // TODO(kylechar): Call OnContextLost() on observers when GPU crashes. base::ObserverList<ui::ContextFactoryObserver> observer_list_; + std::unique_ptr<viz::ClientSharedBitmapManager> shared_bitmap_manager_; scoped_refptr<ui::ContextProviderCommandBuffer> shared_worker_context_provider_; scoped_refptr<ui::ContextProviderCommandBuffer> compositor_context_provider_;
diff --git a/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc index 1ec201b2b..f351ccf 100644 --- a/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc +++ b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
@@ -282,8 +282,8 @@ TRACE_EVENT0("gpu", "VideoCaptureGpuJpegDecoder::FinishInitialization"); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::AutoLock lock(lock_); if (unbound_remote_decoder.is_valid()) { + base::AutoLock lock(lock_); decoder_ = base::MakeUnique<media::MojoJpegDecodeAccelerator>( BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), std::move(unbound_remote_decoder));
diff --git a/extensions/browser/device_local_account_util.cc b/extensions/browser/device_local_account_util.cc index fc8d079..4ecc3674 100644 --- a/extensions/browser/device_local_account_util.cc +++ b/extensions/browser/device_local_account_util.cc
@@ -140,6 +140,7 @@ "aoggjnmghgmcllfenalipjhmooomfdce", // SAML SSO for Chrome Apps "fhndealchbngfhdoncgcokameljahhog", // Certificate Enrollment for Chrome OS "npeicpdbkakmehahjeeohfdhnlpdklia", // WebRTC Network Limiter + "hdkoikmfpncabbdniojdddokkomafcci", // SSRS Reporting Fix for Chrome }; } // namespace
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_controller.h b/ios/chrome/browser/ui/fullscreen/fullscreen_controller.h index 4b4f6e24..f899dc9 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_controller.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_controller.h
@@ -9,6 +9,7 @@ #include <memory> #include "base/macros.h" +#include "base/supports_user_data.h" @class ChromeBroadcaster; @class ChromeBroadcastOberverBridge; @@ -20,10 +21,21 @@ // calculates how much of the toolbar should be visible as a result. When the // user scrolls down the screen, the toolbar should be hidden to allow more of // the page's content to be visible. -class FullscreenController { +class FullscreenController : public base::SupportsUserData::Data { public: - explicit FullscreenController(ChromeBroadcaster* broadcaster); - ~FullscreenController(); + ~FullscreenController() override; + + // Creation and getter functions for FullscreenController. + // TODO(crbug.com/790886): Convert FullscreenController to a BrowserUserData. + static void CreateForUserData(base::SupportsUserData* user_data); + static FullscreenController* FromUserData(base::SupportsUserData* user_data); + + // The ChromeBroadcaster through the FullscreenController receives UI + // information necessary to calculate fullscreen progress. + // TODO(crbug.com/790886): Once FullscreenController is a BrowserUserData, + // remove this ad-hoc broadcaster and drive the animations via the Browser's + // ChromeBroadcaster. + ChromeBroadcaster* broadcaster() { return broadcaster_; } // Adds and removes FullscreenControllerObservers. void AddObserver(FullscreenControllerObserver* observer); @@ -42,6 +54,9 @@ void DecrementDisabledCounter(); private: + // Private contructor used by CreateForUserData(). + explicit FullscreenController(); + // The broadcaster that drives the model. __strong ChromeBroadcaster* broadcaster_ = nil; // The model used to calculate fullscreen state.
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_controller.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_controller.mm index c496895..869cd86d 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_controller.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_controller.mm
@@ -14,8 +14,31 @@ #error "This file requires ARC support." #endif -FullscreenController::FullscreenController(ChromeBroadcaster* broadcaster) - : broadcaster_(broadcaster), +namespace { +// The key under which FullscreenControllers are associated with their user +// data. +const void* const kFullscreenControllerKey = &kFullscreenControllerKey; +} // namespace + +// static +void FullscreenController::CreateForUserData( + base::SupportsUserData* user_data) { + DCHECK(user_data); + if (!FullscreenController::FromUserData(user_data)) { + user_data->SetUserData(kFullscreenControllerKey, + base::WrapUnique(new FullscreenController())); + } +} + +// static +FullscreenController* FullscreenController::FromUserData( + base::SupportsUserData* user_data) { + return static_cast<FullscreenController*>( + user_data->GetUserData(kFullscreenControllerKey)); +} + +FullscreenController::FullscreenController() + : broadcaster_([[ChromeBroadcaster alloc] init]), model_(base::MakeUnique<FullscreenModel>()), bridge_([[ChromeBroadcastOberverBridge alloc] initWithObserver:model_.get()]) {
diff --git a/media/capture/video/android/video_capture_device_android.cc b/media/capture/video/android/video_capture_device_android.cc index b98c0bb..785fc1b 100644 --- a/media/capture/video/android/video_capture_device_android.cc +++ b/media/capture/video/android/video_capture_device_android.cc
@@ -146,7 +146,7 @@ capture_format_.frame_rate = Java_VideoCapture_queryFrameRate(env, j_capture_); capture_format_.pixel_format = GetColorspace(); - DCHECK_NE(capture_format_.pixel_format, media::PIXEL_FORMAT_UNKNOWN); + DCHECK_NE(capture_format_.pixel_format, PIXEL_FORMAT_UNKNOWN); CHECK(capture_format_.frame_size.GetArea() > 0); CHECK(!(capture_format_.frame_size.width() % 2)); CHECK(!(capture_format_.frame_size.height() % 2)); @@ -429,14 +429,14 @@ Java_VideoCapture_getColorspace(env, j_capture_); switch (current_capture_colorspace) { case ANDROID_IMAGE_FORMAT_YV12: - return media::PIXEL_FORMAT_YV12; + return PIXEL_FORMAT_YV12; case ANDROID_IMAGE_FORMAT_YUV_420_888: - return media::PIXEL_FORMAT_I420; + return PIXEL_FORMAT_I420; case ANDROID_IMAGE_FORMAT_NV21: - return media::PIXEL_FORMAT_NV21; + return PIXEL_FORMAT_NV21; case ANDROID_IMAGE_FORMAT_UNKNOWN: default: - return media::PIXEL_FORMAT_UNKNOWN; + return PIXEL_FORMAT_UNKNOWN; } }
diff --git a/media/capture/video/android/video_capture_device_factory_android.cc b/media/capture/video/android/video_capture_device_factory_android.cc index 064d69d08..d9ee746 100644 --- a/media/capture/video/android/video_capture_device_factory_android.cc +++ b/media/capture/video/android/video_capture_device_factory_android.cc
@@ -104,14 +104,13 @@ base::android::ScopedJavaLocalRef<jobject> format( env, env->GetObjectArrayElement(collected_formats.obj(), i)); - VideoPixelFormat pixel_format = media::PIXEL_FORMAT_UNKNOWN; - switch (media::Java_VideoCaptureFactory_getCaptureFormatPixelFormat( - env, format)) { + VideoPixelFormat pixel_format = PIXEL_FORMAT_UNKNOWN; + switch (Java_VideoCaptureFactory_getCaptureFormatPixelFormat(env, format)) { case VideoCaptureDeviceAndroid::ANDROID_IMAGE_FORMAT_YV12: - pixel_format = media::PIXEL_FORMAT_YV12; + pixel_format = PIXEL_FORMAT_YV12; break; case VideoCaptureDeviceAndroid::ANDROID_IMAGE_FORMAT_NV21: - pixel_format = media::PIXEL_FORMAT_NV21; + pixel_format = PIXEL_FORMAT_NV21; break; default: // TODO(mcasas): break here and let the enumeration continue with @@ -120,11 +119,9 @@ continue; } VideoCaptureFormat capture_format( - gfx::Size( - media::Java_VideoCaptureFactory_getCaptureFormatWidth(env, format), - media::Java_VideoCaptureFactory_getCaptureFormatHeight(env, - format)), - media::Java_VideoCaptureFactory_getCaptureFormatFramerate(env, format), + gfx::Size(Java_VideoCaptureFactory_getCaptureFormatWidth(env, format), + Java_VideoCaptureFactory_getCaptureFormatHeight(env, format)), + Java_VideoCaptureFactory_getCaptureFormatFramerate(env, format), pixel_format); capture_formats->push_back(capture_format); DVLOG(1) << device.display_name << " "
diff --git a/media/capture/video/chromeos/mock_video_capture_client.cc b/media/capture/video/chromeos/mock_video_capture_client.cc index b9be6f7..7c22b95f 100644 --- a/media/capture/video/chromeos/mock_video_capture_client.cc +++ b/media/capture/video/chromeos/mock_video_capture_client.cc
@@ -55,8 +55,8 @@ // Trampoline methods to workaround GMOCK problems with std::unique_ptr<>. VideoCaptureDevice::Client::Buffer MockVideoCaptureClient::ReserveOutputBuffer( const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id) { DoReserveOutputBuffer(); NOTREACHED() << "This should never be called"; @@ -82,11 +82,10 @@ } VideoCaptureDevice::Client::Buffer -MockVideoCaptureClient::ResurrectLastOutputBuffer( - const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, - int frame_feedback_id) { +MockVideoCaptureClient::ResurrectLastOutputBuffer(const gfx::Size& dimensions, + VideoPixelFormat format, + VideoPixelStorage storage, + int frame_feedback_id) { DoResurrectLastOutputBuffer(); NOTREACHED() << "This should never be called"; return Buffer();
diff --git a/media/capture/video/chromeos/mock_video_capture_client.h b/media/capture/video/chromeos/mock_video_capture_client.h index e9be4a7..897be99 100644 --- a/media/capture/video/chromeos/mock_video_capture_client.h +++ b/media/capture/video/chromeos/mock_video_capture_client.h
@@ -42,8 +42,8 @@ int frame_feedback_id) override; // Trampoline methods to workaround GMOCK problems with std::unique_ptr<>. Buffer ReserveOutputBuffer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id) override; void OnIncomingCapturedBuffer(Buffer buffer, const VideoCaptureFormat& format, @@ -57,8 +57,8 @@ gfx::Rect visible_rect, const VideoFrameMetadata& additional_metadata) override; Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id) override; private:
diff --git a/media/capture/video/fake_video_capture_device.cc b/media/capture/video/fake_video_capture_device.cc index 6662752..8f6532e 100644 --- a/media/capture/video/fake_video_capture_device.cc +++ b/media/capture/video/fake_video_capture_device.cc
@@ -49,10 +49,10 @@ }; PixelFormatMatchType DetermineFormatMatchType( - media::VideoPixelFormat supported_format, - media::VideoPixelFormat requested_format) { - if (requested_format == media::PIXEL_FORMAT_I420 && - supported_format == media::PIXEL_FORMAT_MJPEG) { + VideoPixelFormat supported_format, + VideoPixelFormat requested_format) { + if (requested_format == PIXEL_FORMAT_I420 && + supported_format == PIXEL_FORMAT_MJPEG) { return PixelFormatMatchType::SUPPORTED_THROUGH_CONVERSION; } return (requested_format == supported_format) @@ -60,7 +60,7 @@ : PixelFormatMatchType::INCOMPATIBLE; } -const media::VideoCaptureFormat& FindClosestSupportedFormat( +const VideoCaptureFormat& FindClosestSupportedFormat( const VideoCaptureFormat& requested_format, const VideoCaptureFormats& supported_formats) { DCHECK(!supported_formats.empty());
diff --git a/media/capture/video/fake_video_capture_device_unittest.cc b/media/capture/video/fake_video_capture_device_unittest.cc index 3abc9a1..ec081a23 100644 --- a/media/capture/video/fake_video_capture_device_unittest.cc +++ b/media/capture/video/fake_video_capture_device_unittest.cc
@@ -121,10 +121,10 @@ } // Virtual methods for capturing using Client's Buffers. Buffer ReserveOutputBuffer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id) override { - EXPECT_EQ(media::PIXEL_STORAGE_CPU, storage); + EXPECT_EQ(PIXEL_STORAGE_CPU, storage); EXPECT_GT(dimensions.GetArea(), 0); const VideoCaptureFormat frame_format(dimensions, 0.0, format); return CreateStubBuffer(0, frame_format.ImageAllocationSize()); @@ -145,8 +145,8 @@ frame_cb_.Run(format); } Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id) override { return Buffer(); } @@ -241,7 +241,7 @@ TEST_P(FakeVideoCaptureDeviceTest, CaptureUsing) { if (testing::get<1>(GetParam()) == FakeVideoCaptureDevice::DeliveryMode::USE_CLIENT_PROVIDED_BUFFERS && - testing::get<0>(GetParam()) == media::PIXEL_FORMAT_MJPEG) { + testing::get<0>(GetParam()) == PIXEL_FORMAT_MJPEG) { // Unsupported case return; } @@ -512,7 +512,7 @@ video_capture_device_factory_->SetToCustomDevicesConfig(config); video_capture_device_factory_->GetDeviceDescriptors(descriptors_.get()); EXPECT_EQ(1u, descriptors_->size()); - media::VideoCaptureFormats supported_formats; + VideoCaptureFormats supported_formats; video_capture_device_factory_->GetSupportedFormats(descriptors_->at(0), &supported_formats); EXPECT_EQ(0u, supported_formats.size()); @@ -539,7 +539,7 @@ int device_index = 0; for (const auto& descriptors_iterator : *descriptors_) { - media::VideoCaptureFormats supported_formats; + VideoCaptureFormats supported_formats; video_capture_device_factory_->GetSupportedFormats(descriptors_iterator, &supported_formats); for (const auto& supported_formats_entry : supported_formats) {
diff --git a/media/capture/video/file_video_capture_device.cc b/media/capture/video/file_video_capture_device.cc index cacd868..57f4b58 100644 --- a/media/capture/video/file_video_capture_device.cc +++ b/media/capture/video/file_video_capture_device.cc
@@ -54,9 +54,9 @@ // format, in this case it means I420. // This code was inspired by third_party/libvpx/.../y4minput.* . void ParseY4MTags(const std::string& file_header, - media::VideoCaptureFormat* video_format) { - media::VideoCaptureFormat format; - format.pixel_format = media::PIXEL_FORMAT_I420; + VideoCaptureFormat* video_format) { + VideoCaptureFormat format; + format.pixel_format = PIXEL_FORMAT_I420; size_t index = 0; size_t blank_position = 0; base::StringPiece token; @@ -114,7 +114,7 @@ virtual ~VideoFileParser(); // Parses file header and collects format information in |capture_format|. - virtual bool Initialize(media::VideoCaptureFormat* capture_format) = 0; + virtual bool Initialize(VideoCaptureFormat* capture_format) = 0; // Gets the start pointer of next frame and stores current frame size in // |frame_size|. @@ -133,7 +133,7 @@ // VideoFileParser implementation, class methods. ~Y4mFileParser() override; - bool Initialize(media::VideoCaptureFormat* capture_format) override; + bool Initialize(VideoCaptureFormat* capture_format) override; const uint8_t* GetNextFrame(int* frame_size) override; private: @@ -149,7 +149,7 @@ // VideoFileParser implementation, class methods. ~MjpegFileParser() override; - bool Initialize(media::VideoCaptureFormat* capture_format) override; + bool Initialize(VideoCaptureFormat* capture_format) override; const uint8_t* GetNextFrame(int* frame_size) override; private: @@ -171,7 +171,7 @@ Y4mFileParser::~Y4mFileParser() = default; -bool Y4mFileParser::Initialize(media::VideoCaptureFormat* capture_format) { +bool Y4mFileParser::Initialize(VideoCaptureFormat* capture_format) { file_.reset(new base::File(file_path_, base::File::FLAG_OPEN | base::File::FLAG_READ)); if (!file_->IsValid()) { @@ -220,7 +220,7 @@ MjpegFileParser::~MjpegFileParser() = default; -bool MjpegFileParser::Initialize(media::VideoCaptureFormat* capture_format) { +bool MjpegFileParser::Initialize(VideoCaptureFormat* capture_format) { mapped_file_.reset(new base::MemoryMappedFile()); if (!mapped_file_->Initialize(file_path_) || !mapped_file_->IsValid()) { @@ -239,7 +239,7 @@ } VideoCaptureFormat format; - format.pixel_format = media::PIXEL_FORMAT_MJPEG; + format.pixel_format = PIXEL_FORMAT_MJPEG; format.frame_size.set_width(result.frame_header.visible_width); format.frame_size.set_height(result.frame_header.visible_height); format.frame_rate = kMJpegFrameRate; @@ -268,7 +268,7 @@ // static bool FileVideoCaptureDevice::GetVideoCaptureFormat( const base::FilePath& file_path, - media::VideoCaptureFormat* video_format) { + VideoCaptureFormat* video_format) { std::unique_ptr<VideoFileParser> file_parser = GetVideoFileParser(file_path, video_format); return file_parser != nullptr; @@ -277,7 +277,7 @@ // static std::unique_ptr<VideoFileParser> FileVideoCaptureDevice::GetVideoFileParser( const base::FilePath& file_path, - media::VideoCaptureFormat* video_format) { + VideoCaptureFormat* video_format) { std::unique_ptr<VideoFileParser> file_parser; std::string file_name(file_path.value().begin(), file_path.value().end());
diff --git a/media/capture/video/file_video_capture_device.h b/media/capture/video/file_video_capture_device.h index 53d2670..161efd59 100644 --- a/media/capture/video/file_video_capture_device.h +++ b/media/capture/video/file_video_capture_device.h
@@ -39,7 +39,7 @@ // or false. // Restrictions: Only trivial Y4M per-frame headers and MJPEG are supported. static bool GetVideoCaptureFormat(const base::FilePath& file_path, - media::VideoCaptureFormat* video_format); + VideoCaptureFormat* video_format); // Constructor of the class, with a fully qualified file path as input, which // represents the Y4M or MJPEG file to stream repeatedly. @@ -58,7 +58,7 @@ // caller, who is responsible for closing it. static std::unique_ptr<VideoFileParser> GetVideoFileParser( const base::FilePath& file_path, - media::VideoCaptureFormat* video_format); + VideoCaptureFormat* video_format); // Called on the |capture_thread_|. void OnAllocateAndStart(const VideoCaptureParams& params,
diff --git a/media/capture/video/linux/v4l2_capture_delegate.cc b/media/capture/video/linux/v4l2_capture_delegate.cc index 7cb3b857..ce969d7 100644 --- a/media/capture/video/linux/v4l2_capture_delegate.cc +++ b/media/capture/video/linux/v4l2_capture_delegate.cc
@@ -447,11 +447,10 @@ // Now check if the device is able to accept a capture framerate set. if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) { // |frame_rate| is float, approximate by a fraction. - streamparm.parm.capture.timeperframe.numerator = - media::kFrameRatePrecision; + streamparm.parm.capture.timeperframe.numerator = kFrameRatePrecision; streamparm.parm.capture.timeperframe.denominator = - (frame_rate) ? (frame_rate * media::kFrameRatePrecision) - : (kTypicalFramerate * media::kFrameRatePrecision); + (frame_rate) ? (frame_rate * kFrameRatePrecision) + : (kTypicalFramerate * kFrameRatePrecision); if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_PARM, &streamparm)) < 0) {
diff --git a/media/capture/video/linux/v4l2_capture_delegate_unittest.cc b/media/capture/video/linux/v4l2_capture_delegate_unittest.cc index 04f7b9f..71a1edff 100644 --- a/media/capture/video/linux/v4l2_capture_delegate_unittest.cc +++ b/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
@@ -182,11 +182,9 @@ base::TimeTicks, base::TimeDelta, int)); - MOCK_METHOD4(ReserveOutputBuffer, - Buffer(const gfx::Size&, - media::VideoPixelFormat, - media::VideoPixelStorage, - int)); + MOCK_METHOD4( + ReserveOutputBuffer, + Buffer(const gfx::Size&, VideoPixelFormat, VideoPixelStorage, int)); void OnIncomingCapturedBuffer(Buffer buffer, const VideoCaptureFormat& frame_format, base::TimeTicks reference_time,
diff --git a/media/capture/video/linux/video_capture_device_linux.cc b/media/capture/video/linux/video_capture_device_linux.cc index e247368..2883ccee 100644 --- a/media/capture/video/linux/video_capture_device_linux.cc +++ b/media/capture/video/linux/video_capture_device_linux.cc
@@ -139,9 +139,9 @@ int VideoCaptureDeviceLinux::TranslatePowerLineFrequencyToV4L2( PowerLineFrequency frequency) { switch (frequency) { - case media::PowerLineFrequency::FREQUENCY_50HZ: + case PowerLineFrequency::FREQUENCY_50HZ: return V4L2_CID_POWER_LINE_FREQUENCY_50HZ; - case media::PowerLineFrequency::FREQUENCY_60HZ: + case PowerLineFrequency::FREQUENCY_60HZ: return V4L2_CID_POWER_LINE_FREQUENCY_60HZ; default: // If we have no idea of the frequency, at least try and set it to AUTO.
diff --git a/media/capture/video/mac/video_capture_device_decklink_mac.mm b/media/capture/video/mac/video_capture_device_decklink_mac.mm index 6d7e8457..10d598c 100644 --- a/media/capture/video/mac/video_capture_device_decklink_mac.mm +++ b/media/capture/video/mac/video_capture_device_decklink_mac.mm
@@ -446,8 +446,7 @@ // is only available on capture. const media::VideoCaptureFormat format( gfx::Size(display_mode->GetWidth(), display_mode->GetHeight()), - GetDisplayModeFrameRate(display_mode), - PIXEL_FORMAT_UNKNOWN); + GetDisplayModeFrameRate(display_mode), PIXEL_FORMAT_UNKNOWN); supported_formats->push_back(format); DVLOG(2) << device.display_name << " " << VideoCaptureFormat::ToString(format);
diff --git a/media/capture/video/mock_video_frame_receiver.h b/media/capture/video/mock_video_frame_receiver.h index 35c5fc4..241566cf0e 100644 --- a/media/capture/video/mock_video_frame_receiver.h +++ b/media/capture/video/mock_video_frame_receiver.h
@@ -19,8 +19,9 @@ MOCK_METHOD3( MockOnFrameReadyInBuffer, void(int buffer_id, - std::unique_ptr<media::VideoCaptureDevice::Client::Buffer:: - ScopedAccessPermission>* buffer_read_permission, + std::unique_ptr< + VideoCaptureDevice::Client::Buffer::ScopedAccessPermission>* + buffer_read_permission, const gfx::Size&)); MOCK_METHOD0(OnError, void()); MOCK_METHOD1(OnLog, void(const std::string& message)); @@ -30,7 +31,7 @@ void OnNewBufferHandle( int buffer_id, - std::unique_ptr<media::VideoCaptureDevice::Client::Buffer::HandleProvider> + std::unique_ptr<VideoCaptureDevice::Client::Buffer::HandleProvider> handle_provider) override { MockOnNewBufferHandle(buffer_id); } @@ -39,7 +40,7 @@ int32_t buffer_id, int frame_feedback_id, std::unique_ptr< - media::VideoCaptureDevice::Client::Buffer::ScopedAccessPermission> + VideoCaptureDevice::Client::Buffer::ScopedAccessPermission> buffer_read_permission, media::mojom::VideoFrameInfoPtr frame_info) override { MockOnFrameReadyInBuffer(buffer_id, &buffer_read_permission,
diff --git a/media/capture/video/shared_memory_handle_provider.h b/media/capture/video/shared_memory_handle_provider.h index d844a98..8a14f3a 100644 --- a/media/capture/video/shared_memory_handle_provider.h +++ b/media/capture/video/shared_memory_handle_provider.h
@@ -19,7 +19,7 @@ // Provides handles from a single, owned base::SharedMemory instance. class CAPTURE_EXPORT SharedMemoryHandleProvider - : public media::VideoCaptureDevice::Client::Buffer::HandleProvider { + : public VideoCaptureDevice::Client::Buffer::HandleProvider { public: // Note: One of the two InitXYZ() methods must be called before using any of // the HandleProvider methods. @@ -39,7 +39,7 @@ mojo::ScopedSharedBufferHandle GetHandleForInterProcessTransit( bool read_only) override; base::SharedMemoryHandle GetNonOwnedSharedMemoryHandleForLegacyIPC() override; - std::unique_ptr<media::VideoCaptureBufferHandle> GetHandleForInProcessAccess() + std::unique_ptr<VideoCaptureBufferHandle> GetHandleForInProcessAccess() override; private:
diff --git a/media/capture/video/video_capture_buffer_pool.h b/media/capture/video/video_capture_buffer_pool.h index 050f487..5fb47c5 100644 --- a/media/capture/video/video_capture_buffer_pool.h +++ b/media/capture/video/video_capture_buffer_pool.h
@@ -68,8 +68,8 @@ // new allocation at a larger size. If so, the ID of the destroyed buffer is // returned via |buffer_id_to_drop|. virtual int ReserveForProducer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id, int* buffer_id_to_drop) = 0; @@ -87,8 +87,8 @@ // A producer may assume the content of the buffer has been preserved and may // also make modifications. virtual int ResurrectLastForProducer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage) = 0; + VideoPixelFormat format, + VideoPixelStorage storage) = 0; // Returns a snapshot of the current number of buffers in-use divided by the // maximum |count_|.
diff --git a/media/capture/video/video_capture_buffer_pool_impl.cc b/media/capture/video/video_capture_buffer_pool_impl.cc index e983383..4c6d696 100644 --- a/media/capture/video/video_capture_buffer_pool_impl.cc +++ b/media/capture/video/video_capture_buffer_pool_impl.cc
@@ -66,12 +66,11 @@ return tracker->GetMemoryMappedAccess(); } -int VideoCaptureBufferPoolImpl::ReserveForProducer( - const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, - int frame_feedback_id, - int* buffer_id_to_drop) { +int VideoCaptureBufferPoolImpl::ReserveForProducer(const gfx::Size& dimensions, + VideoPixelFormat format, + VideoPixelStorage storage, + int frame_feedback_id, + int* buffer_id_to_drop) { base::AutoLock lock(lock_); return ReserveForProducerInternal(dimensions, format, storage, frame_feedback_id, buffer_id_to_drop); @@ -103,7 +102,7 @@ tracker->set_consumer_hold_count(num_clients); // Note: |held_by_producer()| will stay true until // RelinquishProducerReservation() (usually called by destructor of the object - // wrapping this tracker, e.g. a media::VideoFrame). + // wrapping this tracker, e.g. a VideoFrame). } void VideoCaptureBufferPoolImpl::RelinquishConsumerHold(int buffer_id, @@ -122,8 +121,8 @@ int VideoCaptureBufferPoolImpl::ResurrectLastForProducer( const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage) { + VideoPixelFormat format, + VideoPixelStorage storage) { base::AutoLock lock(lock_); // Return early if the last relinquished buffer has been re-used already. @@ -163,8 +162,8 @@ int VideoCaptureBufferPoolImpl::ReserveForProducerInternal( const gfx::Size& dimensions, - media::VideoPixelFormat pixel_format, - media::VideoPixelStorage storage_type, + VideoPixelFormat pixel_format, + VideoPixelStorage storage_type, int frame_feedback_id, int* buffer_id_to_drop) { lock_.AssertAcquired();
diff --git a/media/capture/video/video_capture_buffer_pool_impl.h b/media/capture/video/video_capture_buffer_pool_impl.h index 72b0c43..5a0fafd 100644 --- a/media/capture/video/video_capture_buffer_pool_impl.h +++ b/media/capture/video/video_capture_buffer_pool_impl.h
@@ -43,14 +43,14 @@ std::unique_ptr<VideoCaptureBufferHandle> GetHandleForInProcessAccess( int buffer_id) override; int ReserveForProducer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id, int* buffer_id_to_drop) override; void RelinquishProducerReservation(int buffer_id) override; int ResurrectLastForProducer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage) override; + VideoPixelFormat format, + VideoPixelStorage storage) override; double GetBufferPoolUtilization() const override; void HoldForConsumers(int buffer_id, int num_clients) override; void RelinquishConsumerHold(int buffer_id, int num_clients) override; @@ -60,8 +60,8 @@ ~VideoCaptureBufferPoolImpl() override; int ReserveForProducerInternal(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id, int* tracker_id_to_drop);
diff --git a/media/capture/video/video_capture_buffer_tracker.h b/media/capture/video/video_capture_buffer_tracker.h index b0e4e34..e7f03da 100644 --- a/media/capture/video/video_capture_buffer_tracker.h +++ b/media/capture/video/video_capture_buffer_tracker.h
@@ -26,20 +26,18 @@ consumer_hold_count_(0), frame_feedback_id_(0) {} virtual bool Init(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage_type) = 0; + VideoPixelFormat format, + VideoPixelStorage storage_type) = 0; virtual ~VideoCaptureBufferTracker(){}; const gfx::Size& dimensions() const { return dimensions_; } void set_dimensions(const gfx::Size& dim) { dimensions_ = dim; } size_t max_pixel_count() const { return max_pixel_count_; } void set_max_pixel_count(size_t count) { max_pixel_count_ = count; } - media::VideoPixelFormat pixel_format() const { return pixel_format_; } - void set_pixel_format(media::VideoPixelFormat format) { - pixel_format_ = format; - } - media::VideoPixelStorage storage_type() const { return storage_type_; } - void set_storage_type(media::VideoPixelStorage storage_type) { + VideoPixelFormat pixel_format() const { return pixel_format_; } + void set_pixel_format(VideoPixelFormat format) { pixel_format_ = format; } + VideoPixelStorage storage_type() const { return storage_type_; } + void set_storage_type(VideoPixelStorage storage_type) { storage_type_ = storage_type; } bool held_by_producer() const { return held_by_producer_; } @@ -61,8 +59,8 @@ // the lifetime of a VideoCaptureBufferTracker. gfx::Size dimensions_; size_t max_pixel_count_; - media::VideoPixelFormat pixel_format_; - media::VideoPixelStorage storage_type_; + VideoPixelFormat pixel_format_; + VideoPixelStorage storage_type_; // Indicates whether this VideoCaptureBufferTracker is currently referenced by // the producer.
diff --git a/media/capture/video/video_capture_device.cc b/media/capture/video/video_capture_device.cc index f39cdba..86dc8a74 100644 --- a/media/capture/video/video_capture_device.cc +++ b/media/capture/video/video_capture_device.cc
@@ -58,16 +58,16 @@ countries_using_60Hz + arraysize(countries_using_60Hz); if (std::find(countries_using_60Hz, countries_using_60Hz_end, current_country) == countries_using_60Hz_end) { - return media::PowerLineFrequency::FREQUENCY_50HZ; + return PowerLineFrequency::FREQUENCY_50HZ; } - return media::PowerLineFrequency::FREQUENCY_60HZ; + return PowerLineFrequency::FREQUENCY_60HZ; } PowerLineFrequency VideoCaptureDevice::GetPowerLineFrequency( const VideoCaptureParams& params) const { switch (params.power_line_frequency) { - case media::PowerLineFrequency::FREQUENCY_50HZ: // fall through - case media::PowerLineFrequency::FREQUENCY_60HZ: + case PowerLineFrequency::FREQUENCY_50HZ: // fall through + case PowerLineFrequency::FREQUENCY_60HZ: return params.power_line_frequency; default: return GetPowerLineFrequencyForLocation();
diff --git a/media/capture/video/video_capture_device_client.cc b/media/capture/video/video_capture_device_client.cc index 311605a5..b4dbff5c 100644 --- a/media/capture/video/video_capture_device_client.cc +++ b/media/capture/video/video_capture_device_client.cc
@@ -24,10 +24,6 @@ #include "media/capture/video_capture_types.h" #include "third_party/libyuv/include/libyuv.h" -using media::VideoCaptureFormat; -using media::VideoFrame; -using media::VideoFrameMetadata; - namespace { bool IsFormatSupported(media::VideoPixelFormat pixel_format) { @@ -73,7 +69,7 @@ jpeg_decoder_factory_callback_(jpeg_decoder_factory), external_jpeg_decoder_initialized_(false), buffer_pool_(std::move(buffer_pool)), - last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) { + last_captured_pixel_format_(PIXEL_FORMAT_UNKNOWN) { on_started_using_gpu_cb_ = base::Bind(&VideoFrameReceiver::OnStartedUsingGpuDecode, base::Unretained(receiver_.get())); @@ -109,14 +105,13 @@ base::TimeDelta timestamp, int frame_feedback_id) { TRACE_EVENT0("video", "VideoCaptureDeviceClient::OnIncomingCapturedData"); - DCHECK_EQ(media::PIXEL_STORAGE_CPU, format.pixel_storage); + DCHECK_EQ(PIXEL_STORAGE_CPU, format.pixel_storage); if (last_captured_pixel_format_ != format.pixel_format) { - OnLog("Pixel format: " + - media::VideoPixelFormatToString(format.pixel_format)); + OnLog("Pixel format: " + VideoPixelFormatToString(format.pixel_format)); last_captured_pixel_format_ = format.pixel_format; - if (format.pixel_format == media::PIXEL_FORMAT_MJPEG && + if (format.pixel_format == PIXEL_FORMAT_MJPEG && !external_jpeg_decoder_initialized_) { external_jpeg_decoder_initialized_ = true; external_jpeg_decoder_ = jpeg_decoder_factory_callback_.Run(); @@ -128,7 +123,7 @@ if (!format.IsValid()) return; - if (format.pixel_format == media::PIXEL_FORMAT_Y16) { + if (format.pixel_format == PIXEL_FORMAT_Y16) { return OnIncomingCapturedY16Data(data, length, format, reference_time, timestamp, frame_feedback_id); } @@ -156,9 +151,8 @@ rotation_mode = libyuv::kRotate270; const gfx::Size dimensions(destination_width, destination_height); - Buffer buffer = - ReserveOutputBuffer(dimensions, media::PIXEL_FORMAT_I420, - media::PIXEL_STORAGE_CPU, frame_feedback_id); + Buffer buffer = ReserveOutputBuffer(dimensions, PIXEL_FORMAT_I420, + PIXEL_STORAGE_CPU, frame_feedback_id); #if DCHECK_IS_ON() dropped_frame_counter_ = buffer.is_valid() ? 0 : dropped_frame_counter_ + 1; if (dropped_frame_counter_ >= kMaxDroppedFrames) @@ -174,13 +168,13 @@ auto buffer_access = buffer.handle_provider->GetHandleForInProcessAccess(); uint8_t* y_plane_data = buffer_access->data(); uint8_t* u_plane_data = - y_plane_data + VideoFrame::PlaneSize(media::PIXEL_FORMAT_I420, - VideoFrame::kYPlane, dimensions) - .GetArea(); + y_plane_data + + VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kYPlane, dimensions) + .GetArea(); uint8_t* v_plane_data = - u_plane_data + VideoFrame::PlaneSize(media::PIXEL_FORMAT_I420, - VideoFrame::kUPlane, dimensions) - .GetArea(); + u_plane_data + + VideoFrame::PlaneSize(PIXEL_FORMAT_I420, VideoFrame::kUPlane, dimensions) + .GetArea(); const int yplane_stride = dimensions.width(); const int uv_plane_stride = yplane_stride / 2; @@ -190,33 +184,33 @@ bool flip = false; switch (format.pixel_format) { - case media::PIXEL_FORMAT_UNKNOWN: // Color format not set. + case PIXEL_FORMAT_UNKNOWN: // Color format not set. break; - case media::PIXEL_FORMAT_I420: + case PIXEL_FORMAT_I420: DCHECK(!chopped_width && !chopped_height); origin_colorspace = libyuv::FOURCC_I420; break; - case media::PIXEL_FORMAT_YV12: + case PIXEL_FORMAT_YV12: DCHECK(!chopped_width && !chopped_height); origin_colorspace = libyuv::FOURCC_YV12; break; - case media::PIXEL_FORMAT_NV12: + case PIXEL_FORMAT_NV12: DCHECK(!chopped_width && !chopped_height); origin_colorspace = libyuv::FOURCC_NV12; break; - case media::PIXEL_FORMAT_NV21: + case PIXEL_FORMAT_NV21: DCHECK(!chopped_width && !chopped_height); origin_colorspace = libyuv::FOURCC_NV21; break; - case media::PIXEL_FORMAT_YUY2: + case PIXEL_FORMAT_YUY2: DCHECK(!chopped_width && !chopped_height); origin_colorspace = libyuv::FOURCC_YUY2; break; - case media::PIXEL_FORMAT_UYVY: + case PIXEL_FORMAT_UYVY: DCHECK(!chopped_width && !chopped_height); origin_colorspace = libyuv::FOURCC_UYVY; break; - case media::PIXEL_FORMAT_RGB24: + case PIXEL_FORMAT_RGB24: // Linux RGB24 defines red at lowest byte address, // see http://linuxtv.org/downloads/v4l-dvb-apis/packed-rgb.html. // Windows RGB24 defines blue at lowest byte, @@ -236,16 +230,16 @@ flip = true; #endif break; - case media::PIXEL_FORMAT_RGB32: + case PIXEL_FORMAT_RGB32: // Fallback to PIXEL_FORMAT_ARGB setting |flip| in Windows // platforms. #if defined(OS_WIN) flip = true; #endif - case media::PIXEL_FORMAT_ARGB: + case PIXEL_FORMAT_ARGB: origin_colorspace = libyuv::FOURCC_ARGB; break; - case media::PIXEL_FORMAT_MJPEG: + case PIXEL_FORMAT_MJPEG: origin_colorspace = libyuv::FOURCC_MJPG; break; default: @@ -262,8 +256,8 @@ if (status == VideoCaptureJpegDecoder::FAILED) { external_jpeg_decoder_.reset(); } else if (status == VideoCaptureJpegDecoder::INIT_PASSED && - format.pixel_format == media::PIXEL_FORMAT_MJPEG && - rotation == 0 && !flip) { + format.pixel_format == PIXEL_FORMAT_MJPEG && rotation == 0 && + !flip) { if (on_started_using_gpu_cb_) std::move(on_started_using_gpu_cb_).Run(); external_jpeg_decoder_->DecodeCapturedData( @@ -279,23 +273,21 @@ (flip ? -1 : 1) * format.frame_size.height(), new_unrotated_width, new_unrotated_height, rotation_mode, origin_colorspace) != 0) { DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from " - << media::VideoPixelFormatToString(format.pixel_format); + << VideoPixelFormatToString(format.pixel_format); return; } - const VideoCaptureFormat output_format = - VideoCaptureFormat(dimensions, format.frame_rate, - media::PIXEL_FORMAT_I420, media::PIXEL_STORAGE_CPU); + const VideoCaptureFormat output_format = VideoCaptureFormat( + dimensions, format.frame_rate, PIXEL_FORMAT_I420, PIXEL_STORAGE_CPU); OnIncomingCapturedBuffer(std::move(buffer), output_format, reference_time, timestamp); } -media::VideoCaptureDevice::Client::Buffer -VideoCaptureDeviceClient::ReserveOutputBuffer( - const gfx::Size& frame_size, - media::VideoPixelFormat pixel_format, - media::VideoPixelStorage pixel_storage, - int frame_feedback_id) { +VideoCaptureDevice::Client::Buffer +VideoCaptureDeviceClient::ReserveOutputBuffer(const gfx::Size& frame_size, + VideoPixelFormat pixel_format, + VideoPixelStorage pixel_storage, + int frame_feedback_id) { DFAKE_SCOPED_RECURSIVE_LOCK(call_from_producer_); DCHECK_GT(frame_size.width(), 0); DCHECK_GT(frame_size.height(), 0); @@ -351,9 +343,8 @@ VideoFrameMetadata metadata; metadata.MergeMetadataFrom(&additional_metadata); - metadata.SetDouble(media::VideoFrameMetadata::FRAME_RATE, format.frame_rate); - metadata.SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, - reference_time); + metadata.SetDouble(VideoFrameMetadata::FRAME_RATE, format.frame_rate); + metadata.SetTimeTicks(VideoFrameMetadata::REFERENCE_TIME, reference_time); mojom::VideoFrameInfoPtr info = mojom::VideoFrameInfo::New(); info->timestamp = timestamp; @@ -371,12 +362,11 @@ std::move(info)); } -media::VideoCaptureDevice::Client::Buffer -VideoCaptureDeviceClient::ResurrectLastOutputBuffer( - const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, - int new_frame_feedback_id) { +VideoCaptureDevice::Client::Buffer +VideoCaptureDeviceClient::ResurrectLastOutputBuffer(const gfx::Size& dimensions, + VideoPixelFormat format, + VideoPixelStorage storage, + int new_frame_feedback_id) { DFAKE_SCOPED_RECURSIVE_LOCK(call_from_producer_); const int buffer_id = buffer_pool_->ResurrectLastForProducer(dimensions, format, storage); @@ -416,9 +406,8 @@ base::TimeTicks reference_time, base::TimeDelta timestamp, int frame_feedback_id) { - Buffer buffer = - ReserveOutputBuffer(format.frame_size, media::PIXEL_FORMAT_Y16, - media::PIXEL_STORAGE_CPU, frame_feedback_id); + Buffer buffer = ReserveOutputBuffer(format.frame_size, PIXEL_FORMAT_Y16, + PIXEL_STORAGE_CPU, frame_feedback_id); // The input |length| can be greater than the required buffer size because of // paddings and/or alignments, but it cannot be smaller. DCHECK_GE(static_cast<size_t>(length), format.ImageAllocationSize()); @@ -433,8 +422,8 @@ auto buffer_access = buffer.handle_provider->GetHandleForInProcessAccess(); memcpy(buffer_access->data(), data, length); const VideoCaptureFormat output_format = - VideoCaptureFormat(format.frame_size, format.frame_rate, - media::PIXEL_FORMAT_Y16, media::PIXEL_STORAGE_CPU); + VideoCaptureFormat(format.frame_size, format.frame_rate, PIXEL_FORMAT_Y16, + PIXEL_STORAGE_CPU); OnIncomingCapturedBuffer(std::move(buffer), output_format, reference_time, timestamp); }
diff --git a/media/capture/video/video_capture_device_client.h b/media/capture/video/video_capture_device_client.h index c863a6ee..77bc796 100644 --- a/media/capture/video/video_capture_device_client.h +++ b/media/capture/video/video_capture_device_client.h
@@ -25,7 +25,7 @@ using VideoCaptureJpegDecoderFactoryCB = base::Callback<std::unique_ptr<VideoCaptureJpegDecoder>()>; -// Implementation of media::VideoCaptureDevice::Client that uses a buffer pool +// Implementation of VideoCaptureDevice::Client that uses a buffer pool // to provide buffers and converts incoming data to the I420 format for // consumption by a given VideoFrameReceiver. // @@ -36,7 +36,7 @@ // The owner is responsible for making sure that the instance outlives these // calls. class CAPTURE_EXPORT VideoCaptureDeviceClient - : public media::VideoCaptureDevice::Client { + : public VideoCaptureDevice::Client { public: VideoCaptureDeviceClient( std::unique_ptr<VideoFrameReceiver> receiver, @@ -52,14 +52,14 @@ // VideoCaptureDevice::Client implementation. void OnIncomingCapturedData(const uint8_t* data, int length, - const media::VideoCaptureFormat& frame_format, + const VideoCaptureFormat& frame_format, int rotation, base::TimeTicks reference_time, base::TimeDelta timestamp, int frame_feedback_id = 0) override; Buffer ReserveOutputBuffer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id) override; void OnIncomingCapturedBuffer(Buffer buffer, const VideoCaptureFormat& format, @@ -73,8 +73,8 @@ gfx::Rect visible_rect, const VideoFrameMetadata& additional_metadata) override; Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int new_frame_feedback_id) override; void OnError(const base::Location& from_here, const std::string& reason) override; @@ -113,7 +113,7 @@ static const int kMaxDroppedFrames = 150; #endif // DCHECK_IS_ON() - media::VideoPixelFormat last_captured_pixel_format_; + VideoPixelFormat last_captured_pixel_format_; // Thread collision warner to ensure that producer-facing API is not called // concurrently. Producers are allowed to call from multiple threads, but not
diff --git a/media/capture/video/video_capture_device_client_unittest.cc b/media/capture/video/video_capture_device_client_unittest.cc index b1287313..a53f28e 100644 --- a/media/capture/video/video_capture_device_client_unittest.cc +++ b/media/capture/video/video_capture_device_client_unittest.cc
@@ -31,7 +31,7 @@ namespace { -std::unique_ptr<media::VideoCaptureJpegDecoder> ReturnNullPtrAsJpecDecoder() { +std::unique_ptr<VideoCaptureJpegDecoder> ReturnNullPtrAsJpecDecoder() { return nullptr; } @@ -45,13 +45,12 @@ class VideoCaptureDeviceClientTest : public ::testing::Test { public: VideoCaptureDeviceClientTest() { - scoped_refptr<media::VideoCaptureBufferPoolImpl> buffer_pool( - new media::VideoCaptureBufferPoolImpl( - base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), - 1)); + scoped_refptr<VideoCaptureBufferPoolImpl> buffer_pool( + new VideoCaptureBufferPoolImpl( + base::MakeUnique<VideoCaptureBufferTrackerFactoryImpl>(), 1)); auto controller = base::MakeUnique<MockVideoFrameReceiver>(); receiver_ = controller.get(); - device_client_ = base::MakeUnique<media::VideoCaptureDeviceClient>( + device_client_ = base::MakeUnique<VideoCaptureDeviceClient>( std::move(controller), buffer_pool, base::Bind(&ReturnNullPtrAsJpecDecoder)); } @@ -59,7 +58,7 @@ protected: MockVideoFrameReceiver* receiver_; - std::unique_ptr<media::VideoCaptureDeviceClient> device_client_; + std::unique_ptr<VideoCaptureDeviceClient> device_client_; private: DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceClientTest); @@ -70,9 +69,8 @@ TEST_F(VideoCaptureDeviceClientTest, Minimal) { const size_t kScratchpadSizeInBytes = 400; unsigned char data[kScratchpadSizeInBytes] = {}; - const media::VideoCaptureFormat kFrameFormat( - gfx::Size(10, 10), 30.0f /*frame_rate*/, media::PIXEL_FORMAT_I420, - media::PIXEL_STORAGE_CPU); + const VideoCaptureFormat kFrameFormat(gfx::Size(10, 10), 30.0f /*frame_rate*/, + PIXEL_FORMAT_I420, PIXEL_STORAGE_CPU); DCHECK(device_client_.get()); { InSequence s; @@ -94,11 +92,10 @@ const size_t kScratchpadSizeInBytes = 400; unsigned char data[kScratchpadSizeInBytes] = {}; // kFrameFormat is invalid in a number of ways. - const media::VideoCaptureFormat kFrameFormat( - gfx::Size(media::limits::kMaxDimension + 1, media::limits::kMaxDimension), - media::limits::kMaxFramesPerSecond + 1, - media::VideoPixelFormat::PIXEL_FORMAT_I420, - media::VideoPixelStorage::PIXEL_STORAGE_CPU); + const VideoCaptureFormat kFrameFormat( + gfx::Size(limits::kMaxDimension + 1, limits::kMaxDimension), + limits::kMaxFramesPerSecond + 1, VideoPixelFormat::PIXEL_FORMAT_I420, + VideoPixelStorage::PIXEL_STORAGE_CPU); DCHECK(device_client_.get()); // Expect the the call to fail silently inside the VideoCaptureDeviceClient. EXPECT_CALL(*receiver_, OnLog(_)).Times(1); @@ -113,9 +110,8 @@ TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) { const size_t kScratchpadSizeInBytes = 400; unsigned char data[kScratchpadSizeInBytes] = {}; - const media::VideoCaptureFormat kFrameFormat( - gfx::Size(10, 10), 30.0f /*frame_rate*/, media::PIXEL_FORMAT_I420, - media::PIXEL_STORAGE_CPU); + const VideoCaptureFormat kFrameFormat(gfx::Size(10, 10), 30.0f /*frame_rate*/, + PIXEL_FORMAT_I420, PIXEL_STORAGE_CPU); EXPECT_CALL(*receiver_, OnLog(_)).Times(1); // Simulate that receiver still holds |buffer_read_permission| for the first // buffer when the second call to OnIncomingCapturedData comes in. @@ -124,14 +120,15 @@ std::unique_ptr<VideoCaptureDevice::Client::Buffer::ScopedAccessPermission> read_permission; EXPECT_CALL(*receiver_, MockOnFrameReadyInBuffer(_, _, _)) - .WillOnce(Invoke([&read_permission]( - int buffer_id, - std::unique_ptr<media::VideoCaptureDevice::Client:: - Buffer::ScopedAccessPermission>* - buffer_read_permission, - const gfx::Size&) { - read_permission = std::move(*buffer_read_permission); - })); + .WillOnce(Invoke( + [&read_permission]( + int buffer_id, + std::unique_ptr< + VideoCaptureDevice::Client::Buffer::ScopedAccessPermission>* + buffer_read_permission, + const gfx::Size&) { + read_permission = std::move(*buffer_read_permission); + })); // Pass two frames. The second will be dropped. device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes, kFrameFormat, 0 /*clockwise rotation*/, @@ -154,28 +151,28 @@ ASSERT_GE(kScratchpadSizeInBytes, kCaptureResolution.GetArea() * 4u) << "Scratchpad is too small to hold the largest pixel format (ARGB)."; - media::VideoCaptureParams params; - params.requested_format = media::VideoCaptureFormat( - kCaptureResolution, 30.0f, media::PIXEL_FORMAT_UNKNOWN); + VideoCaptureParams params; + params.requested_format = + VideoCaptureFormat(kCaptureResolution, 30.0f, PIXEL_FORMAT_UNKNOWN); // Only use the VideoPixelFormats that we know supported. Do not add // PIXEL_FORMAT_MJPEG since it would need a real JPEG header. - const media::VideoPixelFormat kSupportedFormats[] = { - media::PIXEL_FORMAT_I420, - media::PIXEL_FORMAT_YV12, - media::PIXEL_FORMAT_NV12, - media::PIXEL_FORMAT_NV21, - media::PIXEL_FORMAT_YUY2, - media::PIXEL_FORMAT_UYVY, + const VideoPixelFormat kSupportedFormats[] = { + PIXEL_FORMAT_I420, + PIXEL_FORMAT_YV12, + PIXEL_FORMAT_NV12, + PIXEL_FORMAT_NV21, + PIXEL_FORMAT_YUY2, + PIXEL_FORMAT_UYVY, #if defined(OS_WIN) || defined(OS_LINUX) - media::PIXEL_FORMAT_RGB24, + PIXEL_FORMAT_RGB24, #endif - media::PIXEL_FORMAT_RGB32, - media::PIXEL_FORMAT_ARGB, - media::PIXEL_FORMAT_Y16, + PIXEL_FORMAT_RGB32, + PIXEL_FORMAT_ARGB, + PIXEL_FORMAT_Y16, }; - for (media::VideoPixelFormat format : kSupportedFormats) { + for (VideoPixelFormat format : kSupportedFormats) { params.requested_format.pixel_format = format; EXPECT_CALL(*receiver_, OnLog(_)).Times(1); @@ -209,13 +206,13 @@ EXPECT_CALL(*receiver_, OnLog(_)).Times(1); - media::VideoCaptureParams params; + VideoCaptureParams params; for (const auto& size_and_rotation : kSizeAndRotations) { ASSERT_GE(kScratchpadSizeInBytes, size_and_rotation.input_resolution.GetArea() * 4u) << "Scratchpad is too small to hold the largest pixel format (ARGB)."; - params.requested_format = media::VideoCaptureFormat( - size_and_rotation.input_resolution, 30.0f, media::PIXEL_FORMAT_ARGB); + params.requested_format = VideoCaptureFormat( + size_and_rotation.input_resolution, 30.0f, PIXEL_FORMAT_ARGB); gfx::Size coded_size; EXPECT_CALL(*receiver_, MockOnFrameReadyInBuffer(_, _, _)) .Times(1)
diff --git a/media/capture/video/video_capture_device_factory.cc b/media/capture/video/video_capture_device_factory.cc index cefeb5c0..2f535ec 100644 --- a/media/capture/video/video_capture_device_factory.cc +++ b/media/capture/video/video_capture_device_factory.cc
@@ -26,14 +26,14 @@ if (command_line->HasSwitch(switches::kUseFakeDeviceForMediaStream)) { if (command_line->HasSwitch(switches::kUseFileForFakeVideoCapture)) { return std::unique_ptr<VideoCaptureDeviceFactory>( - new media::FileVideoCaptureDeviceFactory()); + new FileVideoCaptureDeviceFactory()); } else { std::vector<FakeVideoCaptureDeviceSettings> config; FakeVideoCaptureDeviceFactory::ParseFakeDevicesConfigFromOptionsString( command_line->GetSwitchValueASCII( switches::kUseFakeDeviceForMediaStream), &config); - auto result = base::MakeUnique<media::FakeVideoCaptureDeviceFactory>(); + auto result = base::MakeUnique<FakeVideoCaptureDeviceFactory>(); result->SetToCustomDevicesConfig(config); return std::move(result); }
diff --git a/media/capture/video/video_capture_device_info.cc b/media/capture/video/video_capture_device_info.cc index 50f999b..90a097fd 100644 --- a/media/capture/video/video_capture_device_info.cc +++ b/media/capture/video/video_capture_device_info.cc
@@ -9,7 +9,7 @@ VideoCaptureDeviceInfo::VideoCaptureDeviceInfo() = default; VideoCaptureDeviceInfo::VideoCaptureDeviceInfo( - media::VideoCaptureDeviceDescriptor descriptor) + VideoCaptureDeviceDescriptor descriptor) : descriptor(descriptor) {} VideoCaptureDeviceInfo::VideoCaptureDeviceInfo(
diff --git a/media/capture/video/video_capture_device_info.h b/media/capture/video/video_capture_device_info.h index 32f61c6..88445cb9 100644 --- a/media/capture/video/video_capture_device_info.h +++ b/media/capture/video/video_capture_device_info.h
@@ -10,17 +10,17 @@ namespace media { -// Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported +// Bundles a VideoCaptureDeviceDescriptor with corresponding supported // video formats. struct CAPTURE_EXPORT VideoCaptureDeviceInfo { VideoCaptureDeviceInfo(); - VideoCaptureDeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); + VideoCaptureDeviceInfo(VideoCaptureDeviceDescriptor descriptor); VideoCaptureDeviceInfo(const VideoCaptureDeviceInfo& other); ~VideoCaptureDeviceInfo(); VideoCaptureDeviceInfo& operator=(const VideoCaptureDeviceInfo& other); - media::VideoCaptureDeviceDescriptor descriptor; - media::VideoCaptureFormats supported_formats; + VideoCaptureDeviceDescriptor descriptor; + VideoCaptureFormats supported_formats; }; } // namespace media
diff --git a/media/capture/video/video_capture_device_unittest.cc b/media/capture/video/video_capture_device_unittest.cc index 5160067..c9d9cf4 100644 --- a/media/capture/video/video_capture_device_unittest.cc +++ b/media/capture/video/video_capture_device_unittest.cc
@@ -148,8 +148,8 @@ // Trampoline methods to workaround GMOCK problems with std::unique_ptr<>. Buffer ReserveOutputBuffer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id) override { DoReserveOutputBuffer(); NOTREACHED() << "This should never be called"; @@ -171,8 +171,8 @@ DoOnIncomingCapturedVideoFrame(); } Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions, - media::VideoPixelFormat format, - media::VideoPixelStorage storage, + VideoPixelFormat format, + VideoPixelStorage storage, int frame_feedback_id) { DoResurrectLastOutputBuffer(); NOTREACHED() << "This should never be called"; @@ -638,7 +638,7 @@ &MockImageCaptureClient::DoOnPhotoTaken, image_capture_client_); base::RunLoop run_loop; - base::Closure quit_closure = media::BindToCurrentLoop(run_loop.QuitClosure()); + base::Closure quit_closure = BindToCurrentLoop(run_loop.QuitClosure()); EXPECT_CALL(*image_capture_client_.get(), OnCorrectPhotoTaken()) .Times(1) .WillOnce(RunClosure(quit_closure)); @@ -688,7 +688,7 @@ image_capture_client_); base::RunLoop run_loop; - base::Closure quit_closure = media::BindToCurrentLoop(run_loop.QuitClosure()); + base::Closure quit_closure = BindToCurrentLoop(run_loop.QuitClosure()); EXPECT_CALL(*image_capture_client_.get(), OnCorrectGetPhotoState()) .Times(1) .WillOnce(RunClosure(quit_closure));
diff --git a/media/capture/video/video_capture_jpeg_decoder.h b/media/capture/video/video_capture_jpeg_decoder.h index 535349c..54a0113 100644 --- a/media/capture/video/video_capture_jpeg_decoder.h +++ b/media/capture/video/video_capture_jpeg_decoder.h
@@ -43,10 +43,10 @@ virtual void DecodeCapturedData( const uint8_t* data, size_t in_buffer_size, - const media::VideoCaptureFormat& frame_format, + const VideoCaptureFormat& frame_format, base::TimeTicks reference_time, base::TimeDelta timestamp, - media::VideoCaptureDevice::Client::Buffer out_buffer) = 0; + VideoCaptureDevice::Client::Buffer out_buffer) = 0; }; } // namespace media
diff --git a/media/capture/video/video_capture_system_impl.cc b/media/capture/video/video_capture_system_impl.cc index 84cc8a2f..7f75104 100644 --- a/media/capture/video/video_capture_system_impl.cc +++ b/media/capture/video/video_capture_system_impl.cc
@@ -104,11 +104,11 @@ const VideoCaptureDeviceInfo* VideoCaptureSystemImpl::LookupDeviceInfoFromId( const std::string& device_id) { DCHECK(thread_checker_.CalledOnValidThread()); - auto iter = std::find_if( - devices_info_cache_.begin(), devices_info_cache_.end(), - [&device_id](const media::VideoCaptureDeviceInfo& device_info) { - return device_info.descriptor.device_id == device_id; - }); + auto iter = + std::find_if(devices_info_cache_.begin(), devices_info_cache_.end(), + [&device_id](const VideoCaptureDeviceInfo& device_info) { + return device_info.descriptor.device_id == device_id; + }); if (iter == devices_info_cache_.end()) return nullptr; return &(*iter);
diff --git a/media/capture/video/win/sink_input_pin_win.cc b/media/capture/video/win/sink_input_pin_win.cc index 75b5c42e..8b8db29 100644 --- a/media/capture/video/win/sink_input_pin_win.cc +++ b/media/capture/video/win/sink_input_pin_win.cc
@@ -219,7 +219,7 @@ return S_FALSE; REFERENCE_TIME start_time, end_time; - base::TimeDelta timestamp = media::kNoTimestamp; + base::TimeDelta timestamp = kNoTimestamp; if (SUCCEEDED(sample->GetTime(&start_time, &end_time))) { DCHECK(start_time <= end_time); timestamp = base::TimeDelta::FromMicroseconds(start_time / 10);
diff --git a/media/capture/video/win/video_capture_device_win.cc b/media/capture/video/win/video_capture_device_win.cc index e1e9ac7..5afe42b 100644 --- a/media/capture/video/win/video_capture_device_win.cc +++ b/media/capture/video/win/video_capture_device_win.cc
@@ -844,7 +844,7 @@ // There is a chance that the platform does not provide us with the timestamp, // in which case, we use reference time to calculate a timestamp. - if (timestamp == media::kNoTimestamp) + if (timestamp == kNoTimestamp) timestamp = base::TimeTicks::Now() - first_ref_time_; client_->OnIncomingCapturedData(buffer, length, format, 0, @@ -871,8 +871,8 @@ void VideoCaptureDeviceWin::SetAntiFlickerInCaptureFilter( const VideoCaptureParams& params) { const PowerLineFrequency power_line_frequency = GetPowerLineFrequency(params); - if (power_line_frequency != media::PowerLineFrequency::FREQUENCY_50HZ && - power_line_frequency != media::PowerLineFrequency::FREQUENCY_60HZ) { + if (power_line_frequency != PowerLineFrequency::FREQUENCY_50HZ && + power_line_frequency != PowerLineFrequency::FREQUENCY_60HZ) { return; } ComPtr<IKsPropertySet> ks_propset; @@ -889,8 +889,7 @@ data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; data.Property.Flags = KSPROPERTY_TYPE_SET; data.Value = - (power_line_frequency == media::PowerLineFrequency::FREQUENCY_50HZ) ? 1 - : 2; + (power_line_frequency == PowerLineFrequency::FREQUENCY_50HZ) ? 1 : 2; data.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; hr = ks_propset->Set(PROPSETID_VIDCAP_VIDEOPROCAMP, KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, &data,
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc index b0ab2c9..d3c5a17 100644 --- a/services/ui/ws/window_server.cc +++ b/services/ui/ws/window_server.cc
@@ -90,9 +90,12 @@ viz::mojom::DisplayPrivateAssociatedRequest display_private_request) override { if (manager_) { + // No software compositing on ChromeOS. + bool force_software_compositing = false; manager_->CreateRootCompositorFrameSink( - frame_sink_id, surface_handle, renderer_settings, std::move(request), - std::move(client), std::move(display_private_request)); + frame_sink_id, surface_handle, force_software_compositing, + renderer_settings, std::move(request), std::move(client), + std::move(display_private_request)); } }
diff --git a/services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom b/services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom index 06f8d8a..b1bf5f69 100644 --- a/services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom +++ b/services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom
@@ -47,10 +47,13 @@ // Create a CompositorFrameSink for a privileged client (e.g. WindowServer). // This is only used by privileged clients. The client can call methods that - // talks to the Display (e.g. ResizeDisplay(), SetDisplayVisible(), etc) + // talks to the Display (e.g. ResizeDisplay(), SetDisplayVisible(), etc). + // If |force_software_compositing| is true, then the resulting display + // compositor will not use Gpu acceleration even if it would by default. CreateRootCompositorFrameSink( FrameSinkId frame_sink_id, gpu.mojom.SurfaceHandle widget, + bool force_software_compositing, RendererSettings renderer_settings, associated CompositorFrameSink& compositor_frame_sink, CompositorFrameSinkClient compositor_frame_sink_client,
diff --git a/testing/buildbot/filters/ash_unittests_mash.filter b/testing/buildbot/filters/ash_unittests_mash.filter index c20b032..181542d 100644 --- a/testing/buildbot/filters/ash_unittests_mash.filter +++ b/testing/buildbot/filters/ash_unittests_mash.filter
@@ -54,15 +54,10 @@ # TODO: Top-of-screen mouse reveal doesn't work, maybe problem with # EventGenerator. http://crbug.com/698085 -ImmersiveFullscreenControllerTest.Bubbles --ImmersiveFullscreenControllerTest.Delegate -ImmersiveFullscreenControllerTest.DifferentModalityEnterExit -ImmersiveFullscreenControllerTest.EndRevealViaGesture --ImmersiveFullscreenControllerTest.EventsDoNotLeakToWindowUnderneath -ImmersiveFullscreenControllerTest.Focus --ImmersiveFullscreenControllerTest.Inactive -ImmersiveFullscreenControllerTest.MouseEventsVerticalDisplayLayout --ImmersiveFullscreenControllerTest.MouseHoveredWithoutMoving --ImmersiveFullscreenControllerTest.OnMouseEvent -ImmersiveFullscreenControllerTest.RevealViaGestureChildConsumesEvents -ImmersiveFullscreenControllerTest.Transient
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-common.js b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-common.js index f8f3fcf..72957465 100644 --- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-common.js +++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-common.js
@@ -1,16 +1,13 @@ -/** - * Assert AudioWorklet is enabled. - * - * The content_shell driven by run-webkit-tests.py is supposed to enable all the - * experimental web platform features. - * - * We also want to run the test on the browser. So we check both cases for - * the content shell and the browser. - */ +// Check if AudioWorklet is available before running a test. function assertAudioWorklet() { + let offlineContext = new OfflineAudioContext(1, 1, 44100); + + // We want to be able to run tests both on the browser and the content shell. + // So check if AudioWorklet runtime flag is enabled, or check the context + // has AudioWorklet object. if ((Boolean(window.internals) && Boolean(window.internals.runtimeFlags.audioWorkletEnabled)) || - (Boolean(window.Worklet) && Boolean(window.audioWorklet))) { + offlineContext.audioWorklet instanceof AudioWorklet) { return; }
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-gain-node.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-gain-node.html index 12843b47..0f0ac3ed 100644 --- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-gain-node.html +++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-gain-node.html
@@ -21,8 +21,8 @@ // Sets up AudioWorklet and OfflineAudioContext. audit.define('Initializing AudioWorklet and Context', (task, should) => { - audioWorklet.addModule('gain-processor.js').then(() => { - context = new OfflineAudioContext(1, renderLength, sampleRate); + context = new OfflineAudioContext(1, renderLength, sampleRate); + context.audioWorklet.addModule('gain-processor.js').then(() => { task.done(); }); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-construction.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-construction.html index d0aae9cb..63c1e72 100644 --- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-construction.html +++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-construction.html
@@ -36,17 +36,19 @@ audit.define( {label: 'construction-after-module-loading'}, (task, should) => { - audioWorklet.addModule('dummy-processor.js').then(() => { - let dummyWorkletNode = - new AudioWorkletNode(realtimeContext, 'dummy'); - should(dummyWorkletNode instanceof AudioWorkletNode, - '"dummyWorkletNode" is an instance of AudioWorkletNode') - .beTrue(); - should(() => new AudioWorkletNode(realtimeContext, 'foobar'), - 'Unregistered name "foobar" must throw an exception.') - .throw(); - task.done(); - }); + realtimeContext.audioWorklet.addModule('dummy-processor.js') + .then(() => { + let dummyWorkletNode = + new AudioWorkletNode(realtimeContext, 'dummy'); + should(dummyWorkletNode instanceof AudioWorkletNode, + '"dummyWorkletNode" is an instance of ' + + 'AudioWorkletNode') + .beTrue(); + should(() => new AudioWorkletNode(realtimeContext, 'foobar'), + 'Unregistered name "foobar" must throw an exception.') + .throw(); + task.done(); + }); }); audit.run();
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-options.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-options.html index 0ef5cb2..6e4461d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-options.html +++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-node-options.html
@@ -21,8 +21,8 @@ // Load script file and create a OfflineAudiocontext. audit.define('setup', (task, should) => { - audioWorklet.addModule('dummy-processor.js').then(() => { - context = new OfflineAudioContext(1, 1, sampleRate); + context = new OfflineAudioContext(1, 1, sampleRate); + context.audioWorklet.addModule('dummy-processor.js').then(() => { task.done(); }); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-processor-state.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-processor-state.html index 09f79c1..c1c51740 100644 --- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-processor-state.html +++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/audio-worklet-processor-state.html
@@ -23,59 +23,63 @@ audit.define('pending-running-stopped', (task, should) => { let context = new OfflineAudioContext(1, renderLength, sampleRate); - let timedWorkletNode = new AudioWorkletNode(context, 'timed'); + context.audioWorklet.addModule('state-processor.js').then(() => { + let timedWorkletNode = new AudioWorkletNode(context, 'timed'); - // The construction of associated processor has not been - // completed. In this state, no audio processing can happen and - // all messages to the processor will be queued. - should(timedWorkletNode.processorState, - 'Checking the processor state upon the constructor call') - .beEqualTo('pending'); + // The construction of associated processor has not been + // completed. In this state, no audio processing can happen and + // all messages to the processor will be queued. + should(timedWorkletNode.processorState, + 'Checking the processor state upon the constructor call') + .beEqualTo('pending'); - timedWorkletNode.connect(context.destination); + timedWorkletNode.connect(context.destination); - // Checks the handler of |onprocessorstatechange|. Because the - // processor script is correct, the |running| state change MUST - // be fired. - let isFirstPhase = true; - timedWorkletNode.onprocessorstatechange = () => { - // The first phase should be "running". - if (isFirstPhase) { - should(timedWorkletNode.processorState, - 'Checking the processor state upon ' + - 'processorstatechange event') - .beEqualTo('running'); - isFirstPhase = false; - } else { - // The second phase in this test must be "stopped". - should(timedWorkletNode.processorState, - 'Checking the processor state after ' + - 'processor stopped processing') - .beEqualTo('stopped'); - task.done(); - } - }; + // Checks the handler of |onprocessorstatechange|. Because the + // processor script is correct, the |running| state change MUST + // be fired. + let isFirstPhase = true; + timedWorkletNode.onprocessorstatechange = () => { + // The first phase should be "running". + if (isFirstPhase) { + should(timedWorkletNode.processorState, + 'Checking the processor state upon ' + + 'processorstatechange event') + .beEqualTo('running'); + isFirstPhase = false; + } else { + // The second phase in this test must be "stopped". + should(timedWorkletNode.processorState, + 'Checking the processor state after ' + + 'processor stopped processing') + .beEqualTo('stopped'); + task.done(); + } + }; - context.startRendering(); + context.startRendering(); + }); }); // Test the error state caused by the failure of processor constructor. audit.define('constructor-error', (task, should) => { let context = new OfflineAudioContext(1, renderLength, sampleRate); - let constructorErrorWorkletNode = - new AudioWorkletNode(context, 'constructor-error'); - should(constructorErrorWorkletNode.processorState, - 'constructorErrorWorkletNode.processorState after ' + - 'its construction') - .beEqualTo('pending'); - constructorErrorWorkletNode.onprocessorstatechange = () => { + context.audioWorklet.addModule('state-processor.js').then(() => { + let constructorErrorWorkletNode = + new AudioWorkletNode(context, 'constructor-error'); should(constructorErrorWorkletNode.processorState, - 'workletNode.processorState upon processorstatechange ' + - 'event after the failure from processor.constructor()') - .beEqualTo('error'); - task.done(); - }; + 'constructorErrorWorkletNode.processorState after ' + + 'its construction') + .beEqualTo('pending'); + constructorErrorWorkletNode.onprocessorstatechange = () => { + should(constructorErrorWorkletNode.processorState, + 'workletNode.processorState upon processorstatechange ' + + 'event after the failure from processor.constructor()') + .beEqualTo('error'); + task.done(); + }; + }); }); // Test the error state caused by the failure of processor's process() @@ -83,35 +87,35 @@ audit.define('process-error', (task, should) => { let context = new OfflineAudioContext(1, renderLength, sampleRate); - let processErrorWorkletNode = - new AudioWorkletNode(context, 'process-error'); - should(processErrorWorkletNode.processorState, - 'processErrorWorkletNode.processorState after ' + - 'its construction') - .beEqualTo('pending'); + context.audioWorklet.addModule('state-processor.js').then(() => { + let processErrorWorkletNode = + new AudioWorkletNode(context, 'process-error'); + should(processErrorWorkletNode.processorState, + 'processErrorWorkletNode.processorState after ' + + 'its construction') + .beEqualTo('pending'); - processErrorWorkletNode.connect(context.destination); + processErrorWorkletNode.connect(context.destination); - let isFirstPhase = true; - processErrorWorkletNode.onprocessorstatechange = () => { - if (isFirstPhase) { - // Ignore the first state change event, which is "running"; - isFirstPhase = false; - } else { - should(processErrorWorkletNode.processorState, - 'workletNode.processorState upon processorstatechange ' + - 'event after the failure from processor.process()') - .beEqualTo('error'); - task.done(); - } - }; + let isFirstPhase = true; + processErrorWorkletNode.onprocessorstatechange = () => { + if (isFirstPhase) { + // Ignore the first state change event, which is "running"; + isFirstPhase = false; + } else { + should(processErrorWorkletNode.processorState, + 'workletNode.processorState upon processorstatechange ' + + 'event after the failure from processor.process()') + .beEqualTo('error'); + task.done(); + } + }; - context.startRendering(); + context.startRendering(); + }); }); - audioWorklet.addModule('state-processor.js').then(() => { - audit.run(); - }); + audit.run(); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/context-audio-worklet.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/context-audio-worklet.html new file mode 100644 index 0000000..adadbdbc --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/context-audio-worklet.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> + <head> + <title> + Checking BaseAudioContext.audioWorklet + </title> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> + <script src="../../../webaudio-resources/audit.js"></script> + <script src="audio-worklet-common.js"></script> + </head> + <body> + <script id="layout-test-code"> + // TODO(hongchan): remove this assertion when AudioWorklet shipped. + assertAudioWorklet(); + + let audit = Audit.createTaskRunner(); + + let realtimeContext = new AudioContext(); + let offlineContext = new OfflineAudioContext(1, 1, 44100); + + // Test if AudioWorklet exists. + audit.define('Test if AudioWorklet exists', (task, should) => { + should(realtimeContext.audioWorklet instanceof AudioWorklet && + offlineContext.audioWorklet instanceof AudioWorklet, + 'BaseAudioContext.audioWorklet is an instance of AudioWorklet') + .beTrue(); + task.done(); + }); + + audit.run(); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/dynamic-channel-count.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/dynamic-channel-count.html index 64f95669..e196dfa 100644 --- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/dynamic-channel-count.html +++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/dynamic-channel-count.html
@@ -36,7 +36,7 @@ context.channeCountMode = 'explicit'; context.channelInterpretation = 'discrete'; - audioWorklet.addModule('gain-processor.js').then(() => { + context.audioWorklet.addModule('gain-processor.js').then(() => { let testBuffer = createConstantBuffer(context, 1, testChannelValues); let sourceNode = new AudioBufferSourceNode(context); let gainWorkletNode = new AudioWorkletNode(context, 'gain');
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/message-port.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/message-port.html index 7d55dc82..aef39cc 100644 --- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/message-port.html +++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/message-port.html
@@ -60,7 +60,7 @@ porterWorkletNode.port.postMessage('hello'); }); - audioWorklet.addModule('port-processor.js').then(() => { + context.audioWorklet.addModule('port-processor.js').then(() => { audit.run(); }); </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/window-audio-worklet.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/window-audio-worklet.html deleted file mode 100644 index 5e390ed..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/window-audio-worklet.html +++ /dev/null
@@ -1,46 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title> - Checking window.audioWorklet - </title> - <script src="../../resources/testharness.js"></script> - <script src="../../resources/testharnessreport.js"></script> - <script src="../../../webaudio-resources/audit.js"></script> - <script src="audio-worklet-common.js"></script> - </head> - <body> - <script id="layout-test-code"> - // TODO(hongchan): remove this assertion when AudioWorklet shipped. - assertAudioWorklet(); - - let audit = Audit.createTaskRunner(); - - // Test if AudioWorklet exists. - audit.define('Test if AudioWorklet exists', (task, should) => { - should(window.audioWorklet instanceof Worklet, - 'window.audioWorklet is an instance of Worklet') - .beTrue(); - task.done(); - }); - - // Test the construction of BaseAudioContext before |worklet.addModule()|. - audit.define( - 'Test invocation of addModule() after BaseAudioContext construction', - (task, should) => { - should( - () => { - let context = new AudioContext(); - audioWorklet.addModule('bypass-processor.js'); - }, - 'Calling audioWorklet.addModule() before construction of ' + - 'BaseAudioContext') - .notThrow(); - - task.done(); - }); - - audit.run(); - </script> - </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/worklet-context-interaction.html b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/worklet-context-interaction.html index a2dc5da..75428e6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/worklet-context-interaction.html +++ b/third_party/WebKit/LayoutTests/http/tests/webaudio/audio-worklet/worklet-context-interaction.html
@@ -50,9 +50,12 @@ task.done(); }); - audioWorklet.addModule('dummy-processor.js').then(() => { - audit.run(); - }); + Promise.all([ + realtimeContext.audioWorklet.addModule('dummy-processor.js'), + offlineContext.audioWorklet.addModule('dummy-processor.js') + ]).then(() => { + audit.run(); + }); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/import-on-insecure-context.html b/third_party/WebKit/LayoutTests/http/tests/worklet/import-on-insecure-context.html index 12ac80c..1832af6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/worklet/import-on-insecure-context.html +++ b/third_party/WebKit/LayoutTests/http/tests/worklet/import-on-insecure-context.html
@@ -7,14 +7,18 @@ <script src="/resources/get-host-info.js"></script> <script> -// This test should not be upstreamed to WPT because Worklets are now restrected +// This test should not be upstreamed to WPT because Worklets are now restricted // to secure contexts by Chrome's policy. +const realTimeContext = new AudioContext(); +const offlineContext = new OfflineAudioContext(1, 1, 44100); + if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) { test(t => { assert_not_equals(undefined, CSS.paintWorklet); assert_not_equals(undefined, window.animationWorklet); - assert_not_equals(undefined, window.audioWorklet); + assert_not_equals(undefined, realTimeContext.audioWorklet); + assert_not_equals(undefined, offlineContext.audioWorklet); }, 'Worklets should be available on a secure context.'); window.location = get_host_info().UNAUTHENTICATED_ORIGIN + window.location.pathname; @@ -22,7 +26,8 @@ test(t => { assert_equals(undefined, CSS.paintWorklet); assert_equals(undefined, window.animationWorklet); - assert_equals(undefined, window.audioWorklet); + assert_equals(undefined, realTimeContext.audioWorklet); + assert_equals(undefined, offlineContext.audioWorklet); }, 'Worklets should not be available on an insecure context.'); }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png index 5953f52..555795d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-expected.png index 3202c248..a3f242f7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png index e548b7d..bcd3bd55 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/webaudio/AudioParam/worklet-warnings.html b/third_party/WebKit/LayoutTests/webaudio/AudioParam/worklet-warnings.html index 8778a1c..f8f1d60 100644 --- a/third_party/WebKit/LayoutTests/webaudio/AudioParam/worklet-warnings.html +++ b/third_party/WebKit/LayoutTests/webaudio/AudioParam/worklet-warnings.html
@@ -20,36 +20,37 @@ description: 'Generate warnings if outside nominal range' }, (task, should) => { - window.audioWorklet.addModule(NoiseGenWorkletUrl).then(() => { - // Any reasonable sample rate will work - let sampleRate = 16000; - let renderTime = 1; - let renderLength = renderTime * sampleRate; - let context = - new OfflineAudioContext(1, renderLength, sampleRate); - let noiseGenerator = - new AudioWorkletNode(context, 'noise-generator'); - noiseGenerator.connect(context.destination); - let param = noiseGenerator.parameters.get('amplitude'); - // Set the value inside the nominal range; no warning should be - // generated. - param.value = .1; - // Set the value outside the nominal range to generate a - // warning. - param.value = 99; + // Any reasonable sample rate will work + let sampleRate = 16000; + let renderTime = 1; + let renderLength = renderTime * sampleRate; + let context = + new OfflineAudioContext(1, renderLength, sampleRate); + context.audioWorklet.addModule(NoiseGenWorkletUrl).then(() => { + let noiseGenerator = + new AudioWorkletNode(context, 'noise-generator'); + noiseGenerator.connect(context.destination); + let param = noiseGenerator.parameters.get('amplitude'); + // Set the value inside the nominal range; no warning should be + // generated. + param.value = .1; + // Set the value outside the nominal range to generate a + // warning. + param.value = 99; - // Set up automation outside the nominal range to generate a - // warning. - param.setValueAtTime(-1, renderTime / 4); - param.linearRampToValueAtTime(5, renderTime); + // Set up automation outside the nominal range to generate a + // warning. + param.setValueAtTime(-1, renderTime / 4); + param.linearRampToValueAtTime(5, renderTime); - // Render; we don't care what the generated result is. - context.startRendering() - .then(() => { - should(true, 'Rendering succeeded').beTrue(); - }) - .then(() => task.done()); - })}); + // Render; we don't care what the generated result is. + context.startRendering() + .then(() => { + should(true, 'Rendering succeeded').beTrue(); + }) + .then(() => task.done()); + }); + }); audit.run(); </script>
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/context-properties.js b/third_party/WebKit/LayoutTests/webaudio/resources/context-properties.js index 931a19dd..4961bec9 100644 --- a/third_party/WebKit/LayoutTests/webaudio/resources/context-properties.js +++ b/third_party/WebKit/LayoutTests/webaudio/resources/context-properties.js
@@ -7,6 +7,7 @@ let BaseAudioContextOwnProperties = [ + 'audioWorklet', 'constructor', 'createAnalyser', 'createBiquadFilter',
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index afe8278..a2b83059 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -402,6 +402,9 @@ setter onaddtrack setter onchange setter onremovetrack +interface AudioWorklet : Worklet + attribute @@toStringTag + method constructor interface AudioWorkletNode : AudioNode attribute @@toStringTag method constructor @@ -451,6 +454,7 @@ method detect interface BaseAudioContext : EventTarget attribute @@toStringTag + getter audioWorklet getter currentTime getter destination getter listener @@ -9154,7 +9158,6 @@ attribute window getter animationWorklet getter applicationCache - getter audioWorklet getter caches getter clientInformation getter cookieStore
diff --git a/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMap.cpp b/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMap.cpp index 3a55305..272d87b 100644 --- a/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMap.cpp +++ b/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMap.cpp
@@ -7,10 +7,9 @@ namespace blink { FilteredComputedStylePropertyMap::FilteredComputedStylePropertyMap( - CSSComputedStyleDeclaration* computed_style_declaration, + Node* node, const Vector<CSSPropertyID>& native_properties, - const Vector<AtomicString>& custom_properties, - Node* node) + const Vector<AtomicString>& custom_properties) : ComputedStylePropertyMap(node) { for (const auto& native_property : native_properties) { native_properties_.insert(native_property);
diff --git a/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMap.h b/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMap.h index 78ad45d..79cb4a70d 100644 --- a/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMap.h +++ b/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMap.h
@@ -16,22 +16,20 @@ : public ComputedStylePropertyMap { public: static FilteredComputedStylePropertyMap* Create( - CSSComputedStyleDeclaration* computed_style_declaration, + Node* node, const Vector<CSSPropertyID>& native_properties, - const Vector<AtomicString>& custom_properties, - Node* node) { - return new FilteredComputedStylePropertyMap( - computed_style_declaration, native_properties, custom_properties, node); + const Vector<AtomicString>& custom_properties) { + return new FilteredComputedStylePropertyMap(node, native_properties, + custom_properties); } Vector<String> getProperties() override; private: FilteredComputedStylePropertyMap( - CSSComputedStyleDeclaration*, + Node*, const Vector<CSSPropertyID>& native_properties, - const Vector<AtomicString>& custom_properties, - Node*); + const Vector<AtomicString>& custom_properties); const CSSValue* GetProperty(CSSPropertyID) override; const CSSValue* GetCustomProperty(AtomicString) override;
diff --git a/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMapTest.cpp b/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMapTest.cpp index 2125df0..77c1273 100644 --- a/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMapTest.cpp +++ b/third_party/WebKit/Source/core/css/cssom/FilteredComputedStylePropertyMapTest.cpp
@@ -38,20 +38,20 @@ Vector<AtomicString> empty_custom_properties; FilteredComputedStylePropertyMap* map = - FilteredComputedStylePropertyMap::Create(Declaration(), native_properties, - custom_properties, PageNode()); + FilteredComputedStylePropertyMap::Create(PageNode(), native_properties, + custom_properties); EXPECT_TRUE(map->getProperties().Contains("color")); EXPECT_TRUE(map->getProperties().Contains("align-items")); EXPECT_TRUE(map->getProperties().Contains("--foo")); EXPECT_TRUE(map->getProperties().Contains("--bar")); - map = FilteredComputedStylePropertyMap::Create( - Declaration(), native_properties, empty_custom_properties, PageNode()); + map = FilteredComputedStylePropertyMap::Create(PageNode(), native_properties, + empty_custom_properties); EXPECT_TRUE(map->getProperties().Contains("color")); EXPECT_TRUE(map->getProperties().Contains("align-items")); map = FilteredComputedStylePropertyMap::Create( - Declaration(), empty_native_properties, custom_properties, PageNode()); + PageNode(), empty_native_properties, custom_properties); EXPECT_TRUE(map->getProperties().Contains("--foo")); EXPECT_TRUE(map->getProperties().Contains("--bar")); } @@ -61,9 +61,8 @@ {CSSPropertyColor, CSSPropertyAlignItems}); Vector<AtomicString> empty_custom_properties; FilteredComputedStylePropertyMap* map = - FilteredComputedStylePropertyMap::Create(Declaration(), native_properties, - empty_custom_properties, - PageNode()); + FilteredComputedStylePropertyMap::Create(PageNode(), native_properties, + empty_custom_properties); DummyExceptionStateForTesting exception_state; @@ -93,9 +92,8 @@ Vector<CSSPropertyID> empty_native_properties; Vector<AtomicString> custom_properties({"--foo", "--bar"}); FilteredComputedStylePropertyMap* map = - FilteredComputedStylePropertyMap::Create(Declaration(), - empty_native_properties, - custom_properties, PageNode()); + FilteredComputedStylePropertyMap::Create( + PageNode(), empty_native_properties, custom_properties); DummyExceptionStateForTesting exception_state;
diff --git a/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.cpp b/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.cpp index 16adf4a..0512893 100644 --- a/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.cpp +++ b/third_party/WebKit/Source/modules/csspaint/CSSPaintDefinition.cpp
@@ -105,10 +105,9 @@ context_settings_, zoom); PaintSize* paint_size = PaintSize::Create(specified_size); StylePropertyMapReadonly* style_map = - FilteredComputedStylePropertyMap::Create( - CSSComputedStyleDeclaration::Create(layout_object.GetNode()), - native_invalidation_properties_, custom_invalidation_properties_, - layout_object.GetNode()); + FilteredComputedStylePropertyMap::Create(layout_object.GetNode(), + native_invalidation_properties_, + custom_invalidation_properties_); v8::Local<v8::Value> argv[] = { ToV8(rendering_context, script_state_->GetContext()->Global(), isolate),
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni index bfa3a065..ad0eeac 100644 --- a/third_party/WebKit/Source/modules/modules_idl_files.gni +++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -329,6 +329,7 @@ "webaudio/AudioParamMap.idl", "webaudio/AudioProcessingEvent.idl", "webaudio/AudioScheduledSourceNode.idl", + "webaudio/AudioWorklet.idl", "webaudio/AudioWorkletGlobalScope.idl", "webaudio/AudioWorkletProcessor.idl", "webaudio/AudioWorkletNode.idl", @@ -722,7 +723,6 @@ "vibration/NavigatorVibration.idl", "vr/NavigatorVR.idl", "wake_lock/ScreenWakeLock.idl", - "webaudio/WindowAudioWorklet.idl", "webdatabase/WindowWebDatabase.idl", "webgl/WebGL2RenderingContextBase.idl", "webgl/WebGLRenderingContextBase.idl",
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorklet.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.cpp index f2e4490..2760b3b 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorklet.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.cpp
@@ -6,77 +6,90 @@ #include "bindings/core/v8/V8BindingForCore.h" #include "core/dom/Document.h" +#include "core/frame/LocalDOMWindow.h" #include "core/frame/LocalFrame.h" #include "core/workers/WorkerClients.h" #include "modules/webaudio/AudioWorkletMessagingProxy.h" #include "modules/webaudio/BaseAudioContext.h" +#include "modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h" namespace blink { -AudioWorklet* AudioWorklet::Create(LocalFrame* frame) { - return new AudioWorklet(frame); +AudioWorklet* AudioWorklet::Create(BaseAudioContext* context) { + return RuntimeEnabledFeatures::AudioWorkletEnabled() + ? new AudioWorklet(context) + : nullptr; } -AudioWorklet::AudioWorklet(LocalFrame* frame) : Worklet(frame) {} +AudioWorklet::AudioWorklet(BaseAudioContext* context) + : Worklet(context->GetExecutionContext()->ExecutingWindow()->GetFrame()), + context_(context) {} -AudioWorklet::~AudioWorklet() { - contexts_.clear(); +void AudioWorklet::CreateProcessor(AudioWorkletHandler* handler, + MessagePortChannel message_port_channel) { + DCHECK(IsMainThread()); + DCHECK(GetMessagingProxy()); + GetMessagingProxy()->CreateProcessor(handler, + std::move(message_port_channel)); } -void AudioWorklet::RegisterContext(BaseAudioContext* context) { - DCHECK(!contexts_.Contains(context)); - contexts_.insert(context); +void AudioWorklet::NotifyGlobalScopeIsUpdated() { + DCHECK(IsMainThread()); - // Check if AudioWorklet loads the script and has an active - // AudioWorkletGlobalScope before getting the messaging proxy. - if (IsWorkletMessagingProxyCreated()) - context->SetWorkletMessagingProxy(FindAvailableMessagingProxy()); + if (!worklet_started_) { + context_->NotifyWorkletIsReady(); + worklet_started_ = true; + } } -void AudioWorklet::UnregisterContext(BaseAudioContext* context) { - // This may be called multiple times from BaseAudioContext. - if (!contexts_.Contains(context)) - return; - - contexts_.erase(context); +WebThread* AudioWorklet::GetBackingThread() { + DCHECK(IsMainThread()); + DCHECK(GetMessagingProxy()); + return GetMessagingProxy()->GetWorkletBackingThread(); } -AudioWorkletMessagingProxy* AudioWorklet::FindAvailableMessagingProxy() { - return static_cast<AudioWorkletMessagingProxy*>(FindAvailableGlobalScope()); +const Vector<CrossThreadAudioParamInfo> + AudioWorklet::GetParamInfoListForProcessor( + const String& name) { + DCHECK(IsMainThread()); + DCHECK(GetMessagingProxy()); + return GetMessagingProxy()->GetParamInfoListForProcessor(name); } -bool AudioWorklet::IsWorkletMessagingProxyCreated() const { - return GetNumberOfGlobalScopes() > 0; +bool AudioWorklet::IsProcessorRegistered(const String& name) { + DCHECK(IsMainThread()); + DCHECK(GetMessagingProxy()); + return GetMessagingProxy()->IsProcessorRegistered(name); +} + +bool AudioWorklet::IsReady() { + DCHECK(IsMainThread()); + return GetMessagingProxy() && GetBackingThread(); } bool AudioWorklet::NeedsToCreateGlobalScope() { - // TODO(hongchan): support multiple WorkletGlobalScopes, one scope per a - // BaseAudioContext. In order to do it, FindAvailableGlobalScope() needs to - // be inherited and rewritten. return GetNumberOfGlobalScopes() == 0; } WorkletGlobalScopeProxy* AudioWorklet::CreateGlobalScope() { DCHECK(NeedsToCreateGlobalScope()); - WorkerClients* worker_clients = WorkerClients::Create(); AudioWorkletMessagingProxy* proxy = - new AudioWorkletMessagingProxy(GetExecutionContext(), worker_clients); + new AudioWorkletMessagingProxy(GetExecutionContext(), + WorkerClients::Create(), + this); proxy->Initialize(); - - for (BaseAudioContext* context : contexts_) { - // TODO(hongchan): Currently all BaseAudioContexts shares a single - // AudioWorkletMessagingProxy. Fix this to support one messaging proxy for - // each BaseAudioContext. - if (!context->HasWorkletMessagingProxy()) - context->SetWorkletMessagingProxy(proxy); - } - return proxy; } +AudioWorkletMessagingProxy* AudioWorklet::GetMessagingProxy() { + return NeedsToCreateGlobalScope() + ? nullptr + : static_cast<AudioWorkletMessagingProxy*>(FindAvailableGlobalScope()); +} + void AudioWorklet::Trace(blink::Visitor* visitor) { - visitor->Trace(contexts_); + visitor->Trace(context_); Worklet::Trace(visitor); }
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorklet.h b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.h index 3cde775..27c1ce4 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorklet.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.h
@@ -11,36 +11,59 @@ namespace blink { +class AudioWorkletHandler; class AudioWorkletMessagingProxy; class BaseAudioContext; -class LocalFrame; +class CrossThreadAudioParamInfo; +class MessagePortChannel; class MODULES_EXPORT AudioWorklet final : public Worklet { + DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(AudioWorklet); WTF_MAKE_NONCOPYABLE(AudioWorklet); public: - static AudioWorklet* Create(LocalFrame*); - ~AudioWorklet() override; + // When the AudioWorklet runtime flag is not enabled, this constructor returns + // |nullptr|. + static AudioWorklet* Create(BaseAudioContext*); - void RegisterContext(BaseAudioContext*); - void UnregisterContext(BaseAudioContext*); + ~AudioWorklet() = default; - AudioWorkletMessagingProxy* FindAvailableMessagingProxy(); + void CreateProcessor(AudioWorkletHandler*, MessagePortChannel); - virtual void Trace(blink::Visitor*); + // Invoked by AudioWorkletMessagingProxy. Notifies |context_| when + // AudioWorkletGlobalScope finishes the first script evaluation and is ready + // for the worklet operation. Can be used for other post-evaluation tasks + // in AudioWorklet or BaseAudioContext. + void NotifyGlobalScopeIsUpdated(); + + WebThread* GetBackingThread(); + + const Vector<CrossThreadAudioParamInfo> GetParamInfoListForProcessor( + const String& name); + + bool IsProcessorRegistered(const String& name); + + // Returns |true| when a AudioWorkletMessagingProxy and a WorkletBackingThread + // are ready. + bool IsReady(); + + void Trace(blink::Visitor*) override; private: - explicit AudioWorklet(LocalFrame*); + explicit AudioWorklet(BaseAudioContext*); - // Implements Worklet. + // Implements Worklet bool NeedsToCreateGlobalScope() final; WorkletGlobalScopeProxy* CreateGlobalScope() final; - bool IsWorkletMessagingProxyCreated() const; + // Returns |nullptr| if there is no active WorkletGlobalScope(). + AudioWorkletMessagingProxy* GetMessagingProxy(); - // AudioWorklet keeps the reference of all active BaseAudioContexts, so it - // can notify the contexts when a script is loaded in AudioWorkletGlobalScope. - HeapHashSet<Member<BaseAudioContext>> contexts_; + // To catch the first global scope update and notify the context. + bool worklet_started_ = false; + + Member<BaseAudioContext> context_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/WindowAudioWorklet.idl b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.idl similarity index 71% rename from third_party/WebKit/Source/modules/webaudio/WindowAudioWorklet.idl rename to third_party/WebKit/Source/modules/webaudio/AudioWorklet.idl index da5d51c..2b42eba8 100644 --- a/third_party/WebKit/Source/modules/webaudio/WindowAudioWorklet.idl +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorklet.idl
@@ -5,9 +5,7 @@ // https://webaudio.github.io/web-audio-api/#AudioWorklet [ - ImplementedAs=WindowAudioWorklet, RuntimeEnabled=AudioWorklet, SecureContext -] partial interface Window { - readonly attribute Worklet audioWorklet; +] interface AudioWorklet : Worklet { };
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp index e11192a..e1e85d8 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.cpp
@@ -5,6 +5,7 @@ #include "modules/webaudio/AudioWorkletMessagingProxy.h" #include "core/dom/MessagePort.h" +#include "modules/webaudio/AudioWorklet.h" #include "modules/webaudio/AudioWorkletGlobalScope.h" #include "modules/webaudio/AudioWorkletNode.h" #include "modules/webaudio/AudioWorkletObjectProxy.h" @@ -17,10 +18,10 @@ AudioWorkletMessagingProxy::AudioWorkletMessagingProxy( ExecutionContext* execution_context, - WorkerClients* worker_clients) - : ThreadedWorkletMessagingProxy(execution_context, worker_clients) {} - -AudioWorkletMessagingProxy::~AudioWorkletMessagingProxy() {} + WorkerClients* worker_clients, + AudioWorklet* worklet) + : ThreadedWorkletMessagingProxy(execution_context, worker_clients), + worklet_(worklet) {} void AudioWorkletMessagingProxy::CreateProcessor( AudioWorkletHandler* handler, @@ -61,6 +62,10 @@ processor_info_map_.insert(processor_info.Name(), processor_info.ParamInfoList()); } + + // Notify AudioWorklet object that the global scope has been updated after the + // script evaluation. + worklet_->NotifyGlobalScopeIsUpdated(); } bool AudioWorkletMessagingProxy::IsProcessorRegistered( @@ -94,4 +99,10 @@ WorkletObjectProxy()); } +void AudioWorkletMessagingProxy::Trace(Visitor* visitor) { + visitor->Trace(worklet_); + ThreadedWorkletMessagingProxy::Trace(visitor); +} + + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h index 3cc504a..f7eb17a 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletMessagingProxy.h
@@ -10,6 +10,7 @@ namespace blink { +class AudioWorklet; class AudioWorkletHandler; class CrossThreadAudioParamInfo; class CrossThreadAudioWorkletProcessorInfo; @@ -23,7 +24,7 @@ // scope via AudioWorkletObjectProxy. class AudioWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy { public: - AudioWorkletMessagingProxy(ExecutionContext*, WorkerClients*); + AudioWorkletMessagingProxy(ExecutionContext*, WorkerClients*, AudioWorklet*); // Since the creation of AudioWorkletProcessor needs to be done in the // different thread, this method is a wrapper for cross-thread task posting. @@ -54,9 +55,9 @@ WebThread* GetWorkletBackingThread(); - private: - ~AudioWorkletMessagingProxy() override; + void Trace(Visitor*); + private: // Implements ThreadedWorkletMessagingProxy. std::unique_ptr<ThreadedWorkletObjectProxy> CreateObjectProxy( ThreadedWorkletMessagingProxy*, @@ -66,6 +67,8 @@ // Each entry consists of processor name and associated AudioParam list. HashMap<String, Vector<CrossThreadAudioParamInfo>> processor_info_map_; + + Member<AudioWorklet> worklet_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioWorkletNode.cpp b/third_party/WebKit/Source/modules/webaudio/AudioWorkletNode.cpp index 09f4e37..9ac2c0ff 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioWorkletNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioWorkletNode.cpp
@@ -11,8 +11,7 @@ #include "modules/webaudio/AudioNodeInput.h" #include "modules/webaudio/AudioNodeOutput.h" #include "modules/webaudio/AudioParamDescriptor.h" -#include "modules/webaudio/AudioWorkletGlobalScope.h" -#include "modules/webaudio/AudioWorkletMessagingProxy.h" +#include "modules/webaudio/AudioWorklet.h" #include "modules/webaudio/AudioWorkletProcessor.h" #include "modules/webaudio/AudioWorkletProcessorDefinition.h" #include "modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h" @@ -277,7 +276,7 @@ } } - if (!context->HasWorkletMessagingProxy()) { + if (!context->audioWorklet()->IsReady()) { exception_state.ThrowDOMException( kInvalidStateError, "AudioWorkletNode cannot be created: AudioWorklet does not have a " @@ -286,9 +285,7 @@ return nullptr; } - AudioWorkletMessagingProxy* proxy = context->WorkletMessagingProxy(); - - if (!proxy->IsProcessorRegistered(name)) { + if (!context->audioWorklet()->IsProcessorRegistered(name)) { exception_state.ThrowDOMException( kInvalidStateError, "AudioWorkletNode cannot be created: The node name '" + name + @@ -302,8 +299,8 @@ AudioWorkletNode* node = new AudioWorkletNode(*context, name, options, - proxy->GetParamInfoListForProcessor(name), - channel->port1()); + context->audioWorklet()->GetParamInfoListForProcessor(name), + channel->port1()); if (!node) { exception_state.ThrowDOMException( @@ -319,8 +316,8 @@ // This is non-blocking async call. |node| still can be returned to user // before the scheduled async task is completed. - proxy->CreateProcessor(&node->GetWorkletHandler(), - std::move(processor_port_channel)); + context->audioWorklet()->CreateProcessor(&node->GetWorkletHandler(), + std::move(processor_port_channel)); return node; }
diff --git a/third_party/WebKit/Source/modules/webaudio/BUILD.gn b/third_party/WebKit/Source/modules/webaudio/BUILD.gn index e4824fd..ee8d3e8 100644 --- a/third_party/WebKit/Source/modules/webaudio/BUILD.gn +++ b/third_party/WebKit/Source/modules/webaudio/BUILD.gn
@@ -125,19 +125,9 @@ "WaveShaperNode.h", "WaveShaperProcessor.cpp", "WaveShaperProcessor.h", - "WindowAudioWorklet.cpp", - "WindowAudioWorklet.h", ] if (is_win) { - jumbo_excluded_sources = [ - # Uses Supplement<LocalDOMWindow> with MODULES_EXPORT while - # other files use Supplement<LocalDOMWindow> with - # CORE_EXPORT. Mixing those in the same compilation unit - # triggers link errors in Windows. https://crbug.com/739340 - "WindowAudioWorklet.cpp", - ] - # Result of 32-bit shift implicitly converted to 64 bits. cflags = [ "/wd4334" ] }
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp index 721247f..a2621ef4 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp
@@ -71,7 +71,6 @@ #include "modules/webaudio/ScriptProcessorNode.h" #include "modules/webaudio/StereoPannerNode.h" #include "modules/webaudio/WaveShaperNode.h" -#include "modules/webaudio/WindowAudioWorklet.h" #include "platform/CrossThreadFunctional.h" #include "platform/Histogram.h" #include "platform/audio/IIRFilter.h" @@ -137,9 +136,6 @@ BaseAudioContext::~BaseAudioContext() { GetDeferredTaskHandler().ContextWillBeDestroyed(); - // AudioNodes keep a reference to their context, so there should be no way to - // be in the destructor if there are still AudioNodes around. - DCHECK(!IsDestinationInitialized()); DCHECK(!active_source_nodes_.size()); DCHECK(!is_resolving_resume_promises_); DCHECK(!resume_resolvers_.size()); @@ -152,21 +148,16 @@ FFTFrame::Initialize(); + if (RuntimeEnabledFeatures::AudioWorkletEnabled()) { + audio_worklet_ = AudioWorklet::Create(this); + } + if (destination_node_) { destination_node_->Handler().Initialize(); // The AudioParams in the listener need access to the destination node, so // only create the listener if the destination node exists. listener_ = AudioListener::Create(*this); } - - // Check if a document or a frame supports AudioWorklet. If not, AudioWorklet - // cannot be accessed. - if (RuntimeEnabledFeatures::AudioWorkletEnabled()) { - AudioWorklet* audioWorklet = WindowAudioWorklet::audioWorklet( - *GetExecutionContext()->ExecutingWindow()); - if (audioWorklet) - audioWorklet->RegisterContext(this); - } } void BaseAudioContext::Clear() { @@ -180,17 +171,6 @@ void BaseAudioContext::Uninitialize() { DCHECK(IsMainThread()); - // AudioWorklet may be destroyed before the context goes away. So we have to - // check the pointer. See: crbug.com/503845 - if (RuntimeEnabledFeatures::AudioWorkletEnabled()) { - AudioWorklet* audioWorklet = WindowAudioWorklet::audioWorklet( - *GetExecutionContext()->ExecutingWindow()); - if (audioWorklet) { - audioWorklet->UnregisterContext(this); - worklet_messaging_proxy_.Clear(); - } - } - if (!IsDestinationInitialized()) return; @@ -1012,7 +992,7 @@ visitor->Trace(periodic_wave_square_); visitor->Trace(periodic_wave_sawtooth_); visitor->Trace(periodic_wave_triangle_); - visitor->Trace(worklet_messaging_proxy_); + visitor->Trace(audio_worklet_); EventTargetWithInlineData::Trace(visitor); PausableObject::Trace(visitor); } @@ -1038,15 +1018,12 @@ return nullptr; } -bool BaseAudioContext::HasWorkletMessagingProxy() const { - return has_worklet_messaging_proxy_; +AudioWorklet* BaseAudioContext::audioWorklet() const { + return audio_worklet_.Get(); } -void BaseAudioContext::SetWorkletMessagingProxy( - AudioWorkletMessagingProxy* proxy) { - DCHECK(!worklet_messaging_proxy_); - worklet_messaging_proxy_ = proxy; - has_worklet_messaging_proxy_ = true; +void BaseAudioContext::NotifyWorkletIsReady() { + DCHECK(audioWorklet()->IsReady()); // If the context is running or suspended, restart the destination to switch // the render thread with the worklet thread. Note that restarting can happen @@ -1056,9 +1033,4 @@ } } -AudioWorkletMessagingProxy* BaseAudioContext::WorkletMessagingProxy() { - DCHECK(worklet_messaging_proxy_); - return worklet_messaging_proxy_; -} - } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h index 53f7434..0c1f4c3d 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.h
@@ -55,7 +55,7 @@ class AudioBufferSourceNode; class AudioContextOptions; class AudioListener; -class AudioWorkletMessagingProxy; +class AudioWorklet; class BiquadFilterNode; class ChannelMergerNode; class ChannelSplitterNode; @@ -334,9 +334,13 @@ // gesture while the AudioContext requires a user gesture. void MaybeRecordStartAttempt(); - void SetWorkletMessagingProxy(AudioWorkletMessagingProxy*); - AudioWorkletMessagingProxy* WorkletMessagingProxy(); - bool HasWorkletMessagingProxy() const; + // AudioWorklet IDL + AudioWorklet* audioWorklet() const; + + // Callback from AudioWorklet, invoked when the associated + // AudioWorkletGlobalScope is created and the worklet operation is ready after + // the first script evaluation. + void NotifyWorkletIsReady(); // TODO(crbug.com/764396): Remove this when fixed. virtual void CountValueSetterConflict(bool does_conflict){}; @@ -518,8 +522,7 @@ Optional<AutoplayStatus> autoplay_status_; AudioIOPosition output_position_; - bool has_worklet_messaging_proxy_ = false; - Member<AudioWorkletMessagingProxy> worklet_messaging_proxy_; + Member<AudioWorklet> audio_worklet_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.idl b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.idl index 6e18c353..82a1cce 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.idl +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.idl
@@ -68,5 +68,7 @@ [RaisesException, MeasureAs=AudioContextCreateMediaStreamSource] MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream); [RaisesException, MeasureAs=AudioContextCreateMediaStreamDestination] MediaStreamAudioDestinationNode createMediaStreamDestination(); + [RuntimeEnabled=AudioWorklet, SecureContext] readonly attribute AudioWorklet audioWorklet; + attribute EventHandler onstatechange; };
diff --git a/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp index adc5fd43..f612cf1 100644 --- a/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp
@@ -28,8 +28,8 @@ #include "bindings/core/v8/ExceptionMessages.h" #include "bindings/core/v8/ExceptionState.h" #include "core/dom/ExceptionCode.h" +#include "modules/webaudio/AudioWorklet.h" #include "modules/webaudio/BaseAudioContext.h" -#include "modules/webaudio/AudioWorkletMessagingProxy.h" namespace blink { @@ -89,13 +89,12 @@ void DefaultAudioDestinationHandler::StartDestination() { DCHECK(!destination_->IsPlaying()); - // Use Experimental AudioWorkletThread only when AudioWorklet is enabled and - // there is an active AudioWorkletGlobalScope. - if (RuntimeEnabledFeatures::AudioWorkletEnabled() && - Context()->HasWorkletMessagingProxy()) { - DCHECK(Context()->WorkletMessagingProxy()->GetWorkletBackingThread()); + + // Use Experimental AudioWorkletThread only when AudioWorklet is enabled, and + // the worklet thread and the global scope are ready. + if (Context()->audioWorklet() && Context()->audioWorklet()->IsReady()) { destination_->StartWithWorkletThread( - Context()->WorkletMessagingProxy()->GetWorkletBackingThread()); + Context()->audioWorklet()->GetBackingThread()); } else { destination_->Start(); }
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp index f680aa3d..4fe1b5f 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
@@ -28,8 +28,7 @@ #include <algorithm> #include "modules/webaudio/AudioNodeInput.h" #include "modules/webaudio/AudioNodeOutput.h" -#include "modules/webaudio/AudioWorkletMessagingProxy.h" -#include "modules/webaudio/AudioWorkletThread.h" +#include "modules/webaudio/AudioWorklet.h" #include "modules/webaudio/BaseAudioContext.h" #include "modules/webaudio/OfflineAudioContext.h" #include "platform/CrossThreadFunctional.h" @@ -146,13 +145,10 @@ AudioBuffer* render_target) { DCHECK(IsMainThread()); - // Use Experimental AudioWorkletThread only when AudioWorklet is enabled and - // there is an active AudioWorkletGlobalScope. - if (RuntimeEnabledFeatures::AudioWorkletEnabled() && - Context()->HasWorkletMessagingProxy()) { - DCHECK(Context()->WorkletMessagingProxy()->GetWorkletBackingThread()); - worklet_backing_thread_ = - Context()->WorkletMessagingProxy()->GetWorkletBackingThread(); + // Use Experimental AudioWorkletThread only when AudioWorklet is enabled, and + // the worklet thread and the global scope are ready. + if (Context()->audioWorklet() && Context()->audioWorklet()->IsReady()) { + worklet_backing_thread_ = Context()->audioWorklet()->GetBackingThread(); } else { render_thread_ = Platform::Current()->CreateThread("offline audio renderer"); @@ -365,10 +361,9 @@ WebThread* OfflineAudioDestinationHandler::GetRenderingThread() { DCHECK(IsInitialized()); - // Use Experimental AudioWorkletThread only when AudioWorklet is enabled and - // there is an active AudioWorkletGlobalScope. - if (RuntimeEnabledFeatures::AudioWorkletEnabled() && - Context()->HasWorkletMessagingProxy()) { + // Use Experimental AudioWorkletThread only when AudioWorklet is enabled, and + // the worklet thread and the global scope are ready. + if (Context()->audioWorklet() && Context()->audioWorklet()->IsReady()) { DCHECK(!render_thread_ && worklet_backing_thread_); return worklet_backing_thread_; } @@ -381,12 +376,9 @@ // If the worklet thread is not assigned yet, that means the context has // started without a valid WorkletGlobalScope. Assign the worklet thread, // and it will be picked up when the GetRenderingThread() is called next. - if (RuntimeEnabledFeatures::AudioWorkletEnabled() && - Context()->HasWorkletMessagingProxy() && + if (Context()->audioWorklet() && Context()->audioWorklet()->IsReady() && !worklet_backing_thread_) { - DCHECK(Context()->WorkletMessagingProxy()->GetWorkletBackingThread()); - worklet_backing_thread_ = - Context()->WorkletMessagingProxy()->GetWorkletBackingThread(); + worklet_backing_thread_ = Context()->audioWorklet()->GetBackingThread(); } };
diff --git a/third_party/WebKit/Source/modules/webaudio/WindowAudioWorklet.cpp b/third_party/WebKit/Source/modules/webaudio/WindowAudioWorklet.cpp deleted file mode 100644 index 630331b..0000000 --- a/third_party/WebKit/Source/modules/webaudio/WindowAudioWorklet.cpp +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "modules/webaudio/WindowAudioWorklet.h" - -#include "core/dom/Document.h" -#include "core/frame/LocalDOMWindow.h" -#include "core/frame/LocalFrame.h" - -namespace blink { - -AudioWorklet* WindowAudioWorklet::audioWorklet(LocalDOMWindow& window) { - if (!window.GetFrame()) - return nullptr; - return From(window).audio_worklet_.Get(); -} - -// Break the following cycle when the context gets detached. -// Otherwise, the worklet object will leak. -// -// window => window.audioWorklet -// => WindowAudioWorklet -// => AudioWorklet <--- break this reference -// => ThreadedWorkletMessagingProxy -// => Document -// => ... => window -void WindowAudioWorklet::ContextDestroyed(ExecutionContext*) { - audio_worklet_ = nullptr; -} - -void WindowAudioWorklet::Trace(blink::Visitor* visitor) { - visitor->Trace(audio_worklet_); - Supplement<LocalDOMWindow>::Trace(visitor); - ContextLifecycleObserver::Trace(visitor); -} - -WindowAudioWorklet& WindowAudioWorklet::From(LocalDOMWindow& window) { - WindowAudioWorklet* supplement = static_cast<WindowAudioWorklet*>( - Supplement<LocalDOMWindow>::From(window, SupplementName())); - if (!supplement) { - supplement = new WindowAudioWorklet(window); - ProvideTo(window, SupplementName(), supplement); - } - return *supplement; -} - -WindowAudioWorklet::WindowAudioWorklet(LocalDOMWindow& window) - : ContextLifecycleObserver(window.GetFrame()->GetDocument()), - audio_worklet_(AudioWorklet::Create(window.GetFrame())) { - DCHECK(GetExecutionContext()); -} - -const char* WindowAudioWorklet::SupplementName() { - return "WindowAudioWorklet"; -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/WindowAudioWorklet.h b/third_party/WebKit/Source/modules/webaudio/WindowAudioWorklet.h deleted file mode 100644 index 55e7903c..0000000 --- a/third_party/WebKit/Source/modules/webaudio/WindowAudioWorklet.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WindowAudioWorklet_h -#define WindowAudioWorklet_h - -#include "core/dom/ContextLifecycleObserver.h" -#include "modules/ModulesExport.h" -#include "modules/webaudio/AudioWorklet.h" -#include "platform/Supplementable.h" -#include "platform/heap/Handle.h" - -namespace blink { - -class LocalDOMWindow; - -class MODULES_EXPORT WindowAudioWorklet final - : public GarbageCollected<WindowAudioWorklet>, - public Supplement<LocalDOMWindow>, - public ContextLifecycleObserver { - USING_GARBAGE_COLLECTED_MIXIN(WindowAudioWorklet); - - public: - static AudioWorklet* audioWorklet(LocalDOMWindow&); - - void ContextDestroyed(ExecutionContext*) override; - - void Trace(blink::Visitor*); - - private: - static WindowAudioWorklet& From(LocalDOMWindow&); - - explicit WindowAudioWorklet(LocalDOMWindow&); - static const char* SupplementName(); - - Member<AudioWorklet> audio_worklet_; -}; - -} // namespace blink - -#endif // WindowAudioWorklet_h
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc index 7f6b2040..13c0943 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc
@@ -14,23 +14,16 @@ namespace blink { namespace scheduler { -namespace { - -double TimeDeltaToMilliseconds(const base::TimeDelta& value) { - return value.InMillisecondsF(); -} - -} // namespace - CPUTimeBudgetPool::CPUTimeBudgetPool( const char* name, BudgetPoolController* budget_pool_controller, base::TimeTicks now) : BudgetPool(name, budget_pool_controller), - current_budget_level_(base::TimeDelta(), - "RendererScheduler.BackgroundBudgetMs", - budget_pool_controller, - TimeDeltaToMilliseconds), + current_budget_level_( + base::TimeDelta(), + "RendererScheduler.BackgroundBudgetMs", + budget_pool_controller, + [](const base::TimeDelta& value) { return value.InMillisecondsF(); }), last_checkpoint_(now), cpu_percentage_(1) {}
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 565a6be..aac34fb 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -9035,6 +9035,20 @@ </summary> </histogram> +<histogram name="Chrome.ProcessSingleton.ProcessTerminateErrorCode.Windows" + enum="WinGetLastError"> + <obsolete> + Deprecated as of 12/2017. + </obsolete> + <owner>aseren@yandex-team.ru</owner> + <owner>gab@chromium.org</owner> + <summary> + The error code of remote process termination on Windows in case when remote + process hung. This histogram has been replaced by + Chrome.ProcessSingleton.TerminateProcessErrorCode.Windows histogram. + </summary> +</histogram> + <histogram name="Chrome.ProcessSingleton.RemoteHungProcessTerminateReason" enum="RemoteHungProcessTerminateReason"> <owner>aseren@yandex-team.ru</owner> @@ -12940,6 +12954,15 @@ </summary> </histogram> +<histogram name="DataReductionProxy.NetworkProperties.CacheHit" + units="BooleanCacheHit"> + <owner>tbansal@chromium.org</owner> + <summary> + Records if the network properties of a network were found in the cache or + not. Recorded every time there is a change in the connection type. + </summary> +</histogram> + <histogram name="DataReductionProxy.Pingback.Attempted" enum="BooleanAttempted"> <owner>bengr@chromium.org</owner> <owner>ryansturm@chromium.org</owner> @@ -93008,7 +93031,31 @@ </summary> </histogram> -<histogram name="VR.AssetsComponent.LoadStatus" enum="VRAssetsLoadStatus"> +<histogram name="VR.Component.Assets.DurationUntilReady.OnChromeStart" + units="ms"> + <owner>tiborg@chromium.org</owner> + <summary> + Duration from starting Chrome until VR assets component is ready to use. + </summary> +</histogram> + +<histogram base="true" name="VR.Component.Assets.DurationUntilReady.OnEnter" + units="ms"> + <owner>tiborg@chromium.org</owner> + <summary> + Duration from entering a VR mode until the VR assets component is ready to + use. + </summary> +</histogram> + +<histogram base="true" name="VR.Component.Assets.Status.OnEnter" + enum="VRAssetsComponentEnterStatus"> + <owner>tiborg@chromium.org</owner> + <summary>Status of the VR assets component when entering a VR mode.</summary> +</histogram> + +<histogram name="VR.Component.Assets.VersionAndStatus.OnLoad" + enum="VRAssetsLoadStatus"> <owner>tiborg@chromium.org</owner> <summary> The component version and status of loading the VR assets. The value is @@ -93018,21 +93065,7 @@ </summary> </histogram> -<histogram base="true" name="VR.AssetsComponent.ReadyLatency.OnEnter" - units="ms"> - <owner>tiborg@chromium.org</owner> - <summary> - Duration from entering a VR mode until VR assets component is ready to use. - </summary> -</histogram> - -<histogram base="true" name="VR.AssetsComponent.Status.OnEnter" - enum="VRAssetsComponentEnterStatus"> - <owner>tiborg@chromium.org</owner> - <summary>Status of the VR assets component when entering a VR mode.</summary> -</histogram> - -<histogram name="VR.AssetsComponent.UpdateStatus" +<histogram name="VR.Component.Assets.VersionAndStatus.OnUpdate" enum="VRAssetsComponentUpdateStatus"> <owner>tiborg@chromium.org</owner> <summary> @@ -93044,16 +93077,18 @@ </summary> </histogram> -<histogram base="true" name="VR.DataConnection.OnEnter" +<histogram base="true" name="VR.NetworkConnectionType.OnEnter" enum="NetworkConnectionType"> <owner>tiborg@chromium.org</owner> - <summary>Data connection when entering a VR mode.</summary> + <summary>Network connection type when entering a VR mode.</summary> </histogram> -<histogram name="VR.DataConnection.OnRegisterAssetsComponent" +<histogram name="VR.NetworkConnectionType.OnRegisterComponent" enum="NetworkConnectionType"> <owner>tiborg@chromium.org</owner> - <summary>Data connection when registering the VR assets component.</summary> + <summary> + Network connection type when registering the VR component(s). + </summary> </histogram> <histogram name="VR.Session.VoiceSearch.StartedCount" units="searches"> @@ -109179,13 +109214,13 @@ </histogram_suffixes> <histogram_suffixes name="VR.Mode" separator="."> - <affected-histogram name="VR.AssetsComponent.ReadyLatency.OnEnter"/> - <suffix name="VR" label="Entered either VR Browsing or WebVR mode."/> + <suffix name="AllVR" label="Entered either VR Browsing or WebVR mode."/> <suffix name="VRBrowsing" label="Entered VR Browsing Mode."/> - <suffix name="WebVR" - label="Entered WebVR mode (also includes splash screen)."/> - <affected-histogram name="VR.AssetsComponent.Status.OnEnter"/> - <affected-histogram name="VR.DataConnection.OnEnter"/> + <suffix name="WebVRPresentation" + label="Entered WebVR presentation mode (also includes splash screen)."/> + <affected-histogram name="VR.Component.Assets.DurationUntilReady.OnEnter"/> + <affected-histogram name="VR.Component.Assets.Status.OnEnter"/> + <affected-histogram name="VR.NetworkConnectionType.OnEnter"/> </histogram_suffixes> <histogram_suffixes name="VRFreNotCompleteType" separator=".">
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index 2128b1852..37d7fa6 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -413,10 +413,12 @@ } bool DesktopWindowTreeHostWin::ShouldWindowContentsBeTransparent() const { - // If the window has a native frame, we assume it is an Aero Glass window, and - // is therefore transparent. Note: This is not equivalent to calling - // IsAeroGlassEnabled, because ShouldUseNativeFrame is overridden in a - // subclass. + // The window contents need to be transparent when the titlebar area is drawn + // by the DWM rather than Chrome, so that area can show through. This + // function does not describe the transparency of the whole window appearance, + // but merely of the content Chrome draws, so even when the system titlebars + // appear opaque (Win 8+), the content above them needs to be transparent, or + // they'll be covered by a black (undrawn) region. return ShouldUseNativeFrame() && !IsFullscreen(); }