diff --git a/DEPS b/DEPS index 20c46ef..289b0748 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '65115a1b1a5c72b47492dc447d1d282353ae3121', + 'skia_revision': '60c05f98aa22d89e4ef25acb4799936f5df3cff2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -228,7 +228,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '2410df43d212f3e71fc37601e2b79d431eb5b9da', # commit position 15596 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'fa849a2eb338b0932a973f35e14c56a5544a3072', # commit position 15611 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt b/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt index 5c29c5fd..ecf9fbaf 100644 --- a/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt +++ b/android_webview/tools/system_webview_shell/test/data/webexposed/global-interface-listing-expected.txt
@@ -4436,13 +4436,6 @@ method register setter oncontrollerchange setter onmessage -interface ServiceWorkerMessageEvent : Event - getter data - getter lastEventId - getter origin - getter ports - getter source - method constructor interface ServiceWorkerRegistration : EventTarget getter onupdatefound getter scope
diff --git a/ash/common/system/tray/fixed_sized_scroll_view.cc b/ash/common/system/tray/fixed_sized_scroll_view.cc index e14a610..33fcef69 100644 --- a/ash/common/system/tray/fixed_sized_scroll_view.cc +++ b/ash/common/system/tray/fixed_sized_scroll_view.cc
@@ -19,8 +19,10 @@ FixedSizedScrollView::FixedSizedScrollView() { set_notify_enter_exit_on_child(true); - if (UseMd()) + if (UseMd()) { SetVerticalScrollBar(new views::OverlayScrollBar(false)); + SetHorizontalScrollBar(new views::OverlayScrollBar(true)); + } } FixedSizedScrollView::~FixedSizedScrollView() {} @@ -60,7 +62,7 @@ return views::ScrollView::Layout(); gfx::Rect bounds = gfx::Rect(contents()->GetPreferredSize()); - bounds.set_width(std::max(0, width() - GetScrollBarWidth())); + bounds.set_width(std::max(0, width() - GetScrollBarLayoutWidth())); // Keep the origin of the contents unchanged so that the list will not scroll // away from the current visible region user is viewing. ScrollView::Layout() // will make sure the contents line up with its viewport properly if @@ -71,7 +73,7 @@ views::ScrollView::Layout(); if (!vertical_scroll_bar()->visible()) { gfx::Rect bounds = contents()->bounds(); - bounds.set_width(bounds.width() + GetScrollBarWidth()); + bounds.set_width(bounds.width() + GetScrollBarLayoutWidth()); contents()->SetBoundsRect(bounds); } } @@ -81,7 +83,7 @@ return; gfx::Rect bounds = gfx::Rect(contents()->GetPreferredSize()); - bounds.set_width(std::max(0, width() - GetScrollBarWidth())); + bounds.set_width(std::max(0, width() - GetScrollBarLayoutWidth())); contents()->SetBoundsRect(bounds); }
diff --git a/ash/common/system/tray/tray_details_view.cc b/ash/common/system/tray/tray_details_view.cc index 7086c0c3..2adf398 100644 --- a/ash/common/system/tray/tray_details_view.cc +++ b/ash/common/system/tray/tray_details_view.cc
@@ -536,7 +536,7 @@ // row. gfx::Size scroller_size = scroll_content_->GetPreferredSize(); scroller_->set_fixed_size( - gfx::Size(width() + scroller_->GetScrollBarWidth(), + gfx::Size(width() + scroller_->GetScrollBarLayoutWidth(), scroller_size.height() - (size.height() - height()))); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java index 36eff359..e0f7ad1c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java
@@ -166,6 +166,9 @@ // Notification.Builder.setPublicVersion was added in Android L. builder.setPublicVersion(createPublicNotification(mContext)); } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + builder.setExtras(mExtras); + } Notification notification = builder.build(); notification.bigContentView = bigView;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java index 6635ecca..94ee796 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java
@@ -18,6 +18,7 @@ import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Icon; import android.os.Build; +import android.os.Bundle; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.widget.RoundedIconGenerator; @@ -121,6 +122,7 @@ protected long[] mVibratePattern; protected long mTimestamp; protected boolean mRenotify; + protected Bundle mExtras; private Bitmap mLargeIcon; @@ -309,6 +311,18 @@ } /** + * Sets the extras bundle on supported platforms. + */ + @TargetApi(Build.VERSION_CODES.M) + public NotificationBuilderBase setExtras(Bundle extras) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return this; + } + mExtras = extras; + return this; + } + + /** * Gets the large icon for the notification. * * If a large icon was supplied to the builder, returns this icon, scaled to an appropriate size
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxy.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxy.java index fd9ae67..f601d75 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxy.java
@@ -4,7 +4,10 @@ package org.chromium.chrome.browser.notifications; +import android.annotation.TargetApi; import android.app.Notification; +import android.os.Build; +import android.service.notification.StatusBarNotification; /** * A proxy for the Android Notification Manager. This allows tests to be written without having to @@ -18,4 +21,7 @@ void cancelAll(); void notify(int id, Notification notification); void notify(String tag, int id, Notification notification); + + @TargetApi(Build.VERSION_CODES.M) + StatusBarNotification[] getActiveNotifications(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxyImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxyImpl.java index b05fd0047..ece1f75c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxyImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationManagerProxyImpl.java
@@ -6,6 +6,7 @@ import android.app.Notification; import android.app.NotificationManager; +import android.service.notification.StatusBarNotification; /** * Default implementation of the NotificationManagerProxy, which passes through all calls to the @@ -42,4 +43,9 @@ public void notify(String tag, int id, Notification notification) { mNotificationManager.notify(tag, id, notification); } + + @Override + public StatusBarNotification[] getActiveNotifications() { + return mNotificationManager.getActiveNotifications(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java index 26a96f9..d1c4d1b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java
@@ -15,6 +15,7 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.service.notification.StatusBarNotification; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextUtils; @@ -43,6 +44,8 @@ import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; import javax.annotation.Nullable; @@ -572,6 +575,15 @@ makeDefaults(vibrationPattern.length, silent, vibrateEnabled)); notificationBuilder.setVibrate(makeVibrationPattern(vibrationPattern)); + // The extras bundle is available from API 20 but it's currenlty only used to retrieve + // notifications which is only available from 23 (Marshmallow) onwards. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Bundle extras = new Bundle(); + extras.putString(NotificationConstants.EXTRA_NOTIFICATION_ID, notificationId); + extras.putString(NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_ID, profileId); + notificationBuilder.setExtras(extras); + } + String platformTag = makePlatformTag(notificationId, origin, tag); if (webApkPackage.isEmpty()) { mNotificationManager.notify(platformTag, PLATFORM_ID, notificationBuilder.build()); @@ -676,6 +688,35 @@ } /** + * Returns the notification ids on disply for a given |profileId|. + * + * @param profileId of the profile to retrieve notifications for. + */ + @CalledByNative + private String[] getNotificationsForProfile(String profileId) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return null; + } + + StatusBarNotification[] displayedNotifications = + mNotificationManager.getActiveNotifications(); + List<String> notifications = new ArrayList<String>(); + for (StatusBarNotification notification : displayedNotifications) { + Bundle extras = notification.getNotification().extras; + String notificationId = extras.getString(NotificationConstants.EXTRA_NOTIFICATION_ID); + String notificationProfileId = + extras.getString(NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_ID); + if (notificationId != null && profileId.equals(notificationProfileId)) { + notifications.add(notificationId); + } + } + if (notifications.size() == 0) return null; + + String[] result = new String[notifications.size()]; + return notifications.toArray(result); + } + + /** * Calls NotificationPlatformBridgeAndroid::OnNotificationClicked in native code to indicate * that the notification with the given parameters has been clicked on. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java index 337b6f4..705d7c0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java
@@ -60,6 +60,9 @@ // Notification.Builder.setPublicVersion was added in Android L. builder.setPublicVersion(createPublicNotification(mContext)); } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + builder.setExtras(mExtras); + } return builder.build(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAddress.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAddress.java index c4af2085..9e8102f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAddress.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAddress.java
@@ -163,6 +163,7 @@ switch (checkAddressCompletionStatus(mProfile)) { case COMPLETE: + editTitleResId = R.string.autofill_edit_profile; break; case INVALID_ADDRESS: editMessageResId = R.string.payments_invalid_address;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java index cb71c8a..2069212 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentInstrument.java
@@ -256,7 +256,7 @@ */ private void checkAndUpateCardCompleteness() { int editMessageResId = 0; // Zero is the invalid resource Id. - int editTitleResId = 0; + int editTitleResId = R.string.payments_edit_card; int invalidFieldsCount = 0; if (mBillingAddress == null) { @@ -287,7 +287,7 @@ } mEditMessage = editMessageResId == 0 ? null : mContext.getString(editMessageResId); - mEditTitle = editTitleResId == 0 ? null : mContext.getString(editTitleResId); + mEditTitle = mContext.getString(editTitleResId); mIsComplete = mEditMessage == null; }
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7547369..b71af7e 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -597,25 +597,6 @@ {IDS_FLAGS_SSL_VERSION_MAX_TLS13, switches::kSSLVersionMax, "tls1.3"}, }; -const FeatureEntry::Choice kSecurityChipChoices[] = { - {IDS_FLAGS_SECURITY_CHIP_DEFAULT, "", ""}, - {IDS_FLAGS_SECURITY_CHIP_SHOW_NONSECURE_ONLY, switches::kSecurityChip, - switches::kSecurityChipShowNonSecureOnly}, - {IDS_FLAGS_SECURITY_CHIP_SHOW_ALL, switches::kSecurityChip, - switches::kSecurityChipShowAll}, -}; - -const FeatureEntry::Choice kSecurityChipAnimationChoices[] = { - {IDS_FLAGS_SECURITY_CHIP_ANIMATION_DEFAULT, "", ""}, - {IDS_FLAGS_SECURITY_CHIP_ANIMATION_NONE, switches::kSecurityChipAnimation, - switches::kSecurityChipAnimationNone}, - {IDS_FLAGS_SECURITY_CHIP_ANIMATION_NONSECURE_ONLY, - switches::kSecurityChipAnimation, - switches::kSecurityChipAnimationNonSecureOnly}, - {IDS_FLAGS_SECURITY_CHIP_ANIMATION_ALL, switches::kSecurityChipAnimation, - switches::kSecurityChipAnimationAll}, -}; - #if !defined(OS_ANDROID) const FeatureEntry::Choice kEnableDefaultMediaSessionChoices[] = { {IDS_FLAGS_ENABLE_DEFAULT_MEDIA_SESSION_DISABLED, "", ""}, @@ -2052,12 +2033,6 @@ IDS_FLAGS_EXPENSIVE_BACKGROUND_TIMER_THROTTLING_NAME, IDS_FLAGS_EXPENSIVE_BACKGROUND_TIMER_THROTTLING_DESCRIPTION, kOsAll, FEATURE_VALUE_TYPE(features::kExpensiveBackgroundTimerThrottling)}, - {"security-chip", IDS_FLAGS_SECURITY_CHIP_NAME, - IDS_FLAGS_SECURITY_CHIP_DESCRIPTION, kOsDesktop, - MULTI_VALUE_TYPE(kSecurityChipChoices)}, - {"security-chip-animation", IDS_FLAGS_SECURITY_CHIP_ANIMATION_NAME, - IDS_FLAGS_SECURITY_CHIP_ANIMATION_DESCRIPTION, kOsDesktop, - MULTI_VALUE_TYPE(kSecurityChipAnimationChoices)}, #if defined(OS_CHROMEOS) {"enumerate-audio-devices", IDS_FLAGS_ENABLE_ENUMERATING_AUDIO_DEVICES_NAME, IDS_FLAGS_ENABLE_ENUMERATING_AUDIO_DEVICES_DESCRIPTION, kOsCrOS,
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc b/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc index 0fbca927..8a5fbfe 100644 --- a/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc +++ b/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc
@@ -246,7 +246,7 @@ RunUntilIdle(); EXPECT_TRUE(model()->is_loaded()); GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); } @@ -263,7 +263,7 @@ EXPECT_TRUE(model()->is_loaded()); GetAllPages(); // No page should be captured. - EXPECT_EQ(0U, all_pages().size()); + ASSERT_EQ(0U, all_pages().size()); } // Triggers two snapshot captures during a single page load. Should end up with @@ -281,7 +281,7 @@ EXPECT_EQ(1U, page_added_count()); EXPECT_EQ(0U, model_removed_count()); GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); int64_t first_offline_id = all_pages()[0].offline_id; @@ -294,7 +294,7 @@ EXPECT_EQ(1U, model_removed_count()); // the same page should be simply overridden. GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); EXPECT_NE(first_offline_id, all_pages()[0].offline_id); } @@ -316,7 +316,7 @@ EXPECT_EQ(1U, page_added_count()); EXPECT_EQ(0U, model_removed_count()); GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); int64_t first_offline_id = all_pages()[0].offline_id; @@ -339,7 +339,7 @@ EXPECT_EQ(0U, model_removed_count()); // The exact same page should still be available. GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); EXPECT_EQ(first_offline_id, all_pages()[0].offline_id); } @@ -359,7 +359,7 @@ EXPECT_EQ(1U, page_added_count()); EXPECT_EQ(0U, model_removed_count()); GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); int64_t first_offline_id = all_pages()[0].offline_id; @@ -373,7 +373,7 @@ EXPECT_EQ(1U, model_removed_count()); // the same page should be simply overridden. GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); EXPECT_NE(first_offline_id, all_pages()[0].offline_id); } @@ -394,7 +394,7 @@ EXPECT_EQ(1U, page_added_count()); EXPECT_EQ(0U, model_removed_count()); GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); // Sets a new delegate that will make the second snapshot fail. @@ -417,7 +417,7 @@ EXPECT_EQ(1U, model_removed_count()); // the same page should be simply overridden. GetAllPages(); - EXPECT_EQ(0U, all_pages().size()); + ASSERT_EQ(0U, all_pages().size()); } // Triggers two snapshot captures for two different page loads and URLs. Should @@ -435,7 +435,7 @@ EXPECT_EQ(1U, page_added_count()); EXPECT_EQ(0U, model_removed_count()); GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); NavigateAndCommit(kTestPageUrlOther); @@ -448,7 +448,7 @@ EXPECT_EQ(1U, model_removed_count()); // the same page should be simply overridden. GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrlOther, all_pages()[0].url); } @@ -469,7 +469,7 @@ EXPECT_EQ(2U, page_added_count()); EXPECT_EQ(1U, model_removed_count()); GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); EXPECT_EQ(kTestPageUrl, all_pages()[0].url); int64_t first_offline_id = all_pages()[0].offline_id; @@ -515,7 +515,7 @@ RunUntilIdle(); EXPECT_TRUE(model()->is_loaded()); GetAllPages(); - EXPECT_EQ(0U, all_pages().size()); + ASSERT_EQ(0U, all_pages().size()); } // Checks that no snapshots are created if the Offline Page Cache feature is @@ -530,20 +530,21 @@ EXPECT_TRUE(model()->is_loaded()); GetAllPages(); // No page should be captured. - EXPECT_EQ(0U, all_pages().size()); + ASSERT_EQ(0U, all_pages().size()); } // Simulates a download request to offline the current page. Should end up with // one offline pages. -TEST_F(RecentTabHelperTest, DISABLED_DownloadRequest) { +TEST_F(RecentTabHelperTest, DownloadRequest) { NavigateAndCommit(kTestPageUrl); recent_tab_helper()->ObserveAndDownloadCurrentPage( ClientId("download", "id1"), 153L); recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(); + FastForwardSnapshotController(); RunUntilIdle(); EXPECT_TRUE(model()->is_loaded()); GetAllPages(); - EXPECT_EQ(1U, all_pages().size()); + ASSERT_EQ(1U, all_pages().size()); const OfflinePageItem& page = all_pages()[0]; EXPECT_EQ(kTestPageUrl, page.url); EXPECT_EQ("download", page.client_id.name_space);
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc index 04985568..f12b8667 100644 --- a/chrome/browser/android/vr_shell/vr_shell.cc +++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -106,9 +106,11 @@ gvr_context* gvr_api) : WebContentsObserver(ui_contents), main_contents_(main_contents), + content_compositor_(new VrCompositor(content_window, false)), ui_contents_(ui_contents), + ui_compositor_(new VrCompositor(ui_window, true)), delegate_(delegate), - metrics_helper_(new VrMetricsHelper(main_contents)), + metrics_helper_(new VrMetricsHelper(main_contents_)), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), weak_ptr_factory_(this) { DCHECK(g_instance == nullptr); @@ -118,6 +120,9 @@ content_input_manager_.reset(new VrInputManager(main_contents_)); ui_input_manager_.reset(new VrInputManager(ui_contents_)); + content_compositor_->SetLayer(main_contents_); + ui_compositor_->SetLayer(ui_contents_); + gl_thread_.reset(new GLThread(this, weak_ptr_factory_.GetWeakPtr(), content_input_manager_->GetWeakPtr(), ui_input_manager_->GetWeakPtr(), @@ -133,10 +138,6 @@ html_interface_.reset(new UiInterface( for_web_vr ? UiInterface::Mode::WEB_VR : UiInterface::Mode::STANDARD, main_contents_->IsFullscreen())); - content_compositor_.reset(new VrCompositor(content_window, false)); - content_compositor_->SetLayer(main_contents_); - ui_compositor_.reset(new VrCompositor(ui_window, true)); - ui_compositor_->SetLayer(ui_contents_); vr_web_contents_observer_.reset(new VrWebContentsObserver( main_contents, html_interface_.get(), this));
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h index 5de0c394..bd41379 100644 --- a/chrome/browser/android/vr_shell/vr_shell.h +++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -145,10 +145,11 @@ std::unique_ptr<UiInterface> html_interface_; - std::unique_ptr<VrCompositor> content_compositor_; content::WebContents* main_contents_; - std::unique_ptr<VrCompositor> ui_compositor_; + std::unique_ptr<VrCompositor> content_compositor_; content::WebContents* ui_contents_; + std::unique_ptr<VrCompositor> ui_compositor_; + std::unique_ptr<VrWebContentsObserver> vr_web_contents_observer_; VrShellDelegate* delegate_ = nullptr; @@ -156,8 +157,7 @@ std::unique_ptr<VrInputManager> content_input_manager_; std::unique_ptr<VrInputManager> ui_input_manager_; - - scoped_refptr<VrMetricsHelper> metrics_helper_; + std::unique_ptr<VrMetricsHelper> metrics_helper_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; std::unique_ptr<base::Thread> gl_thread_;
diff --git a/chrome/browser/android/vr_shell/vr_usage_monitor.cc b/chrome/browser/android/vr_shell/vr_usage_monitor.cc index 8bfae60..8381fbf 100644 --- a/chrome/browser/android/vr_shell/vr_usage_monitor.cc +++ b/chrome/browser/android/vr_shell/vr_usage_monitor.cc
@@ -175,32 +175,16 @@ SetVrMode(mode); } -void VrMetricsHelper::SetWebVREnabledOnMainThread(bool is_webvr_presenting) { - DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); +void VrMetricsHelper::SetWebVREnabled(bool is_webvr_presenting) { is_webvr_ = is_webvr_presenting; UpdateMode(); } -void VrMetricsHelper::SetVRActiveOnMainThread(bool is_vr_enabled) { - DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); +void VrMetricsHelper::SetVRActive(bool is_vr_enabled) { is_vr_enabled_ = is_vr_enabled; UpdateMode(); } -void VrMetricsHelper::SetWebVREnabled(bool is_webvr) { - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::Bind(&VrMetricsHelper::SetWebVREnabledOnMainThread, this, - is_webvr)); -} - -void VrMetricsHelper::SetVRActive(bool is_vr_enabled) { - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::Bind(&VrMetricsHelper::SetVRActiveOnMainThread, this, - is_vr_enabled)); -} - void VrMetricsHelper::SetVrMode(VRMode mode) { DCHECK(mode != mode_); @@ -278,8 +262,7 @@ mode_ = mode; } -VrMetricsHelper::VrMetricsHelper(content::WebContents* contents) - : thread_id_(base::PlatformThread::CurrentId()) { +VrMetricsHelper::VrMetricsHelper(content::WebContents* contents) { num_videos_playing_ = contents->GetCurrentlyPlayingVideoCount(); is_fullscreen_ = contents->IsFullscreen(); origin_ = contents->GetLastCommittedURL(); @@ -291,13 +274,10 @@ maximumVideoSessionGap, minimumVideoSessionDuration)); } -VrMetricsHelper::~VrMetricsHelper() { - DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); -} +VrMetricsHelper::~VrMetricsHelper() = default; void VrMetricsHelper::MediaStartedPlaying(const MediaPlayerInfo& media_info, const MediaPlayerId&) { - DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); if (!media_info.has_video) return; @@ -318,7 +298,6 @@ void VrMetricsHelper::MediaStoppedPlaying(const MediaPlayerInfo& media_info, const MediaPlayerId&) { - DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); if (!media_info.has_video) return; @@ -336,7 +315,6 @@ } void VrMetricsHelper::DidFinishNavigation(content::NavigationHandle* handle) { - DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); if (handle != nullptr && handle->HasCommitted() && handle->IsInMainFrame()) { origin_ = handle->GetURL(); // Counting the number of pages viewed is difficult - some websites load @@ -352,7 +330,6 @@ void VrMetricsHelper::DidToggleFullscreenModeForTab(bool entered_fullscreen, bool will_cause_resize) { - DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); is_fullscreen_ = entered_fullscreen; UpdateMode(); }
diff --git a/chrome/browser/android/vr_shell/vr_usage_monitor.h b/chrome/browser/android/vr_shell/vr_usage_monitor.h index 7e1c6e29..594f348 100644 --- a/chrome/browser/android/vr_shell/vr_usage_monitor.h +++ b/chrome/browser/android/vr_shell/vr_usage_monitor.h
@@ -5,7 +5,9 @@ #ifndef CHROME_BROWSER_ANDROID_VR_SHELL_VR_USAGE_MONITOR_H_ #define CHROME_BROWSER_ANDROID_VR_SHELL_VR_USAGE_MONITOR_H_ -#include "base/threading/platform_thread.h" +#include <memory> + +#include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" @@ -51,21 +53,15 @@ DISALLOW_COPY_AND_ASSIGN(SessionTimer); }; -// Most methods of this class are not threadsafe - they must be called -// on the Browser's main thread. This happens by default except for -// SetWebVREnabled and SetVRActive, where we'll post a message to get to the -// correct thread. -// Destruction must happen on the main thread, or there could be corruption when -// WebContentsObserver unregisters itself from the web_contents_. -// There are DCHECKS to ensure these threading rules are satisfied. -class VrMetricsHelper : public content::WebContentsObserver, - public base::RefCountedThreadSafe<VrMetricsHelper> { +// This class is not threadsafe and must only be used from the main thread. +class VrMetricsHelper : public content::WebContentsObserver { public: explicit VrMetricsHelper(content::WebContents*); - + ~VrMetricsHelper() override; void SetWebVREnabled(bool is_webvr_presenting); void SetVRActive(bool is_vr_enabled); + private: // WebContentObserver void MediaStartedPlaying(const MediaPlayerInfo& media_info, const MediaPlayerId&) override; @@ -75,13 +71,6 @@ void DidToggleFullscreenModeForTab(bool entered_fullscreen, bool will_cause_resize) override; - protected: - friend class base::RefCountedThreadSafe<VrMetricsHelper>; - ~VrMetricsHelper() override; - - void SetWebVREnabledOnMainThread(bool is_webvr_presenting); - void SetVRActiveOnMainThread(bool is_vr_enabled); - void SetVrMode(VRMode mode); void UpdateMode(); @@ -102,9 +91,6 @@ int num_session_video_playback_ = 0; GURL origin_; - - // not thread safe, so ensure we are on the same thread at all times: - base::PlatformThreadId thread_id_; }; } // namespace vr_shell
diff --git a/chrome/browser/extensions/api/automation/automation_apitest.cc b/chrome/browser/extensions/api/automation/automation_apitest.cc index 6c0b9a9b..b498453 100644 --- a/chrome/browser/extensions/api/automation/automation_apitest.cc +++ b/chrome/browser/extensions/api/automation/automation_apitest.cc
@@ -83,7 +83,7 @@ content::WebContents* const tab = browser()->tab_strip_model()->GetWebContentsAt(0); ASSERT_FALSE(tab->IsFullAccessibilityModeForTesting()); - ASSERT_FALSE(tab->IsTreeOnlyAccessibilityModeForTesting()); + ASSERT_FALSE(tab->IsWebContentsOnlyAccessibilityModeForTesting()); base::FilePath extension_path = test_data_dir_.AppendASCII("automation/tests/basic"); @@ -92,7 +92,7 @@ ASSERT_TRUE(got_tree.WaitUntilSatisfied()); ASSERT_FALSE(tab->IsFullAccessibilityModeForTesting()); - ASSERT_TRUE(tab->IsTreeOnlyAccessibilityModeForTesting()); + ASSERT_TRUE(tab->IsWebContentsOnlyAccessibilityModeForTesting()); } IN_PROC_BROWSER_TEST_F(AutomationApiTest, SanityCheck) {
diff --git a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc index f564ab7..f2238ac 100644 --- a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc +++ b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc
@@ -28,6 +28,7 @@ #include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_plugin_guest_manager.h" +#include "content/public/browser/media_session.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" @@ -222,6 +223,26 @@ browser_context_); } + void MediaStartedPlaying(const MediaPlayerInfo& video_type, + const MediaPlayerId& id) override { + std::vector<content::AXEventNotificationDetails> details; + content::AXEventNotificationDetails detail; + detail.ax_tree_id = id.first->GetAXTreeID(); + detail.event_type = ui::AX_EVENT_MEDIA_STARTED_PLAYING; + details.push_back(detail); + AccessibilityEventReceived(details); + } + + void MediaStoppedPlaying(const MediaPlayerInfo& video_type, + const MediaPlayerId& id) override { + std::vector<content::AXEventNotificationDetails> details; + content::AXEventNotificationDetails detail; + detail.ax_tree_id = id.first->GetAXTreeID(); + detail.event_type = ui::AX_EVENT_MEDIA_STOPPED_PLAYING; + details.push_back(detail); + AccessibilityEventReceived(details); + } + private: friend class content::WebContentsUserData<AutomationWebContentsObserver>; @@ -271,7 +292,7 @@ } AutomationWebContentsObserver::CreateForWebContents(contents); - contents->EnableTreeOnlyAccessibilityMode(); + contents->EnableWebContentsOnlyAccessibilityMode(); int ax_tree_id = rfh->GetAXTreeID(); @@ -305,7 +326,7 @@ // Only call this if this is the root of a frame tree, to avoid resetting // the accessibility state multiple times. if (!rfh->GetParent()) - contents->EnableTreeOnlyAccessibilityMode(); + contents->EnableWebContentsOnlyAccessibilityMode(); return RespondNow(NoArguments()); } @@ -334,13 +355,36 @@ if (!rfh) return RespondNow(Error("Ignoring action on destroyed node")); - const content::WebContents* contents = + content::WebContents* contents = content::WebContents::FromRenderFrameHost(rfh); if (!CanRequestAutomation(extension(), automation_info, contents)) { return RespondNow( Error(kCannotRequestAutomationOnPage, contents->GetURL().spec())); } + // These actions are handled directly for the WebContents. + if (params->args.action_type == + api::automation_internal::ACTION_TYPE_STARTDUCKINGMEDIA) { + content::MediaSession* session = content::MediaSession::Get(contents); + session->StartDucking(); + return RespondNow(NoArguments()); + } else if (params->args.action_type == + api::automation_internal::ACTION_TYPE_STOPDUCKINGMEDIA) { + content::MediaSession* session = content::MediaSession::Get(contents); + session->StopDucking(); + return RespondNow(NoArguments()); + } else if (params->args.action_type == + api::automation_internal::ACTION_TYPE_RESUMEMEDIA) { + content::MediaSession* session = content::MediaSession::Get(contents); + session->Resume(content::MediaSession::SuspendType::SYSTEM); + return RespondNow(NoArguments()); + } else if (params->args.action_type == + api::automation_internal::ACTION_TYPE_SUSPENDMEDIA) { + content::MediaSession* session = content::MediaSession::Get(contents); + session->Suspend(content::MediaSession::SuspendType::SYSTEM); + return RespondNow(NoArguments()); + } + RenderFrameHostActionAdapter adapter(rfh); return RouteActionToAdapter(params.get(), &adapter); }
diff --git a/chrome/browser/notifications/notification_platform_bridge_android.cc b/chrome/browser/notifications/notification_platform_bridge_android.cc index 0c8c82f..3f64247 100644 --- a/chrome/browser/notifications/notification_platform_bridge_android.cc +++ b/chrome/browser/notifications/notification_platform_bridge_android.cc
@@ -7,6 +7,7 @@ #include <utility> #include <vector> +#include "base/android/build_info.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/command_line.h" @@ -315,8 +316,30 @@ const std::string& profile_id, bool incognito, std::set<std::string>* notifications) const { - // TODO(miguelg): This can actually be implemented for M+ - return false; + DCHECK(notifications); + JNIEnv* env = AttachCurrentThread(); + + // Android only supports retrieving existing notifications from M+ + if (base::android::BuildInfo::GetInstance()->sdk_int() < + base::android::SDK_VERSION_MARSHMALLOW) { + return false; + } + + const ScopedJavaLocalRef<jstring> j_profile_id = + ConvertUTF8ToJavaString(env, profile_id); + + ScopedJavaLocalRef<jobjectArray> j_notification_ids = + Java_NotificationPlatformBridge_getNotificationsForProfile( + env, java_object_, j_profile_id); + if (j_notification_ids.obj()) { + std::vector<std::string> notification_ids; + base::android::AppendJavaStringArrayToStringVector( + env, j_notification_ids.obj(), ¬ification_ids); + for (const auto& id : notification_ids) { + notifications->insert(id); + } + } + return true; } // static
diff --git a/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc index 0970f35..22c0004 100644 --- a/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc +++ b/chrome/browser/ntp_tiles/chrome_popular_sites_factory.cc
@@ -19,7 +19,7 @@ ChromePopularSitesFactory::NewForProfile(Profile* profile) { base::FilePath directory; // remains empty if PathService::Get() fails. PathService::Get(chrome::DIR_USER_DATA, &directory); - return base::MakeUnique<ntp_tiles::PopularSites>( + return base::MakeUnique<ntp_tiles::PopularSitesImpl>( content::BrowserThread::GetBlockingPool(), profile->GetPrefs(), TemplateURLServiceFactory::GetForProfile(profile), g_browser_process->variations_service(), profile->GetRequestContext(),
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index bfc962a..acfa037 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -564,7 +564,7 @@ #if BUILDFLAG(ANDROID_JAVA_UI) variations::VariationsService::RegisterProfilePrefs(registry); - ntp_tiles::PopularSites::RegisterProfilePrefs(registry); + ntp_tiles::PopularSitesImpl::RegisterProfilePrefs(registry); NewTabPagePrefs::RegisterProfilePrefs(registry); PartnerBookmarksShim::RegisterProfilePrefs(registry); #else
diff --git a/chrome/browser/resources/chromeos/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/chromevox/BUILD.gn index 3b2e28d..c0b4895 100644 --- a/chrome/browser/resources/chromeos/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/chromevox/BUILD.gn
@@ -137,6 +137,7 @@ "cvox2/background/i_search.js", "cvox2/background/keyboard_handler.js", "cvox2/background/live_regions.js", + "cvox2/background/media_automation_handler.js", "cvox2/background/next_earcons.js", "cvox2/background/notifications.js", "cvox2/background/output.js",
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/media_automation_handler.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/media_automation_handler.js new file mode 100644 index 0000000..8a57c06 --- /dev/null +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/media_automation_handler.js
@@ -0,0 +1,48 @@ +// 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. + +/** + * @fileoverview Handles media events automation. + */ + +goog.provide('MediaAutomationHandler'); + +goog.require('BaseAutomationHandler'); + +goog.scope(function() { +var AutomationEvent = chrome.automation.AutomationEvent; +var AutomationNode = chrome.automation.AutomationNode; +var EventType = chrome.automation.EventType; +var RoleType = chrome.automation.RoleType; + +/** + * @param {!AutomationNode} node The root to observe media changes. + * @constructor + * @extends {BaseAutomationHandler} + */ +MediaAutomationHandler = function(node) { + BaseAutomationHandler.call(this, node); + + var e = EventType; + this.addListener_(e.mediaStartedPlaying, this.onMediaStartedPlaying); + this.addListener_(e.mediaStoppedPlaying, this.onMediaStoppedPlaying); +}; + +MediaAutomationHandler.prototype = { + __proto__: BaseAutomationHandler.prototype, + + /** + * @param {!AutomationEvent} evt + */ + onMediaStartedPlaying: function(evt) { + }, + + /** + * @param {!AutomationEvent} evt + */ + onMediaStoppedPlaying: function(evt) { + } +}; + +}); // goog.scope
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm index 5fe826d..5f158f2 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm
@@ -9,6 +9,7 @@ #import "base/mac/sdk_forward_declarations.h" #include "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" +#include "chrome/browser/ui/cocoa/l10n_util.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h" #import "chrome/browser/ui/cocoa/location_bar/location_bar_decoration.h" @@ -46,6 +47,9 @@ resizeAnimation_.reset([[NSViewAnimation alloc] init]); [resizeAnimation_ setDuration:kAnimationDuration]; [resizeAnimation_ setAnimationBlockingMode:NSAnimationNonblocking]; + [self setAlignment:cocoa_l10n_util::ShouldDoExperimentalRTLLayout() + ? NSRightTextAlignment + : NSLeftTextAlignment]; // Disable Force Touch in the Omnibox. Note that this API is defined in // 10.10.3 and higher so have to check more than just isYosmiteOrLater().
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h index 02a40a8..1d3a1030 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
@@ -318,22 +318,6 @@ // Indicates whether or not the location bar is currently visible. bool location_bar_visible_; - // True if the HTTPS state should be displayed on the security state - // decoration. This does not apply to the EV cert. - bool should_show_secure_verbose_; - - // True if the non-secure state should be displayed on the security state - // decoration. - bool should_show_nonsecure_verbose_; - - // True if the security state decoration should be animated for a secure - // security level. - bool should_animate_secure_verbose_; - - // True if the security state decoration should be animated for a non-secure - // security level. - bool should_animate_nonsecure_verbose_; - // True if there's enough room for the omnibox to show the security verbose. // If the verbose is displaying the EV cert, then this should always be true. bool is_width_available_for_security_verbose_;
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm index 5816108..7e0308f 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
@@ -5,7 +5,6 @@ #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" #include "base/bind.h" -#include "base/command_line.h" #import "base/mac/mac_util.h" #include "base/stl_util.h" #include "base/strings/string_util.h" @@ -50,8 +49,6 @@ #include "chrome/browser/ui/content_settings/content_setting_image_model.h" #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/grit/theme_resources.h" #include "components/bookmarks/common/bookmark_pref_names.h" @@ -123,10 +120,6 @@ new ManagePasswordsDecoration(command_updater, this)), browser_(browser), location_bar_visible_(true), - should_show_secure_verbose_(false), - should_show_nonsecure_verbose_(false), - should_animate_secure_verbose_(false), - should_animate_nonsecure_verbose_(false), is_width_available_for_security_verbose_(false), security_level_(security_state::NONE), weak_ptr_factory_(this) { @@ -150,39 +143,6 @@ [[field_ cell] setIsPopupMode: !browser->SupportsWindowFeature(Browser::FEATURE_TABSTRIP)]; - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - std::string security_chip; - if (command_line->HasSwitch(switches::kSecurityChip)) { - security_chip = command_line->GetSwitchValueASCII(switches::kSecurityChip); - } else if (base::FeatureList::IsEnabled(features::kSecurityChip)) { - security_chip = variations::GetVariationParamValueByFeature( - features::kSecurityChip, kSecurityChipFeatureVisibilityParam); - } - - if (security_chip == switches::kSecurityChipShowNonSecureOnly) { - should_show_nonsecure_verbose_ = true; - } else if (security_chip == switches::kSecurityChipShowAll) { - should_show_secure_verbose_ = true; - should_show_nonsecure_verbose_ = true; - } - - std::string security_chip_animation; - if (command_line->HasSwitch(switches::kSecurityChipAnimation)) { - security_chip_animation = - command_line->GetSwitchValueASCII(switches::kSecurityChipAnimation); - } else if (base::FeatureList::IsEnabled(features::kSecurityChip)) { - security_chip_animation = variations::GetVariationParamValueByFeature( - features::kSecurityChip, kSecurityChipFeatureAnimationParam); - } - - if (security_chip_animation == - switches::kSecurityChipAnimationNonSecureOnly) { - should_animate_nonsecure_verbose_ = true; - } else if (security_chip_animation == switches::kSecurityChipAnimationAll) { - should_animate_secure_verbose_ = true; - should_animate_nonsecure_verbose_ = true; - } - // Sets images for the decorations, and performs a layout. This call ensures // that this class is in a consistent state after initialization. OnChanged(); @@ -701,14 +661,10 @@ security_state::SecurityLevel security = GetToolbarModel()->GetSecurityLevel(false); - if (security == security_state::EV_SECURE) - return true; - else if (security == security_state::SECURE) - return should_show_secure_verbose_; - - return should_show_nonsecure_verbose_ && - (security == security_state::DANGEROUS || - security == security_state::HTTP_SHOW_WARNING); + return security == security_state::EV_SECURE || + security == security_state::SECURE || + security == security_state::DANGEROUS || + security == security_state::HTTP_SHOW_WARNING; } bool LocationBarViewMac::IsLocationBarDark() const { @@ -925,15 +881,8 @@ bool LocationBarViewMac::CanAnimateSecurityLevel( security_state::SecurityLevel level) const { - using SecurityLevel = security_state::SecurityLevel; - if (IsSecureConnection(level)) { - return should_animate_secure_verbose_; - } else if (security_level_ == SecurityLevel::DANGEROUS || - security_level_ == SecurityLevel::HTTP_SHOW_WARNING) { - return should_animate_nonsecure_verbose_; - } else { - return false; - } + return security_level_ == security_state::SecurityLevel::DANGEROUS || + security_level_ == security_state::SecurityLevel::HTTP_SHOW_WARNING; } bool LocationBarViewMac::IsSecureConnection(
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h index d90e5d8..18c18df0 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h
@@ -10,6 +10,7 @@ #include <memory> +#include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/strings/string16.h" #include "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h" @@ -133,6 +134,8 @@ AutocompleteTextField* field() const { return field_; } private: + FRIEND_TEST_ALL_PREFIXES(OmniboxViewMacTest, WritingDirectionLTR); + FRIEND_TEST_ALL_PREFIXES(OmniboxViewMacTest, WritingDirectionRTL); // Called when the user hits backspace in |field_|. Checks whether // keyword search is being terminated. Returns true if the // backspace should be intercepted (not forwarded on to the standard
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm index 715d115..cd2b95f 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
@@ -17,7 +17,8 @@ #include "chrome/browser/search/search.h" #include "chrome/browser/themes/theme_service.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" -#include "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell.h" +#import "chrome/browser/ui/cocoa/l10n_util.h" +#import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_cell.h" #import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.h" #include "chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.h" #include "chrome/browser/ui/omnibox/chrome_omnibox_client.h" @@ -530,6 +531,10 @@ [paragraph_style setMaximumLineHeight:line_height]; [paragraph_style setMinimumLineHeight:line_height]; [paragraph_style setLineBreakMode:NSLineBreakByTruncatingTail]; + // Set an explicit alignment so it isn't implied from writing direction. + [paragraph_style setAlignment:cocoa_l10n_util::ShouldDoExperimentalRTLLayout() + ? NSRightTextAlignment + : NSLeftTextAlignment]; // If this is a URL, set the top-level paragraph direction to LTR (avoids RTL // characters from making the URL render from right to left, as per RFC 3987 // Section 4.1).
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm index f3d58416..1038d795 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h" +#include "chrome/browser/ui/cocoa/test/scoped_force_rtl_mac.h" #include "chrome/browser/ui/omnibox/chrome_omnibox_client.h" #include "chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.h" #include "chrome/browser/ui/toolbar/chrome_toolbar_model_delegate.h" @@ -176,3 +177,65 @@ view.OnDoCommandBySelector(@selector(moveUp:)); EXPECT_EQ(-1, model->up_or_down_count()); } + +TEST_F(OmniboxViewMacTest, WritingDirectionLTR) { + TestingToolbarModelDelegate delegate; + ToolbarModelImpl toolbar_model(&delegate, 32 * 1024); + TestingOmniboxEditController edit_controller(&toolbar_model); + OmniboxViewMac view(&edit_controller, profile(), NULL, NULL); + + // This is deleted by the omnibox view. + MockOmniboxEditModel* model = + new MockOmniboxEditModel(&view, &edit_controller, profile()); + MockOmniboxPopupView popup_view; + OmniboxPopupModel popup_model(&popup_view, model); + + model->OnSetFocus(true); + SetModel(&view, model); + view.SetUserText(base::ASCIIToUTF16("foo.com")); + model->OnChanged(); + + base::scoped_nsobject<NSMutableAttributedString> string( + [[NSMutableAttributedString alloc] initWithString:@"foo.com"]); + view.ApplyTextStyle(string); + + NSParagraphStyle* paragraphStyle = + [string attribute:NSParagraphStyleAttributeName + atIndex:0 + effectiveRange:NULL]; + DCHECK(paragraphStyle); + EXPECT_EQ(paragraphStyle.alignment, NSLeftTextAlignment); + EXPECT_EQ(paragraphStyle.baseWritingDirection, NSWritingDirectionLeftToRight); +} + +TEST_F(OmniboxViewMacTest, WritingDirectionRTL) { + cocoa_l10n_util::ScopedForceRTLMac rtl; + + TestingToolbarModelDelegate delegate; + ToolbarModelImpl toolbar_model(&delegate, 32 * 1024); + TestingOmniboxEditController edit_controller(&toolbar_model); + OmniboxViewMac view(&edit_controller, profile(), NULL, NULL); + + // This is deleted by the omnibox view. + MockOmniboxEditModel* model = + new MockOmniboxEditModel(&view, &edit_controller, profile()); + MockOmniboxPopupView popup_view; + OmniboxPopupModel popup_model(&popup_view, model); + + model->OnSetFocus(true); + SetModel(&view, model); + view.SetUserText(base::ASCIIToUTF16("foo.com")); + model->OnChanged(); + + base::scoped_nsobject<NSMutableAttributedString> string( + [[NSMutableAttributedString alloc] initWithString:@"foo.com"]); + view.ApplyTextStyle(string); + + NSParagraphStyle* paragraphStyle = + [string attribute:NSParagraphStyleAttributeName + atIndex:0 + effectiveRange:NULL]; + DCHECK(paragraphStyle); + EXPECT_EQ(paragraphStyle.alignment, NSRightTextAlignment); + EXPECT_EQ(paragraphStyle.baseWritingDirection, NSWritingDirectionLeftToRight); +}
diff --git a/chrome/browser/ui/location_bar/location_bar.cc b/chrome/browser/ui/location_bar/location_bar.cc index efa6c16..81b37242 100644 --- a/chrome/browser/ui/location_bar/location_bar.cc +++ b/chrome/browser/ui/location_bar/location_bar.cc
@@ -11,9 +11,6 @@ #include "extensions/common/feature_switch.h" #include "extensions/common/permissions/permissions_data.h" -const char LocationBar::kSecurityChipFeatureVisibilityParam[] = "visibility"; -const char LocationBar::kSecurityChipFeatureAnimationParam[] = "animation"; - LocationBar::LocationBar(Profile* profile) : profile_(profile) { }
diff --git a/chrome/browser/ui/location_bar/location_bar.h b/chrome/browser/ui/location_bar/location_bar.h index e3e316f..2cdd713 100644 --- a/chrome/browser/ui/location_bar/location_bar.h +++ b/chrome/browser/ui/location_bar/location_bar.h
@@ -32,10 +32,6 @@ // location bar to be mocked for testing. class LocationBar { public: - // The parameters for the Security Chip Feature. - static const char kSecurityChipFeatureVisibilityParam[]; - static const char kSecurityChipFeatureAnimationParam[]; - explicit LocationBar(Profile* profile); // Shows the first run bubble anchored to the location bar.
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index fcd840cb..fea3325 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -7,7 +7,6 @@ #include <algorithm> #include <map> -#include "base/command_line.h" #include "base/i18n/rtl.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" @@ -52,8 +51,6 @@ #include "chrome/browser/ui/views/passwords/manage_passwords_icon_views.h" #include "chrome/browser/ui/views/translate/translate_bubble_view.h" #include "chrome/browser/ui/views/translate/translate_icon_view.h" -#include "chrome/common/chrome_features.h" -#include "chrome/common/chrome_switches.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/bookmarks/common/bookmark_pref_names.h" @@ -140,11 +137,7 @@ is_popup_mode_(is_popup_mode), show_focus_rect_(false), template_url_service_(NULL), - web_contents_null_at_last_refresh_(true), - should_show_secure_state_(false), - should_show_nonsecure_state_(false), - should_animate_secure_state_(false), - should_animate_nonsecure_state_(false) { + web_contents_null_at_last_refresh_(true) { edit_bookmarks_enabled_.Init( bookmarks::prefs::kEditBookmarksEnabled, profile->GetPrefs(), base::Bind(&LocationBarView::UpdateWithoutTabRestore, @@ -152,38 +145,6 @@ zoom::ZoomEventManager::GetForBrowserContext(profile) ->AddZoomEventManagerObserver(this); - - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - std::string security_chip_visibility; - if (command_line->HasSwitch(switches::kSecurityChip)) { - security_chip_visibility = - command_line->GetSwitchValueASCII(switches::kSecurityChip); - } else if (base::FeatureList::IsEnabled(features::kSecurityChip)) { - security_chip_visibility = - variations::GetVariationParamValueByFeature( - features::kSecurityChip, kSecurityChipFeatureVisibilityParam); - } - - should_show_secure_state_ = - security_chip_visibility == switches::kSecurityChipShowAll; - should_show_nonsecure_state_ = - should_show_secure_state_ || - security_chip_visibility == switches::kSecurityChipShowNonSecureOnly; - - std::string security_chip_animation; - if (command_line->HasSwitch(switches::kSecurityChipAnimation)) { - security_chip_animation = - command_line->GetSwitchValueASCII(switches::kSecurityChipAnimation); - } else if (base::FeatureList::IsEnabled(features::kSecurityChip)) { - security_chip_animation = variations::GetVariationParamValueByFeature( - features::kSecurityChip, kSecurityChipFeatureAnimationParam); - } - - should_animate_secure_state_ = - security_chip_animation == switches::kSecurityChipAnimationAll; - should_animate_nonsecure_state_ = - should_animate_secure_state_ || - security_chip_animation == switches::kSecurityChipAnimationNonSecureOnly; } LocationBarView::~LocationBarView() { @@ -933,27 +894,16 @@ bool LocationBarView::ShouldShowSecurityChip() const { using SecurityLevel = security_state::SecurityLevel; const SecurityLevel level = GetToolbarModel()->GetSecurityLevel(false); - if (level == SecurityLevel::EV_SECURE) { - return true; - } else if (level == SecurityLevel::SECURE) { - return should_show_secure_state_; - } else { - return should_show_nonsecure_state_ && - (level == SecurityLevel::DANGEROUS || - level == SecurityLevel::HTTP_SHOW_WARNING); - } + return level == SecurityLevel::EV_SECURE || level == SecurityLevel::SECURE || + level == SecurityLevel::DANGEROUS || + level == SecurityLevel::HTTP_SHOW_WARNING; } bool LocationBarView::ShouldAnimateSecurityChip() const { using SecurityLevel = security_state::SecurityLevel; SecurityLevel level = GetToolbarModel()->GetSecurityLevel(false); - if (!ShouldShowSecurityChip()) - return false; - if (level == SecurityLevel::SECURE || level == SecurityLevel::EV_SECURE) - return should_animate_secure_state_; - return should_animate_nonsecure_state_ && - (level == SecurityLevel::DANGEROUS || - level == SecurityLevel::HTTP_SHOW_WARNING); + return level == SecurityLevel::DANGEROUS || + level == SecurityLevel::HTTP_SHOW_WARNING; } ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index 82fb098..44248e05 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -469,12 +469,6 @@ // during the last RefreshPageAction. bool web_contents_null_at_last_refresh_; - // These allow toggling the verbose security state behavior via flags. - bool should_show_secure_state_; - bool should_show_nonsecure_state_; - bool should_animate_secure_state_; - bool should_animate_nonsecure_state_; - DISALLOW_COPY_AND_ASSIGN(LocationBarView); };
diff --git a/chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.cc b/chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.cc index 7c86a6d..7651e06 100644 --- a/chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.cc +++ b/chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.cc
@@ -61,7 +61,7 @@ // views::ScrollView::GetPreferredSize() includes the contents' size, but // not the scrollbar width. Add it in if necessary. if (container_->GetPreferredSize().height() > max_height_) - s.Enlarge(GetScrollBarWidth(), 0); + s.Enlarge(GetScrollBarLayoutWidth(), 0); return s; }
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index f651fe9..3c6c446 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -194,12 +194,6 @@ const base::Feature kSafeSearchUrlReporting{"SafeSearchUrlReporting", base::FEATURE_DISABLED_BY_DEFAULT}; -#if !defined(OS_ANDROID) && !defined(OS_IOS) -// Sets the visibility and animation of the security chip. -const base::Feature kSecurityChip{"SecurityChip", - base::FEATURE_DISABLED_BY_DEFAULT}; -#endif - // A new user experience for transitioning into fullscreen and mouse pointer // lock states. const base::Feature kSimplifiedFullscreenUI{"ViewsSimplifiedFullscreenUI",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 70be0fe..1a983d3 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -117,10 +117,6 @@ extern const base::Feature kSimplifiedFullscreenUI; -#if !defined(OS_ANDROID) && !defined(OS_IOS) -extern const base::Feature kSecurityChip; -#endif - #if defined(SYZYASAN) extern const base::Feature kSyzyasanDeferredFree; #endif
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index ad2727b5..f68f672a 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -580,16 +580,6 @@ // Makes Chrome default browser const char kMakeDefaultBrowser[] = "make-default-browser"; -extern const char kSecurityChip[] = "security-chip"; -extern const char kSecurityChipShowNonSecureOnly[] = "show-nonsecure-only"; -extern const char kSecurityChipShowAll[] = "show-all"; - -extern const char kSecurityChipAnimation[] = "security-chip-animation"; -extern const char kSecurityChipAnimationNone[] = "none"; -extern const char kSecurityChipAnimationNonSecureOnly[] = - "animate-nonsecure-only"; -extern const char kSecurityChipAnimationAll[] = "animate-all"; - // Forces the maximum disk space to be used by the media cache, in bytes. const char kMediaCacheSize[] = "media-cache-size";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 92df33b..95daaf2 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -172,13 +172,6 @@ extern const char kLoadExtension[]; extern const char kLoadMediaRouterComponentExtension[]; extern const char kMakeDefaultBrowser[]; -extern const char kSecurityChip[]; -extern const char kSecurityChipShowNonSecureOnly[]; -extern const char kSecurityChipShowAll[]; -extern const char kSecurityChipAnimation[]; -extern const char kSecurityChipAnimationNone[]; -extern const char kSecurityChipAnimationNonSecureOnly[]; -extern const char kSecurityChipAnimationAll[]; extern const char kMediaCacheSize[]; extern const char kMetricsRecordingOnly[]; extern const char kMonitoringDestinationID[];
diff --git a/chrome/common/extensions/api/automation.idl b/chrome/common/extensions/api/automation.idl index 0cbb64a6e..f9dc153 100644 --- a/chrome/common/extensions/api/automation.idl +++ b/chrome/common/extensions/api/automation.idl
@@ -33,6 +33,8 @@ liveRegionChanged, loadComplete, locationChanged, + mediaStartedPlaying, + mediaStoppedPlaying, menuEnd, menuListItemSelected, menuListValueChanged,
diff --git a/chrome/common/extensions/api/automation_internal.idl b/chrome/common/extensions/api/automation_internal.idl index 6182ebd..e6b1e8b 100644 --- a/chrome/common/extensions/api/automation_internal.idl +++ b/chrome/common/extensions/api/automation_internal.idl
@@ -33,9 +33,13 @@ doDefault, getImageData, makeVisible, + resumeMedia, setAccessibilityFocus, setSequentialFocusNavigationStartingPoint, setSelection, + startDuckingMedia, + stopDuckingMedia, + suspendMedia, showContextMenu };
diff --git a/chrome/renderer/resources/extensions/automation/automation_node.js b/chrome/renderer/resources/extensions/automation/automation_node.js index 54c308a3..225c0d2 100644 --- a/chrome/renderer/resources/extensions/automation/automation_node.js +++ b/chrome/renderer/resources/extensions/automation/automation_node.js
@@ -377,6 +377,10 @@ this.performAction_('makeVisible'); }, + resumeMedia: function() { + this.performAction_('resumeMedia'); + }, + setSelection: function(startIndex, endIndex) { if (this.role == 'textField' || this.role == 'textBox') { this.performAction_('setSelection', @@ -394,6 +398,18 @@ this.performAction_('showContextMenu'); }, + startDuckingMedia: function() { + this.performAction_('startDuckingMedia'); + }, + + stopDuckingMedia: function() { + this.performAction_('stopDuckingMedia'); + }, + + suspendMedia: function() { + this.performAction_('suspendMedia'); + }, + domQuerySelector: function(selector, callback) { if (!this.rootImpl) callback(); @@ -1072,9 +1088,13 @@ 'getImageData', 'makeVisible', 'matches', + 'resumeMedia', 'setSelection', 'setSequentialFocusNavigationStartingPoint', 'showContextMenu', + 'startDuckingMedia', + 'stopDuckingMedia', + 'suspendMedia', 'addEventListener', 'removeEventListener', 'domQuerySelector',
diff --git a/chrome/renderer/resources/extensions/automation_custom_bindings.js b/chrome/renderer/resources/extensions/automation_custom_bindings.js index 53222ab..15415a9 100644 --- a/chrome/renderer/resources/extensions/automation_custom_bindings.js +++ b/chrome/renderer/resources/extensions/automation_custom_bindings.js
@@ -278,16 +278,20 @@ var id = eventParams.treeID; var targetTree = AutomationRootNode.getOrCreate(id); - // Work around an issue where Chrome sends us 'blur' events on the - // root node when nothing has focus, we need to treat those as focus - // events but otherwise not handle blur events specially. var isFocusEvent = false; if (eventParams.eventType == schema.EventType.focus) { isFocusEvent = true; } else if (eventParams.eventType == schema.EventType.blur) { + // Work around an issue where Chrome sends us 'blur' events on the + // root node when nothing has focus, we need to treat those as focus + // events but otherwise not handle blur events specially. var node = privates(targetTree).impl.get(eventParams.targetID); if (node == node.root) isFocusEvent = true; + } else if (eventParams.eventType == schema.EventType.mediaStartedPlaying || + eventParams.eventType == schema.EventType.mediaStoppedPlaying) { + // These events are global to the tree. + eventParams.targetID = privates(targetTree).impl.id; } // When we get a focus event, ignore the actual event target, and instead
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/notifications/MockNotificationManagerProxy.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/notifications/MockNotificationManagerProxy.java index bd9b9b7..0d774e2 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/notifications/MockNotificationManagerProxy.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/notifications/MockNotificationManagerProxy.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.test.util.browser.notifications; import android.app.Notification; +import android.service.notification.StatusBarNotification; import org.chromium.chrome.browser.notifications.NotificationManagerProxy; @@ -101,6 +102,11 @@ mMutationCount++; } + @Override + public StatusBarNotification[] getActiveNotifications() { + return null; + } + private static String makeKey(int id, @Nullable String tag) { String key = Integer.toString(id); if (tag != null) key += KEY_SEPARATOR + tag;
diff --git a/chromecast/browser/cast_media_blocker_unittest.cc b/chromecast/browser/cast_media_blocker_unittest.cc index 25d8a322..dddb008 100644 --- a/chromecast/browser/cast_media_blocker_unittest.cc +++ b/chromecast/browser/cast_media_blocker_unittest.cc
@@ -38,6 +38,8 @@ MOCK_METHOD1(Resume, void(content::MediaSession::SuspendType)); MOCK_METHOD1(Suspend, void(content::MediaSession::SuspendType)); MOCK_METHOD1(Stop, void(content::MediaSession::SuspendType)); + MOCK_METHOD0(StartDucking, void()); + MOCK_METHOD0(StopDucking, void()); MOCK_METHOD1(DidReceiveAction, void(blink::mojom::MediaSessionAction)); private:
diff --git a/cloud_print/BUILD.gn b/cloud_print/BUILD.gn index 75ed5e0..0ec5a6b 100644 --- a/cloud_print/BUILD.gn +++ b/cloud_print/BUILD.gn
@@ -14,7 +14,12 @@ # When compiling 32-bit, also reference the 64-bit driver for installing on # 64-bit systems. if (target_cpu == "x86" && current_cpu == "x86") { - public_deps += [ "//cloud_print/virtual_driver/win/port_monitor(//build/toolchain/win:x64)" ] + if (is_clang) { + win64 = "//build/toolchain/win:clang_x64" + } else { + win64 = "//build/toolchain/win:x64" + } + public_deps += [ "//cloud_print/virtual_driver/win/port_monitor($win64)" ] } } }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java index afe7a3c3..56a8444 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
@@ -1679,10 +1679,16 @@ assertEquals(expectResponseInfo, callback.mResponseInfo != null); assertEquals(expectError, callback.mError != null); assertEquals(expectError, callback.mOnErrorCalled); - assertEquals(failureType == FailureType.CANCEL_SYNC - || failureType == FailureType.CANCEL_ASYNC - || failureType == FailureType.CANCEL_ASYNC_WITHOUT_PAUSE, - callback.mOnCanceledCalled); + // When failureType is FailureType.CANCEL_ASYNC_WITHOUT_PAUSE and failureStep is + // ResponseStep.ON_READ_COMPLETED, there might be an onSucceeded() task already posted. If + // that's the case, onCanceled() will not be invoked. See crbug.com/657415. + if (!(failureType == FailureType.CANCEL_ASYNC_WITHOUT_PAUSE + && failureStep == ResponseStep.ON_READ_COMPLETED)) { + assertEquals(failureType == FailureType.CANCEL_SYNC + || failureType == FailureType.CANCEL_ASYNC + || failureType == FailureType.CANCEL_ASYNC_WITHOUT_PAUSE, + callback.mOnCanceledCalled); + } } @SmallTest
diff --git a/components/ntp_tiles/most_visited_sites.h b/components/ntp_tiles/most_visited_sites.h index 1b1f9f5..27a98c1 100644 --- a/components/ntp_tiles/most_visited_sites.h +++ b/components/ntp_tiles/most_visited_sites.h
@@ -75,8 +75,6 @@ class MostVisitedSites : public history::TopSitesObserver, public MostVisitedSitesSupervisor::Observer { public: - using PopularSitesVector = std::vector<PopularSites::Site>; - // The observer to be notified when the list of most visited sites changes. class Observer { public:
diff --git a/components/ntp_tiles/popular_sites.cc b/components/ntp_tiles/popular_sites.cc index 1631df98..0917a14a 100644 --- a/components/ntp_tiles/popular_sites.cc +++ b/components/ntp_tiles/popular_sites.cc
@@ -127,7 +127,7 @@ PopularSites::Site::~Site() {} -PopularSites::PopularSites( +PopularSitesImpl::PopularSitesImpl( const scoped_refptr<base::SequencedWorkerPool>& blocking_pool, PrefService* prefs, const TemplateURLService* template_url_service, @@ -148,10 +148,10 @@ is_fallback_(false), weak_ptr_factory_(this) {} -PopularSites::~PopularSites() {} +PopularSitesImpl::~PopularSitesImpl() {} -void PopularSites::StartFetch(bool force_download, - const FinishedCallback& callback) { +void PopularSitesImpl::StartFetch(bool force_download, + const FinishedCallback& callback) { DCHECK(!callback_); callback_ = callback; @@ -163,7 +163,7 @@ base::TimeDelta::FromHours(kPopularSitesRedownloadIntervalHours); const bool download_time_is_future = base::Time::Now() < last_download_time; - pending_url_ = GetURLToUse(); + pending_url_ = GetURLToFetch(); const bool url_changed = pending_url_.spec() != prefs_->GetString(kPopularSitesURLPref); @@ -186,17 +186,26 @@ base::PostTaskAndReplyWithResult( blocking_runner_.get(), FROM_HERE, base::Bind(&base::ReadFileToString, local_path_, file_data_ptr), - base::Bind(&PopularSites::OnReadFileDone, weak_ptr_factory_.GetWeakPtr(), + base::Bind(&PopularSitesImpl::OnReadFileDone, + weak_ptr_factory_.GetWeakPtr(), base::Passed(std::move(file_data)))); } -GURL PopularSites::LastURL() const { +const PopularSites::SitesVector& PopularSitesImpl::sites() const { + return sites_; +} + +GURL PopularSitesImpl::GetLastURLFetched() const { return GURL(prefs_->GetString(kPopularSitesURLPref)); } -GURL PopularSites::GetURLToUse() { - const std::string country = GetCountryToUse(); - const std::string version = GetVersionToUse(); +const base::FilePath& PopularSitesImpl::local_path() const { + return local_path_; +} + +GURL PopularSitesImpl::GetURLToFetch() { + const std::string country = GetCountryToFetch(); + const std::string version = GetVersionToFetch(); const GURL override_url = GURL(prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideURL)); @@ -211,7 +220,7 @@ // "--enable-ntp-search-engine-country-detection" switch is present). // - The country provided by the VariationsService. // - A default fallback. -std::string PopularSites::GetCountryToUse() { +std::string PopularSitesImpl::GetCountryToFetch() { std::string country_code = prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideCountry); @@ -239,7 +248,7 @@ // - The explicit "override version" pref set by the user. // - The version from the field trial config (variation parameter). // - A default fallback. -std::string PopularSites::GetVersionToUse() { +std::string PopularSitesImpl::GetVersionToFetch() { std::string version = prefs_->GetString(ntp_tiles::prefs::kPopularSitesOverrideVersion); @@ -253,7 +262,7 @@ } // static -void PopularSites::RegisterProfilePrefs( +void PopularSitesImpl::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* user_prefs) { user_prefs->RegisterStringPref(ntp_tiles::prefs::kPopularSitesOverrideURL, std::string()); @@ -266,8 +275,8 @@ user_prefs->RegisterStringPref(kPopularSitesURLPref, std::string()); } -void PopularSites::OnReadFileDone(std::unique_ptr<std::string> data, - bool success) { +void PopularSitesImpl::OnReadFileDone(std::unique_ptr<std::string> data, + bool success) { if (success) { auto json = base::JSONReader::Read(*data, base::JSON_ALLOW_TRAILING_COMMAS); if (json) { @@ -281,7 +290,7 @@ } } -void PopularSites::FetchPopularSites() { +void PopularSitesImpl::FetchPopularSites() { fetcher_ = URLFetcher::Create(pending_url_, URLFetcher::GET, this); data_use_measurement::DataUseUserData::AttachToFetcher( fetcher_.get(), data_use_measurement::DataUseUserData::NTP_TILES); @@ -292,7 +301,7 @@ fetcher_->Start(); } -void PopularSites::OnURLFetchComplete(const net::URLFetcher* source) { +void PopularSitesImpl::OnURLFetchComplete(const net::URLFetcher* source) { DCHECK_EQ(fetcher_.get(), source); std::unique_ptr<net::URLFetcher> free_fetcher = std::move(fetcher_); @@ -304,29 +313,29 @@ return; } - parse_json_.Run( - json_string, - base::Bind(&PopularSites::OnJsonParsed, weak_ptr_factory_.GetWeakPtr()), - base::Bind(&PopularSites::OnJsonParseFailed, - weak_ptr_factory_.GetWeakPtr())); + parse_json_.Run(json_string, base::Bind(&PopularSitesImpl::OnJsonParsed, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&PopularSitesImpl::OnJsonParseFailed, + weak_ptr_factory_.GetWeakPtr())); } -void PopularSites::OnJsonParsed(std::unique_ptr<base::Value> json) { +void PopularSitesImpl::OnJsonParsed(std::unique_ptr<base::Value> json) { const base::Value* json_ptr = json.get(); base::PostTaskAndReplyWithResult( blocking_runner_.get(), FROM_HERE, base::Bind(&WriteJsonToFile, local_path_, json_ptr), - base::Bind(&PopularSites::OnFileWriteDone, weak_ptr_factory_.GetWeakPtr(), + base::Bind(&PopularSitesImpl::OnFileWriteDone, + weak_ptr_factory_.GetWeakPtr(), base::Passed(std::move(json)))); } -void PopularSites::OnJsonParseFailed(const std::string& error_message) { +void PopularSitesImpl::OnJsonParseFailed(const std::string& error_message) { DLOG(WARNING) << "JSON parsing failed: " << error_message; OnDownloadFailed(); } -void PopularSites::OnFileWriteDone(std::unique_ptr<base::Value> json, - bool success) { +void PopularSitesImpl::OnFileWriteDone(std::unique_ptr<base::Value> json, + bool success) { if (success) { prefs_->SetInt64(kPopularSitesLastDownloadPref, base::Time::Now().ToInternalValue()); @@ -339,7 +348,7 @@ } } -void PopularSites::ParseSiteList(std::unique_ptr<base::Value> json) { +void PopularSitesImpl::ParseSiteList(std::unique_ptr<base::Value> json) { base::ListValue* list = nullptr; if (!json || !json->GetAsList(&list)) { DLOG(WARNING) << "JSON is not a list"; @@ -348,7 +357,7 @@ return; } - std::vector<PopularSites::Site> sites; + SitesVector sites; for (size_t i = 0; i < list->GetSize(); i++) { base::DictionaryValue* item; if (!list->GetDictionary(i, &item)) @@ -364,16 +373,16 @@ std::string large_icon_url; item->GetString("large_icon_url", &large_icon_url); - sites.push_back(PopularSites::Site(title, GURL(url), GURL(favicon_url), - GURL(large_icon_url), - GURL(thumbnail_url))); + sites.push_back(PopularSitesImpl::Site(title, GURL(url), GURL(favicon_url), + GURL(large_icon_url), + GURL(thumbnail_url))); } sites_.swap(sites); callback_.Run(true); } -void PopularSites::OnDownloadFailed() { +void PopularSitesImpl::OnDownloadFailed() { if (!is_fallback_) { DLOG(WARNING) << "Download country site list failed"; is_fallback_ = true;
diff --git a/components/ntp_tiles/popular_sites.h b/components/ntp_tiles/popular_sites.h index d7679fda..104ae63 100644 --- a/components/ntp_tiles/popular_sites.h +++ b/components/ntp_tiles/popular_sites.h
@@ -43,10 +43,9 @@ const base::Callback<void(std::unique_ptr<base::Value>)>& success_callback, const base::Callback<void(const std::string&)>& error_callback)>; -// Downloads and provides a list of suggested popular sites, for display on -// the NTP when there are not enough personalized tiles. Caches the downloaded -// file on disk to avoid re-downloading on every startup. -class PopularSites : public net::URLFetcherDelegate { +// Interface to provide a list of suggested popular sites, for display on the +// NTP when there are not enough personalized tiles. +class PopularSites { public: struct Site { Site(const base::string16& title, @@ -64,15 +63,10 @@ GURL thumbnail_url; }; + using SitesVector = std::vector<Site>; using FinishedCallback = base::Callback<void(bool /* success */)>; - PopularSites(const scoped_refptr<base::SequencedWorkerPool>& blocking_pool, - PrefService* prefs, - const TemplateURLService* template_url_service, - variations::VariationsService* variations_service, - net::URLRequestContextGetter* download_context, - const base::FilePath& directory, - ParseJSONCallback parse_json); + virtual ~PopularSites() = default; // Starts the process of retrieving popular sites. When they are available, // invokes |callback| with the result, on the same thread as the caller. Never @@ -83,21 +77,45 @@ // if it already exists on disk. // // Must be called at most once on a given PopularSites object. - void StartFetch(bool force_download, const FinishedCallback& callback); + // TODO(mastiz): Remove this restriction? + virtual void StartFetch(bool force_download, + const FinishedCallback& callback) = 0; - ~PopularSites() override; + // Returns the list of available sites. + virtual const SitesVector& sites() const = 0; - const std::vector<Site>& sites() const { return sites_; } + // Various internals exposed publicly for diagnostic pages only. + virtual GURL GetLastURLFetched() const = 0; + virtual const base::FilePath& local_path() const = 0; + virtual GURL GetURLToFetch() = 0; + virtual std::string GetCountryToFetch() = 0; + virtual std::string GetVersionToFetch() = 0; +}; - // The URL of the file that was last downloaded. - GURL LastURL() const; +// Actual (non-test) implementation of the PopularSites interface. Caches the +// downloaded file on disk to avoid re-downloading on every startup. +class PopularSitesImpl : public PopularSites, public net::URLFetcherDelegate { + public: + PopularSitesImpl( + const scoped_refptr<base::SequencedWorkerPool>& blocking_pool, + PrefService* prefs, + const TemplateURLService* template_url_service, + variations::VariationsService* variations_service, + net::URLRequestContextGetter* download_context, + const base::FilePath& directory, + ParseJSONCallback parse_json); - const base::FilePath& local_path() const { return local_path_; } + ~PopularSitesImpl() override; - // Public for diagnostic pages only. - GURL GetURLToUse(); - std::string GetCountryToUse(); - std::string GetVersionToUse(); + // PopularSites implementation. + void StartFetch(bool force_download, + const FinishedCallback& callback) override; + const SitesVector& sites() const override; + GURL GetLastURLFetched() const override; + const base::FilePath& local_path() const override; + GURL GetURLToFetch() override; + std::string GetCountryToFetch() override; + std::string GetVersionToFetch() override; // Register preferences used by this class. static void RegisterProfilePrefs( @@ -133,12 +151,12 @@ std::unique_ptr<net::URLFetcher> fetcher_; bool is_fallback_; - std::vector<Site> sites_; + SitesVector sites_; GURL pending_url_; - base::WeakPtrFactory<PopularSites> weak_ptr_factory_; + base::WeakPtrFactory<PopularSitesImpl> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(PopularSites); + DISALLOW_COPY_AND_ASSIGN(PopularSitesImpl); }; } // namespace ntp_tiles
diff --git a/components/ntp_tiles/popular_sites_unittest.cc b/components/ntp_tiles/popular_sites_unittest.cc index 929e68a6..cf2b0d0 100644 --- a/components/ntp_tiles/popular_sites_unittest.cc +++ b/components/ntp_tiles/popular_sites_unittest.cc
@@ -68,7 +68,7 @@ }, worker_pool_owner_(2, "PopularSitesTest."), url_fetcher_factory_(nullptr) { - PopularSites::RegisterProfilePrefs(prefs_.registry()); + PopularSitesImpl::RegisterProfilePrefs(prefs_.registry()); CHECK(scoped_cache_dir_.CreateUniqueTempDir()); cache_dir_ = scoped_cache_dir_.GetPath(); } @@ -106,15 +106,15 @@ } bool FetchPopularSites(bool force_download, - std::vector<PopularSites::Site>* sites) { + PopularSites::SitesVector* sites) { scoped_refptr<net::TestURLRequestContextGetter> url_request_context( new net::TestURLRequestContextGetter( base::ThreadTaskRunnerHandle::Get())); - PopularSites popular_sites(worker_pool_owner_.pool().get(), &prefs_, - /*template_url_service=*/nullptr, - /*variations_service=*/nullptr, - url_request_context.get(), cache_dir_, - base::Bind(JsonUnsafeParser::Parse)); + PopularSitesImpl popular_sites(worker_pool_owner_.pool().get(), &prefs_, + /*template_url_service=*/nullptr, + /*variations_service=*/nullptr, + url_request_context.get(), cache_dir_, + base::Bind(JsonUnsafeParser::Parse)); base::RunLoop loop; bool save_success = false; @@ -149,7 +149,7 @@ "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", {kWikipedia}); - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; EXPECT_TRUE(FetchPopularSites(/*force_download=*/false, &sites)); ASSERT_THAT(sites.size(), Eq(1u)); @@ -168,7 +168,7 @@ "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json", {kYouTube, kChromium}); - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; EXPECT_TRUE(FetchPopularSites(/*force_download=*/false, &sites)); ASSERT_THAT(sites.size(), Eq(2u)); @@ -191,14 +191,14 @@ RespondWith404( "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json"); - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; EXPECT_FALSE(FetchPopularSites(/*force_download=*/false, &sites)); ASSERT_THAT(sites, IsEmpty()); } TEST_F(PopularSitesTest, FailsWithoutFetchIfNoCacheDir) { SetCountryAndVersion("ZZ", "9"); - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; cache_dir_ = base::FilePath(); // Override with invalid file path. EXPECT_FALSE(FetchPopularSites(/*force_download=*/false, &sites)); } @@ -210,7 +210,7 @@ {kWikipedia}); // First request succeeds and gets cached. - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; EXPECT_TRUE(FetchPopularSites(/*force_download=*/false, &sites)); // File disappears from server, but we don't need it because it's cached. @@ -229,7 +229,7 @@ {kWikipedia}); // First request succeeds and caches empty suggestions list (no fallback). - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; EXPECT_TRUE(FetchPopularSites(/*force_download=*/false, &sites)); EXPECT_THAT(sites, IsEmpty()); @@ -248,7 +248,7 @@ {kWikipedia}); // First request succeeds and gets cached. - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; EXPECT_TRUE(FetchPopularSites(/*force_download=*/true, &sites)); EXPECT_THAT(sites[0].url, URLEq("https://zz.m.wikipedia.org/")); @@ -268,7 +268,7 @@ "https://www.gstatic.com/chrome/ntp/suggested_sites_ZX_9.json", {kChromium}); - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; // First request (in ZZ) saves Wikipedia. SetCountryAndVersion("ZZ", "9"); @@ -290,7 +290,7 @@ "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json"); // First request falls back and gets nothing there either. - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; EXPECT_FALSE(FetchPopularSites(/*force_download=*/false, &sites)); // Second request refetches ZZ_9, which now has data. @@ -311,7 +311,7 @@ {kWikipedia}); // First request falls back. - std::vector<PopularSites::Site> sites; + PopularSites::SitesVector sites; EXPECT_TRUE(FetchPopularSites(/*force_download=*/false, &sites)); ASSERT_THAT(sites.size(), Eq(1u)); EXPECT_THAT(sites[0].url, URLEq("https://zz.m.wikipedia.org/"));
diff --git a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc index d10a6c05..4dce944 100644 --- a/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc +++ b/components/ntp_tiles/webui/ntp_tiles_internals_message_handler.cc
@@ -110,9 +110,9 @@ if (client_->DoesSourceExist(NTPTileSource::POPULAR)) { auto popular_sites = client_->MakePopularSites(); - value.SetString("popular.url", popular_sites->GetURLToUse().spec()); - value.SetString("popular.country", popular_sites->GetCountryToUse()); - value.SetString("popular.version", popular_sites->GetVersionToUse()); + value.SetString("popular.url", popular_sites->GetURLToFetch().spec()); + value.SetString("popular.country", popular_sites->GetCountryToFetch()); + value.SetString("popular.version", popular_sites->GetVersionToFetch()); value.SetString( "popular.overrideURL",
diff --git a/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc b/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc index 50f2252..ce02145 100644 --- a/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc +++ b/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc
@@ -152,7 +152,7 @@ base::DictionaryValue result; result.Set("sites", std::move(sites_list)); - result.SetString("url", popular_sites_->LastURL().spec()); + result.SetString("url", popular_sites_->GetLastURLFetched().spec()); web_ui_->CallJavascriptFunction("chrome.popular_sites_internals.receiveSites", result); }
diff --git a/components/previews/core/previews_black_list.h b/components/previews/core/previews_black_list.h index e9151da..6abac75 100644 --- a/components/previews/core/previews_black_list.h +++ b/components/previews/core/previews_black_list.h
@@ -49,7 +49,9 @@ NETWORK_QUALITY_UNAVAILABLE = 6, // The network was fast enough to not warrant previews. NETWORK_NOT_SLOW = 7, - LAST = 8, + // If the page was reloaded, the user should not be shown an offline preview. + RELOAD_DISALLOWED_FOR_OFFLINE = 8, + LAST = 9, }; // Manages the state of black listed domains for the previews experiment. Loads
diff --git a/components/previews/core/previews_io_data.cc b/components/previews/core/previews_io_data.cc index ed9f784d..82d17b2 100644 --- a/components/previews/core/previews_io_data.cc +++ b/components/previews/core/previews_io_data.cc
@@ -15,6 +15,7 @@ #include "components/previews/core/previews_black_list.h" #include "components/previews/core/previews_opt_out_store.h" #include "components/previews/core/previews_ui_service.h" +#include "net/base/load_flags.h" #include "net/nqe/network_quality_estimator.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" @@ -117,6 +118,15 @@ type); return false; } + // LOAD_VALIDATE_CACHE or LOAD_BYPASS_CACHE mean the user reloaded the page. + // If this is a query for offline previews, reloads should be disallowed. + if (type == PreviewsType::OFFLINE && + request.load_flags() & + (net::LOAD_VALIDATE_CACHE | net::LOAD_BYPASS_CACHE)) { + LogPreviewsEligibilityReason( + PreviewsEligibilityReason::RELOAD_DISALLOWED_FOR_OFFLINE, type); + return false; + } LogPreviewsEligibilityReason(PreviewsEligibilityReason::ALLOWED, type); return true; }
diff --git a/components/previews/core/previews_io_data_unittest.cc b/components/previews/core/previews_io_data_unittest.cc index cb8d3aa..39a8925e 100644 --- a/components/previews/core/previews_io_data_unittest.cc +++ b/components/previews/core/previews_io_data_unittest.cc
@@ -25,6 +25,7 @@ #include "components/previews/core/previews_opt_out_store.h" #include "components/previews/core/previews_ui_service.h" #include "components/variations/variations_associated_data.h" +#include "net/base/load_flags.h" #include "net/nqe/effective_connection_type.h" #include "net/nqe/network_quality_estimator_test_util.h" #include "net/url_request/url_request.h" @@ -212,12 +213,21 @@ network_quality_estimator.set_effective_connection_type( net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G); + request->SetLoadFlags(net::LOAD_BYPASS_CACHE); + EXPECT_FALSE(io_data()->ShouldAllowPreview(*request, PreviewsType::OFFLINE)); + histogram_tester.ExpectBucketCount( + "Previews.EligibilityReason.Offline", + static_cast<int>( + PreviewsEligibilityReason::RELOAD_DISALLOWED_FOR_OFFLINE), + 1); + + request->SetLoadFlags(0); EXPECT_TRUE(io_data()->ShouldAllowPreview(*request, PreviewsType::OFFLINE)); histogram_tester.ExpectBucketCount( "Previews.EligibilityReason.Offline", static_cast<int>(PreviewsEligibilityReason::ALLOWED), 1); - histogram_tester.ExpectTotalCount("Previews.EligibilityReason.Offline", 6); + histogram_tester.ExpectTotalCount("Previews.EligibilityReason.Offline", 7); variations::testing::ClearAllVariationParams(); }
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc index e7b47a5..b04c52a 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
@@ -5,6 +5,7 @@ #include "components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h" #include "base/metrics/histogram_macros.h" +#include "base/rand_util.h" #include "components/subresource_filter/content/browser/content_subresource_filter_driver.h" #include "components/subresource_filter/content/common/subresource_filter_messages.h" #include "components/subresource_filter/core/browser/subresource_filter_client.h" @@ -24,6 +25,10 @@ return url.host() + url.path(); } +bool ShouldMeasurePerformance(double rate) { + return base::RandDouble() < rate; +} + } // namespace // static @@ -54,7 +59,8 @@ std::unique_ptr<SubresourceFilterClient> client) : content::WebContentsObserver(web_contents), client_(std::move(client)), - activation_state_(ActivationState::DISABLED) { + activation_state_(ActivationState::DISABLED), + measure_performance_(false) { content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame(); if (main_frame_host && main_frame_host->IsRenderFrameLive()) CreateDriverForFrameHostIfNeeded(main_frame_host); @@ -122,14 +128,10 @@ content::RenderFrameHost* render_frame_host, const GURL& url) { if (activation_state_ != ActivationState::DISABLED) { - // TODO(pkalinnikov): Introduce a variation parameter controlling how often - // the |measure_performance| bit is set. crbug/672519 - constexpr bool measure_performance = true; - auto* driver = DriverFromFrameHost(render_frame_host); DCHECK(driver); driver->ActivateForProvisionalLoad(GetMaximumActivationState(), url, - measure_performance); + measure_performance_); } } @@ -164,6 +166,7 @@ client_->ToggleNotificationVisibility(false); activation_state_ = ActivationState::DISABLED; + measure_performance_ = false; } } @@ -209,9 +212,12 @@ RecordRedirectChainMatchPattern(); if (ShouldActivateForMainFrameURL(url)) { activation_state_ = GetMaximumActivationState(); + measure_performance_ = + ShouldMeasurePerformance(GetPerformanceMeasurementRate()); ActivateForFrameHostIfNeeded(render_frame_host, url); } else { activation_state_ = ActivationState::DISABLED; + measure_performance_ = false; } } else { ActivateForFrameHostIfNeeded(render_frame_host, url);
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h index 6bfd8941..3611723 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h +++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h
@@ -145,6 +145,7 @@ HostPathSet whitelisted_hosts_; ActivationState activation_state_; + bool measure_performance_; // The URLs in the navigation chain. std::vector<GURL> navigation_chain_;
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc index c2b2410..a746256 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc
@@ -234,7 +234,8 @@ rfh_tester->SimulateRedirect(url); } EXPECT_CALL(*driver(), - ActivateForProvisionalLoad(::testing::_, ::testing::_, true)) + ActivateForProvisionalLoad(::testing::_, ::testing::_, + expected_measure_performance())) .Times(expected_activation); if (!content::IsBrowserSideNavigationEnabled()) { factory()->ReadyToCommitNavigationInternal(main_rfh(), @@ -261,7 +262,8 @@ void NavigateAndCommitSubframe(const GURL& url, bool expected_activation) { EXPECT_CALL(*subframe_driver(), - ActivateForProvisionalLoad(::testing::_, ::testing::_, true)) + ActivateForProvisionalLoad(::testing::_, ::testing::_, + expected_measure_performance())) .Times(expected_activation); EXPECT_CALL(*client(), ToggleNotificationVisibility(::testing::_)).Times(0); @@ -298,7 +300,7 @@ void EmulateInPageNavigation(const std::vector<bool>& blacklisted_urls, RedirectChainMatchPattern extected_pattern, bool expected_activation) { - // This test-case examinse the nevigation woth following sequence of event: + // This test examines the navigation with the following sequence of events: // DidStartProvisional(main, "example.com") // ReadyToCommitNavigation(“example.com”) // DidCommitProvisional(main, "example.com") @@ -319,6 +321,13 @@ } private: + static bool expected_measure_performance() { + const double rate = GetPerformanceMeasurementRate(); + // Note: The case when 0 < rate < 1 is not deterministic, don't test it. + EXPECT_TRUE(rate == 0 || rate == 1); + return rate == 1; + } + // Owned by the factory. MockSubresourceFilterClient* client_; MockSubresourceFilterDriver* driver_; @@ -413,6 +422,18 @@ true /* expected_activation */); } +TEST_F(ContentSubresourceFilterDriverFactoryTest, + SpecialCaseNavigationActivationListEnabledWithPerformanceMeasurement) { + base::FieldTrialList field_trial_list(nullptr); + testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle( + base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationStateEnabled, + kActivationScopeActivationList, + kActivationListSocialEngineeringAdsInterstitial, + "1" /* performance_measurement_rate */); + EmulateInPageNavigation({true}, NO_REDIRECTS_HIT, + true /* expected_activation */); +} + TEST_F(ContentSubresourceFilterDriverFactoryTest, RedirectPatternTest) { base::FieldTrialList field_trial_list(nullptr); testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle(
diff --git a/components/subresource_filter/core/browser/subresource_filter_features.cc b/components/subresource_filter/core/browser/subresource_filter_features.cc index e85213c3..9ac0acf 100644 --- a/components/subresource_filter/core/browser/subresource_filter_features.cc +++ b/components/subresource_filter/core/browser/subresource_filter_features.cc
@@ -6,6 +6,7 @@ #include <string> +#include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "components/variations/variations_associated_data.h" @@ -30,6 +31,9 @@ "social_engineering_ads_interstitial"; const char kActivationListPhishingInterstitial[] = "phishing_interstitial"; +const char kPerformanceMeasurementRateParameterName[] = + "performance_measurement_rate"; + ActivationState GetMaximumActivationState() { std::string activation_state = variations::GetVariationParamValueByFeature( kSafeBrowsingSubresourceFilter, kActivationStateParameterName); @@ -70,4 +74,13 @@ return activation_list_type; } +double GetPerformanceMeasurementRate() { + const std::string rate = variations::GetVariationParamValueByFeature( + kSafeBrowsingSubresourceFilter, kPerformanceMeasurementRateParameterName); + double value = 0; + if (!base::StringToDouble(rate, &value) || value < 0) + return 0; + return value < 1 ? value : 1; +} + } // namespace subresource_filter
diff --git a/components/subresource_filter/core/browser/subresource_filter_features.h b/components/subresource_filter/core/browser/subresource_filter_features.h index b19b2dc1..11f54ff 100644 --- a/components/subresource_filter/core/browser/subresource_filter_features.h +++ b/components/subresource_filter/core/browser/subresource_filter_features.h
@@ -30,6 +30,8 @@ extern const char kActivationListSocialEngineeringAdsInterstitial[]; extern const char kActivationListPhishingInterstitial[]; +extern const char kPerformanceMeasurementRateParameterName[]; + // Returns the maximum degree to which subresource filtering should be activated // on any RenderFrame. This will be ActivationState::DISABLED unless the feature // is enabled and variation parameters prescribe a higher activation state. @@ -46,6 +48,11 @@ // variation param is empty, returns most conservative ActivationList::NONE. ActivationList GetCurrentActivationList(); +// Returns a number in the range [0, 1], indicating the fraction of page loads +// that should have extended performance measurements enabled. The rate will be +// 0 unless a greater frequency is specified by variation parameters. +double GetPerformanceMeasurementRate(); + } // namespace subresource_filter #endif // COMPONENTS_SUBRESOURCE_FILTER_SUBRESOURCE_FILTER_FEATURES_H_
diff --git a/components/subresource_filter/core/browser/subresource_filter_features_test_support.cc b/components/subresource_filter/core/browser/subresource_filter_features_test_support.cc index 5396c01..78d2c48 100644 --- a/components/subresource_filter/core/browser/subresource_filter_features_test_support.cc +++ b/components/subresource_filter/core/browser/subresource_filter_features_test_support.cc
@@ -23,23 +23,22 @@ ScopedSubresourceFilterFeatureToggle::ScopedSubresourceFilterFeatureToggle( base::FeatureList::OverrideState feature_state, const std::string& maximum_activation_state, - const std::string& activation_scope) - : ScopedSubresourceFilterFeatureToggle(feature_state, - maximum_activation_state, - activation_scope, - std::string()) {} + const std::string& activation_scope, + const std::string& activation_lists, + const std::string& performance_measurement_rate) + : ScopedSubresourceFilterFeatureToggle( + feature_state, + {{kActivationStateParameterName, maximum_activation_state}, + {kActivationScopeParameterName, activation_scope}, + {kActivationListsParameterName, activation_lists}, + {kPerformanceMeasurementRateParameterName, + performance_measurement_rate}}) {} ScopedSubresourceFilterFeatureToggle::ScopedSubresourceFilterFeatureToggle( base::FeatureList::OverrideState feature_state, - const std::string& maximum_activation_state, - const std::string& activation_scope, - const std::string& activation_lists) { + std::map<std::string, std::string> variation_params) { variations::testing::ClearAllVariationParams(); - std::map<std::string, std::string> variation_params; - variation_params[kActivationStateParameterName] = maximum_activation_state; - variation_params[kActivationScopeParameterName] = activation_scope; - variation_params[kActivationListsParameterName] = activation_lists; EXPECT_TRUE(variations::AssociateVariationParams( kTestFieldTrialName, kTestExperimentGroupName, variation_params));
diff --git a/components/subresource_filter/core/browser/subresource_filter_features_test_support.h b/components/subresource_filter/core/browser/subresource_filter_features_test_support.h index f2065e9..6fe38513 100644 --- a/components/subresource_filter/core/browser/subresource_filter_features_test_support.h +++ b/components/subresource_filter/core/browser/subresource_filter_features_test_support.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_FEATURES_TEST_SUPPORT_H_ #define COMPONENTS_SUBRESOURCE_FILTER_CORE_BROWSER_SUBRESOURCE_FILTER_FEATURES_TEST_SUPPORT_H_ +#include <map> #include <string> #include "base/feature_list.h" @@ -14,21 +15,21 @@ namespace subresource_filter { namespace testing { -// Helper to override the state of the |kSafeBrowsingSubresourceFilter| feature -// and the maximum activation state during tests. Expects a pre-existing global -// base::FieldTrialList singleton. +// Helper to override the state of the |kSafeBrowsingSubresourceFilter| feature, +// and its variation parameters, e.g., maximum activation state and activation +// scope. Expects a pre-existing global base::FieldTrialList singleton. class ScopedSubresourceFilterFeatureToggle { public: ScopedSubresourceFilterFeatureToggle( base::FeatureList::OverrideState feature_state, const std::string& maximum_activation_state, - const std::string& activation_scope); + const std::string& activation_scope, + const std::string& activation_lists = std::string(), + const std::string& performance_measurement_rate = std::string()); ScopedSubresourceFilterFeatureToggle( base::FeatureList::OverrideState feature_state, - const std::string& maximum_activation_state, - const std::string& activation_scope, - const std::string& activation_lists); + std::map<std::string, std::string> variation_params); ~ScopedSubresourceFilterFeatureToggle();
diff --git a/components/subresource_filter/core/browser/subresource_filter_features_unittest.cc b/components/subresource_filter/core/browser/subresource_filter_features_unittest.cc index 51a3d58..d2ab51d 100644 --- a/components/subresource_filter/core/browser/subresource_filter_features_unittest.cc +++ b/components/subresource_filter/core/browser/subresource_filter_features_unittest.cc
@@ -183,4 +183,40 @@ } } +TEST(SubresourceFilterFeaturesTest, PerfMeasurementRate) { + const struct { + bool feature_enabled; + const char* perf_measurement_param; + double expected_perf_measurement_rate; + } kTestCases[] = {{false, "not_a_number", 0}, + {false, "0", 0}, + {false, "1", 0}, + {true, "not_a_number", 0}, + {true, "0.5not_a_number", 0}, + {true, "0", 0}, + {true, "0.000", 0}, + {true, "0.05", 0.05}, + {true, "0.5", 0.5}, + {true, "1", 1}, + {true, "1.0", 1}, + {true, "0.333", 0.333}, + {true, "1e0", 1}}; + + for (const auto& test_case : kTestCases) { + SCOPED_TRACE(::testing::Message("Enabled = ") << test_case.feature_enabled); + SCOPED_TRACE(::testing::Message("PerfMeasurementParam = \"") + << test_case.perf_measurement_param << "\""); + + base::FieldTrialList field_trial_list(nullptr /* entropy_provider */); + testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle( + test_case.feature_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE + : base::FeatureList::OVERRIDE_USE_DEFAULT, + {{kPerformanceMeasurementRateParameterName, + test_case.perf_measurement_param}}); + + EXPECT_EQ(test_case.expected_perf_measurement_rate, + GetPerformanceMeasurementRate()); + } +} + } // namespace subresource_filter
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index d3294588a..827e7ad 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -184,8 +184,6 @@ "$target_gen_dir/devtools/protocol/schema.h", "$target_gen_dir/devtools/protocol/security.cc", "$target_gen_dir/devtools/protocol/security.h", - "$target_gen_dir/devtools/protocol/storage.cc", - "$target_gen_dir/devtools/protocol/storage.h", "$target_gen_dir/devtools/protocol/system_info.cc", "$target_gen_dir/devtools/protocol/system_info.h", "$target_gen_dir/devtools/protocol/tethering.cc", @@ -197,8 +195,6 @@ "../zygote/zygote_linux.cc", "../zygote/zygote_linux.h", "../zygote/zygote_main_linux.cc", - "accessibility/accessibility_mode_helper.cc", - "accessibility/accessibility_mode_helper.h", "accessibility/accessibility_tree_formatter.cc", "accessibility/accessibility_tree_formatter.h", "accessibility/accessibility_tree_formatter_blink.cc",
diff --git a/content/browser/accessibility/accessibility_action_browsertest.cc b/content/browser/accessibility/accessibility_action_browsertest.cc index 3dc80e8..70a7f4f 100644 --- a/content/browser/accessibility/accessibility_action_browsertest.cc +++ b/content/browser/accessibility/accessibility_action_browsertest.cc
@@ -79,7 +79,7 @@ NavigateToURL(shell(), GURL(url::kAboutBlankURL)); AccessibilityNotificationWaiter waiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); GURL url("data:text/html," "<button>One</button>" @@ -92,7 +92,7 @@ ASSERT_NE(nullptr, target); AccessibilityNotificationWaiter waiter2(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_FOCUS); GetManager()->SetFocus(*target); waiter2.WaitForNotification(); @@ -106,7 +106,7 @@ NavigateToURL(shell(), GURL(url::kAboutBlankURL)); AccessibilityNotificationWaiter waiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); GURL url("data:text/html," "<input type=range min=2 value=8 max=10 step=2>"); @@ -120,7 +120,7 @@ // Increment, should result in value changing from 8 to 10. { AccessibilityNotificationWaiter waiter2(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_VALUE_CHANGED); GetManager()->Increment(*target); waiter2.WaitForNotification(); @@ -130,7 +130,7 @@ // Increment, should result in value staying the same (max). { AccessibilityNotificationWaiter waiter2(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_VALUE_CHANGED); GetManager()->Increment(*target); waiter2.WaitForNotification(); @@ -140,7 +140,7 @@ // Decrement, should result in value changing from 10 to 8. { AccessibilityNotificationWaiter waiter2(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_VALUE_CHANGED); GetManager()->Decrement(*target); waiter2.WaitForNotification(); @@ -152,7 +152,7 @@ NavigateToURL(shell(), GURL(url::kAboutBlankURL)); AccessibilityNotificationWaiter waiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); GURL url("data:text/html," "<body>" @@ -179,7 +179,7 @@ ASSERT_NE(nullptr, target); AccessibilityNotificationWaiter waiter2(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_IMAGE_FRAME_UPDATED); GetManager()->GetImageData(*target, gfx::Size()); waiter2.WaitForNotification(); @@ -202,7 +202,7 @@ NavigateToURL(shell(), GURL(url::kAboutBlankURL)); AccessibilityNotificationWaiter waiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); GURL url("data:text/html," "<body>" @@ -223,7 +223,7 @@ ASSERT_NE(nullptr, target); AccessibilityNotificationWaiter waiter2(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_IMAGE_FRAME_UPDATED); GetManager()->GetImageData(*target, gfx::Size(4, 4)); waiter2.WaitForNotification(); @@ -246,7 +246,7 @@ NavigateToURL(shell(), GURL(url::kAboutBlankURL)); AccessibilityNotificationWaiter waiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); GURL url("data:text/html," "<body>" @@ -261,7 +261,7 @@ ASSERT_NE(nullptr, target); AccessibilityNotificationWaiter waiter2(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_IMAGE_FRAME_UPDATED); GetManager()->GetImageData(*target, gfx::Size()); waiter2.WaitForNotification();
diff --git a/content/browser/accessibility/accessibility_ipc_error_browsertest.cc b/content/browser/accessibility/accessibility_ipc_error_browsertest.cc index 7d9f004..cb4d55b 100644 --- a/content/browser/accessibility/accessibility_ipc_error_browsertest.cc +++ b/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
@@ -60,12 +60,12 @@ ASSERT_EQ(nullptr, frame->GetOrCreateBrowserAccessibilityManager()); { - // Enable accessibility (passing AccessibilityModeComplete to + // Enable accessibility (passing ACCESSIBILITY_MODE_COMPLETE to // AccessibilityNotificationWaiter does this automatically) and wait for // the first event. AccessibilityNotificationWaiter waiter( shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LAYOUT_COMPLETE); waiter.WaitForNotification(); } @@ -87,7 +87,7 @@ // notification triggered by the hide. AccessibilityNotificationWaiter waiter( shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LIVE_REGION_CHANGED); ASSERT_TRUE(ExecuteScript( shell(), "document.getElementById('p1').style.display = 'none';")); @@ -104,7 +104,8 @@ const ui::AXTree* tree = nullptr; { AccessibilityNotificationWaiter waiter( - shell()->web_contents(), AccessibilityModeComplete, ui::AX_EVENT_FOCUS); + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, + ui::AX_EVENT_FOCUS); ASSERT_TRUE( ExecuteScript(shell(), "document.getElementById('button').focus();")); waiter.WaitForNotification(); @@ -150,12 +151,12 @@ shell()->web_contents()->GetMainFrame()); { - // Enable accessibility (passing AccessibilityModeComplete to + // Enable accessibility (passing ACCESSIBILITY_MODE_COMPLETE to // AccessibilityNotificationWaiter does this automatically) and wait for // the first event. AccessibilityNotificationWaiter waiter( shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LAYOUT_COMPLETE); waiter.WaitForNotification(); } @@ -185,7 +186,7 @@ AccessibilityNotificationWaiter waiter( shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); waiter.WaitForNotification(); }
diff --git a/content/browser/accessibility/accessibility_mode_browsertest.cc b/content/browser/accessibility/accessibility_mode_browsertest.cc index 11e2ad31b..195362e 100644 --- a/content/browser/accessibility/accessibility_mode_browsertest.cc +++ b/content/browser/accessibility/accessibility_mode_browsertest.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/accessibility/accessibility_mode_helper.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" @@ -42,17 +41,12 @@ } } - AccessibilityMode CorrectedAccessibility(AccessibilityMode mode) { - return AddAccessibilityModeTo(GetBaseAccessibilityMode(), mode); - } - bool ShouldBeBrowserAccessibilityManager(AccessibilityMode mode) { - mode = CorrectedAccessibility(mode); switch (mode) { case AccessibilityModeOff: - case AccessibilityModeTreeOnly: + case ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY: return false; - case AccessibilityModeComplete: + case ACCESSIBILITY_MODE_COMPLETE: return true; default: NOTREACHED(); @@ -64,61 +58,62 @@ IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, AccessibilityModeOff) { NavigateToURL(shell(), GURL(kMinimalPageDataURL)); - EXPECT_EQ(CorrectedAccessibility(AccessibilityModeOff), - web_contents()->GetAccessibilityMode()); + EXPECT_EQ(AccessibilityModeOff, web_contents()->GetAccessibilityMode()); ExpectBrowserAccessibilityManager( ShouldBeBrowserAccessibilityManager(AccessibilityModeOff)); } -IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, AccessibilityModeComplete) { +IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, ACCESSIBILITY_MODE_COMPLETE) { NavigateToURL(shell(), GURL(kMinimalPageDataURL)); - ASSERT_EQ(CorrectedAccessibility(AccessibilityModeOff), - web_contents()->GetAccessibilityMode()); + ASSERT_EQ(AccessibilityModeOff, web_contents()->GetAccessibilityMode()); AccessibilityNotificationWaiter waiter(shell()->web_contents()); - web_contents()->AddAccessibilityMode(AccessibilityModeComplete); - EXPECT_EQ(AccessibilityModeComplete, web_contents()->GetAccessibilityMode()); + web_contents()->AddAccessibilityMode(ACCESSIBILITY_MODE_COMPLETE); + EXPECT_EQ(ACCESSIBILITY_MODE_COMPLETE, + web_contents()->GetAccessibilityMode()); waiter.WaitForNotification(); ExpectBrowserAccessibilityManager( - ShouldBeBrowserAccessibilityManager(AccessibilityModeComplete)); + ShouldBeBrowserAccessibilityManager(ACCESSIBILITY_MODE_COMPLETE)); } -IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, AccessibilityModeTreeOnly) { +IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, + ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY) { NavigateToURL(shell(), GURL(kMinimalPageDataURL)); - ASSERT_EQ(CorrectedAccessibility(AccessibilityModeOff), - web_contents()->GetAccessibilityMode()); + ASSERT_EQ(AccessibilityModeOff, web_contents()->GetAccessibilityMode()); AccessibilityNotificationWaiter waiter(shell()->web_contents()); - web_contents()->AddAccessibilityMode(AccessibilityModeTreeOnly); - EXPECT_EQ(CorrectedAccessibility(AccessibilityModeTreeOnly), + web_contents()->AddAccessibilityMode(ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY); + EXPECT_EQ(ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY, web_contents()->GetAccessibilityMode()); waiter.WaitForNotification(); - // No BrowserAccessibilityManager expected for AccessibilityModeTreeOnly - ExpectBrowserAccessibilityManager( - ShouldBeBrowserAccessibilityManager(AccessibilityModeTreeOnly)); + // No BrowserAccessibilityManager expected for + // ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY + ExpectBrowserAccessibilityManager(ShouldBeBrowserAccessibilityManager( + ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY)); } IN_PROC_BROWSER_TEST_F(AccessibilityModeTest, AddingModes) { NavigateToURL(shell(), GURL(kMinimalPageDataURL)); AccessibilityNotificationWaiter waiter(shell()->web_contents()); - web_contents()->AddAccessibilityMode(AccessibilityModeTreeOnly); - EXPECT_EQ(CorrectedAccessibility(AccessibilityModeTreeOnly), + web_contents()->AddAccessibilityMode(ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY); + EXPECT_EQ(ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY, web_contents()->GetAccessibilityMode()); waiter.WaitForNotification(); - ExpectBrowserAccessibilityManager(ShouldBeBrowserAccessibilityManager( - AccessibilityModeTreeOnly), - "Should be no BrowserAccessibilityManager " - "for AccessibilityModeTreeOnly"); + ExpectBrowserAccessibilityManager( + ShouldBeBrowserAccessibilityManager(ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY), + "Should be no BrowserAccessibilityManager " + "for ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY"); AccessibilityNotificationWaiter waiter2(shell()->web_contents()); - web_contents()->AddAccessibilityMode(AccessibilityModeComplete); - EXPECT_EQ(AccessibilityModeComplete, web_contents()->GetAccessibilityMode()); + web_contents()->AddAccessibilityMode(ACCESSIBILITY_MODE_COMPLETE); + EXPECT_EQ(ACCESSIBILITY_MODE_COMPLETE, + web_contents()->GetAccessibilityMode()); waiter2.WaitForNotification(); - ExpectBrowserAccessibilityManager(ShouldBeBrowserAccessibilityManager( - AccessibilityModeComplete), - "Should be a BrowserAccessibilityManager " - "for AccessibilityModeComplete"); + ExpectBrowserAccessibilityManager( + ShouldBeBrowserAccessibilityManager(ACCESSIBILITY_MODE_COMPLETE), + "Should be a BrowserAccessibilityManager " + "for ACCESSIBILITY_MODE_COMPLETE"); } } // namespace content
diff --git a/content/browser/accessibility/accessibility_mode_helper.cc b/content/browser/accessibility/accessibility_mode_helper.cc deleted file mode 100644 index 9745e63..0000000 --- a/content/browser/accessibility/accessibility_mode_helper.cc +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/logging.h" -#include "content/browser/accessibility/accessibility_mode_helper.h" - -namespace content { - -namespace { - -AccessibilityMode CastToAccessibilityMode(unsigned int int_mode) { - AccessibilityMode mode = static_cast<AccessibilityMode>(int_mode); - switch (mode) { - case AccessibilityModeOff: - case AccessibilityModeComplete: - case AccessibilityModeTreeOnly: - return mode; - } - DCHECK(false) << "Could not convert to AccessibilityMode: " << int_mode; - return AccessibilityModeOff; -} - -} // namespace - -AccessibilityMode GetBaseAccessibilityMode() { - AccessibilityMode accessibility_mode = AccessibilityModeOff; - return accessibility_mode; -} - -AccessibilityMode AddAccessibilityModeTo(AccessibilityMode to, - AccessibilityMode mode_to_add) { - return CastToAccessibilityMode(to | mode_to_add); -} - -AccessibilityMode RemoveAccessibilityModeFrom( - AccessibilityMode from, - AccessibilityMode mode_to_remove) { - unsigned int new_mode = from ^ (mode_to_remove & from); - return CastToAccessibilityMode(new_mode); -} - -} // namespace content
diff --git a/content/browser/accessibility/accessibility_mode_helper.h b/content/browser/accessibility/accessibility_mode_helper.h deleted file mode 100644 index c741173..0000000 --- a/content/browser/accessibility/accessibility_mode_helper.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_MODE_HELPER_H_ -#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_MODE_HELPER_H_ - -#include "content/common/accessibility_mode_enums.h" -#include "content/common/content_export.h" - -namespace content { - -// Returns base accessibility mode constant, depends on OS version. -CONTENT_EXPORT AccessibilityMode GetBaseAccessibilityMode(); - -// Adds the given accessibility mode constant to the given accessibility mode -// bitmap. -CONTENT_EXPORT AccessibilityMode - AddAccessibilityModeTo(AccessibilityMode to, AccessibilityMode mode_to_add); - -// Removes the given accessibility mode constant from the given accessibility -// mode bitmap, managing the bits that are shared with other modes such that a -// bit will only be turned off when all modes that depend on it have been -// removed. -CONTENT_EXPORT AccessibilityMode - RemoveAccessibilityModeFrom(AccessibilityMode to, - AccessibilityMode mode_to_remove); - -} // namespace content - -#endif // CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_MODE_HELPER_H_
diff --git a/content/browser/accessibility/accessibility_mode_helper_unittest.cc b/content/browser/accessibility/accessibility_mode_helper_unittest.cc deleted file mode 100644 index 6bef704..0000000 --- a/content/browser/accessibility/accessibility_mode_helper_unittest.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/accessibility/accessibility_mode_helper.h" -#include "content/common/view_message_enums.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -TEST(AccessibilityModeHelperTest, TestNoOpRemove) { - EXPECT_EQ(AccessibilityModeComplete, - RemoveAccessibilityModeFrom(AccessibilityModeComplete, - AccessibilityModeOff)); -} - -TEST(AccessibilityModeHelperTest, TestRemoveSelf) { - AccessibilityMode kBaseMode = GetBaseAccessibilityMode(); - - EXPECT_EQ(kBaseMode, - RemoveAccessibilityModeFrom(AccessibilityModeComplete, - AccessibilityModeComplete)); -} - -TEST(AccessibilityModeHelperTest, TestAddMode) { - EXPECT_EQ(AccessibilityModeComplete, - AddAccessibilityModeTo(AccessibilityModeTreeOnly, - AccessibilityModeComplete)); -} - -} // namespace content
diff --git a/content/browser/accessibility/accessibility_ui.cc b/content/browser/accessibility/accessibility_ui.cc index 60e7689..e9e7f851 100644 --- a/content/browser/accessibility/accessibility_ui.cc +++ b/content/browser/accessibility/accessibility_ui.cc
@@ -202,8 +202,8 @@ auto* web_contents = static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(rvh)); AccessibilityMode mode = web_contents->GetAccessibilityMode(); - if ((mode & AccessibilityModeComplete) != AccessibilityModeComplete) { - web_contents->AddAccessibilityMode(AccessibilityModeComplete); + if ((mode & ACCESSIBILITY_MODE_COMPLETE) != ACCESSIBILITY_MODE_COMPLETE) { + web_contents->AddAccessibilityMode(ACCESSIBILITY_MODE_COMPLETE); } else { web_contents->SetAccessibilityMode( BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()); @@ -214,7 +214,7 @@ BrowserAccessibilityStateImpl* state = BrowserAccessibilityStateImpl::GetInstance(); AccessibilityMode mode = state->accessibility_mode(); - if ((mode & AccessibilityModeComplete) != AccessibilityModeComplete) + if ((mode & ACCESSIBILITY_MODE_COMPLETE) != ACCESSIBILITY_MODE_COMPLETE) state->EnableAccessibility(); else state->DisableAccessibility();
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index 546286e..81f7cd04 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -14,7 +14,6 @@ #include "base/win/scoped_bstr.h" #include "base/win/scoped_comptr.h" #include "base/win/scoped_variant.h" -#include "content/browser/accessibility/accessibility_mode_helper.h" #include "content/browser/accessibility/accessibility_tree_formatter.h" #include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h" #include "content/browser/accessibility/browser_accessibility_manager_win.h" @@ -105,7 +104,7 @@ void AccessibilityWinBrowserTest::LoadInitialAccessibilityTreeFromHtml( const std::string& html) { AccessibilityNotificationWaiter waiter( - shell()->web_contents(), AccessibilityModeComplete, + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); GURL html_data_url("data:text/html," + html); NavigateToURL(shell(), html_data_url); @@ -163,7 +162,7 @@ // Set the caret on the last character. AccessibilityNotificationWaiter waiter( - shell()->web_contents(), AccessibilityModeComplete, + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_TEXT_SELECTION_CHANGED); std::wstring caret_offset = base::UTF16ToWide(base::IntToString16( static_cast<int>(CONTENTS_LENGTH - 1))); @@ -215,7 +214,7 @@ // Set the caret on the last character. AccessibilityNotificationWaiter waiter( - shell()->web_contents(), AccessibilityModeComplete, + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_TEXT_SELECTION_CHANGED); std::wstring caret_offset = base::UTF16ToWide(base::IntToString16( static_cast<int>(CONTENTS_LENGTH - 1))); @@ -630,9 +629,6 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestBusyAccessibilityTree) { - if (GetBaseAccessibilityMode() != AccessibilityModeOff) - return; - NavigateToURL(shell(), GURL(url::kAboutBlankURL)); // The initial accessible returned should have state STATE_SYSTEM_BUSY while @@ -674,7 +670,7 @@ // Set focus to the radio group. std::unique_ptr<AccessibilityNotificationWaiter> waiter( new AccessibilityNotificationWaiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_FOCUS)); ExecuteScript(L"document.body.children[0].focus()"); waiter->WaitForNotification(); @@ -686,7 +682,7 @@ // Set the active descendant of the radio group waiter.reset(new AccessibilityNotificationWaiter( - shell()->web_contents(), AccessibilityModeComplete, + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_FOCUS)); ExecuteScript( L"document.body.children[0].setAttribute('aria-activedescendant', 'li')"); @@ -719,7 +715,7 @@ // Check the checkbox. std::unique_ptr<AccessibilityNotificationWaiter> waiter( new AccessibilityNotificationWaiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_CHECKED_STATE_CHANGED)); ExecuteScript(L"document.body.children[0].checked=true"); waiter->WaitForNotification(); @@ -746,7 +742,7 @@ // Change the children of the document body. std::unique_ptr<AccessibilityNotificationWaiter> waiter( new AccessibilityNotificationWaiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_CHILDREN_CHANGED)); ExecuteScript(L"document.body.innerHTML='<b>new text</b>'"); waiter->WaitForNotification(); @@ -772,7 +768,7 @@ // Change the children of the document body. std::unique_ptr<AccessibilityNotificationWaiter> waiter( new AccessibilityNotificationWaiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_CHILDREN_CHANGED)); ExecuteScript(L"document.body.children[0].style.visibility='visible'"); waiter->WaitForNotification(); @@ -805,7 +801,7 @@ // Focus the div in the document std::unique_ptr<AccessibilityNotificationWaiter> waiter( new AccessibilityNotificationWaiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_FOCUS)); ExecuteScript(L"document.body.children[0].focus()"); waiter->WaitForNotification(); @@ -819,7 +815,7 @@ // Focus the document accessible. This will un-focus the current node. waiter.reset( new AccessibilityNotificationWaiter( - shell()->web_contents(), AccessibilityModeComplete, + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_BLUR)); base::win::ScopedComPtr<IAccessible> document_accessible( GetRendererAccessible()); @@ -855,7 +851,7 @@ // Set the value of the text control std::unique_ptr<AccessibilityNotificationWaiter> waiter( new AccessibilityNotificationWaiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_VALUE_CHANGED)); ExecuteScript(L"document.body.children[0].value='new value'"); waiter->WaitForNotification(); @@ -1097,7 +1093,7 @@ AccessibilityNotificationWaiter waiter( shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_TEXT_SELECTION_CHANGED); caret_offset = 0; hr = input_text->setCaretOffset(caret_offset); @@ -1121,7 +1117,7 @@ AccessibilityNotificationWaiter waiter( shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_TEXT_SELECTION_CHANGED); caret_offset = 0; hr = textarea_text->setCaretOffset(caret_offset); @@ -1716,7 +1712,7 @@ // Cllicking the image will change its name. EXPECT_HRESULT_SUCCEEDED(image_action->doAction(0)); AccessibilityNotificationWaiter waiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_TEXT_CHANGED); waiter.WaitForNotification(); EXPECT_HRESULT_SUCCEEDED( @@ -1745,7 +1741,7 @@ // Navigate to a new page and wait for the accessibility tree to load. AccessibilityNotificationWaiter waiter( shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); NavigateToURL(shell(), embedded_test_server()->GetURL( "/accessibility/html/article.html"));
diff --git a/content/browser/accessibility/android_granularity_movement_browsertest.cc b/content/browser/accessibility/android_granularity_movement_browsertest.cc index 9ece9acc..d6152ef 100644 --- a/content/browser/accessibility/android_granularity_movement_browsertest.cc +++ b/content/browser/accessibility/android_granularity_movement_browsertest.cc
@@ -40,7 +40,7 @@ // Load the page. AccessibilityNotificationWaiter waiter( - shell()->web_contents(), AccessibilityModeComplete, + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); NavigateToURL(shell(), url); waiter.WaitForNotification(); @@ -70,7 +70,7 @@ BrowserAccessibility* node, int granularity) { AccessibilityNotificationWaiter waiter( - shell()->web_contents(), AccessibilityModeComplete, + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_TREE_CHANGED); node->manager()->SetAccessibilityFocus(*node); waiter.WaitForNotification();
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.cc b/content/browser/accessibility/browser_accessibility_state_impl.cc index a19b103..4c50bb3 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl.cc +++ b/content/browser/accessibility/browser_accessibility_state_impl.cc
@@ -9,7 +9,6 @@ #include "base/command_line.h" #include "base/metrics/histogram_macros.h" #include "build/build_config.h" -#include "content/browser/accessibility/accessibility_mode_helper.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_thread.h" @@ -70,7 +69,7 @@ } void BrowserAccessibilityStateImpl::EnableAccessibility() { - AddAccessibilityMode(AccessibilityModeComplete); + AddAccessibilityModeFlags(ACCESSIBILITY_MODE_COMPLETE); } void BrowserAccessibilityStateImpl::DisableAccessibility() { @@ -81,7 +80,7 @@ accessibility_mode_ = AccessibilityModeOff; if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kForceRendererAccessibility)) { - accessibility_mode_ = AccessibilityModeComplete; + accessibility_mode_ = ACCESSIBILITY_MODE_COMPLETE; } } @@ -95,8 +94,8 @@ } bool BrowserAccessibilityStateImpl::IsAccessibleBrowser() { - return ((accessibility_mode_ & AccessibilityModeComplete) == - AccessibilityModeComplete); + return ((accessibility_mode_ & ACCESSIBILITY_MODE_COMPLETE) == + ACCESSIBILITY_MODE_COMPLETE); } void BrowserAccessibilityStateImpl::AddHistogramCallback( @@ -127,44 +126,33 @@ } #endif -void BrowserAccessibilityStateImpl::AddAccessibilityMode( +void BrowserAccessibilityStateImpl::AddAccessibilityModeFlags( AccessibilityMode mode) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableRendererAccessibility)) { return; } - accessibility_mode_ = - content::AddAccessibilityModeTo(accessibility_mode_, mode); - - AddOrRemoveFromAllWebContents(mode, true); + accessibility_mode_ |= mode; + std::vector<WebContentsImpl*> web_contents_vector = + WebContentsImpl::GetAllWebContents(); + for (size_t i = 0; i < web_contents_vector.size(); ++i) + web_contents_vector[i]->AddAccessibilityMode(accessibility_mode_); } -void BrowserAccessibilityStateImpl::RemoveAccessibilityMode( +void BrowserAccessibilityStateImpl::RemoveAccessibilityModeFlags( AccessibilityMode mode) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kForceRendererAccessibility) && - mode == AccessibilityModeComplete) { + mode == ACCESSIBILITY_MODE_COMPLETE) { return; } - accessibility_mode_ = - content::RemoveAccessibilityModeFrom(accessibility_mode_, mode); - - AddOrRemoveFromAllWebContents(mode, false); -} - -void BrowserAccessibilityStateImpl::AddOrRemoveFromAllWebContents( - AccessibilityMode mode, - bool add) { + accessibility_mode_ = accessibility_mode_ ^ (mode & accessibility_mode_); std::vector<WebContentsImpl*> web_contents_vector = WebContentsImpl::GetAllWebContents(); - for (size_t i = 0; i < web_contents_vector.size(); ++i) { - if (add) - web_contents_vector[i]->AddAccessibilityMode(mode); - else - web_contents_vector[i]->RemoveAccessibilityMode(mode); - } + for (size_t i = 0; i < web_contents_vector.size(); ++i) + web_contents_vector[i]->SetAccessibilityMode(accessibility_mode()); } } // namespace content
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.h b/content/browser/accessibility/browser_accessibility_state_impl.h index 5beb762..043fecce 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl.h +++ b/content/browser/accessibility/browser_accessibility_state_impl.h
@@ -51,14 +51,13 @@ AccessibilityMode accessibility_mode() const { return accessibility_mode_; }; - // Adds the given accessibility mode to the current accessibility mode bitmap. - void AddAccessibilityMode(AccessibilityMode mode); + // Adds the given accessibility mode flags to the current accessibility + // mode bitmap. + void AddAccessibilityModeFlags(AccessibilityMode mode); - // Removes the given accessibility mode from the current accessibility mode - // bitmap, managing the bits that are shared with other modes such that a - // bit will only be turned off when all modes that depend on it have been - // removed. - void RemoveAccessibilityMode(AccessibilityMode mode); + // Remove the given accessibility mode flags from the current accessibility + // mode bitmap. + void RemoveAccessibilityModeFlags(AccessibilityMode mode); // Accessibility objects can have the "hot tracked" state set when // the mouse is hovering over them, but this makes tests flaky because @@ -88,10 +87,6 @@ void UpdatePlatformSpecificHistograms(); - // Updates the accessibility mode of all web contents, including swapped out - // ones. |add| specifies whether the mode should be added or removed. - void AddOrRemoveFromAllWebContents(AccessibilityMode mode, bool add); - AccessibilityMode accessibility_mode_; std::vector<base::Closure> histogram_callbacks_;
diff --git a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc index dc3e99e..bb955ea2 100644 --- a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc +++ b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -45,7 +45,7 @@ // Tell the renderer to send an accessibility tree, then wait for the // notification that it's been received. const ui::AXTree& GetAXTree( - AccessibilityMode accessibility_mode = AccessibilityModeComplete) { + AccessibilityMode accessibility_mode = ACCESSIBILITY_MODE_COMPLETE) { AccessibilityNotificationWaiter waiter( shell()->web_contents(), accessibility_mode,
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc index b694772..1866525 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -257,7 +257,7 @@ NavigateToURL(shell(), url); AccessibilityNotificationWaiter accessibility_waiter( web_contents, - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_NONE); accessibility_waiter.WaitForNotification(); } else { @@ -265,7 +265,7 @@ // "load complete" AX event. AccessibilityNotificationWaiter accessibility_waiter( web_contents, - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); NavigateToURL(shell(), url); accessibility_waiter.WaitForNotification();
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index 28daec1..e2326c4 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -91,7 +91,7 @@ // a result of this function. std::unique_ptr<AccessibilityNotificationWaiter> waiter; waiter.reset(new AccessibilityNotificationWaiter( - shell()->web_contents(), AccessibilityModeComplete, ui::AX_EVENT_NONE)); + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_NONE)); web_contents->GetMainFrame()->ExecuteJavaScriptForTests( base::ASCIIToUTF16("go()")); @@ -104,8 +104,9 @@ // To make sure we've received all accessibility events, add a // sentinel by calling AccessibilityHitTest and waiting for a HOVER // event in response. - waiter.reset(new AccessibilityNotificationWaiter( - shell()->web_contents(), AccessibilityModeComplete, ui::AX_EVENT_HOVER)); + waiter.reset(new AccessibilityNotificationWaiter(shell()->web_contents(), + ACCESSIBILITY_MODE_COMPLETE, + ui::AX_EVENT_HOVER)); BrowserAccessibilityManager* manager = web_contents->GetRootBrowserAccessibilityManager(); manager->HitTest(gfx::Point(0, 0));
diff --git a/content/browser/accessibility/hit_testing_browsertest.cc b/content/browser/accessibility/hit_testing_browsertest.cc index fb9c6707..afcb4f6eb 100644 --- a/content/browser/accessibility/hit_testing_browsertest.cc +++ b/content/browser/accessibility/hit_testing_browsertest.cc
@@ -31,7 +31,8 @@ web_contents->GetRootBrowserAccessibilityManager(); AccessibilityNotificationWaiter hover_waiter( - shell()->web_contents(), AccessibilityModeComplete, ui::AX_EVENT_HOVER); + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, + ui::AX_EVENT_HOVER); for (FrameTreeNode* node : frame_tree->Nodes()) hover_waiter.ListenToAdditionalFrame(node->current_frame_host()); manager->HitTest(point); @@ -58,7 +59,8 @@ // Each call to CachingAsyncHitTest results in at least one HOVER // event received. Block until we receive it. AccessibilityNotificationWaiter hover_waiter( - shell()->web_contents(), AccessibilityModeComplete, ui::AX_EVENT_HOVER); + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, + ui::AX_EVENT_HOVER); for (FrameTreeNode* node : frame_tree->Nodes()) hover_waiter.ListenToAdditionalFrame(node->current_frame_host()); BrowserAccessibility* result = manager->CachingAsyncHitTest(screen_point); @@ -73,7 +75,7 @@ // Load the page. AccessibilityNotificationWaiter waiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); const char url_str[] = "data:text/html," @@ -102,7 +104,7 @@ NavigateToURL(shell(), GURL(url::kAboutBlankURL)); AccessibilityNotificationWaiter waiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); GURL url(embedded_test_server()->GetURL( "/accessibility/html/iframe-coordinates.html")); @@ -158,7 +160,7 @@ NavigateToURL(shell(), GURL(url::kAboutBlankURL)); AccessibilityNotificationWaiter waiter(shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); GURL url(embedded_test_server()->GetURL( "/accessibility/hit_testing/hit_testing.html"));
diff --git a/content/browser/accessibility/touch_accessibility_aura_browsertest.cc b/content/browser/accessibility/touch_accessibility_aura_browsertest.cc index c7e1e8c..70845e4 100644 --- a/content/browser/accessibility/touch_accessibility_aura_browsertest.cc +++ b/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
@@ -36,7 +36,7 @@ void NavigateToUrlAndWaitForAccessibilityTree(const GURL& url) { AccessibilityNotificationWaiter waiter( shell()->web_contents(), - AccessibilityModeComplete, + ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_LOAD_COMPLETE); NavigateToURL(shell(), url); waiter.WaitForNotification(); @@ -93,7 +93,7 @@ // touch exploration event in the center of that cell, and assert that we // get an accessibility hover event fired in the correct cell. AccessibilityNotificationWaiter waiter( - shell()->web_contents(), AccessibilityModeComplete, ui::AX_EVENT_HOVER); + shell()->web_contents(), ACCESSIBILITY_MODE_COMPLETE, ui::AX_EVENT_HOVER); for (int row = 0; row < 5; ++row) { for (int col = 0; col < 7; ++col) { std::string expected_cell_text = base::IntToString(row * 7 + col);
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 458e67f..28e8c88 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc
@@ -1384,7 +1384,7 @@ // this WebContents if that succeeded. accessibility_state->OnScreenReaderDetected(); if (accessibility_state->IsAccessibleBrowser() && web_contents_) - web_contents_->AddAccessibilityMode(AccessibilityModeComplete); + web_contents_->AddAccessibilityMode(ACCESSIBILITY_MODE_COMPLETE); } else { accessibility_state->ResetAccessibilityMode(); if (web_contents_) {
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h index c4c661d..87e47f6 100644 --- a/content/browser/bad_message.h +++ b/content/browser/bad_message.h
@@ -181,6 +181,7 @@ AOAH_NONSENSE_DEVICE_ID = 157, BDH_INVALID_OPTIONS = 158, RFH_DID_ADD_CONSOLE_MESSAGE_BAD_SEVERITY = 159, + AIRH_VOLUME_OUT_OF_RANGE = 160, // Please add new elements here. The naming convention is abbreviated class // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/devtools/BUILD.gn b/content/browser/devtools/BUILD.gn index 5ef4994..5c0d063 100644 --- a/content/browser/devtools/BUILD.gn +++ b/content/browser/devtools/BUILD.gn
@@ -76,8 +76,6 @@ "protocol/schema.h", "protocol/security.cc", "protocol/security.h", - "protocol/storage.cc", - "protocol/storage.h", "protocol/system_info.cc", "protocol/system_info.h", "protocol/tethering.cc",
diff --git a/content/browser/devtools/protocol/devtools_protocol_handler_generator.py b/content/browser/devtools/protocol/devtools_protocol_handler_generator.py index 823d2185c..00f9c00b6 100755 --- a/content/browser/devtools/protocol/devtools_protocol_handler_generator.py +++ b/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
@@ -643,7 +643,7 @@ includes = [] fields_init = [] -browser_domains_list = ["Target", "ServiceWorker", "Input"] +browser_domains_list = ["Target", "ServiceWorker", "Input", "Storage"] browser_commands_list = [] async_commands_list = [ "Input.synthesizePinchGesture",
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc index 9c3a06ce..94415de7 100644 --- a/content/browser/devtools/protocol/storage_handler.cc +++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -9,12 +9,14 @@ #include <vector> #include "base/strings/string_split.h" -#include "content/browser/frame_host/render_frame_host_impl.h" +#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/storage_partition.h" namespace content { -namespace protocol { +namespace devtools { +namespace storage { namespace { static const char kAppCache[] = "appcache"; @@ -29,29 +31,23 @@ static const char kAll[] = "all"; } +typedef DevToolsProtocolClient::Response Response; + StorageHandler::StorageHandler() : host_(nullptr) { } StorageHandler::~StorageHandler() = default; -void StorageHandler::Wire(UberDispatcher* dispatcher) { - Storage::Dispatcher::wire(dispatcher, this); -} - -void StorageHandler::SetRenderFrameHost(RenderFrameHostImpl* host) { +void StorageHandler::SetRenderFrameHost(RenderFrameHost* host) { host_ = host; } -Response StorageHandler::Disable() { - return Response::OK(); -} - Response StorageHandler::ClearDataForOrigin( const std::string& origin, const std::string& storage_types) { if (!host_) - return Response::InternalError(); + return Response::InternalError("Not connected to host"); StoragePartition* partition = host_->GetProcess()->GetStoragePartition(); std::vector<std::string> types = base::SplitString( @@ -91,5 +87,6 @@ return Response::OK(); } -} // namespace protocol +} // namespace storage +} // namespace devtools } // namespace content
diff --git a/content/browser/devtools/protocol/storage_handler.h b/content/browser/devtools/protocol/storage_handler.h index f203a12..d6f7c65 100644 --- a/content/browser/devtools/protocol/storage_handler.h +++ b/content/browser/devtools/protocol/storage_handler.h
@@ -6,34 +6,37 @@ #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_STORAGE_HANDLER_H_ #include "base/macros.h" -#include "content/browser/devtools/protocol/storage.h" +#include "content/browser/devtools/devtools_protocol_handler.h" +#include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h" namespace content { -class RenderFrameHostImpl; +class RenderFrameHost; -namespace protocol { +namespace devtools { +namespace storage { -class StorageHandler : public Storage::Backend { +class StorageHandler { public: - StorageHandler(); - ~StorageHandler() override; + typedef DevToolsProtocolClient::Response Response; - void Wire(UberDispatcher*); - void SetRenderFrameHost(RenderFrameHostImpl* host); - Response Disable() override; + StorageHandler(); + ~StorageHandler(); + + void SetRenderFrameHost(RenderFrameHost* host); Response ClearDataForOrigin( const std::string& origin, - const std::string& storage_types) override; + const std::string& storage_types); private: - RenderFrameHostImpl* host_; + RenderFrameHost* host_; DISALLOW_COPY_AND_ASSIGN(StorageHandler); }; -} // namespace protocol +} // namespace storage +} // namespace devtools } // namespace content #endif // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_STORAGE_HANDLER_H_
diff --git a/content/browser/devtools/protocol_config.json b/content/browser/devtools/protocol_config.json index c64ec06c..cb1899f7 100644 --- a/content/browser/devtools/protocol_config.json +++ b/content/browser/devtools/protocol_config.json
@@ -52,9 +52,6 @@ "domain": "Security" }, { - "domain": "Storage" - }, - { "domain": "SystemInfo", "async": ["getInfo"] },
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index b217d8e..c7693a5 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -397,6 +397,7 @@ input_handler_(new devtools::input::InputHandler()), service_worker_handler_( new devtools::service_worker::ServiceWorkerHandler()), + storage_handler_(new devtools::storage::StorageHandler()), target_handler_(new devtools::target::TargetHandler()), frame_trace_recorder_(nullptr), protocol_handler_(new DevToolsProtocolHandler(this)), @@ -407,6 +408,7 @@ DevToolsProtocolDispatcher* dispatcher = protocol_handler_->dispatcher(); dispatcher->SetInputHandler(input_handler_.get()); dispatcher->SetServiceWorkerHandler(service_worker_handler_.get()); + dispatcher->SetStorageHandler(storage_handler_.get()); dispatcher->SetTargetHandler(target_handler_.get()); SetPending(host); @@ -509,9 +511,6 @@ security_handler_->SetRenderFrameHost(handlers_frame_host_); } - storage_handler_.reset(new protocol::StorageHandler()); - storage_handler_->Wire(session()->dispatcher()); - tracing_handler_.reset(new protocol::TracingHandler( protocol::TracingHandler::Renderer, frame_tree_node_->frame_tree_node_id(), @@ -548,8 +547,6 @@ security_handler_->Disable(); security_handler_.reset(); } - storage_handler_->Disable(); - storage_handler_.reset(); tracing_handler_->Disable(); tracing_handler_.reset();
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h index 2b464da..b17972cd 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.h +++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -42,6 +42,7 @@ namespace devtools { namespace input { class InputHandler; } namespace service_worker { class ServiceWorkerHandler; } +namespace storage { class StorageHandler; } namespace target { class TargetHandler; } } @@ -54,7 +55,6 @@ class PageHandler; class SchemaHandler; class SecurityHandler; -class StorageHandler; class TracingHandler; } // namespace protocol @@ -193,7 +193,8 @@ std::unique_ptr<protocol::SecurityHandler> security_handler_; std::unique_ptr<devtools::service_worker::ServiceWorkerHandler> service_worker_handler_; - std::unique_ptr<protocol::StorageHandler> storage_handler_; + std::unique_ptr<devtools::storage::StorageHandler> + storage_handler_; std::unique_ptr<devtools::target::TargetHandler> target_handler_; std::unique_ptr<protocol::TracingHandler> tracing_handler_; std::unique_ptr<protocol::EmulationHandler> emulation_handler_;
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h index a22a5bf..6f3497c 100644 --- a/content/browser/frame_host/render_frame_host_delegate.h +++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -150,8 +150,9 @@ // Get the accessibility mode for the WebContents that owns this frame. virtual AccessibilityMode GetAccessibilityMode() const; - // Forward accessibility messages to other potential listeners like - // the automation extension API. + // Called when accessibility events or location changes are received + // from a render frame, when the accessibility mode has the + // ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS flag set. virtual void AccessibilityEventReceived( const std::vector<AXEventNotificationDetails>& details) {} virtual void AccessibilityLocationChangesReceived(
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 25d7098..c845479 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -16,7 +16,6 @@ #include "base/process/kill.h" #include "base/time/time.h" #include "build/build_config.h" -#include "content/browser/accessibility/accessibility_mode_helper.h" #include "content/browser/accessibility/ax_tree_id_registry.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" @@ -1899,7 +1898,7 @@ AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode(); if ((accessibility_mode != AccessibilityModeOff) && view && is_active()) { - if (accessibility_mode & AccessibilityModeFlagPlatform) + if (accessibility_mode & ACCESSIBILITY_MODE_FLAG_NATIVE_APIS) GetOrCreateBrowserAccessibilityManager(); std::vector<AXEventNotificationDetails> details; @@ -1926,12 +1925,11 @@ details.push_back(detail); } - if (accessibility_mode & AccessibilityModeFlagPlatform) { + if (accessibility_mode & ACCESSIBILITY_MODE_FLAG_NATIVE_APIS) { if (browser_accessibility_manager_) browser_accessibility_manager_->OnAccessibilityEvents(details); } - // Send the updates to the automation extension API. delegate_->AccessibilityEventReceived(details); // For testing only. @@ -1972,7 +1970,7 @@ render_view_host_->GetWidget()->GetView()); if (view && is_active()) { AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode(); - if (accessibility_mode & AccessibilityModeFlagPlatform) { + if (accessibility_mode & ACCESSIBILITY_MODE_FLAG_NATIVE_APIS) { BrowserAccessibilityManager* manager = GetOrCreateBrowserAccessibilityManager(); if (manager) @@ -1997,7 +1995,7 @@ void RenderFrameHostImpl::OnAccessibilityFindInPageResult( const AccessibilityHostMsg_FindInPageResultParams& params) { AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode(); - if (accessibility_mode & AccessibilityModeFlagPlatform) { + if (accessibility_mode & ACCESSIBILITY_MODE_FLAG_NATIVE_APIS) { BrowserAccessibilityManager* manager = GetOrCreateBrowserAccessibilityManager(); if (manager) { @@ -2871,7 +2869,7 @@ void RenderFrameHostImpl::ActivateFindInPageResultForAccessibility( int request_id) { AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode(); - if (accessibility_mode & AccessibilityModeFlagPlatform) { + if (accessibility_mode & ACCESSIBILITY_MODE_FLAG_NATIVE_APIS) { BrowserAccessibilityManager* manager = GetOrCreateBrowserAccessibilityManager(); if (manager)
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h index a7dc62df..148e3b2 100644 --- a/content/browser/media/session/media_session_impl.h +++ b/content/browser/media/session/media_session_impl.h
@@ -132,11 +132,11 @@ // Let the media session start ducking such that the volume multiplier is // reduced. - CONTENT_EXPORT void StartDucking(); + CONTENT_EXPORT void StartDucking() override; // Let the media session stop ducking such that the volume multiplier is // recovered. - CONTENT_EXPORT void StopDucking(); + CONTENT_EXPORT void StopDucking() override; // Returns if the session can be controlled by Resume() and Suspend calls // above.
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc index 6952862..ac20e606 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.cc +++ b/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -13,47 +13,6 @@ using blink::WebInputEvent; namespace content { -namespace { - -// Whether |event_in_queue| is GesturePinchUpdate or GestureScrollUpdate and -// has the same modifiers/source as the new scroll/pinch event. Compatible -// scroll and pinch event pairs can be logically coalesced. -bool IsCompatibleScrollorPinch( - const GestureEventWithLatencyInfo& new_event, - const GestureEventWithLatencyInfo& event_in_queue) { - DCHECK(new_event.event.type == WebInputEvent::GestureScrollUpdate || - new_event.event.type == WebInputEvent::GesturePinchUpdate) - << "Invalid event type for pinch/scroll coalescing: " - << WebInputEvent::GetName(new_event.event.type); - DLOG_IF(WARNING, new_event.event.timeStampSeconds < - event_in_queue.event.timeStampSeconds) - << "Event time not monotonic?\n"; - return (event_in_queue.event.type == WebInputEvent::GestureScrollUpdate || - event_in_queue.event.type == WebInputEvent::GesturePinchUpdate) && - event_in_queue.event.modifiers == new_event.event.modifiers && - event_in_queue.event.sourceDevice == new_event.event.sourceDevice; -} - -// Returns the transform matrix corresponding to the gesture event. -gfx::Transform GetTransformForEvent( - const GestureEventWithLatencyInfo& gesture_event) { - gfx::Transform gesture_transform; - if (gesture_event.event.type == WebInputEvent::GestureScrollUpdate) { - gesture_transform.Translate(gesture_event.event.data.scrollUpdate.deltaX, - gesture_event.event.data.scrollUpdate.deltaY); - } else if (gesture_event.event.type == WebInputEvent::GesturePinchUpdate) { - float scale = gesture_event.event.data.pinchUpdate.scale; - gesture_transform.Translate(-gesture_event.event.x, -gesture_event.event.y); - gesture_transform.Scale(scale, scale); - gesture_transform.Translate(gesture_event.event.x, gesture_event.event.y); - } else { - NOTREACHED() << "Invalid event type for transform retrieval: " - << WebInputEvent::GetName(gesture_event.event.type); - } - return gesture_transform; -} - -} // namespace GestureEventQueue::Config::Config() { } @@ -335,7 +294,8 @@ const GestureEventWithLatencyInfo& first_event = coalesced_gesture_events_.front(); if (gesture_event.event.type != first_event.event.type && - IsCompatibleScrollorPinch(gesture_event, first_event)) { + ui::IsCompatibleScrollorPinch(gesture_event.event, + first_event.event)) { ignore_next_ack_ = true; client_->SendGestureEventImmediately(gesture_event); } @@ -349,63 +309,50 @@ return; } - if (!IsCompatibleScrollorPinch(gesture_event, *last_event)) { + if (!ui::IsCompatibleScrollorPinch(gesture_event.event, last_event->event)) { coalesced_gesture_events_.push_back(gesture_event); return; } - GestureEventWithLatencyInfo scroll_event; - GestureEventWithLatencyInfo pinch_event; - scroll_event.event.modifiers |= gesture_event.event.modifiers; - scroll_event.event.sourceDevice = gesture_event.event.sourceDevice; - scroll_event.event.timeStampSeconds = gesture_event.event.timeStampSeconds; - // Keep the oldest LatencyInfo. - DCHECK_LE(last_event->latency.trace_id(), gesture_event.latency.trace_id()); - scroll_event.latency = last_event->latency; - pinch_event = scroll_event; - scroll_event.event.type = WebInputEvent::GestureScrollUpdate; - pinch_event.event.type = WebInputEvent::GesturePinchUpdate; - pinch_event.event.x = gesture_event.event.type == - WebInputEvent::GesturePinchUpdate ? - gesture_event.event.x : last_event->event.x; - pinch_event.event.y = gesture_event.event.type == - WebInputEvent::GesturePinchUpdate ? - gesture_event.event.y : last_event->event.y; - - gfx::Transform combined_scroll_pinch = GetTransformForEvent(*last_event); - // Only include the second-to-last event in the coalesced pair if it exists - // and can be combined with the new event. - if (unsent_events_count > 1) { - const GestureEventWithLatencyInfo& second_last_event = - coalesced_gesture_events_[coalesced_gesture_events_.size() - 2]; - if (IsCompatibleScrollorPinch(gesture_event, second_last_event)) { - // Keep the oldest LatencyInfo. - DCHECK_LE(second_last_event.latency.trace_id(), - scroll_event.latency.trace_id()); - scroll_event.latency = second_last_event.latency; - pinch_event.latency = second_last_event.latency; - combined_scroll_pinch.PreconcatTransform( - GetTransformForEvent(second_last_event)); - coalesced_gesture_events_.pop_back(); - } - } - combined_scroll_pinch.ConcatTransform(GetTransformForEvent(gesture_event)); + // Extract the last event in queue. + blink::WebGestureEvent last_gesture_event = + coalesced_gesture_events_.back().event; + DCHECK_LE(coalesced_gesture_events_.back().latency.trace_id(), + gesture_event.latency.trace_id()); + ui::LatencyInfo oldest_latency = coalesced_gesture_events_.back().latency; + oldest_latency.set_coalesced(); coalesced_gesture_events_.pop_back(); - float combined_scale = - SkMScalarToFloat(combined_scroll_pinch.matrix().get(0, 0)); - float combined_scroll_pinch_x = - SkMScalarToFloat(combined_scroll_pinch.matrix().get(0, 3)); - float combined_scroll_pinch_y = - SkMScalarToFloat(combined_scroll_pinch.matrix().get(1, 3)); - scroll_event.event.data.scrollUpdate.deltaX = - (combined_scroll_pinch_x + pinch_event.event.x) / combined_scale - - pinch_event.event.x; - scroll_event.event.data.scrollUpdate.deltaY = - (combined_scroll_pinch_y + pinch_event.event.y) / combined_scale - - pinch_event.event.y; + // Extract the second last event in queue. + ui::ScopedWebInputEvent second_last_gesture_event = nullptr; + if (unsent_events_count > 1 && + ui::IsCompatibleScrollorPinch(gesture_event.event, + coalesced_gesture_events_.back().event)) { + second_last_gesture_event = + ui::WebInputEventTraits::Clone(coalesced_gesture_events_.back().event); + DCHECK_LE(coalesced_gesture_events_.back().latency.trace_id(), + oldest_latency.trace_id()); + oldest_latency = coalesced_gesture_events_.back().latency; + oldest_latency.set_coalesced(); + coalesced_gesture_events_.pop_back(); + } + + std::pair<blink::WebGestureEvent, blink::WebGestureEvent> coalesced_events = + ui::CoalesceScrollAndPinch( + second_last_gesture_event + ? &ui::ToWebGestureEvent(*second_last_gesture_event) + : nullptr, + last_gesture_event, gesture_event.event); + + GestureEventWithLatencyInfo scroll_event; + scroll_event.event = coalesced_events.first; + scroll_event.latency = oldest_latency; + + GestureEventWithLatencyInfo pinch_event; + pinch_event.event = coalesced_events.second; + pinch_event.latency = oldest_latency; + coalesced_gesture_events_.push_back(scroll_event); - pinch_event.event.data.pinchUpdate.scale = combined_scale; coalesced_gesture_events_.push_back(pinch_event); }
diff --git a/content/browser/renderer_host/input/gesture_event_queue.h b/content/browser/renderer_host/input/gesture_event_queue.h index 3f1e240..4649cca 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.h +++ b/content/browser/renderer_host/input/gesture_event_queue.h
@@ -19,7 +19,6 @@ #include "content/common/content_export.h" #include "content/common/input/input_event_ack_state.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" -#include "ui/gfx/transform.h" namespace content { class GestureEventQueueTest;
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc index aefb424..661924a 100644 --- a/content/browser/renderer_host/media/audio_input_renderer_host.cc +++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc
@@ -16,7 +16,9 @@ #include "base/process/process.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" +#include "base/sync_socket.h" #include "build/build_config.h" +#include "content/browser/bad_message.h" #include "content/browser/media/capture/desktop_capture_device_uma_types.h" #include "content/browser/media/capture/web_contents_audio_input_stream.h" #include "content/browser/media/media_internals.h" @@ -48,8 +50,9 @@ if (add_prefix) oss << "AIRH::"; oss << msg; - content::MediaStreamManager::SendMessageToNativeLog(oss.str()); - DVLOG(1) << oss.str(); + const std::string message = oss.str(); + content::MediaStreamManager::SendMessageToNativeLog(message); + DVLOG(1) << message; } } // namespace @@ -105,8 +108,7 @@ audio_mirroring_manager_(audio_mirroring_manager), user_input_monitor_(user_input_monitor), audio_log_(MediaInternals::GetInstance()->CreateAudioLog( - media::AudioLogFactory::AUDIO_INPUT_CONTROLLER)), - weak_factory_(this) {} + media::AudioLogFactory::AUDIO_INPUT_CONTROLLER)) {} AudioInputRendererHost::~AudioInputRendererHost() { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -184,22 +186,9 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); AudioEntry* entry = LookupByController(controller); - if (!entry) { - NOTREACHED() << "AudioInputController is invalid."; - return; - } - - if (!PeerHandle()) { - NOTREACHED() << "Renderer process handle is invalid."; - DeleteEntryOnError(entry, INVALID_PEER_HANDLE); - return; - } - - if (!entry->controller->SharedMemoryAndSyncSocketMode()) { - NOTREACHED() << "Only shared-memory/sync-socket mode is supported."; - DeleteEntryOnError(entry, INVALID_LATENCY_MODE); - return; - } + DCHECK(entry); + DCHECK(PeerHandle()); + DCHECK(entry->controller->SharedMemoryAndSyncSocketMode()); // Once the audio stream is created then complete the creation process by // mapping shared memory and sharing with the renderer process. @@ -239,10 +228,7 @@ // TODO(henrika): See crbug.com/115262 for details on why this method // should be implemented. AudioEntry* entry = LookupByController(controller); - if (!entry) { - NOTREACHED() << "AudioInputController is invalid."; - return; - } + DCHECK(entry) << "AudioInputController is invalid."; LogMessage( entry->stream_id, "DoSendRecordingMessage: stream is now started", true); } @@ -252,10 +238,7 @@ media::AudioInputController::ErrorCode error_code) { DCHECK_CURRENTLY_ON(BrowserThread::IO); AudioEntry* entry = LookupByController(controller); - if (!entry) { - NOTREACHED() << "AudioInputController is invalid."; - return; - } + DCHECK(entry); std::ostringstream oss; oss << "AIC reports error_code=" << error_code; @@ -269,10 +252,7 @@ const std::string& message) { DCHECK_CURRENTLY_ON(BrowserThread::IO); AudioEntry* entry = LookupByController(controller); - if (!entry) { - NOTREACHED() << "AudioInputController is invalid."; - return; - } + DCHECK(entry); // Add stream ID and current audio level reported by AIC to native log. LogMessage(entry->stream_id, message, false); @@ -320,44 +300,41 @@ const AudioInputHostMsg_CreateStream_Config& config) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - std::ostringstream oss; - oss << "[stream_id=" << stream_id << "] " - << "AIRH::OnCreateStream(render_frame_id=" << render_frame_id - << ", session_id=" << session_id << ")"; DCHECK_GT(render_frame_id, 0); // media::AudioParameters is validated in the deserializer. - if (LookupById(stream_id) != NULL) { + if (LookupById(stream_id)) { SendErrorMessage(stream_id, STREAM_ALREADY_EXISTS); MaybeUnregisterKeyboardMicStream(config); return; } + // Check if we have the permission to open the device and which device to use. + const StreamDeviceInfo* info = + media_stream_manager_->audio_input_device_manager() + ->GetOpenedDeviceInfoById(session_id); + if (!info) { + SendErrorMessage(stream_id, PERMISSION_DENIED); + DLOG(WARNING) << "No permission has been granted to input stream with " + << "session_id=" << session_id; + MaybeUnregisterKeyboardMicStream(config); + return; + } + + const MediaStreamType& type = info->device.type; + const std::string& device_id = info->device.id; + const std::string& device_name = info->device.name; media::AudioParameters audio_params(config.params); if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseFakeDeviceForMediaStream)) { audio_params.set_format(media::AudioParameters::AUDIO_FAKE); } - // Check if we have the permission to open the device and which device to use. - MediaStreamType type = MEDIA_NO_SERVICE; - std::string device_name; - std::string device_id = media::AudioDeviceDescription::kDefaultDeviceId; - if (audio_params.format() != media::AudioParameters::AUDIO_FAKE) { - const StreamDeviceInfo* info = media_stream_manager_-> - audio_input_device_manager()->GetOpenedDeviceInfoById(session_id); - if (!info) { - SendErrorMessage(stream_id, PERMISSION_DENIED); - DLOG(WARNING) << "No permission has been granted to input stream with " - << "session_id=" << session_id; - MaybeUnregisterKeyboardMicStream(config); - return; - } - type = info->device.type; - device_id = info->device.id; - device_name = info->device.name; - oss << ": device_name=" << device_name; - } + std::ostringstream oss; + oss << "[stream_id=" << stream_id << "] " + << "AIRH::OnCreateStream(render_frame_id=" << render_frame_id + << ", session_id=" << session_id << ")" + << ": device_name=" << device_name; // Create a new AudioEntry structure. std::unique_ptr<AudioEntry> entry(new AudioEntry()); @@ -450,8 +427,9 @@ } #endif - MediaStreamManager::SendMessageToNativeLog(oss.str()); - DVLOG(1) << oss.str(); + const std::string log_message = oss.str(); + MediaStreamManager::SendMessageToNativeLog(log_message); + DVLOG(1) << log_message; // Since the controller was created successfully, create an entry and add it // to the map. @@ -499,6 +477,12 @@ void AudioInputRendererHost::OnSetVolume(int stream_id, double volume) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (volume < 0 || volume > 1) { + bad_message::ReceivedBadMessage(this, + bad_message::AIRH_VOLUME_OUT_OF_RANGE); + return; + } + AudioEntry* entry = LookupById(stream_id); if (!entry) { SendErrorMessage(stream_id, INVALID_AUDIO_ENTRY); @@ -575,7 +559,7 @@ AudioEntryMap::iterator i = audio_entries_.find(stream_id); if (i != audio_entries_.end()) return i->second; - return NULL; + return nullptr; } AudioInputRendererHost::AudioEntry* AudioInputRendererHost::LookupByController( @@ -589,7 +573,7 @@ if (controller == i->second->controller.get()) return i->second; } - return NULL; + return nullptr; } void AudioInputRendererHost::MaybeUnregisterKeyboardMicStream(
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.h b/content/browser/renderer_host/media/audio_input_renderer_host.h index 284ef56..a6fa5ae 100644 --- a/content/browser/renderer_host/media/audio_input_renderer_host.h +++ b/content/browser/renderer_host/media/audio_input_renderer_host.h
@@ -30,20 +30,10 @@ #include <memory> #include <string> -#include "base/compiler_specific.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/process/process.h" -#include "base/sequenced_task_runner_helpers.h" #include "content/common/media/audio_messages.h" #include "content/public/browser/browser_message_filter.h" -#include "content/public/browser/browser_thread.h" #include "media/audio/audio_input_controller.h" -#include "media/audio/audio_io.h" -#include "media/audio/audio_logging.h" -#include "media/audio/simple_sources.h" -#include "media/media_features.h" namespace media { class AudioManager; @@ -53,13 +43,12 @@ namespace content { class AudioMirroringManager; class MediaStreamManager; -class RenderProcessHost; class CONTENT_EXPORT AudioInputRendererHost : public BrowserMessageFilter, public media::AudioInputController::EventHandler { public: - // Error codes to make native loggin more clear. These error codes are added + // Error codes to make native logging more clear. These error codes are added // to generic error strings to provide a higher degree of details. // Changing these values can lead to problems when matching native debug // logs with the actual cause of error. @@ -85,20 +74,14 @@ // Failed to create native audio input stream. STREAM_CREATE_ERROR, // = 6 - // Renderer process handle is invalid. - INVALID_PEER_HANDLE, // = 7 - - // Only low-latency mode is supported. - INVALID_LATENCY_MODE, // = 8 - // Failed to map and share the shared memory. - MEMORY_SHARING_FAILED, // = 9 + MEMORY_SHARING_FAILED, // = 7, // Unable to prepare the foreign socket handle. - SYNC_SOCKET_ERROR, // = 10 + SYNC_SOCKET_ERROR, // = 8, // This error message comes from the AudioInputController instance. - AUDIO_INPUT_CONTROLLER_ERROR, // = 11 + AUDIO_INPUT_CONTROLLER_ERROR, // = 9, }; // Called from UI thread from the owner of this object. @@ -135,17 +118,16 @@ // filename. void set_renderer_pid(int32_t renderer_pid); + protected: + ~AudioInputRendererHost() override; + private: - // TODO(henrika): extend test suite (compare AudioRenderHost) friend class BrowserThread; - friend class TestAudioInputRendererHost; friend class base::DeleteHelper<AudioInputRendererHost>; struct AudioEntry; typedef std::map<int, AudioEntry*> AudioEntryMap; - ~AudioInputRendererHost() override; - // Methods called on IO thread ---------------------------------------------- // Audio related IPC message handlers. @@ -160,8 +142,8 @@ // Creates an audio input stream with the specified format whose data is // consumed by an entity in the RenderFrame referenced by |render_frame_id|. - // |session_id| is used to find out which device to be used for the stream. - // Upon success/failure, the peer is notified via the + // |session_id| is used to identify the device that should be used for the + // stream. Upon success/failure, the peer is notified via the // NotifyStreamCreated message. void DoCreateStream(int stream_id, int render_frame_id, @@ -196,7 +178,7 @@ // Send an error message to the renderer. void SendErrorMessage(int stream_id, ErrorCode error_code); - // Delete all audio entry and all audio streams + // Delete all audio entries and all audio streams. void DeleteEntries(); // Closes the stream. The stream is then deleted in DeleteEntry() after it @@ -261,8 +243,6 @@ std::unique_ptr<media::AudioLog> audio_log_; - base::WeakPtrFactory<AudioInputRendererHost> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(AudioInputRendererHost); };
diff --git a/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc new file mode 100644 index 0000000..74997b2 --- /dev/null +++ b/content/browser/renderer_host/media/audio_input_renderer_host_unittest.cc
@@ -0,0 +1,571 @@ +// 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 "content/browser/renderer_host/media/audio_input_renderer_host.h" + +#include <vector> + +#include "base/bind.h" +#include "base/command_line.h" +#include "base/run_loop.h" +#include "content/browser/bad_message.h" +#include "content/browser/media/capture/audio_mirroring_manager.h" +#include "content/browser/renderer_host/media/audio_input_device_manager.h" +#include "content/browser/renderer_host/media/media_stream_manager.h" +#include "content/browser/renderer_host/media/media_stream_ui_proxy.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/mock_render_process_host.h" +#include "content/public/test/test_browser_context.h" +#include "content/public/test/test_browser_thread.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "media/audio/audio_device_description.h" +#include "media/audio/audio_input_writer.h" +#include "media/audio/fake_audio_log_factory.h" +#include "media/audio/fake_audio_manager.h" +#include "media/base/media_switches.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" + +using ::media::AudioInputController; +using ::testing::_; +using ::testing::Assign; +using ::testing::InSequence; +using ::testing::Invoke; +using ::testing::Mock; +using ::testing::NotNull; +using ::testing::SaveArg; +using ::testing::StrictMock; + +namespace content { + +namespace { + +const int kStreamId = 100; +const int kRenderProcessId = 42; +const int kRendererPid = 21718; +const int kRenderFrameId = 31415; +const int kSharedMemoryCount = 11; +const char kSecurityOrigin[] = "http://localhost"; +#if defined(OS_WIN) +const wchar_t kBaseFileName[] = L"some_file_name"; +#else +const char kBaseFileName[] = "some_file_name"; +#endif + +url::Origin SecurityOrigin() { + return url::Origin(GURL(kSecurityOrigin)); +} + +AudioInputHostMsg_CreateStream_Config DefaultConfig() { + AudioInputHostMsg_CreateStream_Config config; + config.params = media::AudioParameters::UnavailableDeviceParams(); + config.automatic_gain_control = false; + config.shared_memory_count = kSharedMemoryCount; + return config; +} + +class MockRenderer { + public: + MOCK_METHOD5(NotifyStreamCreated, + void(int /*stream_id*/, + base::SharedMemoryHandle /*handle*/, + base::SyncSocket::TransitDescriptor /*socket_desriptor*/, + uint32_t /*length*/, + uint32_t /*total_segments*/)); + MOCK_METHOD2(NotifyStreamVolume, void(int /*stream_id*/, double /*volume*/)); + MOCK_METHOD2(NotifyStreamStateChanged, + void(int /*stream_id*/, + media::AudioInputIPCDelegateState /*state*/)); + MOCK_METHOD0(WasShutDown, void()); +}; + +// This class overrides Send to intercept the messages that the +// AudioInputRendererHost sends to the renderer. They are sent to +// the provided MockRenderer instead. +class AudioInputRendererHostWithInterception : public AudioInputRendererHost { + public: + AudioInputRendererHostWithInterception( + int render_process_id, + int32_t renderer_pid, + media::AudioManager* audio_manager, + MediaStreamManager* media_stream_manager, + AudioMirroringManager* audio_mirroring_manager, + media::UserInputMonitor* user_input_monitor, + MockRenderer* renderer) + : AudioInputRendererHost(render_process_id, + renderer_pid, + audio_manager, + media_stream_manager, + audio_mirroring_manager, + user_input_monitor), + renderer_(renderer) { + set_peer_process_for_testing(base::Process::Current()); + } + + protected: + ~AudioInputRendererHostWithInterception() override = default; + + private: + bool Send(IPC::Message* message) override { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + bool handled = true; + + IPC_BEGIN_MESSAGE_MAP(AudioInputRendererHostWithInterception, *message) + IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamCreated, + NotifyRendererStreamCreated) + IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamVolume, + NotifyRendererStreamVolume) + IPC_MESSAGE_HANDLER(AudioInputMsg_NotifyStreamStateChanged, + NotifyRendererStreamStateChanged) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + EXPECT_TRUE(handled); + delete message; + return true; + } + + void ShutdownForBadMessage() override { renderer_->WasShutDown(); } + + void NotifyRendererStreamCreated( + int stream_id, + base::SharedMemoryHandle handle, + base::SyncSocket::TransitDescriptor socket_descriptor, + uint32_t length, + uint32_t total_segments) { + // It's difficult to check that the sync socket and shared memory is + // valid in the gmock macros, so we check them here. + EXPECT_NE(base::SyncSocket::UnwrapHandle(socket_descriptor), + base::SyncSocket::kInvalidHandle); + base::SharedMemory memory(handle, /*read_only*/ true); + EXPECT_TRUE(memory.Map(length)); + renderer_->NotifyStreamCreated(stream_id, handle, socket_descriptor, length, + total_segments); + EXPECT_TRUE(memory.Unmap()); + memory.Close(); + } + + void NotifyRendererStreamVolume(int stream_id, double volume) { + renderer_->NotifyStreamVolume(stream_id, volume); + } + + void NotifyRendererStreamStateChanged( + int stream_id, + media::AudioInputIPCDelegateState state) { + renderer_->NotifyStreamStateChanged(stream_id, state); + } + + MockRenderer* renderer_; +}; + +class MockAudioInputController : public AudioInputController { + public: + MockAudioInputController( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + AudioInputController::SyncWriter* writer, + media::AudioManager* audio_manager, + AudioInputController::EventHandler* event_handler, + media::UserInputMonitor* user_input_monitor) + : AudioInputController(event_handler, + writer, + /*debug_writer*/ nullptr, + user_input_monitor, + /*agc*/ false) { + task_runner_ = std::move(task_runner); + task_runner_->PostTask( + FROM_HERE, + base::Bind(&AudioInputController::EventHandler::OnCreated, + base::Unretained(event_handler), base::Unretained(this))); + ON_CALL(*this, Close(_)) + .WillByDefault(Invoke(this, &MockAudioInputController::ExecuteClose)); + ON_CALL(*this, EnableDebugRecording(_)) + .WillByDefault(SaveArg<0>(&file_name)); + } + + EventHandler* handler() { return handler_; } + + // File name that we pretend to do a debug recording to, if any. + base::FilePath debug_file_name() { return file_name; } + + MOCK_METHOD0(Record, void()); + MOCK_METHOD1(Close, void(const base::Closure&)); + MOCK_METHOD1(SetVolume, void(double)); + MOCK_METHOD1(EnableDebugRecording, void(const base::FilePath&)); + MOCK_METHOD0(DisableDebugRecording, void()); + + // AudioInputCallback impl, irrelevant to us. + MOCK_METHOD4( + OnData, + void(media::AudioInputStream*, const media::AudioBus*, uint32_t, double)); + MOCK_METHOD1(OnError, void(media::AudioInputStream*)); + + protected: + ~MockAudioInputController() override = default; + + private: + void ExecuteClose(const base::Closure& task) { + // Hop to audio manager thread before calling task, since this is the real + // behavior. + task_runner_->PostTaskAndReply(FROM_HERE, base::Bind([]() {}), task); + } + + base::FilePath file_name; +}; + +class MockControllerFactory : public AudioInputController::Factory { + public: + using MockController = StrictMock<MockAudioInputController>; + + MockControllerFactory() { + AudioInputController::set_factory_for_testing(this); + } + + ~MockControllerFactory() override { + AudioInputController::set_factory_for_testing(nullptr); + } + + // AudioInputController::Factory implementaion: + AudioInputController* Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + AudioInputController::SyncWriter* sync_writer, + media::AudioManager* audio_manager, + AudioInputController::EventHandler* event_handler, + media::AudioParameters params, + media::UserInputMonitor* user_input_monitor) override { + ControllerCreated(); + scoped_refptr<MockController> controller = + new MockController(std::move(task_runner), sync_writer, audio_manager, + event_handler, user_input_monitor); + controller_list_.push_back(controller); + return controller.get(); + } + + MockController* controller(size_t i) { + EXPECT_GT(controller_list_.size(), i); + return controller_list_[i].get(); + } + + MOCK_METHOD0(ControllerCreated, void()); + + private: + std::vector<scoped_refptr<MockController>> controller_list_; +}; + +} // namespace + +class AudioInputRendererHostTest : public testing::Test { + public: + AudioInputRendererHostTest() { + base::CommandLine* flags = base::CommandLine::ForCurrentProcess(); + flags->AppendSwitch(switches::kUseFakeDeviceForMediaStream); + flags->AppendSwitch(switches::kUseFakeUIForMediaStream); + + audio_manager_.reset(new media::FakeAudioManager( + base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), &log_factory_)); + media_stream_manager_ = + base::MakeUnique<MediaStreamManager>(audio_manager_.get()); + airh_ = new AudioInputRendererHostWithInterception( + kRenderProcessId, kRendererPid, media::AudioManager::Get(), + media_stream_manager_.get(), AudioMirroringManager::GetInstance(), + nullptr, &renderer_); + } + + ~AudioInputRendererHostTest() override { + airh_->OnChannelClosing(); + base::RunLoop().RunUntilIdle(); + } + + protected: + // Makes device |device_id| with name |name| available to open with the + // session id returned. + int Open(const std::string& device_id, const std::string& name) { + int session_id = media_stream_manager_->audio_input_device_manager()->Open( + StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, name, device_id)); + base::RunLoop().RunUntilIdle(); + return session_id; + } + + std::string GetRawNondefaultId() { + std::string id; + MediaDevicesManager::BoolDeviceTypes devices_to_enumerate; + devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true; + + media_stream_manager_->media_devices_manager()->EnumerateDevices( + devices_to_enumerate, + base::Bind( + [](std::string* id, const MediaDeviceEnumeration& result) { + // Index 0 is default, so use 1. + CHECK(result[MediaDeviceType::MEDIA_DEVICE_TYPE_AUDIO_INPUT] + .size() > 1) + << "Expected to have a nondefault device."; + *id = result[MediaDeviceType::MEDIA_DEVICE_TYPE_AUDIO_INPUT][1] + .device_id; + }, + base::Unretained(&id))); + base::RunLoop().RunUntilIdle(); + return id; + } + + media::FakeAudioLogFactory log_factory_; + StrictMock<MockControllerFactory> controller_factory_; + std::unique_ptr<MediaStreamManager> media_stream_manager_; + TestBrowserThreadBundle thread_bundle_; + media::ScopedAudioManagerPtr audio_manager_; + StrictMock<MockRenderer> renderer_; + scoped_refptr<AudioInputRendererHost> airh_; + + private: + DISALLOW_COPY_AND_ASSIGN(AudioInputRendererHostTest); +}; + +// Checks that a controller is created and a reply is sent when creating a +// stream. +TEST_F(AudioInputRendererHostTest, CreateWithDefaultDevice) { + int session_id = + Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(controller_factory_, ControllerCreated()); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + + base::RunLoop().RunUntilIdle(); + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); +} + +// If authorization hasn't been granted, only reply with and error and do +// nothing else. +TEST_F(AudioInputRendererHostTest, CreateWithoutAuthorization_Error) { + EXPECT_CALL(renderer_, + NotifyStreamStateChanged( + kStreamId, media::AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR)); + + int session_id = 0; + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + base::RunLoop().RunUntilIdle(); +} + +// Like CreateWithDefaultDevice but with a nondefault device. +TEST_F(AudioInputRendererHostTest, CreateWithNonDefaultDevice) { + int session_id = Open("Nondefault device", GetRawNondefaultId()); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(controller_factory_, ControllerCreated()); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + + base::RunLoop().RunUntilIdle(); + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); +} + +// Checks that stream is started when calling record. +TEST_F(AudioInputRendererHostTest, CreateRecordClose) { + int session_id = + Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(controller_factory_, ControllerCreated()); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + base::RunLoop().RunUntilIdle(); + + EXPECT_CALL(*controller_factory_.controller(0), Record()); + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); + + airh_->OnMessageReceived(AudioInputHostMsg_RecordStream(kStreamId)); + base::RunLoop().RunUntilIdle(); + airh_->OnMessageReceived(AudioInputHostMsg_CloseStream(kStreamId)); + base::RunLoop().RunUntilIdle(); +} + +// In addition to the above, also check that a SetVolume message is propagated +// to the controller. +TEST_F(AudioInputRendererHostTest, CreateSetVolumeRecordClose) { + int session_id = + Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(controller_factory_, ControllerCreated()); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + base::RunLoop().RunUntilIdle(); + + EXPECT_CALL(*controller_factory_.controller(0), SetVolume(0.5)); + EXPECT_CALL(*controller_factory_.controller(0), Record()); + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); + + airh_->OnMessageReceived(AudioInputHostMsg_SetVolume(kStreamId, 0.5)); + airh_->OnMessageReceived(AudioInputHostMsg_RecordStream(kStreamId)); + airh_->OnMessageReceived(AudioInputHostMsg_CloseStream(kStreamId)); + + base::RunLoop().RunUntilIdle(); +} + +// Check that a too large volume is treated like a bad message and doesn't +// reach the controller. +TEST_F(AudioInputRendererHostTest, SetVolumeTooLarge_BadMessage) { + int session_id = + Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(controller_factory_, ControllerCreated()); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + base::RunLoop().RunUntilIdle(); + + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); + EXPECT_CALL(renderer_, WasShutDown()); + + airh_->OnMessageReceived(AudioInputHostMsg_SetVolume(kStreamId, 5)); + + base::RunLoop().RunUntilIdle(); +} + +// Like above. +TEST_F(AudioInputRendererHostTest, SetVolumeNegative_BadMessage) { + int session_id = + Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(controller_factory_, ControllerCreated()); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + base::RunLoop().RunUntilIdle(); + + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); + EXPECT_CALL(renderer_, WasShutDown()); + + airh_->OnMessageReceived(AudioInputHostMsg_SetVolume(kStreamId, -0.5)); + + base::RunLoop().RunUntilIdle(); +} + +// Checks that a stream_id cannot be reused. +TEST_F(AudioInputRendererHostTest, CreateTwice_Error) { + int session_id = + Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(renderer_, + NotifyStreamStateChanged( + kStreamId, media::AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR)); + EXPECT_CALL(controller_factory_, ControllerCreated()); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + base::RunLoop().RunUntilIdle(); + + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); +} + +// Checks that when two streams are created, messages are routed to the correct +// stream. Also checks that when enabling debug recording, the streams get +// different file names. +TEST_F(AudioInputRendererHostTest, TwoStreams) { + int session_id = + Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId + 1, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(controller_factory_, ControllerCreated()).Times(2); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId + 1, kRenderFrameId, session_id, DefaultConfig())); + base::RunLoop().RunUntilIdle(); + +#if BUILDFLAG(ENABLE_WEBRTC) + EXPECT_CALL(*controller_factory_.controller(0), EnableDebugRecording(_)); + EXPECT_CALL(*controller_factory_.controller(1), EnableDebugRecording(_)); + + airh_->EnableDebugRecording(base::FilePath(kBaseFileName)); + base::RunLoop().RunUntilIdle(); + + EXPECT_NE(controller_factory_.controller(0)->debug_file_name(), + controller_factory_.controller(1)->debug_file_name()); + EXPECT_CALL(*controller_factory_.controller(0), DisableDebugRecording()); + EXPECT_CALL(*controller_factory_.controller(1), DisableDebugRecording()); + + airh_->DisableDebugRecording(); +#endif // ENABLE_WEBRTC + + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); + EXPECT_CALL(*controller_factory_.controller(1), Close(_)); +} + +// Checks that the stream is properly cleaned up and a notification is sent to +// the renderer when the stream encounters an error. +TEST_F(AudioInputRendererHostTest, Error_ClosesController) { + int session_id = + Open("Default device", media::AudioDeviceDescription::kDefaultDeviceId); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(controller_factory_, ControllerCreated()); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + + base::RunLoop().RunUntilIdle(); + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); + EXPECT_CALL(renderer_, + NotifyStreamStateChanged( + kStreamId, media::AUDIO_INPUT_IPC_DELEGATE_STATE_ERROR)); + + controller_factory_.controller(0)->handler()->OnError( + controller_factory_.controller(0), AudioInputController::UNKNOWN_ERROR); + + // Check Close expectation before the destructor. + base::RunLoop().RunUntilIdle(); + Mock::VerifyAndClear(controller_factory_.controller(0)); +} + +// Checks that tab capture streams can be created. +TEST_F(AudioInputRendererHostTest, TabCaptureStream) { + StreamControls controls(/* request_audio */ true, /* request_video */ false); + controls.audio.device_id = base::StringPrintf( + "web-contents-media-stream://%d:%d", kRenderProcessId, kRenderFrameId); + controls.audio.stream_source = kMediaStreamSourceTab; + std::string request_label = media_stream_manager_->MakeMediaAccessRequest( + kRenderProcessId, kRenderFrameId, 0, controls, SecurityOrigin(), + base::Bind([](const MediaStreamDevices& devices, + std::unique_ptr<MediaStreamUIProxy>) {})); + base::RunLoop().RunUntilIdle(); + int session_id = Open("Tab capture", controls.audio.device_id); + + EXPECT_CALL(renderer_, + NotifyStreamCreated(kStreamId, _, _, _, kSharedMemoryCount)); + EXPECT_CALL(controller_factory_, ControllerCreated()); + + airh_->OnMessageReceived(AudioInputHostMsg_CreateStream( + kStreamId, kRenderFrameId, session_id, DefaultConfig())); + base::RunLoop().RunUntilIdle(); + + EXPECT_CALL(*controller_factory_.controller(0), Close(_)); +} + +} // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index a33e65d7..adf4451 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -29,7 +29,6 @@ #include "build/build_config.h" #include "cc/base/switches.h" #include "cc/output/compositor_frame.h" -#include "content/browser/accessibility/accessibility_mode_helper.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/bad_message.h" #include "content/browser/browser_plugin/browser_plugin_guest.h"
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index dc72ecc..71b1dcb 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -1346,10 +1346,6 @@ // https://crbug.com/491334 #define MAYBE_SurfaceHitTestPointerEventsNone \ DISABLED_SurfaceHitTestPointerEventsNone -#elif defined(THREAD_SANITIZER) -// Flaky on TSAN. https://crbug.com/582277 -#define MAYBE_SurfaceHitTestPointerEventsNone \ - DISABLED_SurfaceHitTestPointerEventsNone #else #define MAYBE_SurfaceHitTestPointerEventsNone SurfaceHitTestPointerEventsNone #endif
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index bd1a646..35f0efe1 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -32,7 +32,6 @@ #include "components/mime_util/mime_util.h" #include "components/rappor/public/rappor_utils.h" #include "components/url_formatter/url_formatter.h" -#include "content/browser/accessibility/accessibility_mode_helper.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/bad_message.h" #include "content/browser/browser_plugin/browser_plugin_embedder.h" @@ -963,11 +962,7 @@ } void WebContentsImpl::AddAccessibilityMode(AccessibilityMode mode) { - SetAccessibilityMode(AddAccessibilityModeTo(accessibility_mode_, mode)); -} - -void WebContentsImpl::RemoveAccessibilityMode(AccessibilityMode mode) { - SetAccessibilityMode(RemoveAccessibilityModeFrom(accessibility_mode_, mode)); + SetAccessibilityMode(accessibility_mode_ | mode); } void WebContentsImpl::RequestAXTreeSnapshot(AXTreeSnapshotCallback callback) { @@ -1078,21 +1073,21 @@ return renderer_preferences_.user_agent_override; } -void WebContentsImpl::EnableTreeOnlyAccessibilityMode() { +void WebContentsImpl::EnableWebContentsOnlyAccessibilityMode() { if (GetAccessibilityMode() != AccessibilityModeOff) { for (RenderFrameHost* rfh : GetAllFrames()) ResetAccessibility(rfh); } else { - AddAccessibilityMode(AccessibilityModeTreeOnly); + AddAccessibilityMode(ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY); } } -bool WebContentsImpl::IsTreeOnlyAccessibilityModeForTesting() const { - return accessibility_mode_ == AccessibilityModeTreeOnly; +bool WebContentsImpl::IsWebContentsOnlyAccessibilityModeForTesting() const { + return accessibility_mode_ == ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY; } bool WebContentsImpl::IsFullAccessibilityModeForTesting() const { - return accessibility_mode_ == AccessibilityModeComplete; + return accessibility_mode_ == ACCESSIBILITY_MODE_COMPLETE; } const PageImportanceSignals& WebContentsImpl::GetPageImportanceSignals() const {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 5644671e..589ad951 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -226,12 +226,6 @@ // bitmap. void AddAccessibilityMode(AccessibilityMode mode); - // Removes the given accessibility mode from the current accessibility - // mode bitmap, managing the bits that are shared with other modes such - // that a bit will only be turned off when all modes that depend on it - // have been removed. - void RemoveAccessibilityMode(AccessibilityMode mode); - // Request a one-time snapshot of the accessibility tree without changing // the accessibility mode. using AXTreeSnapshotCallback = @@ -294,8 +288,8 @@ WebUI* GetCommittedWebUI() const override; void SetUserAgentOverride(const std::string& override) override; const std::string& GetUserAgentOverride() const override; - void EnableTreeOnlyAccessibilityMode() override; - bool IsTreeOnlyAccessibilityModeForTesting() const override; + void EnableWebContentsOnlyAccessibilityMode() override; + bool IsWebContentsOnlyAccessibilityModeForTesting() const override; bool IsFullAccessibilityModeForTesting() const override; const PageImportanceSignals& GetPageImportanceSignals() const override; const base::string16& GetTitle() const override;
diff --git a/content/common/accessibility_mode_enums.h b/content/common/accessibility_mode_enums.h index ae059f2..46f8b4b 100644 --- a/content/common/accessibility_mode_enums.h +++ b/content/common/accessibility_mode_enums.h
@@ -8,27 +8,61 @@ // Note: keep enums in content/browser/resources/accessibility/accessibility.js // in sync with these two enums. enum AccessibilityModeFlag { - // Accessibility updates are processed to create platform trees and events are - // passed to platform APIs in the browser. - AccessibilityModeFlagPlatform = 1 << 0, + // Native accessibility APIs, specific to each platform, are enabled. + // When this flag is set that indicates the presence of a third-party + // client accessing Chrome via accessibility APIs. However, unless one + // of the flags below is set, the contents of web pages will not be + // accessible. + ACCESSIBILITY_MODE_FLAG_NATIVE_APIS = 1 << 0, - // Accessibility is on, and the full tree is computed. If this flag is off, - // only limited information about editable text nodes is sent to the browser - // process. Useful for implementing limited UIA on tablets. - AccessibilityModeFlagFullTree = 1 << 1, + // The renderer process will generate an accessibility tree containing + // basic information about all nodes, including role, name, value, + // state, and location. This is the minimum flag required in order for + // web contents to be accessible, and the remaining flags are meaningless + // unless this one is set. + // + // Note that sometimes this flag will be set when + // ACCESSIBILITY_MODE_FLAG_NATIVE_APIS is not, when the content layer embedder + // is providing accessibility support via some other mechanism other than + // what's implemented in content/browser. + ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS = 1 << 1, + + // The accessibility tree will contain inline text boxes, which are + // necessary to expose information about line breaks and word boundaries. + // Without this flag, you can retrieve the plaintext value of a text field + // but not the information about how it's broken down into lines. + // + // Note that when this flag is off it's still possible to request inline + // text boxes for a specific node on-demand, asynchronously. + ACCESSIBILITY_MODE_FLAG_INLINE_TEXT_BOXES = 1 << 2, + + // The accessibility tree will contain extra accessibility + // attributes typically only needed by screen readers and other + // assistive technology for blind users. Examples include text style + // attributes, table cell information, live region properties, range + // values, and relationship attributes. + ACCESSIBILITY_MODE_FLAG_SCREEN_READER = 1 << 3, + + // The accessibility tree will contain the HTML tag name and HTML attributes + // for all accessibility nodes that come from web content. + ACCESSIBILITY_MODE_FLAG_HTML = 1 << 4, }; -enum AccessibilityMode { - // All accessibility is off. - AccessibilityModeOff = 0, +typedef int AccessibilityMode; - // Renderer accessibility is on, and platform APIs are called. - AccessibilityModeComplete = - AccessibilityModeFlagPlatform | AccessibilityModeFlagFullTree, +const AccessibilityMode AccessibilityModeOff = 0; - // Renderer accessibility is on, and events are passed to any extensions - // requesting automation, but not to platform accessibility. - AccessibilityModeTreeOnly = AccessibilityModeFlagFullTree, -}; +const AccessibilityMode ACCESSIBILITY_MODE_COMPLETE = + ACCESSIBILITY_MODE_FLAG_NATIVE_APIS | + ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS | + ACCESSIBILITY_MODE_FLAG_INLINE_TEXT_BOXES | + ACCESSIBILITY_MODE_FLAG_SCREEN_READER | + ACCESSIBILITY_MODE_FLAG_HTML; + +const AccessibilityMode ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY = + ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS | + ACCESSIBILITY_MODE_FLAG_INLINE_TEXT_BOXES | + ACCESSIBILITY_MODE_FLAG_SCREEN_READER | + ACCESSIBILITY_MODE_FLAG_HTML; #endif // CONTENT_COMMON_ACCESSIBILITY_MODE_ENUMS_H_
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 478fb11..39326bd 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -80,9 +80,6 @@ #define IPC_MESSAGE_START FrameMsgStart -IPC_ENUM_TRAITS_MIN_MAX_VALUE(AccessibilityMode, - AccessibilityModeOff, - AccessibilityModeComplete) IPC_ENUM_TRAITS_MIN_MAX_VALUE(content::JavaScriptMessageType, content::JAVASCRIPT_MESSAGE_TYPE_ALERT, content::JAVASCRIPT_MESSAGE_TYPE_PROMPT)
diff --git a/content/public/browser/media_session.h b/content/public/browser/media_session.h index 78a1889..509629f 100644 --- a/content/public/browser/media_session.h +++ b/content/public/browser/media_session.h
@@ -55,6 +55,14 @@ // Tell the media session a user action has performed. virtual void DidReceiveAction(blink::mojom::MediaSessionAction action) = 0; + // Let the media session start ducking such that the volume multiplier is + // reduced. + virtual void StartDucking() = 0; + + // Let the media session stop ducking such that the volume multiplier is + // recovered. + virtual void StopDucking() = 0; + protected: MediaSession() = default; };
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index dab1686..a5e2535 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -302,13 +302,13 @@ virtual void SetUserAgentOverride(const std::string& override) = 0; virtual const std::string& GetUserAgentOverride() const = 0; - // Enable the accessibility tree for this WebContents in the renderer, - // but don't enable creating a native accessibility tree on the browser - // side. - virtual void EnableTreeOnlyAccessibilityMode() = 0; + // Set the accessibility mode so that accessibility events are forwarded + // to each WebContentsObserver. + virtual void EnableWebContentsOnlyAccessibilityMode() = 0; - // Returns true only if "tree only" accessibility mode is on. - virtual bool IsTreeOnlyAccessibilityModeForTesting() const = 0; + // Returns true only if the WebContentsObserver accessibility mode is + // enabled. + virtual bool IsWebContentsOnlyAccessibilityModeForTesting() const = 0; // Returns true only if complete accessibility mode is on, meaning there's // both renderer accessibility, and a native browser accessibility tree.
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h index 6d945a2..74218f22 100644 --- a/content/public/browser/web_contents_observer.h +++ b/content/public/browser/web_contents_observer.h
@@ -445,12 +445,11 @@ // Invoked when a user cancels a before unload dialog. virtual void BeforeUnloadDialogCancelled() {} - // Invoked when an accessibility event is received from the renderer process. + // Called when accessibility events or location changes are received + // from a render frame, but only when the accessibility mode has the + // ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS flag set. virtual void AccessibilityEventReceived( const std::vector<AXEventNotificationDetails>& details) {} - - // Invoked when an accessibility location change is received from the - // renderer process. virtual void AccessibilityLocationChangesReceived( const std::vector<AXLocationChangeNotificationDetails>& details) {}
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 0bac669..fac5648 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -27,7 +27,6 @@ #include "build/build_config.h" #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_manager.h" -#include "content/browser/accessibility/accessibility_mode_helper.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/browser_plugin/browser_plugin_guest.h" @@ -1027,7 +1026,7 @@ void EnableAccessibilityForWebContents(WebContents* web_contents) { WebContentsImpl* web_contents_impl = static_cast<WebContentsImpl*>(web_contents); - web_contents_impl->SetAccessibilityMode(AccessibilityModeComplete); + web_contents_impl->SetAccessibilityMode(ACCESSIBILITY_MODE_COMPLETE); } void WaitForAccessibilityFocusChange() {
diff --git a/content/renderer/media/audio_input_message_filter.cc b/content/renderer/media/audio_input_message_filter.cc index ff24d70..1659af3c8 100644 --- a/content/renderer/media/audio_input_message_filter.cc +++ b/content/renderer/media/audio_input_message_filter.cc
@@ -215,6 +215,8 @@ void AudioInputMessageFilter::AudioInputIPCImpl::SetVolume(double volume) { DCHECK_NE(stream_id_, kStreamIDNotSet); + DCHECK_GE(volume, 0); + DCHECK_LE(volume, 1); filter_->Send(new AudioInputHostMsg_SetVolume(stream_id_, volume)); }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index df68a66..0179a9c 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -2117,7 +2117,7 @@ render_accessibility_ = NULL; } - if (accessibility_mode_ & AccessibilityModeFlagFullTree) + if (accessibility_mode_ & ACCESSIBILITY_MODE_FLAG_WEB_CONTENTS) render_accessibility_ = new RenderAccessibilityImpl(this); for (auto& observer : observers_)
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 88d711e..c0bc0a4 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -1969,16 +1969,17 @@ ASSERT_EQ(AccessibilityModeOff, frame()->accessibility_mode()); ASSERT_FALSE(frame()->render_accessibility()); - frame()->SetAccessibilityMode(AccessibilityModeTreeOnly); - ASSERT_EQ(AccessibilityModeTreeOnly, frame()->accessibility_mode()); + frame()->SetAccessibilityMode(ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY); + ASSERT_EQ(ACCESSIBILITY_MODE_WEB_CONTENTS_ONLY, + frame()->accessibility_mode()); ASSERT_TRUE(frame()->render_accessibility()); frame()->SetAccessibilityMode(AccessibilityModeOff); ASSERT_EQ(AccessibilityModeOff, frame()->accessibility_mode()); ASSERT_FALSE(frame()->render_accessibility()); - frame()->SetAccessibilityMode(AccessibilityModeComplete); - ASSERT_EQ(AccessibilityModeComplete, frame()->accessibility_mode()); + frame()->SetAccessibilityMode(ACCESSIBILITY_MODE_COMPLETE); + ASSERT_EQ(ACCESSIBILITY_MODE_COMPLETE, frame()->accessibility_mode()); ASSERT_TRUE(frame()->render_accessibility()); }
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 6115d96..16dc1388 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -2627,8 +2627,8 @@ AccessibilityMode accessibility_mode = GetMainRenderFrame()->accessibility_mode(); bool matches_accessibility_mode_complete = - (accessibility_mode & AccessibilityModeComplete) == - AccessibilityModeComplete; + (accessibility_mode & ACCESSIBILITY_MODE_COMPLETE) == + ACCESSIBILITY_MODE_COMPLETE; if (matches_accessibility_mode_complete) return false;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 66fe09d..749c1cfd5 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -941,7 +941,6 @@ defines = [] sources = [ - "../browser/accessibility/accessibility_mode_helper_unittest.cc", "../browser/accessibility/browser_accessibility_mac_unittest.mm", "../browser/accessibility/browser_accessibility_manager_unittest.cc", "../browser/accessibility/browser_accessibility_win_unittest.cc", @@ -1180,6 +1179,7 @@ "../browser/renderer_host/input/web_input_event_util_unittest.cc", "../browser/renderer_host/media/audio_input_debug_writer_unittest.cc", "../browser/renderer_host/media/audio_input_device_manager_unittest.cc", + "../browser/renderer_host/media/audio_input_renderer_host_unittest.cc", "../browser/renderer_host/media/audio_input_sync_writer_unittest.cc", "../browser/renderer_host/media/audio_output_authorization_handler_unittest.cc", "../browser/renderer_host/media/audio_output_delegate_unittest.cc",
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index 7cd41523..bf6ae6b 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -48,6 +48,8 @@ bug=660844) # WebGL 2.0.1 self.Fail('conformance2/rendering/rendering-sampling-feedback-loop.html', bug=660844) # WebGL 2.0.1 + self.Fail('conformance2/rendering/read-draw-when-missing-image.html', + bug=672719) # WebGL 2.0.1 self.Fail('conformance2/glsl3/float-parsing.html', bug=672722) # WebGL 2.0.1 self.Fail('conformance2/textures/misc/' +
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 06457f1..cd5e0ae 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -7912,10 +7912,6 @@ return; } - // Detect that designated read/depth/stencil buffer in read framebuffer miss - // image, and the corresponding buffers in draw framebuffer have image. - bool read_framebuffer_miss_image = false; - // Check whether read framebuffer and draw framebuffer have identical image // TODO(yunchao): consider doing something like CheckFramebufferStatus(). // We cache the validation results, and if read_framebuffer doesn't change, @@ -7939,18 +7935,6 @@ is_feedback_loop = FeedbackLoopTrue; } else if (!read_framebuffer || !draw_framebuffer) { is_feedback_loop = FeedbackLoopFalse; - if (read_framebuffer) { - if (((mask & GL_COLOR_BUFFER_BIT) != 0 && - !GetBoundReadFramebufferInternalFormat()) || - ((mask & GL_DEPTH_BUFFER_BIT) != 0 && - !read_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT) && - BoundFramebufferHasDepthAttachment()) || - ((mask & GL_STENCIL_BUFFER_BIT) != 0 && - !read_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT) && - BoundFramebufferHasStencilAttachment())) { - read_framebuffer_miss_image = true; - } - } } else { DCHECK(read_framebuffer && draw_framebuffer); if ((mask & GL_DEPTH_BUFFER_BIT) != 0) { @@ -7960,9 +7944,6 @@ draw_framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT); if (!depth_buffer_draw || !depth_buffer_read) { mask &= ~GL_DEPTH_BUFFER_BIT; - if (depth_buffer_draw) { - read_framebuffer_miss_image = true; - } } else if (depth_buffer_draw->IsSameAttachment(depth_buffer_read)) { is_feedback_loop = FeedbackLoopTrue; } @@ -7974,14 +7955,11 @@ draw_framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT); if (!stencil_buffer_draw || !stencil_buffer_read) { mask &= ~GL_STENCIL_BUFFER_BIT; - if (stencil_buffer_draw) { - read_framebuffer_miss_image = true; - } } else if (stencil_buffer_draw->IsSameAttachment(stencil_buffer_read)) { is_feedback_loop = FeedbackLoopTrue; } } - if (!mask && !read_framebuffer_miss_image) + if (!mask) return; } @@ -8016,9 +7994,6 @@ GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii)); if (dst_format == 0) continue; - if (!src_internal_format) { - read_framebuffer_miss_image = true; - } if (GetColorEncodingFromInternalFormat(dst_format) == GL_SRGB) draw_buffers_has_srgb = true; if (read_buffer_samples > 0 && @@ -8058,11 +8033,6 @@ "source buffer and destination buffers are identical"); return; } - if (read_framebuffer_miss_image == true) { - LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, - "The designated attachment point(s) in read framebuffer miss image"); - return; - } if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) { if (filter != GL_NEAREST) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc index 3a0e0be..65c8c28b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
@@ -3961,18 +3961,21 @@ 1.0f, // depth false, // scissor test 0, 0, 128, 64); + EXPECT_CALL(*gl_, BlitFramebufferEXT(0, 0, _, _, 0, 0, _, _, + GL_COLOR_BUFFER_BIT, GL_LINEAR)) + .Times(1) + .RetiresOnSaturation(); BlitFramebufferCHROMIUM cmd; cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_LINEAR); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - // Generate INVALID_OPERATION because of missing read buffer image. - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); } } TEST_P(GLES3DecoderTest, BlitFramebufferMissingDepthOrStencil) { // Run BlitFramebufferCHROMIUM with depth or stencil bits, from/to a read/draw - // framebuffer that doesn't have depth/stencil. It should generate - // INVALID_OPERATION. + // framebuffer that doesn't have depth/stencil. The bits should be silently + // ignored. DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId); DoRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, @@ -4020,13 +4023,16 @@ EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER)) .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BlitFramebufferEXT(0, 0, 1, 1, 0, 0, 1, 1, + _, _)) + .Times(0); BlitFramebufferCHROMIUM cmd; cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_DEPTH_BUFFER_BIT, GL_NEAREST); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_STENCIL_BUFFER_BIT, GL_NEAREST); EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); } // Switch FBOs and try the same.
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index 5d6c5c2d..bcea0d6f 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -175,6 +175,7 @@ "//ios/chrome/browser/open_from_clipboard", "//ios/chrome/browser/physical_web", "//ios/chrome/browser/prefs", + "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/services/gcm", "//ios/chrome/browser/translate", "//ios/chrome/browser/update_client",
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn index 50c1e4f..ff04e6ea 100644 --- a/ios/chrome/browser/browser_state/BUILD.gn +++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -89,6 +89,7 @@ "//ios/chrome/browser/ntp_snippets", "//ios/chrome/browser/passwords", "//ios/chrome/browser/prefs", + "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/reading_list", "//ios/chrome/browser/search_engines", "//ios/chrome/browser/services/gcm", @@ -109,7 +110,7 @@ "//ios/chrome/browser", "//ios/chrome/browser/browser_state_metrics", "//ios/chrome/browser/net", - "//ios/chrome/browser/prefs", + "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/signin", "//ios/chrome/browser/sync", "//ios/chrome/browser/sync/glue", @@ -146,6 +147,7 @@ "//ios/chrome/browser/history", "//ios/chrome/browser/net", "//ios/chrome/browser/prefs", + "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/sync/glue", "//ios/chrome/test:test_support", "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/device_sharing/BUILD.gn b/ios/chrome/browser/device_sharing/BUILD.gn index 2c22242..ef719c3f 100644 --- a/ios/chrome/browser/device_sharing/BUILD.gn +++ b/ios/chrome/browser/device_sharing/BUILD.gn
@@ -12,7 +12,6 @@ "//base", "//components/handoff", "//components/prefs", - "//ios/chrome/browser", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/prefs", "//net", @@ -30,7 +29,6 @@ "//base", "//components/handoff", "//components/sync_preferences:test_support", - "//ios/chrome/browser", "//ios/chrome/browser/browser_state:test_support", "//ios/web:test_support", "//testing/gtest",
diff --git a/ios/chrome/browser/device_sharing/device_sharing_manager.mm b/ios/chrome/browser/device_sharing/device_sharing_manager.mm index 1039eb5..5449d181 100644 --- a/ios/chrome/browser/device_sharing/device_sharing_manager.mm +++ b/ios/chrome/browser/device_sharing/device_sharing_manager.mm
@@ -8,10 +8,10 @@ #include "base/mac/scoped_nsobject.h" #import "components/handoff/handoff_manager.h" +#include "components/handoff/pref_names_ios.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/prefs/pref_observer_bridge.h" #include "url/gurl.h"
diff --git a/ios/chrome/browser/device_sharing/device_sharing_manager_unittest.mm b/ios/chrome/browser/device_sharing/device_sharing_manager_unittest.mm index afa58dc5..33d5024 100644 --- a/ios/chrome/browser/device_sharing/device_sharing_manager_unittest.mm +++ b/ios/chrome/browser/device_sharing/device_sharing_manager_unittest.mm
@@ -9,9 +9,9 @@ #include "base/mac/foundation_util.h" #include "base/mac/scoped_nsobject.h" #import "components/handoff/handoff_manager.h" +#include "components/handoff/pref_names_ios.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" -#include "ios/chrome/browser/pref_names.h" #include "ios/web/public/test/test_web_thread_bundle.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h"
diff --git a/ios/chrome/browser/ntp_tiles/ios_popular_sites_factory.cc b/ios/chrome/browser/ntp_tiles/ios_popular_sites_factory.cc index 577f30cd..e1282205 100644 --- a/ios/chrome/browser/ntp_tiles/ios_popular_sites_factory.cc +++ b/ios/chrome/browser/ntp_tiles/ios_popular_sites_factory.cc
@@ -21,7 +21,7 @@ ios::ChromeBrowserState* browser_state) { base::FilePath popular_sites_path; base::PathService::Get(ios::DIR_USER_DATA, &popular_sites_path); - return base::MakeUnique<ntp_tiles::PopularSites>( + return base::MakeUnique<ntp_tiles::PopularSitesImpl>( web::WebThread::GetBlockingPool(), browser_state->GetPrefs(), ios::TemplateURLServiceFactory::GetForBrowserState(browser_state), GetApplicationContext()->GetVariationsService(),
diff --git a/ios/chrome/browser/pref_names.h b/ios/chrome/browser/pref_names.h index feff827..1d0d9ad 100644 --- a/ios/chrome/browser/pref_names.h +++ b/ios/chrome/browser/pref_names.h
@@ -5,11 +5,6 @@ #ifndef IOS_CHROME_BROWSER_PREF_NAMES_H_ #define IOS_CHROME_BROWSER_PREF_NAMES_H_ -// TODO(crbug.com/663469): Remove these includes once embedders are migrated to -// use the new pref header. -#include "components/handoff/pref_names_ios.h" -#include "ios/public/provider/chrome/browser/voice/voice_search_prefs.h" - namespace prefs { extern const char kAcceptLanguages[];
diff --git a/ios/chrome/browser/prefs/BUILD.gn b/ios/chrome/browser/prefs/BUILD.gn index 459855a6..84c6e4a 100644 --- a/ios/chrome/browser/prefs/BUILD.gn +++ b/ios/chrome/browser/prefs/BUILD.gn
@@ -4,8 +4,6 @@ source_set("prefs") { sources = [ - "browser_prefs.h", - "browser_prefs.mm", "ios_chrome_pref_model_associator_client.cc", "ios_chrome_pref_model_associator_client.h", "ios_chrome_pref_service_factory.cc", @@ -15,6 +13,26 @@ ] deps = [ "//base", + "//components/content_settings/core/browser", + "//components/prefs", + "//components/proxy_config", + "//components/search_engines", + "//components/sync_preferences", + "//ios/chrome/browser", + ] + + # TODO(sdefresne): remove once downstream dependencies have been fixed. + public_deps = [ + ":browser_prefs", + ] +} + +source_set("browser_prefs") { + sources = [ + "browser_prefs.h", + "browser_prefs.mm", + ] + deps = [ "//components/autofill/core/browser", "//components/browsing_data/core", "//components/content_settings/core/browser", @@ -36,7 +54,6 @@ "//components/ssl_config", "//components/strings", "//components/sync", - "//components/sync_preferences", "//components/translate/core/browser", "//components/translate/core/common", "//components/update_client", @@ -50,7 +67,6 @@ "//ios/chrome/browser/metrics", "//ios/chrome/browser/net", "//ios/chrome/browser/physical_web", - "//ios/chrome/browser/reading_list", "//ios/chrome/browser/signin", "//ios/chrome/browser/voice:prefs", "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index 7f0c97d..5affdc0 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -93,7 +93,7 @@ ntp_snippets::RemoteSuggestionsProvider::RegisterProfilePrefs(registry); ntp_snippets::ContentSuggestionsService::RegisterProfilePrefs(registry); ntp_tiles::MostVisitedSites::RegisterProfilePrefs(registry); - ntp_tiles::PopularSites::RegisterProfilePrefs(registry); + ntp_tiles::PopularSitesImpl::RegisterProfilePrefs(registry); ios::NotificationPromo::RegisterProfilePrefs(registry); password_manager::PasswordManager::RegisterProfilePrefs(registry); PrefProxyConfigTrackerImpl::RegisterProfilePrefs(registry);
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn index 4a13d58..c31264b 100644 --- a/ios/chrome/browser/signin/BUILD.gn +++ b/ios/chrome/browser/signin/BUILD.gn
@@ -120,7 +120,7 @@ "//google_apis", "//ios/chrome/browser", "//ios/chrome/browser/browser_state:test_support", - "//ios/chrome/browser/prefs", + "//ios/chrome/browser/prefs:browser_prefs", "//ios/chrome/browser/sync", "//ios/chrome/browser/sync:test_support", "//ios/chrome/test:test_support",
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 7d140100..3281242 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -25,7 +25,7 @@ "//components/prefs:test_support", "//ios/chrome/browser", "//ios/chrome/browser/browser_state:browser_state_impl", - "//ios/chrome/browser/prefs", + "//ios/chrome/browser/prefs:browser_prefs", "//ios/public/provider/chrome/browser", "//ios/public/provider/chrome/browser:test_support", "//ios/web",
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc index 6391c9e1..6bef687 100644 --- a/media/audio/audio_input_controller.cc +++ b/media/audio/audio_input_controller.cc
@@ -128,9 +128,11 @@ return nullptr; if (factory_) { - return factory_->Create( - audio_manager, event_handler, params, user_input_monitor); + return factory_->Create(audio_manager->GetTaskRunner(), + /*sync_writer*/ nullptr, audio_manager, + event_handler, params, user_input_monitor); } + scoped_refptr<AudioInputController> controller(new AudioInputController( event_handler, nullptr, nullptr, user_input_monitor, false)); @@ -167,6 +169,12 @@ if (!params.IsValid() || (params.channels() > kMaxInputChannels)) return nullptr; + if (factory_) { + return factory_->Create(audio_manager->GetTaskRunner(), sync_writer, + audio_manager, event_handler, params, + user_input_monitor); + } + // Create the AudioInputController object and ensure that it runs on // the audio-manager thread. scoped_refptr<AudioInputController> controller(new AudioInputController( @@ -200,6 +208,12 @@ DCHECK(sync_writer); DCHECK(stream); + if (factory_) { + return factory_->Create( + task_runner, sync_writer, AudioManager::Get(), event_handler, + media::AudioParameters::UnavailableDeviceParams(), user_input_monitor); + } + // Create the AudioInputController object and ensure that it runs on // the audio-manager thread. scoped_refptr<AudioInputController> controller(new AudioInputController(
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h index 86f7cb3..e778838 100644 --- a/media/audio/audio_input_controller.h +++ b/media/audio/audio_input_controller.h
@@ -147,6 +147,8 @@ class Factory { public: virtual AudioInputController* Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + SyncWriter* sync_writer, AudioManager* audio_manager, EventHandler* event_handler, AudioParameters params, @@ -232,10 +234,10 @@ bool SharedMemoryAndSyncSocketMode() const { return sync_writer_ != NULL; } // Enable debug recording of audio input. - void EnableDebugRecording(const base::FilePath& file_name); + virtual void EnableDebugRecording(const base::FilePath& file_name); // Disable debug recording of audio input. - void DisableDebugRecording(); + virtual void DisableDebugRecording(); protected: friend class base::RefCountedThreadSafe<AudioInputController>;
diff --git a/media/audio/test_audio_input_controller_factory.cc b/media/audio/test_audio_input_controller_factory.cc index 9685f4b..024e7ad 100644 --- a/media/audio/test_audio_input_controller_factory.cc +++ b/media/audio/test_audio_input_controller_factory.cc
@@ -52,6 +52,8 @@ } AudioInputController* TestAudioInputControllerFactory::Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + AudioInputController::SyncWriter* sync_writer, AudioManager* audio_manager, AudioInputController::EventHandler* event_handler, AudioParameters params,
diff --git a/media/audio/test_audio_input_controller_factory.h b/media/audio/test_audio_input_controller_factory.h index 66e2cc5..4a04d36e 100644 --- a/media/audio/test_audio_input_controller_factory.h +++ b/media/audio/test_audio_input_controller_factory.h
@@ -100,6 +100,8 @@ // AudioInputController::Factory methods. AudioInputController* Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + AudioInputController::SyncWriter* sync_writer, AudioManager* audio_manager, AudioInputController::EventHandler* event_handler, AudioParameters params,
diff --git a/net/ssl/ssl_private_key_test_util.cc b/net/ssl/ssl_private_key_test_util.cc index 0e60cbc..ddeaca7 100644 --- a/net/ssl/ssl_private_key_test_util.cc +++ b/net/ssl/ssl_private_key_test_util.cc
@@ -117,12 +117,12 @@ const base::StringPiece& digest, EVP_PKEY* key, std::string* result) { - size_t sig_len; + size_t sig_len = EVP_PKEY_size(key); bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr)); if (!ctx || !EVP_PKEY_sign_init(ctx.get()) || !EVP_PKEY_CTX_set_signature_md(ctx.get(), md) || - !EVP_PKEY_sign(ctx.get(), OpenSSLWriteInto(result, EVP_PKEY_size(key)), - &sig_len, reinterpret_cast<const uint8_t*>(digest.data()), + !EVP_PKEY_sign(ctx.get(), OpenSSLWriteInto(result, sig_len), &sig_len, + reinterpret_cast<const uint8_t*>(digest.data()), digest.size())) { return false; }
diff --git a/testing/libfuzzer/efficient_fuzzer.md b/testing/libfuzzer/efficient_fuzzer.md index fa7efa9..7c3be85 100644 --- a/testing/libfuzzer/efficient_fuzzer.md +++ b/testing/libfuzzer/efficient_fuzzer.md
@@ -199,7 +199,7 @@ ./third_party/llvm-build/Release+Asserts/bin/sancov \ -symbolize my_fuzzer my_fuzzer.123.sancov > my_fuzzer.symcov # Launch coverage report server -curl http://llvm.org/svn/llvm-project/llvm/trunk/tools/sancov/coverage-report-server.py | python3 \ +curl https://llvm.org/svn/llvm-project/llvm/trunk/tools/sancov/coverage-report-server.py | python3 \ --symcov my_fuzzer.symcov --srcpath path_to_chromium_sources # Navigate to http://localhost:8001/ to view coverage report ```
diff --git a/third_party/WebKit/LayoutTests/fast/events/constructors/serviceworker-message-event-constructor-expected.txt b/third_party/WebKit/LayoutTests/fast/events/constructors/serviceworker-message-event-constructor-expected.txt deleted file mode 100644 index 1ed07792..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/constructors/serviceworker-message-event-constructor-expected.txt +++ /dev/null
@@ -1,112 +0,0 @@ -This tests the constructor for the ServiceWorkerMessageEvent DOM class. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS new ServiceWorkerMessageEvent('eventType').bubbles is false -PASS new ServiceWorkerMessageEvent('eventType').cancelable is false -PASS new ServiceWorkerMessageEvent('eventType').data is null -PASS new ServiceWorkerMessageEvent('eventType').origin is "" -PASS new ServiceWorkerMessageEvent('eventType').lastEventId is "" -PASS new ServiceWorkerMessageEvent('eventType').source is null -PASS new ServiceWorkerMessageEvent('eventType').ports is null -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: false }).bubbles is false -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true }).bubbles is true -PASS new ServiceWorkerMessageEvent('eventType', { cancelable: false }).cancelable is false -PASS new ServiceWorkerMessageEvent('eventType', { cancelable: true }).cancelable is true -PASS new ServiceWorkerMessageEvent('eventType', { data: test_object }).data is test_object -PASS new ServiceWorkerMessageEvent('eventType', { data: document }).data is document -PASS new ServiceWorkerMessageEvent('eventType', { data: undefined }).data is null -PASS new ServiceWorkerMessageEvent('eventType', { data: null }).data is null -PASS new ServiceWorkerMessageEvent('eventType', { data: false }).data is false -PASS new ServiceWorkerMessageEvent('eventType', { data: true }).data is true -PASS new ServiceWorkerMessageEvent('eventType', { data: '' }).data is "" -PASS new ServiceWorkerMessageEvent('eventType', { data: 'chocolate' }).data is "chocolate" -PASS new ServiceWorkerMessageEvent('eventType', { data: 12345 }).data is 12345 -PASS new ServiceWorkerMessageEvent('eventType', { data: 18446744073709551615 }).data is 18446744073709552000 -PASS new ServiceWorkerMessageEvent('eventType', { data: NaN }).data is NaN -PASS new ServiceWorkerMessageEvent('eventType', { data: {valueOf: function () { return test_object; } } }).data == test_object is false -PASS new ServiceWorkerMessageEvent('eventType', { get data() { return 123; } }).data is 123 -PASS new ServiceWorkerMessageEvent('eventType', { get data() { throw 'ServiceWorkerMessageEvent Error'; } }) threw exception ServiceWorkerMessageEvent Error. -PASS new ServiceWorkerMessageEvent('eventType', { origin: 'melancholy' }).origin is "melancholy" -PASS new ServiceWorkerMessageEvent('eventType', { origin: '' }).origin is "" -PASS new ServiceWorkerMessageEvent('eventType', { origin: undefined }).origin is "" -PASS new ServiceWorkerMessageEvent('eventType', { origin: null }).origin is "null" -PASS new ServiceWorkerMessageEvent('eventType', { origin: false }).origin is "false" -PASS new ServiceWorkerMessageEvent('eventType', { origin: true }).origin is "true" -PASS new ServiceWorkerMessageEvent('eventType', { origin: 12345 }).origin is "12345" -PASS new ServiceWorkerMessageEvent('eventType', { origin: 18446744073709551615 }).origin is "18446744073709552000" -PASS new ServiceWorkerMessageEvent('eventType', { origin: NaN }).origin is "NaN" -PASS new ServiceWorkerMessageEvent('eventType', { origin: [] }).origin is "" -PASS new ServiceWorkerMessageEvent('eventType', { origin: [1, 2, 3] }).origin is "1,2,3" -PASS new ServiceWorkerMessageEvent('eventType', { origin: {melancholy: 12345} }).origin is "[object Object]" -PASS new ServiceWorkerMessageEvent('eventType', { origin: {valueOf: function () { return 'melancholy'; } } }).origin is "[object Object]" -PASS new ServiceWorkerMessageEvent('eventType', { get origin() { return 123; } }).origin is "123" -PASS new ServiceWorkerMessageEvent('eventType', { get origin() { throw 'ServiceWorkerMessageEvent Error'; } }) threw exception ServiceWorkerMessageEvent Error. -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: 'melancholy' }).lastEventId is "melancholy" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: '' }).lastEventId is "" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: undefined }).lastEventId is "" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: null }).lastEventId is "null" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: false }).lastEventId is "false" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: true }).lastEventId is "true" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: 12345 }).lastEventId is "12345" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: 18446744073709551615 }).lastEventId is "18446744073709552000" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: NaN }).lastEventId is "NaN" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: [] }).lastEventId is "" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: [1, 2, 3] }).lastEventId is "1,2,3" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: {melancholy: 12345} }).lastEventId is "[object Object]" -PASS new ServiceWorkerMessageEvent('eventType', { lastEventId: {valueOf: function () { return 'melancholy'; } } }).lastEventId is "[object Object]" -PASS new ServiceWorkerMessageEvent('eventType', { get lastEventId() { return 123; } }).lastEventId is "123" -PASS new ServiceWorkerMessageEvent('eventType', { get lastEventId() { throw 'ServiceWorkerMessageEvent Error'; } }) threw exception ServiceWorkerMessageEvent Error. -PASS new ServiceWorkerMessageEvent('eventType', { ports: [channel.port1], source: channel.port1 }).source is channel.port1 -PASS new ServiceWorkerMessageEvent('eventType', { source: window }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: this }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: test_object }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: document }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: document.body }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: undefined }).source is null -PASS new ServiceWorkerMessageEvent('eventType', { source: null }).source is null -PASS new ServiceWorkerMessageEvent('eventType', { source: false }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: true }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: '' }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: 'chocolate' }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: 12345 }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: 18446744073709551615 }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: NaN }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { source: {valueOf: function () { return window; } } }).source == window threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { get source() { return channel.port1; } }).source is channel.port1 -PASS new ServiceWorkerMessageEvent('eventType', { get source() { return 123; } }).source threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The provided value is not of type '(ServiceWorker or MessagePort)'. -PASS new ServiceWorkerMessageEvent('eventType', { get source() { throw 'ServiceWorkerMessageEvent Error'; } }) threw exception ServiceWorkerMessageEvent Error. -PASS new ServiceWorkerMessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[0] is channel.port1 -PASS new ServiceWorkerMessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[1] is channel.port2 -PASS new ServiceWorkerMessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[2] is channel2.port1 -PASS new ServiceWorkerMessageEvent('eventType', { ports: [] }).ports is [] -PASS new ServiceWorkerMessageEvent('eventType', { ports: undefined }).ports is null -PASS new ServiceWorkerMessageEvent('eventType', { ports: null }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { ports: [1, 2, 3] }).ports[2] threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': Invalid Array element type. -PASS new ServiceWorkerMessageEvent('eventType', { ports: test_object }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { ports: document }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { ports: false }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { ports: true }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { ports: '' }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { ports: 'chocolate' }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { ports: 12345 }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { ports: 18446744073709551615 }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { ports: NaN }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { get ports() { return 123; } }).ports threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { get ports() { throw 'ServiceWorkerMessageEvent Error'; } }) threw exception ServiceWorkerMessageEvent Error. -PASS new ServiceWorkerMessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0] threw exception TypeError: Failed to construct 'ServiceWorkerMessageEvent': The value provided is neither an array, nor does it have indexed properties.. -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).bubbles is true -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).cancelable is true -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).data is test_object -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).origin is "wonderful" -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).lastEventId is "excellent" -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).source is port -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).ports[0] is channel.port1 -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).ports[1] is channel.port2 -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).ports[2] is channel2.port1 -PASS new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: {length: 3, 0: channel.port1, 1: channel.port2, 2: channel2.port1} }).ports[2] is channel2.port1 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/events/constructors/serviceworker-message-event-constructor.html b/third_party/WebKit/LayoutTests/fast/events/constructors/serviceworker-message-event-constructor.html deleted file mode 100644 index d1a207c..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/constructors/serviceworker-message-event-constructor.html +++ /dev/null
@@ -1,136 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script src="../../../resources/js-test.js"></script> -</head> -<body> -<script> - -description("This tests the constructor for the ServiceWorkerMessageEvent DOM class."); - -var test_object = {nyannyan: 123}; - -// No initializer is passed. -shouldBe("new ServiceWorkerMessageEvent('eventType').bubbles", "false"); -shouldBe("new ServiceWorkerMessageEvent('eventType').cancelable", "false"); -shouldBe("new ServiceWorkerMessageEvent('eventType').data", "null"); -shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType').origin", ""); -shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType').lastEventId", ""); -shouldBe("new ServiceWorkerMessageEvent('eventType').source", "null"); -shouldBe("new ServiceWorkerMessageEvent('eventType').ports", "null"); - -// bubbles is passed. -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: false }).bubbles", "false"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: true }).bubbles", "true"); - -// cancelable is passed. -shouldBe("new ServiceWorkerMessageEvent('eventType', { cancelable: false }).cancelable", "false"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { cancelable: true }).cancelable", "true"); - -// data is passed. -shouldBe("new ServiceWorkerMessageEvent('eventType', { data: test_object }).data", "test_object"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { data: document }).data", "document"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { data: undefined }).data", "null"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { data: null }).data", "null"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { data: false }).data", "false"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { data: true }).data", "true"); -shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { data: '' }).data", ""); -shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { data: 'chocolate' }).data", "chocolate"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { data: 12345 }).data", "12345"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { data: 18446744073709551615 }).data", "18446744073709552000"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { data: NaN }).data", "NaN"); -// Note that valueOf() is not called, when the left hand side is evaluated. -shouldBeFalse("new ServiceWorkerMessageEvent('eventType', { data: {valueOf: function () { return test_object; } } }).data == test_object"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { get data() { return 123; } }).data", "123"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { get data() { throw 'ServiceWorkerMessageEvent Error'; } })"); - -// origin or lastEventId is passed. -["origin", "lastEventId"].forEach(function (attr) { - // Strings. - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": 'melancholy' })." + attr, "melancholy"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": '' })." + attr, ""); - - // Non-strings. - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": undefined })." + attr, ""); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": null })." + attr, "null"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": false })." + attr, "false"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": true })." + attr, "true"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": 12345 })." + attr, "12345"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": 18446744073709551615 })." + attr, "18446744073709552000"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": NaN })." + attr, "NaN"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": [] })." + attr, ""); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": [1, 2, 3] })." + attr, "1,2,3"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": {melancholy: 12345} })." + attr, "[object Object]"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { " + attr + ": {valueOf: function () { return 'melancholy'; } } })." + attr, "[object Object]"); - shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { get " + attr + "() { return 123; } })." + attr, "123"); - shouldThrow("new ServiceWorkerMessageEvent('eventType', { get " + attr + "() { throw 'ServiceWorkerMessageEvent Error'; } })"); -}); - -// MessagePort objects. -var channel = new MessageChannel(); -shouldBe("new ServiceWorkerMessageEvent('eventType', { ports: [channel.port1], source: channel.port1 }).source", "channel.port1"); - -// Unacceptable source objects (not a ServiceWorker or a MessagePort). -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: window }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: this }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: test_object }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: document }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: document.body }).source"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { source: undefined }).source", "null"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { source: null }).source", "null"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: false }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: true }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: '' }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: 'chocolate' }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: 12345 }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: 18446744073709551615 }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: NaN }).source"); -// Note that valueOf() is not called, when the left hand side is evaluated. -shouldThrow("new ServiceWorkerMessageEvent('eventType', { source: {valueOf: function () { return window; } } }).source == window"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { get source() { return channel.port1; } }).source", "channel.port1"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { get source() { return 123; } }).source"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { get source() { throw 'ServiceWorkerMessageEvent Error'; } })"); - -// ports is passed. -// Valid message ports. -var channel2 = new MessageChannel(); -shouldBe("new ServiceWorkerMessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[0]", "channel.port1"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[1]", "channel.port2"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { ports: [channel.port1, channel.port2, channel2.port1] }).ports[2]", "channel2.port1"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { ports: [] }).ports", "[]"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { ports: undefined }).ports", "null"); - -// Invalid message ports. -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: null }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: [1, 2, 3] }).ports[2]"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: test_object }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: document }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: false }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: true }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: '' }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: 'chocolate' }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: 12345 }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: 18446744073709551615 }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: NaN }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { get ports() { return 123; } }).ports"); -shouldThrow("new ServiceWorkerMessageEvent('eventType', { get ports() { throw 'ServiceWorkerMessageEvent Error'; } })"); -// Note that valueOf() is not called, when the left hand side is evaluated. -shouldThrow("new ServiceWorkerMessageEvent('eventType', { ports: {valueOf: function () { return [channel.port1, channel.port2, channel.port2]; } } }).ports[0]"); - -// All initializers are passed. - -var port = new MessageChannel().port1; -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).bubbles", "true"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).cancelable", "true"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).data", "test_object"); -shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).origin", "wonderful"); -shouldBeEqualToString("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).lastEventId", "excellent"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).source", "port"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).ports[0]", "channel.port1"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).ports[1]", "channel.port2"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: [channel.port1, channel.port2, channel2.port1] }).ports[2]", "channel2.port1"); -shouldBe("new ServiceWorkerMessageEvent('eventType', { bubbles: true, cancelable: true, data: test_object, origin: 'wonderful', lastEventId: 'excellent', source: port, ports: {length: 3, 0: channel.port1, 1: channel.port2, 2: channel2.port1} }).ports[2]", "channel2.port1"); - -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/postmessage-to-client.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/postmessage-to-client.html index fadc7d2a..4862f47 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/postmessage-to-client.html +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/postmessage-to-client.html
@@ -25,16 +25,26 @@ }) .then(e => { var message = e.data; - assert_equals(e.origin, location.origin, - 'origin of message should be origin of Service Worker'); + assert_equals(e.constructor, w.MessageEvent, + 'message events should use MessageEvent interface.'); + assert_equals(e.type, 'message', 'type should be "message".'); + assert_equals( + e.origin, location.origin, + 'origin of message should be origin of Service Worker.'); assert_equals(e.lastEventId, '', - 'lastEventId should be an empty string'); + 'lastEventId should be an empty string.'); + assert_equals(e.source.constructor, w.ServiceWorker, + 'source should use ServiceWorker interface.'); + assert_equals( + e.source, w.navigator.serviceWorker.controller, + 'source should be the service worker that sent the message.'); + assert_equals(e.ports.length, 0, 'ports should be an empty array.'); assert_equals(message, 'Sending message via clients'); return new Promise(resolve => { w.navigator.serviceWorker.onmessage = resolve; }); }) .then(e => { assert_equals(e.data, 'quit'); }); - }, 'postMessage from ServiceWorker to Client'); + }, 'postMessage from ServiceWorker to Client.'); </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/serviceworker-message-event.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/serviceworker-message-event.html deleted file mode 100644 index 66e29612..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/serviceworker-message-event.html +++ /dev/null
@@ -1,43 +0,0 @@ -<!DOCTYPE html> -<title>Service Worker: ServiceWorkerMessageEvent</title> -<script src="../resources/testharness.js"></script> -<script src="../resources/testharnessreport.js"></script> -<script src="resources/test-helpers.js"></script> -<script> - -promise_test(function(t) { - var scope = 'resources/blank.html'; - var url = 'resources/postmessage-to-client-worker.js'; - return service_worker_unregister_and_register(t, url, scope) - .then(function(r) { - return wait_for_state(t, r.installing, 'activated'); - }) - .then(function() { - return with_iframe(scope); - }) - .then(function(frame) { - var w = frame.contentWindow; - var worker = w.navigator.serviceWorker.controller; - // Test constructor with ServiceWorker object as source. - var e = new ServiceWorkerMessageEvent('eventType', {source: worker}); - assert_equals(e.source, worker, - 'Source should equal to the passing service worker'); - return new Promise(function(resolve) { - w.navigator.serviceWorker.onmessage = t.step_func(function(e) { - assert_true(e instanceof w.ServiceWorkerMessageEvent); - assert_true(e.source instanceof w.ServiceWorker); - assert_equals(e.type, 'message'); - assert_equals(e.source, worker, - 'Source worker should equal to the controller'); - assert_equals(e.ports.length, 0); - resolve(); - }); - worker.postMessage('PING'); - }); - }) - .then(function() { - return service_worker_unregister_and_done(t, scope); - }); - }, 'Test ServiceWorkerMessageEvent type.'); - -</script>
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt index 71a6b78..38a3512 100644 --- a/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt +++ b/third_party/WebKit/LayoutTests/imported/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects-exceptions-expected.txt
@@ -10,7 +10,7 @@ FAIL [[Delete]] Should throw on cross-origin objects assert_throws: Can't delete cross-origin indexed property function "function () { delete C[0]; }" did not throw FAIL [[DefineOwnProperty]] Should throw for cross-origin objects assert_throws: Can't define cross-origin value property length function "function () { Object.defineProperty(obj, prop, valueDesc); }" did not throw FAIL [[Enumerate]] should return an empty iterator assert_unreached: Shouldn't have been able to enumerate stop on cross-origin Window Reached unreachable code -FAIL [[OwnPropertyKeys]] should return all properties from cross-origin objects assert_array_equals: Object.getOwnPropertyNames() gives the right answer for cross-origin Window lengths differ, expected 862 got 13 +FAIL [[OwnPropertyKeys]] should return all properties from cross-origin objects assert_array_equals: Object.getOwnPropertyNames() gives the right answer for cross-origin Window lengths differ, expected 861 got 13 PASS A and B jointly observe the same identity for cross-origin Window and Location PASS Cross-origin functions get local Function.prototype FAIL Cross-origin Window accessors get local Function.prototype Cannot read property 'name' of undefined
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt index e562d96..eb181eee 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -5307,14 +5307,6 @@ method register setter oncontrollerchange setter onmessage -interface ServiceWorkerMessageEvent : Event - attribute @@toStringTag - getter data - getter lastEventId - getter origin - getter ports - getter source - method constructor interface ServiceWorkerRegistration : EventTarget attribute @@toStringTag getter active
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt index ca9ee76..6d96be00 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -5365,14 +5365,6 @@ method register setter oncontrollerchange setter onmessage -interface ServiceWorkerMessageEvent : Event - attribute @@toStringTag - getter data - getter lastEventId - getter origin - getter ports - getter source - method constructor interface ServiceWorkerRegistration : EventTarget attribute @@toStringTag getter active
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 1a8febfa..3b31cdd 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -6258,14 +6258,6 @@ method register setter oncontrollerchange setter onmessage -interface ServiceWorkerMessageEvent : Event - attribute @@toStringTag - getter data - getter lastEventId - getter origin - getter ports - getter source - method constructor interface ServiceWorkerRegistration : EventTarget attribute @@toStringTag getter active
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp index d7b32a1b..93d36fd 100644 --- a/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8MessageEventCustom.cpp
@@ -110,7 +110,7 @@ v8::Local<v8::Value> dataArg = info[3]; TOSTRING_VOID(V8StringResource<>, originArg, info[4]); TOSTRING_VOID(V8StringResource<>, lastEventIdArg, info[5]); - DOMWindow* sourceArg = toDOMWindow(info.GetIsolate(), info[6]); + EventTarget* sourceArg = toEventTarget(info.GetIsolate(), info[6]); MessagePortArray* portArray = nullptr; const int portArrayIndex = 7; if (!isUndefinedOrNull(info[portArrayIndex])) {
diff --git a/third_party/WebKit/Source/bindings/modules/BUILD.gn b/third_party/WebKit/Source/bindings/modules/BUILD.gn index 3b763d0..37c9fb3d 100644 --- a/third_party/WebKit/Source/bindings/modules/BUILD.gn +++ b/third_party/WebKit/Source/bindings/modules/BUILD.gn
@@ -45,7 +45,6 @@ "//third_party/WebKit/Source/modules/serviceworkers/FetchEvent.idl", "//third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.idl", "//third_party/WebKit/Source/modules/serviceworkers/InstallEvent.idl", - "//third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerMessageEvent.idl", "//third_party/WebKit/Source/modules/speech/SpeechRecognitionError.idl", "//third_party/WebKit/Source/modules/speech/SpeechRecognitionEvent.idl", "//third_party/WebKit/Source/modules/speech/SpeechSynthesisEvent.idl",
diff --git a/third_party/WebKit/Source/bindings/modules/v8/custom/V8ServiceWorkerMessageEventCustom.cpp b/third_party/WebKit/Source/bindings/modules/v8/custom/V8ServiceWorkerMessageEventCustom.cpp deleted file mode 100644 index 9b290966..0000000 --- a/third_party/WebKit/Source/bindings/modules/v8/custom/V8ServiceWorkerMessageEventCustom.cpp +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "bindings/modules/v8/V8ServiceWorkerMessageEvent.h" - -#include "bindings/modules/v8/V8ServiceWorkerMessageEventInit.h" -#include "bindings/modules/v8/V8ServiceWorkerMessageEventInternal.h" - -namespace blink { - -void V8ServiceWorkerMessageEvent::constructorCustom( - const v8::FunctionCallbackInfo<v8::Value>& info) { - V8ServiceWorkerMessageEventInternal::constructorCustom< - ServiceWorkerMessageEvent, ServiceWorkerMessageEventInit>(info); -} - -void V8ServiceWorkerMessageEvent::dataAttributeGetterCustom( - const v8::FunctionCallbackInfo<v8::Value>& info) { - V8ServiceWorkerMessageEventInternal::dataAttributeGetterCustom< - ServiceWorkerMessageEvent>(info); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/bindings/modules/v8/custom/custom.gni b/third_party/WebKit/Source/bindings/modules/v8/custom/custom.gni index 249329a8..d07743b 100644 --- a/third_party/WebKit/Source/bindings/modules/v8/custom/custom.gni +++ b/third_party/WebKit/Source/bindings/modules/v8/custom/custom.gni
@@ -10,7 +10,6 @@ "V8ExtendableMessageEventCustom.cpp", "V8IDBObserverCustom.cpp", "V8RemotePlaybackCustom.cpp", - "V8ServiceWorkerMessageEventCustom.cpp", "V8WebGLRenderingContextCustom.cpp", "V8WebGL2RenderingContextCustom.cpp", ],
diff --git a/third_party/WebKit/Source/bindings/modules/v8/generated.gni b/third_party/WebKit/Source/bindings/modules/v8/generated.gni index 0d8f27d..564be191 100644 --- a/third_party/WebKit/Source/bindings/modules/v8/generated.gni +++ b/third_party/WebKit/Source/bindings/modules/v8/generated.gni
@@ -46,8 +46,6 @@ "$bindings_modules_v8_output_dir/RenderingContext.h", "$bindings_modules_v8_output_dir/RequestOrUSVString.cpp", "$bindings_modules_v8_output_dir/RequestOrUSVString.h", - "$bindings_modules_v8_output_dir/ServiceWorkerOrMessagePort.cpp", - "$bindings_modules_v8_output_dir/ServiceWorkerOrMessagePort.h", "$bindings_modules_v8_output_dir/StringOrArrayBufferOrNFCMessage.cpp", "$bindings_modules_v8_output_dir/StringOrArrayBufferOrNFCMessage.h", "$bindings_modules_v8_output_dir/StringOrCanvasGradientOrCanvasPattern.cpp",
diff --git a/third_party/WebKit/Source/core/events/EventTarget.cpp b/third_party/WebKit/Source/core/events/EventTarget.cpp index 3bfa7163..0814cb3 100644 --- a/third_party/WebKit/Source/core/events/EventTarget.cpp +++ b/third_party/WebKit/Source/core/events/EventTarget.cpp
@@ -173,6 +173,10 @@ return nullptr; } +ServiceWorker* EventTarget::toServiceWorker() { + return nullptr; +} + inline LocalDOMWindow* EventTarget::executingWindow() { if (ExecutionContext* context = getExecutionContext()) return context->executingWindow();
diff --git a/third_party/WebKit/Source/core/events/EventTarget.h b/third_party/WebKit/Source/core/events/EventTarget.h index 75088002..6b77c11e 100644 --- a/third_party/WebKit/Source/core/events/EventTarget.h +++ b/third_party/WebKit/Source/core/events/EventTarget.h
@@ -56,6 +56,7 @@ class ExceptionState; class MessagePort; class Node; +class ServiceWorker; struct FiringEventIterator { DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); @@ -119,6 +120,7 @@ virtual const LocalDOMWindow* toLocalDOMWindow() const; virtual LocalDOMWindow* toLocalDOMWindow(); virtual MessagePort* toMessagePort(); + virtual ServiceWorker* toServiceWorker(); bool addEventListener(const AtomicString& eventType, EventListener*,
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.cpp b/third_party/WebKit/Source/core/events/MessageEvent.cpp index 2be9e882..ed0b628 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.cpp +++ b/third_party/WebKit/Source/core/events/MessageEvent.cpp
@@ -36,7 +36,8 @@ namespace blink { static inline bool isValidSource(EventTarget* source) { - return !source || source->toLocalDOMWindow() || source->toMessagePort(); + return !source || source->toLocalDOMWindow() || source->toMessagePort() || + source->toServiceWorker(); } MessageEvent::MessageEvent() : m_dataType(DataTypeScriptValue) {} @@ -155,7 +156,7 @@ ScriptValue data, const String& origin, const String& lastEventId, - DOMWindow* source, + EventTarget* source, MessagePortArray* ports) { if (isBeingDispatched()) return; @@ -177,7 +178,7 @@ PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, - DOMWindow* source, + EventTarget* source, MessagePortArray* ports) { if (isBeingDispatched()) return;
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.h b/third_party/WebKit/Source/core/events/MessageEvent.h index b7fb883..de9700cad 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.h +++ b/third_party/WebKit/Source/core/events/MessageEvent.h
@@ -37,7 +37,6 @@ #include "core/events/EventTarget.h" #include "core/events/MessageEventInit.h" #include "core/fileapi/Blob.h" -#include "core/frame/DOMWindow.h" #include "wtf/Compiler.h" #include <memory> @@ -99,7 +98,7 @@ ScriptValue data, const String& origin, const String& lastEventId, - DOMWindow* source, + EventTarget* source, MessagePortArray*); void initMessageEvent(const AtomicString& type, bool canBubble, @@ -107,7 +106,7 @@ PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, - DOMWindow* source, + EventTarget* source, MessagePortArray*); const String& origin() const { return m_origin; }
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.idl b/third_party/WebKit/Source/core/events/MessageEvent.idl index 5c3a7e34..61dc799 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.idl +++ b/third_party/WebKit/Source/core/events/MessageEvent.idl
@@ -49,6 +49,6 @@ [Default=Undefined] optional any dataArg, [Default=Undefined] optional DOMString originArg, [Default=Undefined] optional DOMString lastEventIdArg, - [Default=Undefined] optional Window sourceArg, + [Default=Undefined] optional EventTarget sourceArg, [Default=Undefined] optional sequence<MessagePort> portsArg); };
diff --git a/third_party/WebKit/Source/core/frame/History.idl b/third_party/WebKit/Source/core/frame/History.idl index fef8e1f..6add189 100644 --- a/third_party/WebKit/Source/core/frame/History.idl +++ b/third_party/WebKit/Source/core/frame/History.idl
@@ -35,8 +35,6 @@ [CallWith=ExecutionContext] void go(optional long delta = 0); [CallWith=ExecutionContext] void back(); [CallWith=ExecutionContext] void forward(); - // TODO(foolip): The SerializedScriptValue types should be any. - // TODO(foolip): The title arguments should not be nullable. - [RaisesException] void pushState(SerializedScriptValue data, DOMString? title, optional DOMString? url = null); - [RaisesException] void replaceState(SerializedScriptValue data, DOMString? title, optional DOMString? url = null); + [RaisesException] void pushState(SerializedScriptValue data, DOMString title, optional DOMString? url = null); + [RaisesException] void replaceState(SerializedScriptValue data, DOMString title, optional DOMString? url = null); };
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapOptions.idl b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapOptions.idl index d34204e7..4073e6a 100644 --- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapOptions.idl +++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapOptions.idl
@@ -12,7 +12,7 @@ ImageOrientation imageOrientation = "none"; PremultiplyAlpha premultiplyAlpha = "default"; CanvasColorSpace colorSpaceConversion = "default"; - [RuntimeEnabled=ExperimentalCanvasFeatures, EnforceRange] unsigned long? resizeWidth; - [RuntimeEnabled=ExperimentalCanvasFeatures, EnforceRange] unsigned long? resizeHeight; + [RuntimeEnabled=ExperimentalCanvasFeatures, EnforceRange] unsigned long resizeWidth; + [RuntimeEnabled=ExperimentalCanvasFeatures, EnforceRange] unsigned long resizeHeight; [RuntimeEnabled=ExperimentalCanvasFeatures] ResizeQuality resizeQuality = "low"; };
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.cpp index fb1904068..3b5b2fe 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.cpp
@@ -23,23 +23,17 @@ #include "core/layout/svg/LayoutSVGViewportContainer.h" #include "core/layout/svg/SVGLayoutSupport.h" -#include "core/paint/SVGContainerPainter.h" #include "core/svg/SVGSVGElement.h" -#include "core/svg/SVGUseElement.h" -#include "platform/graphics/GraphicsContext.h" namespace blink { -LayoutSVGViewportContainer::LayoutSVGViewportContainer(SVGElement* node) +LayoutSVGViewportContainer::LayoutSVGViewportContainer(SVGSVGElement* node) : LayoutSVGContainer(node), m_isLayoutSizeChanged(false), m_needsTransformUpdate(true) {} void LayoutSVGViewportContainer::determineIfLayoutSizeChanged() { - ASSERT(element()); - if (!isSVGSVGElement(*element())) - return; - + DCHECK(isSVGSVGElement(element())); m_isLayoutSizeChanged = toSVGSVGElement(element())->hasRelativeLengths() && selfNeedsLayout(); }
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.h index 389b9b37..713cffd 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.h
@@ -27,11 +27,13 @@ namespace blink { +class SVGSVGElement; + // This is used for non-root <svg> elements which are SVGTransformable thus we // inherit from LayoutSVGContainer instead of LayoutSVGTransformableContainer. class LayoutSVGViewportContainer final : public LayoutSVGContainer { public: - explicit LayoutSVGViewportContainer(SVGElement*); + explicit LayoutSVGViewportContainer(SVGSVGElement*); FloatRect viewport() const { return m_viewport; } bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
diff --git a/third_party/WebKit/Source/modules/compositorworker/WindowAnimationWorklet.cpp b/third_party/WebKit/Source/modules/compositorworker/WindowAnimationWorklet.cpp index 3512051b..15a48034 100644 --- a/third_party/WebKit/Source/modules/compositorworker/WindowAnimationWorklet.cpp +++ b/third_party/WebKit/Source/modules/compositorworker/WindowAnimationWorklet.cpp
@@ -4,6 +4,7 @@ #include "modules/compositorworker/WindowAnimationWorklet.h" +#include "core/dom/Document.h" #include "core/frame/LocalDOMWindow.h" #include "core/frame/LocalFrame.h" #include "modules/compositorworker/AnimationWorklet.h" @@ -11,7 +12,7 @@ namespace blink { WindowAnimationWorklet::WindowAnimationWorklet(LocalDOMWindow& window) - : DOMWindowProperty(window.frame()) {} + : ContextLifecycleObserver(window.frame()->document()) {} const char* WindowAnimationWorklet::supplementName() { return "WindowAnimationWorklet"; @@ -30,24 +31,36 @@ // static Worklet* WindowAnimationWorklet::animationWorklet(DOMWindow& window) { - return from(toLocalDOMWindow(window)).animationWorklet(); + return from(toLocalDOMWindow(window)) + .animationWorklet(toLocalDOMWindow(window)); } -AnimationWorklet* WindowAnimationWorklet::animationWorklet() { - if (!m_animationWorklet && frame()) - m_animationWorklet = AnimationWorklet::create(frame()); +AnimationWorklet* WindowAnimationWorklet::animationWorklet( + LocalDOMWindow& window) { + if (!m_animationWorklet && getExecutionContext()) { + DCHECK(window.frame()); + m_animationWorklet = AnimationWorklet::create(window.frame()); + } return m_animationWorklet.get(); } -void WindowAnimationWorklet::frameDestroyed() { - m_animationWorklet.clear(); - DOMWindowProperty::frameDestroyed(); +// Break the following cycle when the context gets detached. +// Otherwise, the worklet object will leak. +// +// window => window.animationWorklet +// => WindowAnimationWorklet +// => AnimationWorklet <--- break this reference +// => ThreadedWorkletMessagingProxy +// => Document +// => ... => window +void WindowAnimationWorklet::contextDestroyed() { + m_animationWorklet = nullptr; } DEFINE_TRACE(WindowAnimationWorklet) { visitor->trace(m_animationWorklet); Supplement<LocalDOMWindow>::trace(visitor); - DOMWindowProperty::trace(visitor); + ContextLifecycleObserver::trace(visitor); } } // namespace blink
diff --git a/third_party/WebKit/Source/modules/compositorworker/WindowAnimationWorklet.h b/third_party/WebKit/Source/modules/compositorworker/WindowAnimationWorklet.h index 9e3349f..3635ec3 100644 --- a/third_party/WebKit/Source/modules/compositorworker/WindowAnimationWorklet.h +++ b/third_party/WebKit/Source/modules/compositorworker/WindowAnimationWorklet.h
@@ -5,7 +5,7 @@ #ifndef WindowAnimationWorklet_h #define WindowAnimationWorklet_h -#include "core/frame/DOMWindowProperty.h" +#include "core/dom/ContextLifecycleObserver.h" #include "modules/ModulesExport.h" #include "platform/Supplementable.h" #include "platform/heap/Handle.h" @@ -20,15 +20,15 @@ class MODULES_EXPORT WindowAnimationWorklet final : public GarbageCollected<WindowAnimationWorklet>, public Supplement<LocalDOMWindow>, - public DOMWindowProperty { + public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(WindowAnimationWorklet); public: static WindowAnimationWorklet& from(LocalDOMWindow&); static Worklet* animationWorklet(DOMWindow&); - AnimationWorklet* animationWorklet(); + AnimationWorklet* animationWorklet(LocalDOMWindow&); - void frameDestroyed() override; + void contextDestroyed() override; DECLARE_TRACE();
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni index bae6525..cbc4dc9 100644 --- a/third_party/WebKit/Source/modules/modules_idl_files.gni +++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -242,7 +242,6 @@ "serviceworkers/ServiceWorker.idl", "serviceworkers/ServiceWorkerContainer.idl", "serviceworkers/ServiceWorkerGlobalScope.idl", - "serviceworkers/ServiceWorkerMessageEvent.idl", "serviceworkers/ServiceWorkerRegistration.idl", "serviceworkers/WindowClient.idl", "shapedetection/BarcodeDetector.idl", @@ -493,7 +492,6 @@ "serviceworkers/ForeignFetchResponse.idl", "serviceworkers/NavigationPreloadState.idl", "serviceworkers/RegistrationOptions.idl", - "serviceworkers/ServiceWorkerMessageEventInit.idl", "shapedetection/FaceDetectorOptions.idl", "speech/SpeechRecognitionErrorInit.idl", "speech/SpeechRecognitionEventInit.idl", @@ -870,8 +868,6 @@ "$blink_modules_output_dir/serviceworkers/NavigationPreloadState.h", "$blink_modules_output_dir/serviceworkers/RegistrationOptions.cpp", "$blink_modules_output_dir/serviceworkers/RegistrationOptions.h", - "$blink_modules_output_dir/serviceworkers/ServiceWorkerMessageEventInit.cpp", - "$blink_modules_output_dir/serviceworkers/ServiceWorkerMessageEventInit.h", "$blink_modules_output_dir/shapedetection/FaceDetectorOptions.cpp", "$blink_modules_output_dir/shapedetection/FaceDetectorOptions.h", "$blink_modules_output_dir/speech/SpeechRecognitionErrorInit.cpp",
diff --git a/third_party/WebKit/Source/modules/serviceworkers/BUILD.gn b/third_party/WebKit/Source/modules/serviceworkers/BUILD.gn index 550563d..b08ba25 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/BUILD.gn +++ b/third_party/WebKit/Source/modules/serviceworkers/BUILD.gn
@@ -44,8 +44,6 @@ "ServiceWorkerGlobalScopeClient.h", "ServiceWorkerLinkResource.cpp", "ServiceWorkerLinkResource.h", - "ServiceWorkerMessageEvent.cpp", - "ServiceWorkerMessageEvent.h", "ServiceWorkerRegistration.cpp", "ServiceWorkerRegistration.h", "ServiceWorkerScriptCachedMetadataHandler.cpp",
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.h index 5f06610b..12d4e69 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.h +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.h
@@ -69,6 +69,8 @@ String state() const; DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange); + ServiceWorker* toServiceWorker() override { return this; } + // ScriptWrappable overrides. bool hasPendingActivity() const final;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp index 711d7d7..1132fd5 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainer.cpp
@@ -41,6 +41,7 @@ #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" #include "core/dom/MessagePort.h" +#include "core/events/MessageEvent.h" #include "core/frame/LocalDOMWindow.h" #include "core/frame/UseCounter.h" #include "core/frame/csp/ContentSecurityPolicy.h" @@ -49,7 +50,6 @@ #include "modules/serviceworkers/ServiceWorker.h" #include "modules/serviceworkers/ServiceWorkerContainerClient.h" #include "modules/serviceworkers/ServiceWorkerError.h" -#include "modules/serviceworkers/ServiceWorkerMessageEvent.h" #include "modules/serviceworkers/ServiceWorkerRegistration.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/weborigin/SchemeRegistry.h" @@ -454,9 +454,9 @@ RefPtr<SerializedScriptValue> value = SerializedScriptValue::create(message); ServiceWorker* source = ServiceWorker::from( getExecutionContext(), WTF::wrapUnique(handle.release())); - dispatchEvent(ServiceWorkerMessageEvent::create( - ports, value, source, - getExecutionContext()->getSecurityOrigin()->toString())); + dispatchEvent(MessageEvent::create( + ports, value, getExecutionContext()->getSecurityOrigin()->toString(), + String() /* lastEventId */, source, String() /* suborigin */)); } const AtomicString& ServiceWorkerContainer::interfaceName() const {
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerMessageEvent.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerMessageEvent.cpp deleted file mode 100644 index 11972c6..0000000 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerMessageEvent.cpp +++ /dev/null
@@ -1,83 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "modules/serviceworkers/ServiceWorkerMessageEvent.h" - -namespace blink { - -ServiceWorkerMessageEvent::ServiceWorkerMessageEvent( - const AtomicString& type, - const ServiceWorkerMessageEventInit& initializer) - : Event(type, initializer) { - if (initializer.hasOrigin()) - m_origin = initializer.origin(); - if (initializer.hasLastEventId()) - m_lastEventId = initializer.lastEventId(); - if (initializer.hasSource()) { - if (initializer.source().isServiceWorker()) - m_sourceAsServiceWorker = initializer.source().getAsServiceWorker(); - else if (initializer.source().isMessagePort()) - m_sourceAsMessagePort = initializer.source().getAsMessagePort(); - } - if (initializer.hasPorts()) - m_ports = new MessagePortArray(initializer.ports()); -} - -ServiceWorkerMessageEvent::ServiceWorkerMessageEvent( - PassRefPtr<SerializedScriptValue> data, - const String& origin, - const String& lastEventId, - ServiceWorker* source, - MessagePortArray* ports) - : Event(EventTypeNames::message, false, false), - m_serializedData(data), - m_origin(origin), - m_lastEventId(lastEventId), - m_sourceAsServiceWorker(source), - m_ports(ports) { - if (m_serializedData) - m_serializedData->registerMemoryAllocatedWithCurrentScriptContext(); -} - -ServiceWorkerMessageEvent::~ServiceWorkerMessageEvent() {} - -MessagePortArray ServiceWorkerMessageEvent::ports(bool& isNull) const { - // TODO(bashi): Currently we return a copied array because the binding - // layer could modify the content of the array while executing JS callbacks. - // Avoid copying once we can make sure that the binding layer won't - // modify the content. - if (m_ports) { - isNull = false; - return *m_ports; - } - isNull = true; - return MessagePortArray(); -} - -MessagePortArray ServiceWorkerMessageEvent::ports() const { - bool unused; - return ports(unused); -} - -void ServiceWorkerMessageEvent::source( - ServiceWorkerOrMessagePort& result) const { - if (m_sourceAsServiceWorker) - result = - ServiceWorkerOrMessagePort::fromServiceWorker(m_sourceAsServiceWorker); - else if (m_sourceAsMessagePort) - result = ServiceWorkerOrMessagePort::fromMessagePort(m_sourceAsMessagePort); -} - -const AtomicString& ServiceWorkerMessageEvent::interfaceName() const { - return EventNames::ServiceWorkerMessageEvent; -} - -DEFINE_TRACE(ServiceWorkerMessageEvent) { - visitor->trace(m_sourceAsServiceWorker); - visitor->trace(m_sourceAsMessagePort); - visitor->trace(m_ports); - Event::trace(visitor); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerMessageEvent.h b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerMessageEvent.h deleted file mode 100644 index 4829e13..0000000 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerMessageEvent.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ServiceWorkerMessageEvent_h -#define ServiceWorkerMessageEvent_h - -#include "core/dom/DOMArrayBuffer.h" -#include "core/dom/MessagePort.h" -#include "modules/EventModules.h" -#include "modules/ModulesExport.h" -#include "modules/serviceworkers/ServiceWorkerMessageEventInit.h" - -namespace blink { - -class MODULES_EXPORT ServiceWorkerMessageEvent final : public Event { - DEFINE_WRAPPERTYPEINFO(); - - public: - static ServiceWorkerMessageEvent* create( - const AtomicString& type, - const ServiceWorkerMessageEventInit& initializer) { - return new ServiceWorkerMessageEvent(type, initializer); - } - - static ServiceWorkerMessageEvent* create( - MessagePortArray* ports, - PassRefPtr<SerializedScriptValue> data, - ServiceWorker* source, - const String& origin) { - return new ServiceWorkerMessageEvent(std::move(data), origin, String(), - source, ports); - } - - ~ServiceWorkerMessageEvent() override; - - SerializedScriptValue* serializedData() const { - return m_serializedData.get(); - } - void setSerializedData(PassRefPtr<SerializedScriptValue> serializedData) { - m_serializedData = serializedData; - } - const String& origin() const { return m_origin; } - const String& lastEventId() const { return m_lastEventId; } - MessagePortArray ports(bool& isNull) const; - MessagePortArray ports() const; - void source(ServiceWorkerOrMessagePort& result) const; - - const AtomicString& interfaceName() const override; - - DECLARE_VIRTUAL_TRACE(); - - private: - ServiceWorkerMessageEvent(const AtomicString& type, - const ServiceWorkerMessageEventInit& initializer); - ServiceWorkerMessageEvent(PassRefPtr<SerializedScriptValue> data, - const String& origin, - const String& lastEventId, - ServiceWorker* source, - MessagePortArray* ports); - - RefPtr<SerializedScriptValue> m_serializedData; - String m_origin; - String m_lastEventId; - Member<ServiceWorker> m_sourceAsServiceWorker; - Member<MessagePort> m_sourceAsMessagePort; - Member<MessagePortArray> m_ports; -}; - -} // namespace blink - -#endif // ServiceWorkerMessageEvent_h
diff --git a/tools/boilerplate.py b/tools/boilerplate.py index 74a2a4d..b26493e 100755 --- a/tools/boilerplate.py +++ b/tools/boilerplate.py
@@ -51,15 +51,22 @@ ]) -def _CppImplementation(filename): +def _RemoveTestSuffix(filename): base, _ = os.path.splitext(filename) - include = '#include "' + base + '.h"' + suffixes = [ '_test', '_unittest', '_browsertest' ] + for suffix in suffixes: + l = len(suffix) + if base[-l:] == suffix: + return base[:-l] + return base + +def _CppImplementation(filename): + include = '#include "' + _RemoveTestSuffix(filename) + '.h"' return '\n'.join(['', include]) def _ObjCppImplementation(filename): - base, _ = os.path.splitext(filename) - include = '#import "' + base + '.h"' + include = '#import "' + _RemoveTestSuffix(filename) + '.h"' return '\n'.join(['', include])
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 543fa7e..4fa4726 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -77003,6 +77003,7 @@ <int value="157" label="AOAH_NONSENSE_DEVICE_ID"/> <int value="158" label="BDH_INVALID_OPTIONS"/> <int value="159" label="RFH_DID_ADD_CONSOLE_MESSAGE_BAD_SEVERITY"/> + <int value="160" label="AIRH_VOLUME_OUT_OF_RANGE"/> </enum> <enum name="BadMessageReasonExtensions" type="int"> @@ -99311,6 +99312,9 @@ <int value="5" label="User is blacklisted for the specific host."/> <int value="6" label="The network quality estimate is not available."/> <int value="7" label="The network is not slow enough to show previews."/> + <int value="8" + label="The page was being reloaded and the preview type can not be + shown on a reload."/> </enum> <enum name="PreviewsInfoBarAction" type="int">
diff --git a/ui/accessibility/ax_enums.idl b/ui/accessibility/ax_enums.idl index 2209a27..ac8b0eb 100644 --- a/ui/accessibility/ax_enums.idl +++ b/ui/accessibility/ax_enums.idl
@@ -45,6 +45,8 @@ live_region_changed, // Web load_complete, // Web location_changed, // Web + media_started_playing, // Automation + media_stopped_playing, // Automation menu_end, // Native / Win menu_list_item_selected, // Web menu_list_value_changed, // Web
diff --git a/ui/events/blink/BUILD.gn b/ui/events/blink/BUILD.gn index 588f1f4..dcae5dc5 100644 --- a/ui/events/blink/BUILD.gn +++ b/ui/events/blink/BUILD.gn
@@ -37,6 +37,7 @@ "//ui/events:dom_keycode_converter", "//ui/events:events_base", "//ui/events:gesture_detection", + "//ui/gfx", "//ui/gfx/geometry", ]
diff --git a/ui/events/blink/DEPS b/ui/events/blink/DEPS index 198f59ef..a04f3df8 100644 --- a/ui/events/blink/DEPS +++ b/ui/events/blink/DEPS
@@ -14,6 +14,7 @@ "+third_party/WebKit/public/web/WebActiveWheelFlingParameters.h", "+ui/display/win", + "+ui/gfx", "+ui/gfx/geometry", "+ui/events" ]
diff --git a/ui/events/blink/blink_event_util.cc b/ui/events/blink/blink_event_util.cc index 5148bf1..939a1c4 100644 --- a/ui/events/blink/blink_event_util.cc +++ b/ui/events/blink/blink_event_util.cc
@@ -16,7 +16,6 @@ #include "base/time/time.h" #include "build/build_config.h" -#include "third_party/WebKit/public/platform/WebGestureEvent.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" #include "ui/events/base_event_utils.h" #include "ui/events/event_constants.h" @@ -26,6 +25,7 @@ #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/gfx/geometry/safe_integer_conversions.h" #include "ui/gfx/geometry/vector2d.h" +#include "ui/gfx/transform.h" using blink::WebGestureEvent; using blink::WebInputEvent; @@ -381,6 +381,24 @@ } } +// Returns the transform matrix corresponding to the gesture event. +gfx::Transform GetTransformForEvent(const WebGestureEvent& gesture_event) { + gfx::Transform gesture_transform; + if (gesture_event.type == WebInputEvent::GestureScrollUpdate) { + gesture_transform.Translate(gesture_event.data.scrollUpdate.deltaX, + gesture_event.data.scrollUpdate.deltaY); + } else if (gesture_event.type == WebInputEvent::GesturePinchUpdate) { + float scale = gesture_event.data.pinchUpdate.scale; + gesture_transform.Translate(-gesture_event.x, -gesture_event.y); + gesture_transform.Scale(scale, scale); + gesture_transform.Translate(gesture_event.x, gesture_event.y); + } else { + NOTREACHED() << "Invalid event type for transform retrieval: " + << WebInputEvent::GetName(gesture_event.type); + } + return gesture_transform; +} + } // namespace bool CanCoalesce(const blink::WebInputEvent& event_to_coalesce, @@ -439,6 +457,73 @@ } } +// Whether |event_in_queue| is GesturePinchUpdate or GestureScrollUpdate and +// has the same modifiers/source as the new scroll/pinch event. Compatible +// scroll and pinch event pairs can be logically coalesced. +bool IsCompatibleScrollorPinch(const WebGestureEvent& new_event, + const WebGestureEvent& event_in_queue) { + DCHECK(new_event.type == WebInputEvent::GestureScrollUpdate || + new_event.type == WebInputEvent::GesturePinchUpdate) + << "Invalid event type for pinch/scroll coalescing: " + << WebInputEvent::GetName(new_event.type); + DLOG_IF(WARNING, new_event.timeStampSeconds < event_in_queue.timeStampSeconds) + << "Event time not monotonic?\n"; + return (event_in_queue.type == WebInputEvent::GestureScrollUpdate || + event_in_queue.type == WebInputEvent::GesturePinchUpdate) && + event_in_queue.modifiers == new_event.modifiers && + event_in_queue.sourceDevice == new_event.sourceDevice; +} + +std::pair<WebGestureEvent, WebGestureEvent> CoalesceScrollAndPinch( + const WebGestureEvent* second_last_event, + const WebGestureEvent& last_event, + const WebGestureEvent& new_event) { + DCHECK(!CanCoalesce(new_event, last_event)) + << "New event can be coalesced with the last event in queue directly."; + DCHECK(IsContinuousGestureEvent(new_event.type)); + DCHECK(IsCompatibleScrollorPinch(new_event, last_event)); + DCHECK(!second_last_event || + IsCompatibleScrollorPinch(new_event, *second_last_event)); + + WebGestureEvent scroll_event; + WebGestureEvent pinch_event; + scroll_event.modifiers |= new_event.modifiers; + scroll_event.sourceDevice = new_event.sourceDevice; + scroll_event.timeStampSeconds = new_event.timeStampSeconds; + pinch_event = scroll_event; + scroll_event.type = WebInputEvent::GestureScrollUpdate; + pinch_event.type = WebInputEvent::GesturePinchUpdate; + pinch_event.x = new_event.type == WebInputEvent::GesturePinchUpdate + ? new_event.x + : last_event.x; + pinch_event.y = new_event.type == WebInputEvent::GesturePinchUpdate + ? new_event.y + : last_event.y; + + gfx::Transform combined_scroll_pinch = GetTransformForEvent(last_event); + if (second_last_event) { + combined_scroll_pinch.PreconcatTransform( + GetTransformForEvent(*second_last_event)); + } + combined_scroll_pinch.ConcatTransform(GetTransformForEvent(new_event)); + + float combined_scale = + SkMScalarToFloat(combined_scroll_pinch.matrix().get(0, 0)); + float combined_scroll_pinch_x = + SkMScalarToFloat(combined_scroll_pinch.matrix().get(0, 3)); + float combined_scroll_pinch_y = + SkMScalarToFloat(combined_scroll_pinch.matrix().get(1, 3)); + scroll_event.data.scrollUpdate.deltaX = + (combined_scroll_pinch_x + pinch_event.x) / combined_scale - + pinch_event.x; + scroll_event.data.scrollUpdate.deltaY = + (combined_scroll_pinch_y + pinch_event.y) / combined_scale - + pinch_event.y; + pinch_event.data.pinchUpdate.scale = combined_scale; + + return std::make_pair(scroll_event, pinch_event); +} + blink::WebTouchEvent CreateWebTouchEventFromMotionEvent( const MotionEvent& event, bool moved_beyond_slop_region) {
diff --git a/ui/events/blink/blink_event_util.h b/ui/events/blink/blink_event_util.h index 5636d58..8eae9b03e 100644 --- a/ui/events/blink/blink_event_util.h +++ b/ui/events/blink/blink_event_util.h
@@ -7,12 +7,11 @@ #include <memory> +#include "third_party/WebKit/public/platform/WebGestureEvent.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" #include "ui/events/gesture_detection/motion_event.h" namespace blink { -class WebGestureEvent; -class WebInputEvent; class WebTouchEvent; } @@ -33,6 +32,16 @@ void Coalesce(const blink::WebInputEvent& event_to_coalesce, blink::WebInputEvent* event); +bool IsCompatibleScrollorPinch(const blink::WebGestureEvent& new_event, + const blink::WebGestureEvent& event_in_queue); + +// Coalesces 3 GestureScroll/PinchUpdate into 2 events. +// Returns <GestureScrollUpdate, GesturePinchUpdate>. +std::pair<blink::WebGestureEvent, blink::WebGestureEvent> +CoalesceScrollAndPinch(const blink::WebGestureEvent* second_last_event, + const blink::WebGestureEvent& last_event, + const blink::WebGestureEvent& new_event); + blink::WebTouchEvent CreateWebTouchEventFromMotionEvent( const MotionEvent& event, bool may_cause_scrolling); @@ -84,6 +93,12 @@ bool IsContinuousGestureEvent(blink::WebInputEvent::Type); +inline const blink::WebGestureEvent& ToWebGestureEvent( + const blink::WebInputEvent& event) { + DCHECK(IsGestureScollOrPinch(event.type)); + return static_cast<const blink::WebGestureEvent&>(event); +} + } // namespace ui #endif // UI_EVENTS_BLINK_BLINK_EVENT_UTIL_H_
diff --git a/ui/events/blink/compositor_thread_event_queue.cc b/ui/events/blink/compositor_thread_event_queue.cc index 9eec24e..47e906f 100644 --- a/ui/events/blink/compositor_thread_event_queue.cc +++ b/ui/events/blink/compositor_thread_event_queue.cc
@@ -4,22 +4,82 @@ #include "ui/events/blink/compositor_thread_event_queue.h" +#include "base/memory/ptr_util.h" +#include "ui/events/blink/blink_event_util.h" +#include "ui/events/blink/web_input_event_traits.h" + namespace ui { CompositorThreadEventQueue::CompositorThreadEventQueue() {} CompositorThreadEventQueue::~CompositorThreadEventQueue() {} -// TODO(chongz): Support coalescing events across interleaved boundaries. -// https://crbug.com/661601 -void CompositorThreadEventQueue::Queue(std::unique_ptr<EventWithCallback> event, - base::TimeTicks timestamp_now) { - if (!queue_.empty() && queue_.back()->CanCoalesceWith(*event)) { - queue_.back()->CoalesceWith(event.get(), timestamp_now); +void CompositorThreadEventQueue::Queue( + std::unique_ptr<EventWithCallback> new_event, + base::TimeTicks timestamp_now) { + if (queue_.empty() || !IsContinuousGestureEvent(new_event->event().type) || + !IsCompatibleScrollorPinch(ToWebGestureEvent(new_event->event()), + ToWebGestureEvent(queue_.back()->event()))) { + queue_.emplace_back(std::move(new_event)); return; } - queue_.emplace_back(std::move(event)); + if (queue_.back()->CanCoalesceWith(*new_event)) { + queue_.back()->CoalesceWith(new_event.get(), timestamp_now); + return; + } + + // Extract the last event in queue. + std::unique_ptr<EventWithCallback> last_event = std::move(queue_.back()); + queue_.pop_back(); + DCHECK_LE(last_event->latency_info().trace_id(), + new_event->latency_info().trace_id()); + LatencyInfo oldest_latency = last_event->latency_info(); + oldest_latency.set_coalesced(); + base::TimeTicks oldest_creation_timestamp = last_event->creation_timestamp(); + auto combined_original_events = + base::MakeUnique<EventWithCallback::OriginalEventList>(); + combined_original_events->splice(combined_original_events->end(), + last_event->original_events()); + combined_original_events->splice(combined_original_events->end(), + new_event->original_events()); + + // Extract the second last event in queue. + std::unique_ptr<EventWithCallback> second_last_event = nullptr; + if (!queue_.empty() && + IsCompatibleScrollorPinch(ToWebGestureEvent(new_event->event()), + ToWebGestureEvent(queue_.back()->event()))) { + second_last_event = std::move(queue_.back()); + queue_.pop_back(); + DCHECK_LE(second_last_event->latency_info().trace_id(), + oldest_latency.trace_id()); + oldest_latency = second_last_event->latency_info(); + oldest_latency.set_coalesced(); + oldest_creation_timestamp = second_last_event->creation_timestamp(); + combined_original_events->splice(combined_original_events->begin(), + second_last_event->original_events()); + } + + std::pair<blink::WebGestureEvent, blink::WebGestureEvent> coalesced_events = + CoalesceScrollAndPinch( + second_last_event ? &ToWebGestureEvent(second_last_event->event()) + : nullptr, + ToWebGestureEvent(last_event->event()), + ToWebGestureEvent(new_event->event())); + + std::unique_ptr<EventWithCallback> scroll_event = + base::MakeUnique<EventWithCallback>( + WebInputEventTraits::Clone(coalesced_events.first), oldest_latency, + oldest_creation_timestamp, timestamp_now, nullptr); + + std::unique_ptr<EventWithCallback> pinch_event = + base::MakeUnique<EventWithCallback>( + WebInputEventTraits::Clone(coalesced_events.second), oldest_latency, + oldest_creation_timestamp, timestamp_now, + std::move(combined_original_events)); + + queue_.emplace_back(std::move(scroll_event)); + queue_.emplace_back(std::move(pinch_event)); } std::unique_ptr<EventWithCallback> CompositorThreadEventQueue::Pop() {
diff --git a/ui/events/blink/event_with_callback.cc b/ui/events/blink/event_with_callback.cc index bcbd862e..e2c90a2 100644 --- a/ui/events/blink/event_with_callback.cc +++ b/ui/events/blink/event_with_callback.cc
@@ -26,6 +26,20 @@ original_events_.emplace_back(std::move(event), callback); } +EventWithCallback::EventWithCallback( + ScopedWebInputEvent event, + const LatencyInfo& latency, + base::TimeTicks creation_timestamp, + base::TimeTicks last_coalesced_timestamp, + std::unique_ptr<OriginalEventList> original_events) + : event_(std::move(event)), + latency_(latency), + creation_timestamp_(creation_timestamp), + last_coalesced_timestamp_(last_coalesced_timestamp) { + if (original_events) + original_events_.splice(original_events_.end(), *original_events); +} + EventWithCallback::~EventWithCallback() {} bool EventWithCallback::CanCoalesceWith(const EventWithCallback& other) const {
diff --git a/ui/events/blink/event_with_callback.h b/ui/events/blink/event_with_callback.h index c6fd612..14f6eee 100644 --- a/ui/events/blink/event_with_callback.h +++ b/ui/events/blink/event_with_callback.h
@@ -18,11 +18,26 @@ class EventWithCallback { public: + struct OriginalEventWithCallback { + OriginalEventWithCallback( + ScopedWebInputEvent event, + const InputHandlerProxy::EventDispositionCallback& callback); + ~OriginalEventWithCallback(); + ScopedWebInputEvent event_; + InputHandlerProxy::EventDispositionCallback callback_; + }; + using OriginalEventList = std::list<OriginalEventWithCallback>; + EventWithCallback( ScopedWebInputEvent event, const LatencyInfo& latency, base::TimeTicks timestamp_now, const InputHandlerProxy::EventDispositionCallback& callback); + EventWithCallback(ScopedWebInputEvent event, + const LatencyInfo& latency, + base::TimeTicks creation_timestamp, + base::TimeTicks last_coalesced_timestamp, + std::unique_ptr<OriginalEventList> original_events); ~EventWithCallback(); bool CanCoalesceWith(const EventWithCallback& other) const WARN_UNUSED_RESULT; @@ -39,23 +54,16 @@ return last_coalesced_timestamp_; } size_t coalesced_count() const { return original_events_.size(); } + OriginalEventList& original_events() { return original_events_; } private: friend class test::InputHandlerProxyEventQueueTest; - struct OriginalEventWithCallback { - OriginalEventWithCallback( - ScopedWebInputEvent event, - const InputHandlerProxy::EventDispositionCallback& callback); - ~OriginalEventWithCallback(); - ScopedWebInputEvent event_; - InputHandlerProxy::EventDispositionCallback callback_; - }; void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock); ScopedWebInputEvent event_; LatencyInfo latency_; - std::list<OriginalEventWithCallback> original_events_; + OriginalEventList original_events_; base::TimeTicks creation_timestamp_; base::TimeTicks last_coalesced_timestamp_;
diff --git a/ui/events/blink/input_handler_proxy_unittest.cc b/ui/events/blink/input_handler_proxy_unittest.cc index 8a0f7e1c..deac383 100644 --- a/ui/events/blink/input_handler_proxy_unittest.cc +++ b/ui/events/blink/input_handler_proxy_unittest.cc
@@ -21,6 +21,7 @@ #include "third_party/WebKit/public/platform/WebGestureCurve.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" #include "third_party/WebKit/public/platform/WebPoint.h" +#include "ui/events/blink/blink_event_util.h" #include "ui/events/blink/compositor_thread_event_queue.h" #include "ui/events/blink/did_overscroll_params.h" #include "ui/events/blink/event_with_callback.h" @@ -3087,6 +3088,54 @@ 1); } +TEST_F(InputHandlerProxyEventQueueTest, VSyncAlignedCoalesceScrollAndPinch) { + // Start scroll in the first frame. + EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_)) + .WillOnce(testing::Return(kImplThreadScrollState)); + EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput()).Times(1); + + // GSUs and GPUs in one sequence should be coalesced into 1 GSU and 1 GPU. + HandleGestureEvent(WebInputEvent::GestureScrollBegin); + HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -20); + HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -7); + HandleGestureEvent(WebInputEvent::GesturePinchUpdate, 2.0f, 13, 10); + HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -10); + HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -6); + HandleGestureEvent(WebInputEvent::GestureScrollEnd); + HandleGestureEvent(WebInputEvent::GesturePinchBegin); + HandleGestureEvent(WebInputEvent::GesturePinchUpdate, 0.2f, 2, 20); + HandleGestureEvent(WebInputEvent::GesturePinchUpdate, 10.0f, 1, 10); + HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -30); + HandleGestureEvent(WebInputEvent::GesturePinchUpdate, 0.25f, 3, 30); + HandleGestureEvent(WebInputEvent::GestureScrollUpdate, -10); + HandleGestureEvent(WebInputEvent::GesturePinchEnd); + + // Only the first GSB was dispatched. + EXPECT_EQ(7ul, event_queue().size()); + EXPECT_EQ(1ul, event_disposition_recorder_.size()); + + EXPECT_EQ(WebInputEvent::GestureScrollUpdate, event_queue()[0]->event().type); + EXPECT_EQ( + -35, + ToWebGestureEvent(event_queue()[0]->event()).data.scrollUpdate.deltaY); + EXPECT_EQ(WebInputEvent::GesturePinchUpdate, event_queue()[1]->event().type); + EXPECT_EQ( + 2.0f, + ToWebGestureEvent(event_queue()[1]->event()).data.pinchUpdate.scale); + EXPECT_EQ(WebInputEvent::GestureScrollEnd, event_queue()[2]->event().type); + EXPECT_EQ(WebInputEvent::GesturePinchBegin, event_queue()[3]->event().type); + EXPECT_EQ(WebInputEvent::GestureScrollUpdate, event_queue()[4]->event().type); + EXPECT_EQ( + -85, + ToWebGestureEvent(event_queue()[4]->event()).data.scrollUpdate.deltaY); + EXPECT_EQ(WebInputEvent::GesturePinchUpdate, event_queue()[5]->event().type); + EXPECT_EQ( + 0.5f, + ToWebGestureEvent(event_queue()[5]->event()).data.pinchUpdate.scale); + EXPECT_EQ(WebInputEvent::GesturePinchEnd, event_queue()[6]->event().type); + testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); +} + INSTANTIATE_TEST_CASE_P(AnimateInput, InputHandlerProxyTest, testing::ValuesIn(test_types));
diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc index 2cae22a..90d9768 100644 --- a/ui/message_center/views/message_center_view.cc +++ b/ui/message_center/views/message_center_view.cc
@@ -95,6 +95,7 @@ scroller_ = new views::ScrollView(); scroller_->ClipHeightTo(kMinScrollViewHeight, max_height - button_height); scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false)); + scroller_->SetHorizontalScrollBar(new views::OverlayScrollBar(true)); scroller_->set_background( views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
diff --git a/ui/message_center/views/notifier_settings_view.cc b/ui/message_center/views/notifier_settings_view.cc index e4ecb98..d27e03a5 100644 --- a/ui/message_center/views/notifier_settings_view.cc +++ b/ui/message_center/views/notifier_settings_view.cc
@@ -442,6 +442,7 @@ scroller_ = new views::ScrollView(); scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false)); + scroller_->SetHorizontalScrollBar(new views::OverlayScrollBar(true)); AddChildView(scroller_); std::vector<Notifier*> notifiers; @@ -570,7 +571,7 @@ int content_width = width(); int content_height = contents_view->GetHeightForWidth(content_width); if (title_height + content_height > height()) { - content_width -= scroller_->GetScrollBarWidth(); + content_width -= scroller_->GetScrollBarLayoutWidth(); content_height = contents_view->GetHeightForWidth(content_width); } contents_view->SetBounds(0, 0, content_width, content_height); @@ -582,7 +583,7 @@ int total_height = title_label_->GetPreferredSize().height() + scroller_->contents()->GetPreferredSize().height(); if (total_height > kMinimumHeight) - size.Enlarge(scroller_->GetScrollBarWidth(), 0); + size.Enlarge(scroller_->GetScrollBarLayoutWidth(), 0); return size; }
diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc index cf212b7c..35f7f1b 100644 --- a/ui/views/controls/scroll_view.cc +++ b/ui/views/controls/scroll_view.cc
@@ -243,12 +243,14 @@ max_height_ = max_height; } -int ScrollView::GetScrollBarWidth() const { - return vert_sb_ ? vert_sb_->GetLayoutSize() : 0; +int ScrollView::GetScrollBarLayoutWidth() const { + return vert_sb_ && !vert_sb_->OverlapsContent() ? vert_sb_->GetThickness() + : 0; } -int ScrollView::GetScrollBarHeight() const { - return horiz_sb_ ? horiz_sb_->GetLayoutSize() : 0; +int ScrollView::GetScrollBarLayoutHeight() const { + return horiz_sb_ && !horiz_sb_->OverlapsContent() ? horiz_sb_->GetThickness() + : 0; } void ScrollView::SetHorizontalScrollBar(ScrollBar* horiz_sb) { @@ -302,6 +304,14 @@ } void ScrollView::Layout() { +#if defined(OS_MACOSX) + // On Mac, scrollbars may update their style one at a time, so they may + // temporarily be of different types. Refuse to lay out at this point. + if (horiz_sb_->OverlapsContent() != vert_sb_->OverlapsContent()) + return; +#endif + DCHECK_EQ(horiz_sb_->OverlapsContent(), vert_sb_->OverlapsContent()); + if (focus_ring_) focus_ring_->Layout(); @@ -310,7 +320,7 @@ int content_width = available_rect.width(); int content_height = contents_->GetHeightForWidth(content_width); if (content_height > height()) { - content_width = std::max(content_width - GetScrollBarWidth(), 0); + content_width = std::max(content_width - GetScrollBarLayoutWidth(), 0); content_height = contents_->GetHeightForWidth(content_width); } contents_->SetSize(gfx::Size(content_width, content_height)); @@ -342,9 +352,9 @@ gfx::Size viewport_size = viewport_bounds.size(); // Assumes a vertical scrollbar since most of the current views are designed // for this. - int horiz_sb_height = GetScrollBarHeight(); - int vert_sb_width = GetScrollBarWidth(); - viewport_bounds.set_width(viewport_bounds.width() - vert_sb_width); + const int horiz_sb_layout_height = GetScrollBarLayoutHeight(); + const int vert_sb_layout_width = GetScrollBarLayoutWidth(); + viewport_bounds.set_width(viewport_bounds.width() - vert_sb_layout_width); // Update the bounds right now so the inner views can fit in it. contents_viewport_->SetBoundsRect(viewport_bounds); @@ -363,7 +373,9 @@ &horiz_sb_required, &vert_sb_required); } - bool corner_view_required = horiz_sb_required && vert_sb_required; + // Overlay scrollbars don't need a corner view. + bool corner_view_required = + horiz_sb_required && vert_sb_required && !vert_sb_->OverlapsContent(); // Take action. SetControlVisibility(horiz_sb_, horiz_sb_required); SetControlVisibility(vert_sb_, vert_sb_required); @@ -372,37 +384,45 @@ // Non-default. if (horiz_sb_required) { viewport_bounds.set_height( - std::max(0, viewport_bounds.height() - horiz_sb_height)); + std::max(0, viewport_bounds.height() - horiz_sb_layout_height)); should_layout_contents = true; } // Default. if (!vert_sb_required) { - viewport_bounds.set_width(viewport_bounds.width() + vert_sb_width); + viewport_bounds.set_width(viewport_bounds.width() + vert_sb_layout_width); should_layout_contents = true; } - int height_offset = horiz_sb_required ? - horiz_sb_->GetContentOverlapSize() : 0; - int width_offset = vert_sb_required ? - vert_sb_->GetContentOverlapSize() : 0; - if (horiz_sb_required) { - horiz_sb_->SetBounds(contents_x, - viewport_bounds.bottom() - height_offset, - viewport_bounds.right() - contents_x - width_offset, - horiz_sb_height + height_offset); + gfx::Rect horiz_sb_bounds(contents_x, viewport_bounds.bottom(), + viewport_bounds.right() - contents_x, + horiz_sb_layout_height); + if (horiz_sb_->OverlapsContent()) { + horiz_sb_bounds.Inset( + gfx::Insets(-horiz_sb_->GetThickness(), 0, 0, + vert_sb_required ? vert_sb_->GetThickness() : 0)); + } + + horiz_sb_->SetBoundsRect(horiz_sb_bounds); } if (vert_sb_required) { - int width_offset = vert_sb_->GetContentOverlapSize(); - vert_sb_->SetBounds(viewport_bounds.right() - width_offset, - contents_y, - vert_sb_width + width_offset, - viewport_bounds.bottom() - contents_y - height_offset); + gfx::Rect vert_sb_bounds(viewport_bounds.right(), contents_y, + vert_sb_layout_width, + viewport_bounds.bottom() - contents_y); + if (vert_sb_->OverlapsContent()) { + // In the overlay scrollbar case, the scrollbar only covers the viewport + // (and not the header). + vert_sb_bounds.Inset( + gfx::Insets(header_height, -vert_sb_->GetThickness(), + horiz_sb_required ? horiz_sb_->GetThickness() : 0, 0)); + } + + vert_sb_->SetBoundsRect(vert_sb_bounds); } if (corner_view_required) { // Show the resize corner. corner_view_->SetBounds(vert_sb_->bounds().x(), horiz_sb_->bounds().y(), - vert_sb_width, horiz_sb_height); + vert_sb_layout_width, horiz_sb_layout_height); } // Update to the real client size with the visible scrollbars. @@ -619,10 +639,12 @@ content_size.height() <= vp_size.height()) { *horiz_is_shown = false; *vert_is_shown = false; - } else if (content_size.width() <= vp_size.width() - GetScrollBarWidth()) { + } else if (content_size.width() <= + vp_size.width() - GetScrollBarLayoutWidth()) { *horiz_is_shown = false; *vert_is_shown = true; - } else if (content_size.height() <= vp_size.height() - GetScrollBarHeight()) { + } else if (content_size.height() <= + vp_size.height() - GetScrollBarLayoutHeight()) { *horiz_is_shown = true; *vert_is_shown = false; } else {
diff --git a/ui/views/controls/scroll_view.h b/ui/views/controls/scroll_view.h index 288be67..6dc4393 100644 --- a/ui/views/controls/scroll_view.h +++ b/ui/views/controls/scroll_view.h
@@ -74,10 +74,10 @@ // Returns whether or not the ScrollView is bounded (as set by ClipHeightTo). bool is_bounded() const { return max_height_ >= 0 && min_height_ >= 0; } - // Retrieves the width/height of scrollbars. These return 0 if the scrollbar - // has not yet been created. - int GetScrollBarWidth() const; - int GetScrollBarHeight() const; + // Retrieves the width/height reserved for scrollbars. These return 0 if the + // scrollbar has not yet been created or in the case of overlay scrollbars. + int GetScrollBarLayoutWidth() const; + int GetScrollBarLayoutHeight() const; // Returns the horizontal/vertical scrollbar. This may return NULL. const ScrollBar* horizontal_scroll_bar() const { return horiz_sb_; }
diff --git a/ui/views/controls/scroll_view_unittest.cc b/ui/views/controls/scroll_view_unittest.cc index c4a5ca7..1aa29e15 100644 --- a/ui/views/controls/scroll_view_unittest.cc +++ b/ui/views/controls/scroll_view_unittest.cc
@@ -167,6 +167,14 @@ protected: #endif + int VerticalScrollBarWidth() { + return scroll_view_.vertical_scroll_bar()->GetThickness(); + } + + int HorizontalScrollBarHeight() { + return scroll_view_.horizontal_scroll_bar()->GetThickness(); + } + ScrollView scroll_view_; private: @@ -309,7 +317,7 @@ // Size the contents such that vertical scrollbar is needed. contents->SetBounds(0, 0, 50, 400); scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarWidth(), + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); CheckScrollbarVisibility(scroll_view_, VERTICAL, true); @@ -323,7 +331,7 @@ contents->SetBounds(0, 0, 400, 50); scroll_view_.Layout(); EXPECT_EQ(100, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarHeight(), + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), contents->parent()->height()); CheckScrollbarVisibility(scroll_view_, VERTICAL, false); CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); @@ -331,9 +339,9 @@ // Both horizontal and vertical. contents->SetBounds(0, 0, 300, 400); scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarWidth(), + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarHeight(), + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), contents->parent()->height()); CheckScrollbarVisibility(scroll_view_, VERTICAL, true); CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); @@ -347,16 +355,16 @@ kBottomPadding, kRightPadding)); contents->SetBounds(0, 0, 50, 400); scroll_view_.Layout(); - EXPECT_EQ( - 100 - scroll_view_.GetScrollBarWidth() - kLeftPadding - kRightPadding, - contents->parent()->width()); + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth() - kLeftPadding - + kRightPadding, + contents->parent()->width()); EXPECT_EQ(100 - kTopPadding - kBottomPadding, contents->parent()->height()); EXPECT_TRUE(!scroll_view_.horizontal_scroll_bar() || !scroll_view_.horizontal_scroll_bar()->visible()); ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); gfx::Rect bounds = scroll_view_.vertical_scroll_bar()->bounds(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarWidth() - kRightPadding, bounds.x()); + EXPECT_EQ(100 - VerticalScrollBarWidth() - kRightPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding, bounds.right()); EXPECT_EQ(kTopPadding, bounds.y()); EXPECT_EQ(100 - kBottomPadding, bounds.bottom()); @@ -365,9 +373,9 @@ contents->SetBounds(0, 0, 400, 50); scroll_view_.Layout(); EXPECT_EQ(100 - kLeftPadding - kRightPadding, contents->parent()->width()); - EXPECT_EQ( - 100 - scroll_view_.GetScrollBarHeight() - kTopPadding - kBottomPadding, - contents->parent()->height()); + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - kTopPadding - + kBottomPadding, + contents->parent()->height()); ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); EXPECT_TRUE(!scroll_view_.vertical_scroll_bar() || @@ -375,38 +383,35 @@ bounds = scroll_view_.horizontal_scroll_bar()->bounds(); EXPECT_EQ(kLeftPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding, bounds.right()); - EXPECT_EQ(100 - kBottomPadding - scroll_view_.GetScrollBarHeight(), - bounds.y()); + EXPECT_EQ(100 - kBottomPadding - HorizontalScrollBarHeight(), bounds.y()); EXPECT_EQ(100 - kBottomPadding, bounds.bottom()); // Both horizontal and vertical with border. contents->SetBounds(0, 0, 300, 400); scroll_view_.Layout(); - EXPECT_EQ( - 100 - scroll_view_.GetScrollBarWidth() - kLeftPadding - kRightPadding, - contents->parent()->width()); - EXPECT_EQ( - 100 - scroll_view_.GetScrollBarHeight() - kTopPadding - kBottomPadding, - contents->parent()->height()); + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth() - kLeftPadding - + kRightPadding, + contents->parent()->width()); + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - kTopPadding - + kBottomPadding, + contents->parent()->height()); bounds = scroll_view_.horizontal_scroll_bar()->bounds(); // Check horiz. ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); bounds = scroll_view_.horizontal_scroll_bar()->bounds(); EXPECT_EQ(kLeftPadding, bounds.x()); - EXPECT_EQ(100 - kRightPadding - scroll_view_.GetScrollBarWidth(), - bounds.right()); - EXPECT_EQ(100 - kBottomPadding - scroll_view_.GetScrollBarHeight(), - bounds.y()); + EXPECT_EQ(100 - kRightPadding - VerticalScrollBarWidth(), bounds.right()); + EXPECT_EQ(100 - kBottomPadding - HorizontalScrollBarHeight(), bounds.y()); EXPECT_EQ(100 - kBottomPadding, bounds.bottom()); // Check vert. ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); bounds = scroll_view_.vertical_scroll_bar()->bounds(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarWidth() - kRightPadding, bounds.x()); + EXPECT_EQ(100 - VerticalScrollBarWidth() - kRightPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding, bounds.right()); EXPECT_EQ(kTopPadding, bounds.y()); - EXPECT_EQ(100 - kBottomPadding - scroll_view_.GetScrollBarHeight(), + EXPECT_EQ(100 - kBottomPadding - HorizontalScrollBarHeight(), bounds.bottom()); } @@ -464,19 +469,25 @@ scroll_view_.Layout(); EXPECT_EQ(0, contents->parent()->x()); EXPECT_EQ(20, contents->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarWidth(), + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), contents->parent()->width()); EXPECT_EQ(80, contents->parent()->height()); EXPECT_EQ(0, header->parent()->x()); EXPECT_EQ(0, header->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarWidth(), header->parent()->width()); + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + header->parent()->width()); EXPECT_EQ(20, header->parent()->height()); EXPECT_TRUE(!scroll_view_.horizontal_scroll_bar() || !scroll_view_.horizontal_scroll_bar()->visible()); ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); - // Make sure the vertical scrollbar overlaps the header. - EXPECT_EQ(header->y(), scroll_view_.vertical_scroll_bar()->y()); + // Make sure the vertical scrollbar overlaps the header for traditional + // scrollbars and doesn't overlap the header for overlay scrollbars. + const int expected_scrollbar_y = + scroll_view_.vertical_scroll_bar()->OverlapsContent() + ? header->bounds().bottom() + : header->y(); + EXPECT_EQ(expected_scrollbar_y, scroll_view_.vertical_scroll_bar()->y()); EXPECT_EQ(header->y(), contents->y()); // Size the contents such that horizontal scrollbar is needed. @@ -485,7 +496,7 @@ EXPECT_EQ(0, contents->parent()->x()); EXPECT_EQ(20, contents->parent()->y()); EXPECT_EQ(100, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarHeight() - 20, + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - 20, contents->parent()->height()); EXPECT_EQ(0, header->parent()->x()); EXPECT_EQ(0, header->parent()->y()); @@ -501,13 +512,14 @@ scroll_view_.Layout(); EXPECT_EQ(0, contents->parent()->x()); EXPECT_EQ(20, contents->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarWidth(), + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarHeight() - 20, + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - 20, contents->parent()->height()); EXPECT_EQ(0, header->parent()->x()); EXPECT_EQ(0, header->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarWidth(), header->parent()->width()); + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + header->parent()->width()); EXPECT_EQ(20, header->parent()->height()); ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); @@ -560,7 +572,7 @@ const int viewport_height = test_api.contents_viewport()->height(); // Expect there to be a horizontal scrollbar, making the viewport shorter. - EXPECT_LT(viewport_height, 100); + EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), viewport_height); gfx::ScrollOffset offset = test_api.CurrentOffset(); EXPECT_EQ(415 - viewport_height, offset.y()); @@ -618,10 +630,6 @@ // Verifies ClipHeightTo() uses the maximum height when the content is longer // thamn the maximum height value. TEST_F(ScrollViewTest, ClipHeightToTallContentHeight) { - // Use a scrollbar that is disabled by default, so the width of the content is - // not affected. - scroll_view_.SetVerticalScrollBar(new views::OverlayScrollBar(false)); - scroll_view_.ClipHeightTo(kMinHeight, kMaxHeight); const int kTallContentHeight = 1000; @@ -633,8 +641,9 @@ scroll_view_.SizeToPreferredSize(); scroll_view_.Layout(); - EXPECT_EQ(gfx::Size(kWidth, kTallContentHeight), - scroll_view_.contents()->size()); + // The width may be less than kWidth if the scroll bar takes up some width. + EXPECT_GE(kWidth, scroll_view_.contents()->width()); + EXPECT_EQ(kTallContentHeight, scroll_view_.contents()->height()); EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_.size()); } @@ -654,8 +663,7 @@ scroll_view_.SetSize(new_size); scroll_view_.Layout(); - int scroll_bar_width = scroll_view_.GetScrollBarWidth(); - int expected_width = kWidth - scroll_bar_width; + int expected_width = kWidth - scroll_view_.GetScrollBarLayoutWidth(); EXPECT_EQ(scroll_view_.contents()->size().width(), expected_width); EXPECT_EQ(scroll_view_.contents()->size().height(), 1000 * expected_width); EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_.size()); @@ -665,17 +673,24 @@ View* contents = InstallContents(); View* corner_view = ScrollViewTestApi(&scroll_view_).corner_view(); - // Corner view should be visible when both scrollbars are visible. contents->SetBounds(0, 0, 200, 200); scroll_view_.Layout(); + + // Corner view should not exist if using overlay scrollbars. + if (scroll_view_.vertical_scroll_bar()->OverlapsContent()) { + EXPECT_FALSE(corner_view->parent()); + return; + } + + // Corner view should be visible when both scrollbars are visible. EXPECT_EQ(&scroll_view_, corner_view->parent()); EXPECT_TRUE(corner_view->visible()); // Corner view should be aligned to the scrollbars. EXPECT_EQ(scroll_view_.vertical_scroll_bar()->x(), corner_view->x()); EXPECT_EQ(scroll_view_.horizontal_scroll_bar()->y(), corner_view->y()); - EXPECT_EQ(scroll_view_.GetScrollBarWidth(), corner_view->width()); - EXPECT_EQ(scroll_view_.GetScrollBarHeight(), corner_view->height()); + EXPECT_EQ(scroll_view_.GetScrollBarLayoutWidth(), corner_view->width()); + EXPECT_EQ(scroll_view_.GetScrollBarLayoutHeight(), corner_view->height()); // Corner view should be removed when only the vertical scrollbar is visible. contents->SetBounds(0, 0, 50, 200); @@ -712,7 +727,7 @@ scroll_view_.Layout(); EXPECT_EQ(100, contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - EXPECT_EQ(0, scroll_view_.GetScrollBarWidth()); + EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutWidth()); CheckScrollbarVisibility(scroll_view_, VERTICAL, true); CheckScrollbarVisibility(scroll_view_, HORIZONTAL, false); @@ -721,7 +736,7 @@ scroll_view_.Layout(); EXPECT_EQ(100, contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - EXPECT_EQ(0, scroll_view_.GetScrollBarHeight()); + EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutHeight()); CheckScrollbarVisibility(scroll_view_, VERTICAL, false); CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); @@ -730,8 +745,8 @@ scroll_view_.Layout(); EXPECT_EQ(100, contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - EXPECT_EQ(0, scroll_view_.GetScrollBarWidth()); - EXPECT_EQ(0, scroll_view_.GetScrollBarHeight()); + EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutWidth()); + EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutHeight()); CheckScrollbarVisibility(scroll_view_, VERTICAL, true); CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); @@ -744,12 +759,10 @@ // Switch to the non-overlay style and check that the ViewPort is now sized // to be smaller, and ScrollbarWidth and ScrollbarHeight are non-zero. SetOverlayScrollersEnabled(false); - EXPECT_EQ(100 - scroll_view_.GetScrollBarWidth(), - contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarHeight(), - contents->parent()->height()); - EXPECT_NE(0, scroll_view_.GetScrollBarWidth()); - EXPECT_NE(0, scroll_view_.GetScrollBarHeight()); + EXPECT_EQ(100 - VerticalScrollBarWidth(), contents->parent()->width()); + EXPECT_EQ(100 - HorizontalScrollBarHeight(), contents->parent()->height()); + EXPECT_NE(0, VerticalScrollBarWidth()); + EXPECT_NE(0, HorizontalScrollBarHeight()); } // Test overlay scrollbar behavior when just resting fingers on the trackpad.
diff --git a/ui/views/controls/scrollbar/base_scroll_bar.cc b/ui/views/controls/scrollbar/base_scroll_bar.cc index 123e59c..f343948 100644 --- a/ui/views/controls/scrollbar/base_scroll_bar.cc +++ b/ui/views/controls/scrollbar/base_scroll_bar.cc
@@ -400,6 +400,10 @@ return thumb_->GetPosition(); } +bool BaseScrollBar::OverlapsContent() const { + return false; +} + /////////////////////////////////////////////////////////////////////////////// // BaseScrollBar, protected:
diff --git a/ui/views/controls/scrollbar/base_scroll_bar.h b/ui/views/controls/scrollbar/base_scroll_bar.h index 9355e7c..5d077737 100644 --- a/ui/views/controls/scrollbar/base_scroll_bar.h +++ b/ui/views/controls/scrollbar/base_scroll_bar.h
@@ -78,8 +78,9 @@ void Update(int viewport_size, int content_size, int contents_scroll_offset) override; - int GetLayoutSize() const override = 0; int GetPosition() const override; + int GetThickness() const override = 0; + bool OverlapsContent() const override; // ScrollDelegate overrides: bool OnScroll(float dx, float dy) override;
diff --git a/ui/views/controls/scrollbar/cocoa_scroll_bar.h b/ui/views/controls/scrollbar/cocoa_scroll_bar.h index 8b91f6c3..3f1ba279 100644 --- a/ui/views/controls/scrollbar/cocoa_scroll_bar.h +++ b/ui/views/controls/scrollbar/cocoa_scroll_bar.h
@@ -59,8 +59,8 @@ gfx::Rect GetTrackBounds() const override; // ScrollBar: - int GetLayoutSize() const override; - int GetContentOverlapSize() const override; + int GetThickness() const override; + bool OverlapsContent() const override; // View: void Layout() override;
diff --git a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm index 40390cd..9d54b67 100644 --- a/ui/views/controls/scrollbar/cocoa_scroll_bar.mm +++ b/ui/views/controls/scrollbar/cocoa_scroll_bar.mm
@@ -208,12 +208,12 @@ ////////////////////////////////////////////////////////////////// // CocoaScrollBar, ScrollBar: -int CocoaScrollBar::GetLayoutSize() const { - return scroller_style_ == NSScrollerStyleOverlay ? 0 : ScrollbarThickness(); +int CocoaScrollBar::GetThickness() const { + return ScrollbarThickness(); } -int CocoaScrollBar::GetContentOverlapSize() const { - return scroller_style_ == NSScrollerStyleLegacy ? 0 : ScrollbarThickness(); +bool CocoaScrollBar::OverlapsContent() const { + return scroller_style_ == NSScrollerStyleOverlay; } //////////////////////////////////////////////////////////////////
diff --git a/ui/views/controls/scrollbar/overlay_scroll_bar.cc b/ui/views/controls/scrollbar/overlay_scroll_bar.cc index 358a097..5ea32a4 100644 --- a/ui/views/controls/scrollbar/overlay_scroll_bar.cc +++ b/ui/views/controls/scrollbar/overlay_scroll_bar.cc
@@ -128,12 +128,12 @@ return local; } -int OverlayScrollBar::GetLayoutSize() const { - return 0; +int OverlayScrollBar::GetThickness() const { + return kThumbThickness; } -int OverlayScrollBar::GetContentOverlapSize() const { - return kThumbThickness; +bool OverlayScrollBar::OverlapsContent() const { + return true; } void OverlayScrollBar::Layout() {
diff --git a/ui/views/controls/scrollbar/overlay_scroll_bar.h b/ui/views/controls/scrollbar/overlay_scroll_bar.h index 4771abb..5a21d424 100644 --- a/ui/views/controls/scrollbar/overlay_scroll_bar.h +++ b/ui/views/controls/scrollbar/overlay_scroll_bar.h
@@ -22,8 +22,8 @@ gfx::Rect GetTrackBounds() const override; // ScrollBar overrides: - int GetLayoutSize() const override; - int GetContentOverlapSize() const override; + int GetThickness() const override; + bool OverlapsContent() const override; // View overrides: void Layout() override;
diff --git a/ui/views/controls/scrollbar/scroll_bar.cc b/ui/views/controls/scrollbar/scroll_bar.cc index ea5d94b..6714693 100644 --- a/ui/views/controls/scrollbar/scroll_bar.cc +++ b/ui/views/controls/scrollbar/scroll_bar.cc
@@ -31,10 +31,6 @@ return 0; } -int ScrollBar::GetContentOverlapSize() const { - return 0; -} - void ScrollBar::ObserveScrollEvent(const ui::ScrollEvent& event) {} ScrollBar::ScrollBar(bool is_horiz)
diff --git a/ui/views/controls/scrollbar/scroll_bar.h b/ui/views/controls/scrollbar/scroll_bar.h index acda1430..ac162b7 100644 --- a/ui/views/controls/scrollbar/scroll_bar.h +++ b/ui/views/controls/scrollbar/scroll_bar.h
@@ -81,14 +81,14 @@ // Returns the position of the scrollbar. virtual int GetPosition() const = 0; - // Get the width or height of this scrollbar, for use in layout calculations. - // For a vertical scrollbar, this is the width of the scrollbar, likewise it - // is the height for a horizontal scrollbar. - virtual int GetLayoutSize() const = 0; + // Get the width or height of this scrollbar. For a vertical scrollbar, this + // is the width of the scrollbar, likewise it is the height for a horizontal + // scrollbar. + virtual int GetThickness() const = 0; - // Get the width or height for this scrollbar which overlaps with the content. - // Default is 0. - virtual int GetContentOverlapSize() const; + // Returns true if the scrollbar should sit on top of the content area (e.g. + // for overlay scrollbars). + virtual bool OverlapsContent() const = 0; // Called when a ScrollEvent (in any, or no, direction) is seen by the parent // ScrollView. E.g., this may reveal an overlay scrollbar to indicate
diff --git a/ui/views/controls/scrollbar/scroll_bar_views.cc b/ui/views/controls/scrollbar/scroll_bar_views.cc index 066a56c..882e381 100644 --- a/ui/views/controls/scrollbar/scroll_bar_views.cc +++ b/ui/views/controls/scrollbar/scroll_bar_views.cc
@@ -278,15 +278,15 @@ } gfx::Size ScrollBarViews::GetPreferredSize() const { - return gfx::Size(IsHorizontal() ? 0 : GetLayoutSize(), - IsHorizontal() ? GetLayoutSize() : 0); + return gfx::Size(IsHorizontal() ? 0 : GetThickness(), + IsHorizontal() ? GetThickness() : 0); } const char* ScrollBarViews::GetClassName() const { return kViewClassName; } -int ScrollBarViews::GetLayoutSize() const { +int ScrollBarViews::GetThickness() const { const ui::NativeTheme* theme = GetNativeTheme(); return IsHorizontal() ? GetHorizontalScrollBarHeight(theme) : GetVerticalScrollBarWidth(theme);
diff --git a/ui/views/controls/scrollbar/scroll_bar_views.h b/ui/views/controls/scrollbar/scroll_bar_views.h index 7c480166..8fff6fd 100644 --- a/ui/views/controls/scrollbar/scroll_bar_views.h +++ b/ui/views/controls/scrollbar/scroll_bar_views.h
@@ -39,7 +39,7 @@ const char* GetClassName() const override; // ScrollBar overrides: - int GetLayoutSize() const override; + int GetThickness() const override; // BaseButton::ButtonListener overrides: void ButtonPressed(Button* sender, const ui::Event& event) override;