diff --git a/WATCHLISTS b/WATCHLISTS index f588378..42bd3b2a 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -2262,7 +2262,8 @@ 'video': ['posciak+watch@chromium.org'], 'video_capture': ['chfremer+watch@chromium.org'], 'views': ['tfarina@chromium.org'], - 'virtual_keyboard': ['dfaden+virtualkb@google.com', + 'virtual_keyboard': ['blakeo+virtualkb@chromium.org', + 'dfaden+virtualkb@google.com', 'groby+virtualkb@chromium.org', 'oka+watchvk@chromium.org', 'yhanada+watchvk@chromium.org'],
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc index 242c6d0..5474a60 100644 --- a/ash/root_window_controller_unittest.cc +++ b/ash/root_window_controller_unittest.cc
@@ -1064,13 +1064,14 @@ keyboard_window->set_owned_by_parent(false); keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds( root_window->bounds(), keyboard_height)); + keyboard_window->Show(); ui->EnsureCaretInWorkArea(); ASSERT_EQ(root_window->bounds().width(), text_input_client.caret_exclude_rect().width()); ASSERT_EQ(keyboard_height, text_input_client.caret_exclude_rect().height()); - input_method->SetFocusedTextInputClient(NULL); + input_method->SetFocusedTextInputClient(nullptr); } TEST_F(VirtualKeyboardRootWindowControllerTest, @@ -1111,9 +1112,13 @@ keyboard_window->set_owned_by_parent(false); keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds( primary_root_window->bounds(), keyboard_height)); + keyboard_window->Show(); + ui->EnsureCaretInWorkArea(); EXPECT_TRUE(primary_root_window->GetBoundsInScreen().Contains( text_input_client.caret_exclude_rect())); + EXPECT_EQ(primary_root_window->GetBoundsInScreen().width(), + text_input_client.caret_exclude_rect().width()); EXPECT_FALSE(secondary_root_window->GetBoundsInScreen().Contains( text_input_client.caret_exclude_rect())); @@ -1128,6 +1133,8 @@ text_input_client.caret_exclude_rect())); EXPECT_TRUE(secondary_root_window->GetBoundsInScreen().Contains( text_input_client.caret_exclude_rect())); + EXPECT_EQ(secondary_root_window->GetBoundsInScreen().width(), + text_input_client.caret_exclude_rect().width()); input_method->SetFocusedTextInputClient(nullptr); }
diff --git a/ash/shell.h b/ash/shell.h index 53363db..e3991f2 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -13,7 +13,6 @@ #include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shelf_types.h" #include "ash/session/session_observer.h" -#include "ash/wm/cursor_manager_chromeos.h" #include "ash/wm/system_modal_container_event_filter_delegate.h" #include "base/gtest_prod_util.h" #include "base/macros.h" @@ -25,6 +24,10 @@ #include "ui/wm/core/cursor_manager.h" #include "ui/wm/public/activation_change_observer.h" +#if defined(OS_CHROMEOS) +#include "ash/wm/cursor_manager_chromeos.h" +#endif // defined(OS_CHROMEOS) + class PrefRegistrySimple; class PrefService;
diff --git a/ash/wm_window.cc b/ash/wm_window.cc index d8387b9..2365c63 100644 --- a/ash/wm_window.cc +++ b/ash/wm_window.cc
@@ -42,6 +42,7 @@ #include "ui/views/widget/widget_delegate.h" #include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/easy_resize_window_targeter.h" +#include "ui/wm/core/ime_util_chromeos.h" #include "ui/wm/core/transient_window_manager.h" #include "ui/wm/core/visibility_controller.h" #include "ui/wm/core/window_util.h" @@ -420,6 +421,7 @@ void WmWindow::ClearRestoreBounds() { window_->ClearProperty(aura::client::kRestoreBoundsKey); + window_->ClearProperty(::wm::kVirtualKeyboardRestoreBoundsKey); } void WmWindow::SetRestoreBoundsInScreen(const gfx::Rect& bounds) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 3a91d289..9e158aec 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -725,7 +725,7 @@ mHandler.post(new Runnable() { @Override public void run() { - tracker.dismissed(); + tracker.dismissed(FeatureConstants.DOWNLOAD_HOME_FEATURE); getAppMenuHandler().setMenuHighlight(null); } });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/IPHInfoBarSupport.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/IPHInfoBarSupport.java index f4a986f5..595583a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/IPHInfoBarSupport.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/IPHInfoBarSupport.java
@@ -9,6 +9,7 @@ import android.view.View; import android.widget.PopupWindow.OnDismissListener; +import org.chromium.base.annotations.SuppressFBWarnings; import org.chromium.chrome.R; import org.chromium.chrome.browser.feature_engagement_tracker.FeatureEngagementTrackerFactory; import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarContainerObserver; @@ -52,6 +53,9 @@ /** The bubble that is currently showing the in-product help. */ public TextBubble bubble; + + /** The in-product help feature that the popup relates to. */ + public String feature; } /** The state of the currently showing in-product window or {@code null} if none is showing. */ @@ -68,6 +72,12 @@ @Override public void notifyAnimationFinished(int animationType) {} + // Calling {@link ViewAnchoredTextBubble#dismiss()} will invoke {@link #onDismiss} which will + // set the value of {@link #mCurrentState} to null, which is what the assert checks. Since this + // goes through the Android SDK, FindBugs does not see this as happening, so the FindBugs + // warning for a field guaranteed to be non-null being checked for null equality needs to be + // suppressed. + @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") @Override public void notifyAllAnimationsFinished(Item frontInfoBar) { View view = frontInfoBar == null ? null : frontInfoBar.getView(); @@ -76,7 +86,7 @@ // Clean up any old infobar if necessary. if (mCurrentState.view != view) { mCurrentState.bubble.dismiss(); - mCurrentState = null; + assert mCurrentState == null; } } @@ -97,17 +107,24 @@ mCurrentState.bubble.addOnDismissListener(this); mCurrentState.bubble.setDismissOnTouchInteraction(true); mCurrentState.bubble.show(); + mCurrentState.feature = params.feature; } // InfoBarContainerObserver implementation. @Override public void onAddInfoBar(InfoBarContainer container, InfoBar infoBar, boolean isFirst) {} + // Calling {@link ViewAnchoredTextBubble#dismiss()} will invoke {@link #onDismiss} which will + // set the value of {@link #mCurrentState} to null, which is what the assert checks. Since this + // goes through the Android SDK, FindBugs does not see this as happening, so the FindBugs + // warning for a field guaranteed to be non-null being checked for null equality needs to be + // suppressed. + @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") @Override public void onRemoveInfoBar(InfoBarContainer container, InfoBar infoBar, boolean isLast) { if (mCurrentState != null && infoBar.getView() == mCurrentState.view) { mCurrentState.bubble.dismiss(); - mCurrentState = null; + assert mCurrentState == null; } } @@ -117,8 +134,10 @@ // PopupWindow.OnDismissListener implementation. @Override public void onDismiss() { + assert mCurrentState != null; + String feature = mCurrentState.feature; mCurrentState = null; - mTracker.dismissed(); + mTracker.dismissed(feature); } private void logEvent(Item infoBar) { @@ -140,4 +159,4 @@ return null; } } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 411f44b..6477a20 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -534,7 +534,7 @@ mHandler.post(new Runnable() { @Override public void run() { - tracker.dismissed(); + tracker.dismissed(FeatureConstants.DOWNLOAD_PAGE_FEATURE); activity.getAppMenuHandler().setMenuHighlight(null); } });
diff --git a/chrome/browser/certificate_manager_model.cc b/chrome/browser/certificate_manager_model.cc index f4cbb0f3..d3c3ebf 100644 --- a/chrome/browser/certificate_manager_model.cc +++ b/chrome/browser/certificate_manager_model.cc
@@ -12,9 +12,6 @@ #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "chrome/browser/chromeos/certificate_provider/certificate_provider.h" -#include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h" -#include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h" #include "chrome/browser/net/nss_context.h" #include "chrome/browser/ui/crypto_module_password_dialog_nss.h" #include "chrome/common/net/x509_certificate_model.h" @@ -27,6 +24,15 @@ #include "net/cert/x509_certificate.h" #include "ui/base/l10n/l10n_util.h" +// TODO(wychen): ChromeOS headers should only be included when building +// ChromeOS, and the following headers should be guarded by +// #if defined(OS_CHROMEOS). However, the types are actually +// used, and it takes another CL to clean them up. +// Reference: crbug.com/720159 +#include "chrome/browser/chromeos/certificate_provider/certificate_provider.h" +#include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h" +#include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h" + using content::BrowserThread; // CertificateManagerModel is created on the UI thread. It needs a
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index dfb99af..00d589b5 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -118,7 +118,6 @@ #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" #include "chrome/installer/util/google_update_settings.h" -#include "chromeos/chromeos_constants.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/common/autofill_switches.h" #include "components/browsing_data/core/browsing_data_utils.h" @@ -246,6 +245,7 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" +#include "chromeos/chromeos_constants.h" #include "chromeos/chromeos_switches.h" #include "components/user_manager/user_manager.h" #include "mash/public/interfaces/launchable.mojom.h"
diff --git a/chrome/browser/cryptauth/chrome_cryptauth_service.cc b/chrome/browser/cryptauth/chrome_cryptauth_service.cc index 3429a5e..cb91f83 100644 --- a/chrome/browser/cryptauth/chrome_cryptauth_service.cc +++ b/chrome/browser/cryptauth/chrome_cryptauth_service.cc
@@ -11,7 +11,6 @@ #include "base/version.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_content_browser_client.h" -#include "chrome/browser/chromeos/login/easy_unlock/secure_message_delegate_chromeos.h" #include "chrome/browser/gcm/gcm_profile_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" @@ -38,6 +37,7 @@ #if defined(OS_CHROMEOS) #include "ash/shell.h" #include "base/linux_util.h" +#include "chrome/browser/chromeos/login/easy_unlock/secure_message_delegate_chromeos.h" #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" #include "ui/gfx/geometry/rect.h"
diff --git a/chrome/browser/diagnostics/diagnostics_controller_unittest.cc b/chrome/browser/diagnostics/diagnostics_controller_unittest.cc index eb18d80..d004fb35 100644 --- a/chrome/browser/diagnostics/diagnostics_controller_unittest.cc +++ b/chrome/browser/diagnostics/diagnostics_controller_unittest.cc
@@ -18,9 +18,12 @@ #include "chrome/browser/diagnostics/sqlite_diagnostics.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" -#include "chromeos/chromeos_constants.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_CHROMEOS) +#include "chromeos/chromeos_constants.h" +#endif // defined(OS_CHROMEOS) + namespace diagnostics { // Basic harness to acquire and release the required temporary environment to
diff --git a/chrome/browser/diagnostics/sqlite_diagnostics.cc b/chrome/browser/diagnostics/sqlite_diagnostics.cc index 42056e4..07401504 100644 --- a/chrome/browser/diagnostics/sqlite_diagnostics.cc +++ b/chrome/browser/diagnostics/sqlite_diagnostics.cc
@@ -22,7 +22,6 @@ #include "build/build_config.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" -#include "chromeos/chromeos_constants.h" #include "components/history/core/browser/history_constants.h" #include "components/webdata/common/webdata_constants.h" #include "content/public/common/content_constants.h" @@ -31,6 +30,10 @@ #include "storage/browser/database/database_tracker.h" #include "third_party/sqlite/sqlite3.h" +#if defined(OS_CHROMEOS) +#include "chromeos/chromeos_constants.h" +#endif // defined(OS_CHROMEOS) + namespace diagnostics { namespace {
diff --git a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc index 8cb98ee..f00d182c 100644 --- a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc +++ b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc
@@ -8,12 +8,15 @@ #include "chrome/browser/extensions/api/page_capture/page_capture_api.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/common/chrome_switches.h" -#include "chromeos/login/login_state.h" #include "content/public/common/content_switches.h" #include "content/public/test/test_utils.h" #include "extensions/browser/extension_dialog_auto_confirm.h" #include "net/dns/mock_host_resolver.h" +#if defined(OS_CHROMEOS) +#include "chromeos/login/login_state.h" +#endif // defined(OS_CHROMEOS) + using extensions::PageCaptureSaveAsMHTMLFunction; using extensions::ScopedTestDialogAutoConfirm;
diff --git a/chrome/browser/extensions/api/settings_private/settings_private_event_router.h b/chrome/browser/extensions/api/settings_private/settings_private_event_router.h index 4c2f166..3b79001d 100644 --- a/chrome/browser/extensions/api/settings_private/settings_private_event_router.h +++ b/chrome/browser/extensions/api/settings_private/settings_private_event_router.h
@@ -9,12 +9,18 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/extensions/api/settings_private/prefs_util.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h" #include "extensions/browser/event_router.h" +// TODO(wychen): ChromeOS headers should only be included when building +// ChromeOS, and the following headers should be guarded by +// #if defined(OS_CHROMEOS). However, the types are actually +// used, and it takes another CL to clean them up. +// Reference: crbug.com/720159 +#include "chrome/browser/chromeos/settings/cros_settings.h" + namespace content { class BrowserContext; }
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index 9bbcc9d..ef400b6 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -22,7 +22,6 @@ #include "chrome/common/extensions/extension_process_policy.h" #include "chrome/test/base/search_test_utils.h" #include "chrome/test/base/ui_test_utils.h" -#include "chromeos/login/login_state.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_frame_host.h" @@ -42,6 +41,10 @@ #include "net/test/test_data_directory.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" +#if defined(OS_CHROMEOS) +#include "chromeos/login/login_state.h" +#endif // defined(OS_CHROMEOS) + using content::WebContents; namespace extensions {
diff --git a/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc index af3259e..f9abaf7 100644 --- a/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "chrome/common/extensions/extension_test_util.h" -#include "chromeos/login/login_state.h" #include "content/public/browser/resource_request_info.h" #include "content/public/common/previews_state.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -24,6 +23,10 @@ #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_CHROMEOS) +#include "chromeos/login/login_state.h" +#endif // defined(OS_CHROMEOS) + using content::ResourceRequestInfo; using extensions::Extension; using extensions::Manifest;
diff --git a/chrome/browser/net/predictor_tab_helper.cc b/chrome/browser/net/predictor_tab_helper.cc index 7b08a01..20f4157d 100644 --- a/chrome/browser/net/predictor_tab_helper.cc +++ b/chrome/browser/net/predictor_tab_helper.cc
@@ -5,13 +5,16 @@ #include "chrome/browser/net/predictor_tab_helper.h" #include "base/feature_list.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/net/predictor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/url_constants.h" #include "content/public/browser/navigation_handle.h" #include "content/public/common/browser_side_navigation_policy.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#endif // defined(OS_CHROMEOS) + DEFINE_WEB_CONTENTS_USER_DATA_KEY(chrome_browser_net::PredictorTabHelper); namespace chrome_browser_net {
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc index 4e3f002..f1dd3c1b 100644 --- a/chrome/browser/profiles/profile_manager_unittest.cc +++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -19,7 +19,6 @@ #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/prefs/browser_prefs.h"
diff --git a/chrome/browser/resources/safe_browsing/README.md b/chrome/browser/resources/safe_browsing/README.md index c745b96..15916e4 100644 --- a/chrome/browser/resources/safe_browsing/README.md +++ b/chrome/browser/resources/safe_browsing/README.md
@@ -10,7 +10,7 @@ ## Procedure for adding/modifying file type(s) - * **Edit** `download_file_types.asciipb` and update `histograms.xml` + * **Edit** `download_file_types.asciipb` and update `enums.xml` * Get it reviewed, **submit.** * **Push** it to all users via component update: * Wait 1-3 day for this to run on Canary to verify it doesn't crash Chrome. @@ -34,7 +34,7 @@ first one wins. Only the `default_file_type` should leave this unset. * `uma_value`: (required) must be unique and match one in the - `SBClientDownloadExtensions` enum in `histograms.xml`. + `SBClientDownloadExtensions` enum in `enums.xml`. * `is_archive`: `True` if this filetype is a container for other files. Leave it unset for `false`.
diff --git a/chrome/browser/resources/safe_browsing/download_file_types.asciipb b/chrome/browser/resources/safe_browsing/download_file_types.asciipb index 6641e0de..a61c0826 100644 --- a/chrome/browser/resources/safe_browsing/download_file_types.asciipb +++ b/chrome/browser/resources/safe_browsing/download_file_types.asciipb
@@ -8,7 +8,7 @@ ## ## Top level settings ## -version_id: 9 +version_id: 10 sampled_ping_probability: 0.01 default_file_type { uma_value: 18 @@ -1809,6 +1809,28 @@ } } file_types { + # HTML file. This extension is abused by UwS campaigns to evade referrer + # attribution via a two-level download scheme. crbug.com/719784 + extension: "htm" + uma_value: 284 + ping_setting: FULL_PING + platform_settings { + danger_level: NOT_DANGEROUS + auto_open_hint: ALLOW_AUTO_OPEN + } +} +file_types { + # HTML file. This extension is abused by UwS campaigns to evade referrer + # attribution via a two-level download scheme. crbug.com/719784 + extension: "html" + uma_value: 285 + ping_setting: FULL_PING + platform_settings { + danger_level: NOT_DANGEROUS + auto_open_hint: ALLOW_AUTO_OPEN + } +} +file_types { # Hypertext Template File. See https://support.microsoft.com/kb/181689. extension: "htt" uma_value: 79
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc index 03ec3dbd..4152ac0 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -74,11 +74,11 @@ TEST_F(ChromePasswordProtectionServiceTest, VerifyFinchControlForLowReputationPingSBEROnlyNoIncognito) { MockChromePasswordProtectionService service; - // By default kLowReputationPinging feature is disabled. - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + // By default kPasswordFieldOnFocusPinging feature is disabled. + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); - // Enables kLowReputationPinging feature. - scoped_feature_list_.InitAndEnableFeature(kLowReputationPinging); + // Enables kPasswordFieldOnFocusPinging feature. + scoped_feature_list_.InitAndEnableFeature(kPasswordFieldOnFocusPinging); // Creates finch trial parameters correspond to the following experiment: // "name": "SBEROnlyNoIncognito", // "params": { @@ -87,38 +87,38 @@ // "history_sync": "false" // }, // "enable_features": [ - // "LowReputationPinging" + // "PasswordFieldOnFocusPinging" // ] Parameters sber_and_no_incognito = CreateParameters(false, false, true, false); - SetFeatureParams(kLowReputationPinging, "SBEROnlyNoIncognito", + SetFeatureParams(kPasswordFieldOnFocusPinging, "SBEROnlyNoIncognito", sber_and_no_incognito); service.ConfigService(false /*incognito*/, false /*SBER*/, false /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, false /*SBER*/, true /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, true /*SBER*/, false /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, true /*SBER*/, true /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, false /*SBER*/, false /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, false /*SBER*/, true /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, true /*SBER*/, false /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, true /*SBER*/, true /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); } TEST_F(ChromePasswordProtectionServiceTest, VerifyFinchControlForLowReputationPingSBERAndHistorySyncNoIncognito) { MockChromePasswordProtectionService service; - // By default kLowReputationPinging feature is disabled. - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + // By default kPasswordFieldOnFocusPinging feature is disabled. + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); - // Enables kLowReputationPinging feature. - scoped_feature_list_.InitAndEnableFeature(kLowReputationPinging); + // Enables kPasswordFieldOnFocusPinging feature. + scoped_feature_list_.InitAndEnableFeature(kPasswordFieldOnFocusPinging); // Creates finch trial parameters correspond to the following experiment: // "name": "SBERAndHistorySyncNoIncognito", // "params": { @@ -127,38 +127,38 @@ // "history_sync": "true" // }, // "enable_features": [ - // "LowReputationPinging" + // "PasswordFieldOnFocusPinging" // ] Parameters sber_and_sync_no_incognito = CreateParameters(false, false, true, true); - SetFeatureParams(kLowReputationPinging, "SBERAndHistorySyncNoIncognito", - sber_and_sync_no_incognito); + SetFeatureParams(kPasswordFieldOnFocusPinging, + "SBERAndHistorySyncNoIncognito", sber_and_sync_no_incognito); service.ConfigService(false /*incognito*/, false /*SBER*/, false /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, false /*SBER*/, true /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, true /*SBER*/, false /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, true /*SBER*/, true /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, false /*SBER*/, false /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, false /*SBER*/, true /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, true /*SBER*/, false /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, true /*SBER*/, true /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); } TEST_F(ChromePasswordProtectionServiceTest, VerifyFinchControlForLowReputationPingAllButNoIncognito) { MockChromePasswordProtectionService service; - // By default kLowReputationPinging feature is disabled. - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + // By default kPasswordFieldOnFocusPinging feature is disabled. + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); - // Enables kLowReputationPinging feature. - scoped_feature_list_.InitAndEnableFeature(kLowReputationPinging); + // Enables kPasswordFieldOnFocusPinging feature. + scoped_feature_list_.InitAndEnableFeature(kPasswordFieldOnFocusPinging); // Creates finch trial parameters correspond to the following experiment: // "name": "AllButNoIncognito", // "params": { @@ -166,36 +166,37 @@ // "incongito": "false" // }, // "enable_features": [ - // "LowReputationPinging" + // "PasswordFieldOnFocusPinging" // ] Parameters all_users = CreateParameters(false, true, true, true); - SetFeatureParams(kLowReputationPinging, "AllButNoIncognito", all_users); + SetFeatureParams(kPasswordFieldOnFocusPinging, "AllButNoIncognito", + all_users); service.ConfigService(false /*incognito*/, false /*SBER*/, false /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, false /*SBER*/, true /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, true /*SBER*/, false /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, true /*SBER*/, true /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, false /*SBER*/, false /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, false /*SBER*/, true /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, true /*SBER*/, false /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, true /*SBER*/, true /*sync*/); - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); } TEST_F(ChromePasswordProtectionServiceTest, VerifyFinchControlForLowReputationPingAll) { MockChromePasswordProtectionService service; - // By default kLowReputationPinging feature is disabled. - EXPECT_FALSE(service.IsPingingEnabled(kLowReputationPinging)); + // By default kPasswordFieldOnFocusPinging feature is disabled. + EXPECT_FALSE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); - // Enables kLowReputationPinging feature. - scoped_feature_list_.InitAndEnableFeature(kLowReputationPinging); + // Enables kPasswordFieldOnFocusPinging feature. + scoped_feature_list_.InitAndEnableFeature(kPasswordFieldOnFocusPinging); // Creates finch trial parameters correspond to the following experiment: // "name": "All", // "params": { @@ -203,26 +204,26 @@ // "incognito": "true" // }, // "enable_features": [ - // "LowReputationPinging" + // "PasswordFieldOnFocusPinging" // ] Parameters all_users = CreateParameters(true, true, true, true); - SetFeatureParams(kLowReputationPinging, "All", all_users); + SetFeatureParams(kPasswordFieldOnFocusPinging, "All", all_users); service.ConfigService(false /*incognito*/, false /*SBER*/, false /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, false /*SBER*/, true /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, true /*SBER*/, false /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(false /*incognito*/, true /*SBER*/, true /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, false /*SBER*/, false /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, false /*SBER*/, true /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, true /*SBER*/, false /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); service.ConfigService(true /*incognito*/, true /*SBER*/, true /*sync*/); - EXPECT_TRUE(service.IsPingingEnabled(kLowReputationPinging)); + EXPECT_TRUE(service.IsPingingEnabled(kPasswordFieldOnFocusPinging)); } } // namespace safe_browsing
diff --git a/chrome/browser/ssl/security_state_tab_helper.cc b/chrome/browser/ssl/security_state_tab_helper.cc index 56bb713..a5c7c94 100644 --- a/chrome/browser/ssl/security_state_tab_helper.cc +++ b/chrome/browser/ssl/security_state_tab_helper.cc
@@ -9,8 +9,6 @@ #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/policy/policy_cert_service.h" -#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/ui_manager.h" @@ -29,6 +27,11 @@ #include "third_party/boringssl/src/include/openssl/ssl.h" #include "ui/base/l10n/l10n_util.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/policy/policy_cert_service.h" +#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" +#endif // defined(OS_CHROMEOS) + DEFINE_WEB_CONTENTS_USER_DATA_KEY(SecurityStateTabHelper); using safe_browsing::SafeBrowsingUIManager;
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index eb9a252..7d0394f 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1035,6 +1035,11 @@ WebContents* new_contents, int index, int reason) { +// Mac correctly sets the initial background color of new tabs to the theme +// background color, so it does not need this block of code. Aura should +// implement this as well. +// https://crbug.com/719230 +#if !defined(OS_MACOSX) // Copies the background color from an old WebContents to a new one that // replaces it on the screen. This allows the new WebContents to use the // old one's background color as the starting background color, before having @@ -1050,6 +1055,7 @@ if (old_view && new_view) new_view->SetBackgroundColor(old_view->background_color()); } +#endif base::RecordAction(UserMetricsAction("ActiveTabChanged"));
diff --git a/chrome/browser/ui/browser_unittest.cc b/chrome/browser/ui/browser_unittest.cc index 62bcd32..9e99d68 100644 --- a/chrome/browser/ui/browser_unittest.cc +++ b/chrome/browser/ui/browser_unittest.cc
@@ -68,7 +68,14 @@ EXPECT_TRUE(contents2->IsCrashed()); } -TEST_F(BrowserUnitTest, SetBackgroundColorForNewTab) { +// This tests a workaround which is not necessary on Mac. +// https://crbug.com/719230 +#if defined(OS_MACOSX) +#define MAYBE_SetBackgroundColorForNewTab DISABLED_SetBackgroundColorForNewTab +#else +#define MAYBE_SetBackgroundColorForNewTab SetBackgroundColorForNewTab +#endif +TEST_F(BrowserUnitTest, MAYBE_SetBackgroundColorForNewTab) { TabStripModel* tab_strip_model = browser()->tab_strip_model(); WebContents* contents1 = CreateTestWebContents();
diff --git a/chrome/browser/ui/input_method/input_method_engine_base.h b/chrome/browser/ui/input_method/input_method_engine_base.h index 9076c73..db7d6f6 100644 --- a/chrome/browser/ui/input_method/input_method_engine_base.h +++ b/chrome/browser/ui/input_method/input_method_engine_base.h
@@ -11,11 +11,14 @@ #include <vector> #include "base/time/time.h" -#include "ui/base/ime/chromeos/input_method_descriptor.h" #include "ui/base/ime/composition_text.h" #include "ui/base/ime/ime_engine_handler_interface.h" #include "url/gurl.h" +#if defined(OS_CHROMEOS) +#include "ui/base/ime/chromeos/input_method_descriptor.h" +#endif // defined(OS_CHROMEOS) + class Profile; namespace ui {
diff --git a/components/feature_engagement_tracker/internal/BUILD.gn b/components/feature_engagement_tracker/internal/BUILD.gn index 8f629d9..4673bdc 100644 --- a/components/feature_engagement_tracker/internal/BUILD.gn +++ b/components/feature_engagement_tracker/internal/BUILD.gn
@@ -23,11 +23,8 @@ "editable_configuration.h", "feature_config_storage_validator.cc", "feature_config_storage_validator.h", - "feature_constants.cc", "feature_engagement_tracker_impl.cc", "feature_engagement_tracker_impl.h", - "feature_list.cc", - "feature_list.h", "in_memory_store.cc", "in_memory_store.h", "model.h",
diff --git a/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.cc b/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.cc index f22a3d12..c2dd33f 100644 --- a/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.cc +++ b/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.cc
@@ -13,8 +13,8 @@ #include "base/bind.h" #include "base/feature_list.h" #include "base/memory/ptr_util.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" #include "components/feature_engagement_tracker/public/feature_engagement_tracker.h" +#include "components/feature_engagement_tracker/public/feature_list.h" #include "jni/FeatureEngagementTrackerImpl_jni.h" namespace feature_engagement_tracker { @@ -121,8 +121,12 @@ void FeatureEngagementTrackerImplAndroid::Dismissed( JNIEnv* env, - const base::android::JavaRef<jobject>& jobj) { - feature_engagement_tracker_impl_->Dismissed(); + const base::android::JavaRef<jobject>& jobj, + const base::android::JavaParamRef<jstring>& jfeature) { + std::string feature = ConvertJavaStringToUTF8(env, jfeature); + DCHECK(features_.find(feature) != features_.end()); + + feature_engagement_tracker_impl_->Dismissed(*features_[feature]); } bool FeatureEngagementTrackerImplAndroid::IsInitialized(
diff --git a/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.h b/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.h index 79f3c41..8818474 100644 --- a/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.h +++ b/components/feature_engagement_tracker/internal/android/feature_engagement_tracker_impl_android.h
@@ -14,7 +14,7 @@ #include "base/macros.h" #include "base/supports_user_data.h" #include "components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" +#include "components/feature_engagement_tracker/public/feature_list.h" namespace base { struct Feature; @@ -53,7 +53,8 @@ const base::android::JavaRef<jobject>& jobj, const base::android::JavaParamRef<jstring>& jfeature); virtual void Dismissed(JNIEnv* env, - const base::android::JavaRef<jobject>& jobj); + const base::android::JavaRef<jobject>& jobj, + const base::android::JavaParamRef<jstring>& jfeature); virtual bool IsInitialized(JNIEnv* env, const base::android::JavaRef<jobject>& jobj); virtual void AddOnInitializedCallback(
diff --git a/components/feature_engagement_tracker/internal/android/java/src/org/chromium/components/feature_engagement_tracker/internal/FeatureEngagementTrackerImpl.java b/components/feature_engagement_tracker/internal/android/java/src/org/chromium/components/feature_engagement_tracker/internal/FeatureEngagementTrackerImpl.java index 8626790..1ef81e75 100644 --- a/components/feature_engagement_tracker/internal/android/java/src/org/chromium/components/feature_engagement_tracker/internal/FeatureEngagementTrackerImpl.java +++ b/components/feature_engagement_tracker/internal/android/java/src/org/chromium/components/feature_engagement_tracker/internal/FeatureEngagementTrackerImpl.java
@@ -42,9 +42,9 @@ } @Override - public void dismissed() { + public void dismissed(String feature) { assert mNativePtr != 0; - nativeDismissed(mNativePtr); + nativeDismissed(mNativePtr, feature); } @Override @@ -74,7 +74,8 @@ long nativeFeatureEngagementTrackerImplAndroid, String event); private native boolean nativeShouldTriggerHelpUI( long nativeFeatureEngagementTrackerImplAndroid, String feature); - private native void nativeDismissed(long nativeFeatureEngagementTrackerImplAndroid); + private native void nativeDismissed( + long nativeFeatureEngagementTrackerImplAndroid, String feature); private native boolean nativeIsInitialized(long nativeFeatureEngagementTrackerImplAndroid); private native void nativeAddOnInitializedCallback( long nativeFeatureEngagementTrackerImplAndroid, Callback<Boolean> callback);
diff --git a/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc b/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc index e388ec2..9207b57 100644 --- a/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc +++ b/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc
@@ -18,7 +18,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "components/feature_engagement_tracker/internal/configuration.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" +#include "components/feature_engagement_tracker/public/feature_list.h" namespace {
diff --git a/components/feature_engagement_tracker/internal/chrome_variations_configuration.h b/components/feature_engagement_tracker/internal/chrome_variations_configuration.h index e140d13f..15774ae7 100644 --- a/components/feature_engagement_tracker/internal/chrome_variations_configuration.h +++ b/components/feature_engagement_tracker/internal/chrome_variations_configuration.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "components/feature_engagement_tracker/internal/configuration.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" +#include "components/feature_engagement_tracker/public/feature_list.h" namespace base { struct Feature;
diff --git a/components/feature_engagement_tracker/internal/condition_validator.h b/components/feature_engagement_tracker/internal/condition_validator.h index 14c4316..3272b7b 100644 --- a/components/feature_engagement_tracker/internal/condition_validator.h +++ b/components/feature_engagement_tracker/internal/condition_validator.h
@@ -8,7 +8,7 @@ #include <string> #include "base/macros.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" +#include "components/feature_engagement_tracker/public/feature_list.h" namespace base { struct Feature;
diff --git a/components/feature_engagement_tracker/internal/feature_config_storage_validator.cc b/components/feature_engagement_tracker/internal/feature_config_storage_validator.cc index 1af635e..fe08b24 100644 --- a/components/feature_engagement_tracker/internal/feature_config_storage_validator.cc +++ b/components/feature_engagement_tracker/internal/feature_config_storage_validator.cc
@@ -8,7 +8,7 @@ #include <unordered_set> #include "components/feature_engagement_tracker/internal/configuration.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" +#include "components/feature_engagement_tracker/public/feature_list.h" namespace feature_engagement_tracker {
diff --git a/components/feature_engagement_tracker/internal/feature_config_storage_validator.h b/components/feature_engagement_tracker/internal/feature_config_storage_validator.h index d0ba4241..c511548 100644 --- a/components/feature_engagement_tracker/internal/feature_config_storage_validator.h +++ b/components/feature_engagement_tracker/internal/feature_config_storage_validator.h
@@ -10,8 +10,8 @@ #include <unordered_set> #include "base/macros.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" #include "components/feature_engagement_tracker/internal/storage_validator.h" +#include "components/feature_engagement_tracker/public/feature_list.h" namespace feature_engagement_tracker { class Configuration;
diff --git a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.cc b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.cc index ecda0ed..1e8f031 100644 --- a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.cc +++ b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.cc
@@ -9,7 +9,6 @@ #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" #include "components/feature_engagement_tracker/internal/editable_configuration.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" #include "components/feature_engagement_tracker/internal/in_memory_store.h" #include "components/feature_engagement_tracker/internal/model_impl.h" #include "components/feature_engagement_tracker/internal/never_condition_validator.h" @@ -17,6 +16,7 @@ #include "components/feature_engagement_tracker/internal/once_condition_validator.h" #include "components/feature_engagement_tracker/internal/single_invalid_configuration.h" #include "components/feature_engagement_tracker/public/feature_constants.h" +#include "components/feature_engagement_tracker/public/feature_list.h" namespace feature_engagement_tracker { @@ -98,7 +98,7 @@ return result; } -void FeatureEngagementTrackerImpl::Dismissed() { +void FeatureEngagementTrackerImpl::Dismissed(const base::Feature& feature) { // TODO(nyquist): Track this event. model_->SetIsCurrentlyShowing(false); }
diff --git a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h index 9ce2dc9..9f7db4a39 100644 --- a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h +++ b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl.h
@@ -35,7 +35,7 @@ // FeatureEngagementTracker implementation. void NotifyEvent(const std::string& event) override; bool ShouldTriggerHelpUI(const base::Feature& feature) override; - void Dismissed() override; + void Dismissed(const base::Feature& feature) override; bool IsInitialized() override; void AddOnInitializedCallback(OnInitializedCallback callback) override;
diff --git a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc index 05eb055..2b44010 100644 --- a/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc +++ b/components/feature_engagement_tracker/internal/feature_engagement_tracker_impl_unittest.cc
@@ -278,14 +278,14 @@ // After dismissing the current in-product help, that feature can not be shown // again, but a different feature should. - tracker_->Dismissed(); + tracker_->Dismissed(kTestFeatureFoo); EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureFoo)); EXPECT_TRUE(tracker_->ShouldTriggerHelpUI(kTestFeatureBar)); EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux)); // After dismissing the second registered feature, no more in-product help // should be shown, since kTestFeatureQux is invalid. - tracker_->Dismissed(); + tracker_->Dismissed(kTestFeatureBar); EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureFoo)); EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureBar)); EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTestFeatureQux));
diff --git a/components/feature_engagement_tracker/internal/never_condition_validator.h b/components/feature_engagement_tracker/internal/never_condition_validator.h index 7f67212..0a51ca6 100644 --- a/components/feature_engagement_tracker/internal/never_condition_validator.h +++ b/components/feature_engagement_tracker/internal/never_condition_validator.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "components/feature_engagement_tracker/internal/condition_validator.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" +#include "components/feature_engagement_tracker/public/feature_list.h" namespace base { struct Feature;
diff --git a/components/feature_engagement_tracker/internal/once_condition_validator.h b/components/feature_engagement_tracker/internal/once_condition_validator.h index dfcb70e8..a5d6cb7c 100644 --- a/components/feature_engagement_tracker/internal/once_condition_validator.h +++ b/components/feature_engagement_tracker/internal/once_condition_validator.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "components/feature_engagement_tracker/internal/condition_validator.h" -#include "components/feature_engagement_tracker/internal/feature_list.h" +#include "components/feature_engagement_tracker/public/feature_list.h" namespace base { struct Feature;
diff --git a/components/feature_engagement_tracker/public/BUILD.gn b/components/feature_engagement_tracker/public/BUILD.gn index c69469b2..3be36c7 100644 --- a/components/feature_engagement_tracker/public/BUILD.gn +++ b/components/feature_engagement_tracker/public/BUILD.gn
@@ -9,8 +9,11 @@ source_set("public") { sources = [ + "feature_constants.cc", "feature_constants.h", "feature_engagement_tracker.h", + "feature_list.cc", + "feature_list.h", ] deps = [
diff --git a/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/FeatureEngagementTracker.java b/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/FeatureEngagementTracker.java index 633993f..0f702b18 100644 --- a/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/FeatureEngagementTracker.java +++ b/components/feature_engagement_tracker/public/android/java/src/org/chromium/components/feature_engagement_tracker/FeatureEngagementTracker.java
@@ -31,9 +31,9 @@ boolean shouldTriggerHelpUI(String feature); /** - * Must be called after display of feature enlightenment finishes. + * Must be called after display of feature enlightenment finishes for a particular feature. */ - void dismissed(); + void dismissed(String feature); /** * Returns whether the tracker has been successfully initialized. During startup, this will be
diff --git a/components/feature_engagement_tracker/internal/feature_constants.cc b/components/feature_engagement_tracker/public/feature_constants.cc similarity index 100% rename from components/feature_engagement_tracker/internal/feature_constants.cc rename to components/feature_engagement_tracker/public/feature_constants.cc
diff --git a/components/feature_engagement_tracker/public/feature_engagement_tracker.h b/components/feature_engagement_tracker/public/feature_engagement_tracker.h index d969a81..53f82b2 100644 --- a/components/feature_engagement_tracker/public/feature_engagement_tracker.h +++ b/components/feature_engagement_tracker/public/feature_engagement_tracker.h
@@ -58,8 +58,9 @@ virtual bool ShouldTriggerHelpUI(const base::Feature& feature) WARN_UNUSED_RESULT = 0; - // Must be called after display of feature enlightenment finishes. - virtual void Dismissed() = 0; + // Must be called after display of feature enlightenment finishes for a + // particular |feature|. + virtual void Dismissed(const base::Feature& feature) = 0; // Returns whether the tracker has been successfully initialized. During // startup, this will be false until the internal model has been loaded at
diff --git a/components/feature_engagement_tracker/internal/feature_list.cc b/components/feature_engagement_tracker/public/feature_list.cc similarity index 89% rename from components/feature_engagement_tracker/internal/feature_list.cc rename to components/feature_engagement_tracker/public/feature_list.cc index 9dcbae3..6d600c4 100644 --- a/components/feature_engagement_tracker/internal/feature_list.cc +++ b/components/feature_engagement_tracker/public/feature_list.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/feature_engagement_tracker/internal/feature_list.h" +#include "components/feature_engagement_tracker/public/feature_list.h" #include "base/feature_list.h" #include "components/feature_engagement_tracker/public/feature_constants.h"
diff --git a/components/feature_engagement_tracker/internal/feature_list.h b/components/feature_engagement_tracker/public/feature_list.h similarity index 100% rename from components/feature_engagement_tracker/internal/feature_list.h rename to components/feature_engagement_tracker/public/feature_list.h
diff --git a/components/leveldb/leveldb_database_impl.cc b/components/leveldb/leveldb_database_impl.cc index 5387409..59ab078 100644 --- a/components/leveldb/leveldb_database_impl.cc +++ b/components/leveldb/leveldb_database_impl.cc
@@ -6,6 +6,7 @@ #include <map> #include <string> +#include <utility> #include "base/optional.h" #include "base/rand_util.h" @@ -48,33 +49,32 @@ void LevelDBDatabaseImpl::Put(const std::vector<uint8_t>& key, const std::vector<uint8_t>& value, - const PutCallback& callback) { + PutCallback callback) { leveldb::Status status = db_->Put(leveldb::WriteOptions(), GetSliceFor(key), GetSliceFor(value)); - callback.Run(LeveldbStatusToError(status)); + std::move(callback).Run(LeveldbStatusToError(status)); } void LevelDBDatabaseImpl::Delete(const std::vector<uint8_t>& key, - const DeleteCallback& callback) { + DeleteCallback callback) { leveldb::Status status = db_->Delete(leveldb::WriteOptions(), GetSliceFor(key)); - callback.Run(LeveldbStatusToError(status)); + std::move(callback).Run(LeveldbStatusToError(status)); } -void LevelDBDatabaseImpl::DeletePrefixed( - const std::vector<uint8_t>& key_prefix, - const DeletePrefixedCallback& callback) { +void LevelDBDatabaseImpl::DeletePrefixed(const std::vector<uint8_t>& key_prefix, + DeletePrefixedCallback callback) { leveldb::WriteBatch batch; leveldb::Status status = DeletePrefixedHelper( GetSliceFor(key_prefix), &batch); if (status.ok()) status = db_->Write(leveldb::WriteOptions(), &batch); - callback.Run(LeveldbStatusToError(status)); + std::move(callback).Run(LeveldbStatusToError(status)); } void LevelDBDatabaseImpl::Write( std::vector<mojom::BatchedOperationPtr> operations, - const WriteCallback& callback) { + WriteCallback callback) { leveldb::WriteBatch batch; for (size_t i = 0; i < operations.size(); ++i) { @@ -100,19 +100,20 @@ } leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); - callback.Run(LeveldbStatusToError(status)); + std::move(callback).Run(LeveldbStatusToError(status)); } void LevelDBDatabaseImpl::Get(const std::vector<uint8_t>& key, - const GetCallback& callback) { + GetCallback callback) { std::string value; leveldb::Status status = db_->Get(leveldb::ReadOptions(), GetSliceFor(key), &value); - callback.Run(LeveldbStatusToError(status), StdStringToUint8Vector(value)); + std::move(callback).Run(LeveldbStatusToError(status), + StdStringToUint8Vector(value)); } void LevelDBDatabaseImpl::GetPrefixed(const std::vector<uint8_t>& key_prefix, - const GetPrefixedCallback& callback) { + GetPrefixedCallback callback) { std::vector<mojom::KeyValuePtr> data; leveldb::Status status = ForEachWithPrefix( db_.get(), GetSliceFor(key_prefix), @@ -122,14 +123,14 @@ kv->value = GetVectorFor(value); data.push_back(std::move(kv)); }); - callback.Run(LeveldbStatusToError(status), std::move(data)); + std::move(callback).Run(LeveldbStatusToError(status), std::move(data)); } -void LevelDBDatabaseImpl::GetSnapshot(const GetSnapshotCallback& callback) { +void LevelDBDatabaseImpl::GetSnapshot(GetSnapshotCallback callback) { const Snapshot* s = db_->GetSnapshot(); base::UnguessableToken token = base::UnguessableToken::Create(); snapshot_map_.insert(std::make_pair(token, s)); - callback.Run(token); + std::move(callback).Run(token); } void LevelDBDatabaseImpl::ReleaseSnapshot( @@ -144,12 +145,12 @@ void LevelDBDatabaseImpl::GetFromSnapshot( const base::UnguessableToken& snapshot, const std::vector<uint8_t>& key, - const GetCallback& callback) { + GetCallback callback) { // If the snapshot id is invalid, send back invalid argument auto it = snapshot_map_.find(snapshot); if (it == snapshot_map_.end()) { - callback.Run(mojom::DatabaseError::INVALID_ARGUMENT, - std::vector<uint8_t>()); + std::move(callback).Run(mojom::DatabaseError::INVALID_ARGUMENT, + std::vector<uint8_t>()); return; } @@ -157,23 +158,24 @@ leveldb::ReadOptions options; options.snapshot = it->second; leveldb::Status status = db_->Get(options, GetSliceFor(key), &value); - callback.Run(LeveldbStatusToError(status), StdStringToUint8Vector(value)); + std::move(callback).Run(LeveldbStatusToError(status), + StdStringToUint8Vector(value)); } -void LevelDBDatabaseImpl::NewIterator(const NewIteratorCallback& callback) { +void LevelDBDatabaseImpl::NewIterator(NewIteratorCallback callback) { Iterator* iterator = db_->NewIterator(leveldb::ReadOptions()); base::UnguessableToken token = base::UnguessableToken::Create(); iterator_map_.insert(std::make_pair(token, iterator)); - callback.Run(token); + std::move(callback).Run(token); } void LevelDBDatabaseImpl::NewIteratorFromSnapshot( const base::UnguessableToken& snapshot, - const NewIteratorFromSnapshotCallback& callback) { + NewIteratorFromSnapshotCallback callback) { // If the snapshot id is invalid, send back invalid argument auto it = snapshot_map_.find(snapshot); if (it == snapshot_map_.end()) { - callback.Run(base::Optional<base::UnguessableToken>()); + std::move(callback).Run(base::Optional<base::UnguessableToken>()); return; } @@ -183,7 +185,7 @@ Iterator* iterator = db_->NewIterator(options); base::UnguessableToken new_token = base::UnguessableToken::Create(); iterator_map_.insert(std::make_pair(new_token, iterator)); - callback.Run(new_token); + std::move(callback).Run(new_token); } void LevelDBDatabaseImpl::ReleaseIterator( @@ -197,89 +199,88 @@ void LevelDBDatabaseImpl::IteratorSeekToFirst( const base::UnguessableToken& iterator, - const IteratorSeekToFirstCallback& callback) { + IteratorSeekToFirstCallback callback) { auto it = iterator_map_.find(iterator); if (it == iterator_map_.end()) { - callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt, - base::nullopt); + std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT, + base::nullopt, base::nullopt); return; } it->second->SeekToFirst(); - ReplyToIteratorMessage(it->second, callback); + ReplyToIteratorMessage(it->second, std::move(callback)); } void LevelDBDatabaseImpl::IteratorSeekToLast( const base::UnguessableToken& iterator, - const IteratorSeekToLastCallback& callback) { + IteratorSeekToLastCallback callback) { auto it = iterator_map_.find(iterator); if (it == iterator_map_.end()) { - callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt, - base::nullopt); + std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT, + base::nullopt, base::nullopt); return; } it->second->SeekToLast(); - ReplyToIteratorMessage(it->second, callback); + ReplyToIteratorMessage(it->second, std::move(callback)); } -void LevelDBDatabaseImpl::IteratorSeek( - const base::UnguessableToken& iterator, - const std::vector<uint8_t>& target, - const IteratorSeekToLastCallback& callback) { +void LevelDBDatabaseImpl::IteratorSeek(const base::UnguessableToken& iterator, + const std::vector<uint8_t>& target, + IteratorSeekToLastCallback callback) { auto it = iterator_map_.find(iterator); if (it == iterator_map_.end()) { - callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt, - base::nullopt); + std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT, + base::nullopt, base::nullopt); return; } it->second->Seek(GetSliceFor(target)); - ReplyToIteratorMessage(it->second, callback); + ReplyToIteratorMessage(it->second, std::move(callback)); } void LevelDBDatabaseImpl::IteratorNext(const base::UnguessableToken& iterator, - const IteratorNextCallback& callback) { + IteratorNextCallback callback) { auto it = iterator_map_.find(iterator); if (it == iterator_map_.end()) { - callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt, - base::nullopt); + std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT, + base::nullopt, base::nullopt); return; } it->second->Next(); - ReplyToIteratorMessage(it->second, callback); + ReplyToIteratorMessage(it->second, std::move(callback)); } void LevelDBDatabaseImpl::IteratorPrev(const base::UnguessableToken& iterator, - const IteratorPrevCallback& callback) { + IteratorPrevCallback callback) { auto it = iterator_map_.find(iterator); if (it == iterator_map_.end()) { - callback.Run(false, mojom::DatabaseError::INVALID_ARGUMENT, base::nullopt, - base::nullopt); + std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT, + base::nullopt, base::nullopt); return; } it->second->Prev(); - ReplyToIteratorMessage(it->second, callback); + ReplyToIteratorMessage(it->second, std::move(callback)); } void LevelDBDatabaseImpl::ReplyToIteratorMessage( leveldb::Iterator* it, - const IteratorSeekToFirstCallback& callback) { + IteratorSeekToFirstCallback callback) { if (!it->Valid()) { - callback.Run(false, LeveldbStatusToError(it->status()), base::nullopt, - base::nullopt); + std::move(callback).Run(false, LeveldbStatusToError(it->status()), + base::nullopt, base::nullopt); return; } - callback.Run(true, LeveldbStatusToError(it->status()), - GetVectorFor(it->key()), GetVectorFor(it->value())); + std::move(callback).Run(true, LeveldbStatusToError(it->status()), + GetVectorFor(it->key()), GetVectorFor(it->value())); } leveldb::Status LevelDBDatabaseImpl::DeletePrefixedHelper(
diff --git a/components/leveldb/leveldb_database_impl.h b/components/leveldb/leveldb_database_impl.h index f621c5f5..277748d4 100644 --- a/components/leveldb/leveldb_database_impl.h +++ b/components/leveldb/leveldb_database_impl.h
@@ -24,46 +24,44 @@ // Overridden from LevelDBDatabase: void Put(const std::vector<uint8_t>& key, const std::vector<uint8_t>& value, - const PutCallback& callback) override; + PutCallback callback) override; void Delete(const std::vector<uint8_t>& key, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeletePrefixed(const std::vector<uint8_t>& key_prefix, - const DeletePrefixedCallback& callback) override; + DeletePrefixedCallback callback) override; void Write(std::vector<mojom::BatchedOperationPtr> operations, - const WriteCallback& callback) override; - void Get(const std::vector<uint8_t>& key, - const GetCallback& callback) override; + WriteCallback callback) override; + void Get(const std::vector<uint8_t>& key, GetCallback callback) override; void GetPrefixed(const std::vector<uint8_t>& key_prefix, - const GetPrefixedCallback& callback) override; - void GetSnapshot(const GetSnapshotCallback& callback) override; + GetPrefixedCallback callback) override; + void GetSnapshot(GetSnapshotCallback callback) override; void ReleaseSnapshot(const base::UnguessableToken& snapshot) override; void GetFromSnapshot(const base::UnguessableToken& snapshot, const std::vector<uint8_t>& key, - const GetCallback& callback) override; - void NewIterator(const NewIteratorCallback& callback) override; + GetCallback callback) override; + void NewIterator(NewIteratorCallback callback) override; void NewIteratorFromSnapshot( const base::UnguessableToken& snapshot, - const NewIteratorFromSnapshotCallback& callback) override; + NewIteratorFromSnapshotCallback callback) override; void ReleaseIterator(const base::UnguessableToken& iterator) override; - void IteratorSeekToFirst( - const base::UnguessableToken& iterator, - const IteratorSeekToFirstCallback& callback) override; + void IteratorSeekToFirst(const base::UnguessableToken& iterator, + IteratorSeekToFirstCallback callback) override; void IteratorSeekToLast(const base::UnguessableToken& iterator, - const IteratorSeekToLastCallback& callback) override; + IteratorSeekToLastCallback callback) override; void IteratorSeek(const base::UnguessableToken& iterator, const std::vector<uint8_t>& target, - const IteratorSeekToLastCallback& callback) override; + IteratorSeekToLastCallback callback) override; void IteratorNext(const base::UnguessableToken& iterator, - const IteratorNextCallback& callback) override; + IteratorNextCallback callback) override; void IteratorPrev(const base::UnguessableToken& iterator, - const IteratorPrevCallback& callback) override; + IteratorPrevCallback callback) override; private: // Returns the state of |it| to a caller. Note: This assumes that all the // iterator movement methods have the same callback signature. We don't // directly reference the underlying type in case of bindings change. void ReplyToIteratorMessage(leveldb::Iterator* it, - const IteratorSeekToFirstCallback& callback); + IteratorSeekToFirstCallback callback); leveldb::Status DeletePrefixedHelper(const leveldb::Slice& key_prefix, leveldb::WriteBatch* batch);
diff --git a/components/leveldb/leveldb_service_impl.cc b/components/leveldb/leveldb_service_impl.cc index 2f754112..f2e4eb85 100644 --- a/components/leveldb/leveldb_service_impl.cc +++ b/components/leveldb/leveldb_service_impl.cc
@@ -5,6 +5,7 @@ #include "components/leveldb/leveldb_service_impl.h" #include <memory> +#include <utility> #include "base/memory/ptr_util.h" #include "components/leveldb/env_mojo.h" @@ -30,9 +31,9 @@ filesystem::mojom::DirectoryPtr directory, const std::string& dbname, leveldb::mojom::LevelDBDatabaseAssociatedRequest database, - const OpenCallback& callback) { + OpenCallback callback) { OpenWithOptions(leveldb::mojom::OpenOptions::New(), std::move(directory), - dbname, std::move(database), callback); + dbname, std::move(database), std::move(callback)); } void LevelDBServiceImpl::OpenWithOptions( @@ -40,7 +41,7 @@ filesystem::mojom::DirectoryPtr directory, const std::string& dbname, leveldb::mojom::LevelDBDatabaseAssociatedRequest database, - const OpenCallback& callback) { + OpenCallback callback) { leveldb::Options options; options.create_if_missing = open_options->create_if_missing; options.error_if_exists = open_options->error_if_exists; @@ -68,12 +69,12 @@ std::move(database)); } - callback.Run(LeveldbStatusToError(s)); + std::move(callback).Run(LeveldbStatusToError(s)); } void LevelDBServiceImpl::OpenInMemory( leveldb::mojom::LevelDBDatabaseAssociatedRequest database, - const OpenCallback& callback) { + OpenCallback callback) { leveldb::Options options; options.create_if_missing = true; options.max_open_files = 0; // Use minimum. @@ -91,19 +92,20 @@ std::move(database)); } - callback.Run(LeveldbStatusToError(s)); + std::move(callback).Run(LeveldbStatusToError(s)); } void LevelDBServiceImpl::Destroy(filesystem::mojom::DirectoryPtr directory, const std::string& dbname, - const DestroyCallback& callback) { + DestroyCallback callback) { leveldb::Options options; // Register our directory with the file thread. LevelDBMojoProxy::OpaqueDir* dir = thread_->RegisterDirectory(std::move(directory)); std::unique_ptr<MojoEnv> env_mojo(new MojoEnv(thread_, dir)); options.env = env_mojo.get(); - callback.Run(LeveldbStatusToError(leveldb::DestroyDB(dbname, options))); + std::move(callback).Run( + LeveldbStatusToError(leveldb::DestroyDB(dbname, options))); } } // namespace leveldb
diff --git a/components/leveldb/leveldb_service_impl.h b/components/leveldb/leveldb_service_impl.h index 3cc1210..344168c4 100644 --- a/components/leveldb/leveldb_service_impl.h +++ b/components/leveldb/leveldb_service_impl.h
@@ -26,18 +26,18 @@ void Open(filesystem::mojom::DirectoryPtr directory, const std::string& dbname, leveldb::mojom::LevelDBDatabaseAssociatedRequest database, - const OpenCallback& callback) override; + OpenCallback callback) override; void OpenWithOptions( leveldb::mojom::OpenOptionsPtr open_options, filesystem::mojom::DirectoryPtr directory, const std::string& dbname, leveldb::mojom::LevelDBDatabaseAssociatedRequest database, - const OpenCallback& callback) override; + OpenCallback callback) override; void OpenInMemory(leveldb::mojom::LevelDBDatabaseAssociatedRequest database, - const OpenInMemoryCallback& callback) override; + OpenInMemoryCallback callback) override; void Destroy(filesystem::mojom::DirectoryPtr directory, const std::string& dbname, - const DestroyCallback& callback) override; + DestroyCallback callback) override; private: // Thread to own the mojo message pipe. Because leveldb spawns multiple
diff --git a/components/leveldb/public/interfaces/BUILD.gn b/components/leveldb/public/interfaces/BUILD.gn index 514eeb9..317863f 100644 --- a/components/leveldb/public/interfaces/BUILD.gn +++ b/components/leveldb/public/interfaces/BUILD.gn
@@ -16,4 +16,6 @@ public_deps = [ "//mojo/common:common_custom_types", ] + + use_once_callback = true }
diff --git a/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc b/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc index c7c99c9..b6802d3 100644 --- a/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc +++ b/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
@@ -40,45 +40,45 @@ // CallStackProfileCollectorTest: void BounceFrame(const base::StackSamplingProfiler::Frame& in, - const BounceFrameCallback& callback) override { - callback.Run(in); + BounceFrameCallback callback) override { + std::move(callback).Run(in); } void BounceModule(const base::StackSamplingProfiler::Module& in, - const BounceModuleCallback& callback) override { - callback.Run(in); + BounceModuleCallback callback) override { + std::move(callback).Run(in); } void BounceProfile(base::StackSamplingProfiler::CallStackProfile in, - const BounceProfileCallback& callback) override { - callback.Run(std::move(in)); + BounceProfileCallback callback) override { + std::move(callback).Run(std::move(in)); } void BounceTrigger(CallStackProfileParams::Trigger in, - const BounceTriggerCallback& callback) override { - callback.Run(in); + BounceTriggerCallback callback) override { + std::move(callback).Run(in); } void BounceProcess(CallStackProfileParams::Process in, - const BounceProcessCallback& callback) override { - callback.Run(in); + BounceProcessCallback callback) override { + std::move(callback).Run(in); } void BounceThread(CallStackProfileParams::Thread in, - const BounceThreadCallback& callback) override { - callback.Run(in); + BounceThreadCallback callback) override { + std::move(callback).Run(in); } void BounceSampleOrderingSpec( CallStackProfileParams::SampleOrderingSpec in, - const BounceSampleOrderingSpecCallback& callback) override { - callback.Run(in); + BounceSampleOrderingSpecCallback callback) override { + std::move(callback).Run(in); } void BounceCallStackProfileParams( const CallStackProfileParams& in, - const BounceCallStackProfileParamsCallback& callback) override { - callback.Run(in); + BounceCallStackProfileParamsCallback callback) override { + std::move(callback).Run(in); } private:
diff --git a/components/metrics/public/interfaces/BUILD.gn b/components/metrics/public/interfaces/BUILD.gn index cfe9661..df9ec797 100644 --- a/components/metrics/public/interfaces/BUILD.gn +++ b/components/metrics/public/interfaces/BUILD.gn
@@ -23,6 +23,8 @@ ":call_stack_mojo_bindings", "//mojo/common:common_custom_types", ] + + use_once_callback = true } mojom("single_sample_metrics_mojo_bindings") {
diff --git a/components/safe_browsing/password_protection/password_protection_service.cc b/components/safe_browsing/password_protection/password_protection_service.cc index 3203837..ee3af7c 100644 --- a/components/safe_browsing/password_protection/password_protection_service.cc +++ b/components/safe_browsing/password_protection/password_protection_service.cc
@@ -64,8 +64,8 @@ } // namespace -const base::Feature kLowReputationPinging{"LowReputationPinging", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kPasswordFieldOnFocusPinging{ + "PasswordFieldOnFocusPinging", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kProtectedPasswordEntryPinging{ "ProtectedPasswordEntryPinging", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -221,7 +221,7 @@ const GURL& password_form_action, const GURL& password_form_frame_url) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!IsPingingEnabled(kLowReputationPinging)) + if (!IsPingingEnabled(kPasswordFieldOnFocusPinging)) return; // Skip URLs that we can't get a reliable reputation for. @@ -317,7 +317,7 @@ user_population->set_is_history_sync_enabled(IsHistorySyncEnabled()); base::FieldTrial* low_reputation_field_trial = - base::FeatureList::GetFieldTrial(kLowReputationPinging); + base::FeatureList::GetFieldTrial(kPasswordFieldOnFocusPinging); if (low_reputation_field_trial) { user_population->add_finch_active_groups( low_reputation_field_trial->trial_name() + "|" +
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h index 9963266..e688efc 100644 --- a/components/safe_browsing/password_protection/password_protection_service.h +++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -33,7 +33,7 @@ class SafeBrowsingDatabaseManager; class PasswordProtectionRequest; -extern const base::Feature kLowReputationPinging; +extern const base::Feature kPasswordFieldOnFocusPinging; extern const base::Feature kProtectedPasswordEntryPinging; // Manage password protection pings and verdicts. There is one instance of this
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 308bdc71..b92c30d 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -78,6 +78,7 @@ #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/hit_test.h" #include "ui/base/ime/input_method.h" +#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_types.h" #include "ui/compositor/compositor_vsync_manager.h" #include "ui/compositor/dip_util.h" @@ -94,6 +95,7 @@ #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/skia_util.h" #include "ui/touch_selection/touch_selection_controller.h" +#include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/public/activation_client.h" #include "ui/wm/public/scoped_tooltip_disabler.h" #include "ui/wm/public/tooltip_client.h" @@ -119,6 +121,10 @@ #include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h" #endif +#if defined(OS_CHROMEOS) +#include "ui/wm/core/ime_util_chromeos.h" +#endif + using gfx::RectToSkIRect; using gfx::SkIRectToRect; @@ -1281,22 +1287,11 @@ gfx::Rect RenderWidgetHostViewAura::ConvertRectFromScreen( const gfx::Rect& rect) const { - gfx::Point origin = rect.origin(); - gfx::Point end = gfx::Point(rect.right(), rect.bottom()); - - aura::Window* root_window = window_->GetRootWindow(); - if (root_window) { - aura::client::ScreenPositionClient* screen_position_client = - aura::client::GetScreenPositionClient(root_window); - screen_position_client->ConvertPointFromScreen(window_, &origin); - screen_position_client->ConvertPointFromScreen(window_, &end); - return gfx::Rect(origin.x(), - origin.y(), - end.x() - origin.x(), - end.y() - origin.y()); - } - - return rect; + gfx::Rect result = rect; + if (window_->GetRootWindow() && + aura::client::GetScreenPositionClient(window_->GetRootWindow())) + wm::ConvertRectFromScreen(window_, &result); + return result; } gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const { @@ -1434,16 +1429,24 @@ rfh->ExtendSelectionAndDelete(before, after); } -void RenderWidgetHostViewAura::EnsureCaretNotInRect(const gfx::Rect& rect) { - gfx::Rect rect_in_local_space = ConvertRectFromScreen(rect); - gfx::Rect hiding_area_in_this_window = - gfx::IntersectRects(rect_in_local_space, window_->bounds()); +void RenderWidgetHostViewAura::EnsureCaretNotInRect( + const gfx::Rect& rect_in_screen) { + aura::Window* top_level_window = window_->GetToplevelWindow(); +#if defined(OS_CHROMEOS) + wm::EnsureWindowNotInRect(top_level_window, rect_in_screen); +#endif - if (hiding_area_in_this_window.IsEmpty()) + // Perform overscroll if the caret is still hidden by the keyboard. + const gfx::Rect hidden_window_bounds_in_screen = gfx::IntersectRects( + rect_in_screen, top_level_window->GetBoundsInScreen()); + if (hidden_window_bounds_in_screen.IsEmpty()) return; - host_->ScrollFocusedEditableNodeIntoRect( - gfx::SubtractRects(window_->bounds(), hiding_area_in_this_window)); + gfx::Rect visible_area_in_local_space = gfx::SubtractRects( + window_->GetBoundsInScreen(), hidden_window_bounds_in_screen); + visible_area_in_local_space = + ConvertRectFromScreen(visible_area_in_local_space); + host_->ScrollFocusedEditableNodeIntoRect(visible_area_in_local_space); } bool RenderWidgetHostViewAura::IsTextEditCommandEnabled( @@ -2225,8 +2228,12 @@ void RenderWidgetHostViewAura::DetachFromInputMethod() { ui::InputMethod* input_method = GetInputMethod(); - if (input_method) + if (input_method) { input_method->DetachTextInputClient(this); +#if defined(OS_CHROMEOS) + wm::RestoreWindowBoundsOnClientFocusLost(window_->GetToplevelWindow()); +#endif // defined(OS_CHROMEOS) + } } void RenderWidgetHostViewAura::ForwardKeyboardEvent(
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 1e3d1099..b4a4c994 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -374,6 +374,8 @@ FinishCompositionByMouse); FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, ForwardsBeginFrameAcks); + FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, + VirtualKeyboardFocusEnsureCaretInRect); FRIEND_TEST_ALL_PREFIXES(WebContentsViewAuraTest, WebContentsViewReparent);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index adcb5bf6..3694c796 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -83,6 +83,7 @@ #include "ui/aura/window_event_dispatcher.h" #include "ui/aura/window_observer.h" #include "ui/base/clipboard/clipboard.h" +#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_types.h" #include "ui/compositor/compositor.h" #include "ui/compositor/layer_tree_owner.h" @@ -102,6 +103,10 @@ #include "ui/wm/core/default_screen_position_client.h" #include "ui/wm/core/window_util.h" +#if defined(OS_CHROMEOS) +#include "ui/base/ime/input_method.h" +#endif + using testing::_; using blink::WebGestureEvent; @@ -4687,6 +4692,56 @@ EXPECT_EQ(4U, sink_->message_count()); } +#if defined(OS_CHROMEOS) +// Check that when accessibility virtual keyboard is enabled, windows are +// shifted up when focused and restored when focus is lost. +TEST_F(RenderWidgetHostViewAuraTest, VirtualKeyboardFocusEnsureCaretInRect) { + // TODO (oshima): Test that overscroll occurs. + + // Enable new virtual keyboard behavior. + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(::switches::kUseNewVirtualKeyboardBehavior)) + command_line->AppendSwitch(::switches::kUseNewVirtualKeyboardBehavior); + + view_->InitAsChild(nullptr); + aura::client::ParentWindowWithContext( + view_->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(), + gfx::Rect()); + aura::Window* root_window = parent_view_->GetNativeView()->GetRootWindow(); + wm::DefaultScreenPositionClient screen_position_client; + aura::client::SetScreenPositionClient(root_window, &screen_position_client); + + const gfx::Rect orig_view_bounds = gfx::Rect(0, 300, 400, 200); + const gfx::Rect shifted_view_bounds = gfx::Rect(0, 200, 400, 200); + const gfx::Rect root_bounds = root_window->bounds(); + const int keyboard_height = 200; + const gfx::Rect keyboard_view_bounds = + gfx::Rect(0, root_bounds.height() - keyboard_height, root_bounds.width(), + keyboard_height); + + ui::InputMethod* input_method = root_window->GetHost()->GetInputMethod(); + + // Focus the window. + view_->SetBounds(orig_view_bounds); + input_method->SetFocusedTextInputClient(view_); + EXPECT_EQ(view_->GetNativeView()->bounds(), orig_view_bounds); + + // Simulate virtual keyboard. + input_method->SetOnScreenKeyboardBounds(keyboard_view_bounds); + + // Window should be shifted. + EXPECT_EQ(view_->GetNativeView()->bounds(), shifted_view_bounds); + + // Detach the RenderWidgetHostViewAura from the IME. + view_->DetachFromInputMethod(); + + // Window should be restored. + EXPECT_EQ(view_->GetNativeView()->bounds(), orig_view_bounds); + + aura::client::SetScreenPositionClient(root_window, nullptr); +} +#endif // defined(OS_CHROMEOS) + // Tests that when view initiated shutdown happens (i.e. RWHView is deleted // before RWH), we clean up properly and don't leak the RWHVGuest. TEST_F(RenderWidgetHostViewGuestAuraTest, GuestViewDoesNotLeak) {
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 1122904..b2f3540e 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1519,6 +1519,7 @@ "//third_party/widevine/cdm:headers", "//ui/accessibility", "//ui/base:test_support", + "//ui/base/ime", "//ui/compositor:test_support", "//ui/display", "//ui/display:test_support",
diff --git a/content/test/data/media/mediarecorder_test_utils.js b/content/test/data/media/mediarecorder_test_utils.js index 400b19e..1cec7a7 100644 --- a/content/test/data/media/mediarecorder_test_utils.js +++ b/content/test/data/media/mediarecorder_test_utils.js
@@ -22,13 +22,13 @@ console.log('Waiting for', description.toString()); var check = setInterval(function() { var elapsed = new Date() - startTime; - if (elapsed > 3000) { + if (predicate()) { + clearInterval(check); + resolve(); + } else if (elapsed > 3000) { startTime = new Date(); console.log('Still waiting for satisfaction of ' + predicate.toString()); - } else if (predicate()) { - clearInterval(check); - resolve(); } }, 50); });
diff --git a/content/test/mock_leveldb_database.cc b/content/test/mock_leveldb_database.cc index 60a5db7..83b7d5f2 100644 --- a/content/test/mock_leveldb_database.cc +++ b/content/test/mock_leveldb_database.cc
@@ -4,6 +4,8 @@ #include "content/test/mock_leveldb_database.h" +#include <utility> + #include "base/strings/string_piece.h" #include "base/strings/string_util.h" @@ -49,28 +51,27 @@ void MockLevelDBDatabase::Put(const std::vector<uint8_t>& key, const std::vector<uint8_t>& value, - const PutCallback& callback) { + PutCallback callback) { mock_data_[key] = value; - callback.Run(leveldb::mojom::DatabaseError::OK); + std::move(callback).Run(leveldb::mojom::DatabaseError::OK); } void MockLevelDBDatabase::Delete(const std::vector<uint8_t>& key, - const DeleteCallback& callback) { + DeleteCallback callback) { mock_data_.erase(key); - callback.Run(leveldb::mojom::DatabaseError::OK); + std::move(callback).Run(leveldb::mojom::DatabaseError::OK); } -void MockLevelDBDatabase::DeletePrefixed( - const std::vector<uint8_t>& key_prefix, - const DeletePrefixedCallback& callback) { +void MockLevelDBDatabase::DeletePrefixed(const std::vector<uint8_t>& key_prefix, + DeletePrefixedCallback callback) { mock_data_.erase(mock_data_.lower_bound(key_prefix), mock_data_.lower_bound(successor(key_prefix))); - callback.Run(leveldb::mojom::DatabaseError::OK); + std::move(callback).Run(leveldb::mojom::DatabaseError::OK); } void MockLevelDBDatabase::Write( std::vector<leveldb::mojom::BatchedOperationPtr> operations, - const WriteCallback& callback) { + WriteCallback callback) { for (const auto& op : operations) { switch (op->type) { case leveldb::mojom::BatchOperationType::PUT_KEY: @@ -85,33 +86,31 @@ break; } } - callback.Run(leveldb::mojom::DatabaseError::OK); + std::move(callback).Run(leveldb::mojom::DatabaseError::OK); } void MockLevelDBDatabase::Get(const std::vector<uint8_t>& key, - const GetCallback& callback) { + GetCallback callback) { if (mock_data_.find(key) != mock_data_.end()) { - callback.Run(leveldb::mojom::DatabaseError::OK, mock_data_[key]); + std::move(callback).Run(leveldb::mojom::DatabaseError::OK, mock_data_[key]); } else { - callback.Run(leveldb::mojom::DatabaseError::NOT_FOUND, - std::vector<uint8_t>()); + std::move(callback).Run(leveldb::mojom::DatabaseError::NOT_FOUND, + std::vector<uint8_t>()); } } -void MockLevelDBDatabase::GetPrefixed( - const std::vector<uint8_t>& key_prefix, - const GetPrefixedCallback& callback) { +void MockLevelDBDatabase::GetPrefixed(const std::vector<uint8_t>& key_prefix, + GetPrefixedCallback callback) { std::vector<leveldb::mojom::KeyValuePtr> data; for (const auto& row : mock_data_) { if (StartsWith(row.first, key_prefix)) { data.push_back(CreateKeyValue(row.first, row.second)); } } - callback.Run(leveldb::mojom::DatabaseError::OK, std::move(data)); + std::move(callback).Run(leveldb::mojom::DatabaseError::OK, std::move(data)); } -void MockLevelDBDatabase::GetSnapshot( - const GetSnapshotCallback& callback) { +void MockLevelDBDatabase::GetSnapshot(GetSnapshotCallback callback) { NOTREACHED(); } @@ -123,18 +122,17 @@ void MockLevelDBDatabase::GetFromSnapshot( const base::UnguessableToken& snapshot, const std::vector<uint8_t>& key, - const GetCallback& callback) { + GetCallback callback) { NOTREACHED(); } -void MockLevelDBDatabase::NewIterator( - const NewIteratorCallback& callback) { +void MockLevelDBDatabase::NewIterator(NewIteratorCallback callback) { NOTREACHED(); } void MockLevelDBDatabase::NewIteratorFromSnapshot( const base::UnguessableToken& snapshot, - const NewIteratorFromSnapshotCallback& callback) { + NewIteratorFromSnapshotCallback callback) { NOTREACHED(); } @@ -145,32 +143,29 @@ void MockLevelDBDatabase::IteratorSeekToFirst( const base::UnguessableToken& iterator, - const IteratorSeekToFirstCallback& callback) { + IteratorSeekToFirstCallback callback) { NOTREACHED(); } void MockLevelDBDatabase::IteratorSeekToLast( const base::UnguessableToken& iterator, - const IteratorSeekToLastCallback& callback) { + IteratorSeekToLastCallback callback) { NOTREACHED(); } -void MockLevelDBDatabase::IteratorSeek( - const base::UnguessableToken& iterator, - const std::vector<uint8_t>& target, - const IteratorSeekToLastCallback& callback) { +void MockLevelDBDatabase::IteratorSeek(const base::UnguessableToken& iterator, + const std::vector<uint8_t>& target, + IteratorSeekToLastCallback callback) { NOTREACHED(); } -void MockLevelDBDatabase::IteratorNext( - const base::UnguessableToken& iterator, - const IteratorNextCallback& callback) { +void MockLevelDBDatabase::IteratorNext(const base::UnguessableToken& iterator, + IteratorNextCallback callback) { NOTREACHED(); } -void MockLevelDBDatabase::IteratorPrev( - const base::UnguessableToken& iterator, - const IteratorPrevCallback& callback) { +void MockLevelDBDatabase::IteratorPrev(const base::UnguessableToken& iterator, + IteratorPrevCallback callback) { NOTREACHED(); }
diff --git a/content/test/mock_leveldb_database.h b/content/test/mock_leveldb_database.h index 29a2abd..4d5728d 100644 --- a/content/test/mock_leveldb_database.h +++ b/content/test/mock_leveldb_database.h
@@ -19,39 +19,37 @@ // LevelDBDatabase: void Put(const std::vector<uint8_t>& key, const std::vector<uint8_t>& value, - const PutCallback& callback) override; + PutCallback callback) override; void Delete(const std::vector<uint8_t>& key, - const DeleteCallback& callback) override; + DeleteCallback callback) override; void DeletePrefixed(const std::vector<uint8_t>& key_prefix, - const DeletePrefixedCallback& callback) override; + DeletePrefixedCallback callback) override; void Write(std::vector<leveldb::mojom::BatchedOperationPtr> operations, - const WriteCallback& callback) override; - void Get(const std::vector<uint8_t>& key, - const GetCallback& callback) override; + WriteCallback callback) override; + void Get(const std::vector<uint8_t>& key, GetCallback callback) override; void GetPrefixed(const std::vector<uint8_t>& key_prefix, - const GetPrefixedCallback& callback) override; - void GetSnapshot(const GetSnapshotCallback& callback) override; + GetPrefixedCallback callback) override; + void GetSnapshot(GetSnapshotCallback callback) override; void ReleaseSnapshot(const base::UnguessableToken& snapshot) override; void GetFromSnapshot(const base::UnguessableToken& snapshot, const std::vector<uint8_t>& key, - const GetCallback& callback) override; - void NewIterator(const NewIteratorCallback& callback) override; + GetCallback callback) override; + void NewIterator(NewIteratorCallback callback) override; void NewIteratorFromSnapshot( const base::UnguessableToken& snapshot, - const NewIteratorFromSnapshotCallback& callback) override; + NewIteratorFromSnapshotCallback callback) override; void ReleaseIterator(const base::UnguessableToken& iterator) override; - void IteratorSeekToFirst( - const base::UnguessableToken& iterator, - const IteratorSeekToFirstCallback& callback) override; + void IteratorSeekToFirst(const base::UnguessableToken& iterator, + IteratorSeekToFirstCallback callback) override; void IteratorSeekToLast(const base::UnguessableToken& iterator, - const IteratorSeekToLastCallback& callback) override; + IteratorSeekToLastCallback callback) override; void IteratorSeek(const base::UnguessableToken& iterator, const std::vector<uint8_t>& target, - const IteratorSeekToLastCallback& callback) override; + IteratorSeekToLastCallback callback) override; void IteratorNext(const base::UnguessableToken& iterator, - const IteratorNextCallback& callback) override; + IteratorNextCallback callback) override; void IteratorPrev(const base::UnguessableToken& iterator, - const IteratorPrevCallback& callback) override; + IteratorPrevCallback callback) override; private: std::map<std::vector<uint8_t>, std::vector<uint8_t>>& mock_data_;
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index 334f3f4..d2e23090 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -24,7 +24,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "base/values.h" -#include "chromeos/login/login_state.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_request_info.h" #include "content/public/common/browser_side_navigation_policy.h" @@ -72,6 +71,10 @@ #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" +#if defined(OS_CHROMEOS) +#include "chromeos/login/login_state.h" +#endif // defined(OS_CHROMEOS) + using content::BrowserThread; using content::ResourceRequestInfo; using extension_web_request_api_helpers::ExtraInfoSpec;
diff --git a/extensions/browser/api/web_request/web_request_permissions.cc b/extensions/browser/api/web_request/web_request_permissions.cc index 8b2f2f4..22dcaf58 100644 --- a/extensions/browser/api/web_request/web_request_permissions.cc +++ b/extensions/browser/api/web_request/web_request_permissions.cc
@@ -7,7 +7,6 @@ #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "chromeos/login/login_state.h" #include "content/public/browser/resource_request_info.h" #include "extensions/browser/extension_navigation_ui_data.h" #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" @@ -20,6 +19,10 @@ #include "url/gurl.h" #include "url/origin.h" +#if defined(OS_CHROMEOS) +#include "chromeos/login/login_state.h" +#endif // defined(OS_CHROMEOS) + using content::ResourceRequestInfo; using extensions::PermissionsData;
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn index 113d24f..4e28b1c 100644 --- a/ios/chrome/browser/tabs/BUILD.gn +++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -33,8 +33,6 @@ source_set("tabs_internal") { sources = [ - "tab.h", - "tab.mm", "tab_model.mm", "tab_model_synced_window_delegate.mm", "tab_model_synced_window_delegate_getter.mm", @@ -124,6 +122,8 @@ source_set("tabs_internal_arc") { sources = [ "legacy_tab_helper.mm", + "tab.h", + "tab.mm", "tab_helper_util.mm", "tab_model_closing_web_state_observer.h", "tab_model_closing_web_state_observer.mm", @@ -142,34 +142,82 @@ deps = [ ":tabs", "//base", + "//components/content_settings/core/browser", + "//components/favicon/core", "//components/favicon/ios", + "//components/google/core/browser", "//components/history/core/browser", "//components/history/ios/browser", + "//components/infobars/core", "//components/keyed_service/core", + "//components/metrics_services_manager", + "//components/navigation_metrics", + "//components/prefs", + "//components/reading_list/core", + "//components/search_engines", "//components/sessions", + "//components/signin/core/browser", "//components/signin/ios/browser", + "//components/strings", + "//components/url_formatter", + "//ios/chrome/app/strings", "//ios/chrome/browser", + "//ios/chrome/browser/autofill", + "//ios/chrome/browser/autofill:autofill_internal", "//ios/chrome/browser/bookmarks", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/content_settings", "//ios/chrome/browser/favicon", "//ios/chrome/browser/find_in_page", + "//ios/chrome/browser/geolocation:geolocation_internal", "//ios/chrome/browser/history", "//ios/chrome/browser/infobars", + "//ios/chrome/browser/metrics", + "//ios/chrome/browser/metrics:metrics_internal", + "//ios/chrome/browser/native_app_launcher:native_app_launcher_internal", + "//ios/chrome/browser/passwords", + "//ios/chrome/browser/passwords:passwords_internal", "//ios/chrome/browser/reading_list", + "//ios/chrome/browser/search_engines", "//ios/chrome/browser/sessions", + "//ios/chrome/browser/sessions:serialisation", "//ios/chrome/browser/signin", + "//ios/chrome/browser/signin:signin_internal", + "//ios/chrome/browser/snapshots", + "//ios/chrome/browser/snapshots:snapshots_internal", "//ios/chrome/browser/ssl", "//ios/chrome/browser/store_kit", "//ios/chrome/browser/sync", "//ios/chrome/browser/translate", + "//ios/chrome/browser/u2f", + "//ios/chrome/browser/ui", + "//ios/chrome/browser/ui:ui_internal", + "//ios/chrome/browser/ui/alert_coordinator", + "//ios/chrome/browser/ui/commands", + "//ios/chrome/browser/ui/downloads", + "//ios/chrome/browser/ui/overscroll_actions", + "//ios/chrome/browser/ui/reader_mode", + "//ios/chrome/browser/ui/sad_tab", + "//ios/chrome/browser/ui/toolbar", + "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web", + "//ios/chrome/browser/web:sad_tab_tab_helper_delegate", "//ios/chrome/browser/web:web_internal", "//ios/chrome/browser/web_state_list", + "//ios/net", "//ios/public/provider/chrome/browser", + "//ios/public/provider/chrome/browser/native_app_launcher", "//ios/web", + "//ios/web:user_agent", + "//net", + "//ui/base", "//url", ] - libs = [ "Foundation.framework" ] + libs = [ + "CoreLocation.framework", + "Foundation.framework", + "UIKit.framework", + ] configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/chrome/browser/tabs/tab.h b/ios/chrome/browser/tabs/tab.h index 43091fc..075f848 100644 --- a/ios/chrome/browser/tabs/tab.h +++ b/ios/chrome/browser/tabs/tab.h
@@ -113,7 +113,7 @@ @property(nonatomic, readonly) const GURL& visibleURL; // The Passkit Dialog provider used to show the UI to download a passkit object. -@property(nonatomic, assign) id<PassKitDialogProvider> passKitDialogProvider; +@property(nonatomic, weak) id<PassKitDialogProvider> passKitDialogProvider; // The current title of the tab. @property(nonatomic, readonly) NSString* title; @@ -133,27 +133,27 @@ @property(nonatomic, readonly) web::WebState* webState; @property(nonatomic, readonly) CRWWebController* webController; + +// Handles saving and autofill of passwords. @property(nonatomic, readonly) PasswordController* passwordController; @property(nonatomic, readonly) BOOL canGoBack; @property(nonatomic, readonly) BOOL canGoForward; -@property(nonatomic, assign) id<TabDelegate> delegate; -@property(nonatomic, assign) id<TabHeadersDelegate> tabHeadersDelegate; -@property(nonatomic, assign) id<TabSnapshottingDelegate> - tabSnapshottingDelegate; +@property(nonatomic, weak) id<TabDelegate> delegate; +@property(nonatomic, weak) id<TabHeadersDelegate> tabHeadersDelegate; +@property(nonatomic, weak) id<TabSnapshottingDelegate> tabSnapshottingDelegate; @property(nonatomic, readonly) id<FindInPageControllerDelegate> findInPageControllerDelegate; // Whether or not desktop user agent is used for the currently visible page. @property(nonatomic, readonly) BOOL usesDesktopUserAgent; -@property(nonatomic, assign) id<FullScreenControllerDelegate> +@property(nonatomic, weak) id<FullScreenControllerDelegate> fullScreenControllerDelegate; @property(nonatomic, readonly) OverscrollActionsController* overscrollActionsController; -@property(nonatomic, assign) id<OverscrollActionsControllerDelegate> +@property(nonatomic, weak) id<OverscrollActionsControllerDelegate> overscrollActionsControllerDelegate; -@property(nonatomic, assign) id<SnapshotOverlayProvider> - snapshotOverlayProvider; +@property(nonatomic, weak) id<SnapshotOverlayProvider> snapshotOverlayProvider; // Delegate used to show HTTP Authentication dialogs. @property(nonatomic, weak) id<TabDialogDelegate> dialogDelegate;
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index 0162ee0..56df201 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -12,13 +12,11 @@ #include "base/bind.h" #include "base/ios/block_types.h" -#import "base/ios/weak_nsobject.h" #include "base/json/string_escape.h" #include "base/logging.h" #include "base/mac/bind_objc_block.h" #include "base/mac/foundation_util.h" -#include "base/mac/objc_property_releaser.h" -#include "base/mac/scoped_nsobject.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" @@ -144,9 +142,9 @@ #include "ui/base/page_transition_types.h" #include "url/origin.h" -using base::UserMetricsAction; -using web::NavigationManagerImpl; -using net::RequestTracker; +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif NSString* const kTabUrlStartedLoadingNotificationForCrashReporting = @"kTabUrlStartedLoadingNotificationForCrashReporting"; @@ -204,17 +202,27 @@ return (ui::PageTransition::PAGE_TRANSITION_IS_REDIRECT_MASK & item->GetTransitionType()) == 0; } + +// TabHistoryContext is used by history to scope the lifetime of navigation +// entry references to Tab. +class TabHistoryContext : public history::Context { + public: + TabHistoryContext() {} + ~TabHistoryContext() {} + + private: + DISALLOW_COPY_AND_ASSIGN(TabHistoryContext); +}; } // namespace @interface Tab ()<CRWWebStateObserver, CRWWebControllerObserver, FindInPageControllerDelegate, ReaderModeControllerDelegate> { - TabModel* parentTabModel_; // weak - ios::ChromeBrowserState* browserState_; // weak + __weak TabModel* parentTabModel_; + ios::ChromeBrowserState* browserState_; - base::scoped_nsobject<OpenInController> openInController_; - base::WeakNSProtocol<id<PassKitDialogProvider>> passKitDialogProvider_; + OpenInController* openInController_; // Whether or not this tab is currently being displayed. BOOL visible_; @@ -237,69 +245,41 @@ // Last visited timestamp. double lastVisitedTimestamp_; - base::mac::ObjCPropertyReleaser propertyReleaser_Tab_; - - id<TabDelegate> delegate_; // weak - base::WeakNSProtocol<id<TabDialogDelegate>> dialogDelegate_; - base::WeakNSProtocol<id<SnapshotOverlayProvider>> snapshotOverlayProvider_; - - // Delegate used for snapshotting geometry. - id<TabSnapshottingDelegate> tabSnapshottingDelegate_; // weak - // The Full Screen Controller responsible for hiding/showing the toolbar. - base::scoped_nsobject<FullScreenController> fullScreenController_; - - // The delegate responsible for headers over the tab. - id<TabHeadersDelegate> tabHeadersDelegate_; // weak - - base::WeakNSProtocol<id<FullScreenControllerDelegate>> - fullScreenControllerDelegate_; + FullScreenController* fullScreenController_; // The Overscroll controller responsible for displaying the // overscrollActionsView above the toolbar. - base::scoped_nsobject<OverscrollActionsController> - overscrollActionsController_; - base::WeakNSProtocol<id<OverscrollActionsControllerDelegate>> - overscrollActionsControllerDelegate_; - - base::scoped_nsobject<NSString> tabId_; + OverscrollActionsController* overscrollActionsController_; // Lightweight object dealing with various different UI behaviours when // opening a URL in an external application. - base::scoped_nsobject<ExternalAppLauncher> externalAppLauncher_; + ExternalAppLauncher* externalAppLauncher_; // Handles suggestions for form entry. - base::scoped_nsobject<FormSuggestionController> suggestionController_; + FormSuggestionController* suggestionController_; // Manages the input accessory view during form input. - base::scoped_nsobject<FormInputAccessoryViewController> - inputAccessoryViewController_; - - // TODO(crbug.com/661665): move the WebContentsObservers into their own - // container. - // Handles saving and autofill of passwords. - base::scoped_nsobject<PasswordController> passwordController_; + FormInputAccessoryViewController* inputAccessoryViewController_; // Handles autofill. - base::scoped_nsobject<AutofillController> autofillController_; + AutofillController* autofillController_; // Handles GAL infobar on web pages. - base::scoped_nsobject<NativeAppNavigationController> - nativeAppNavigationController_; + NativeAppNavigationController* nativeAppNavigationController_; // Handles caching and retrieving of snapshots. - base::scoped_nsobject<SnapshotManager> snapshotManager_; + SnapshotManager* snapshotManager_; // Handles retrieving, generating and updating snapshots of CRWWebController's // web page. - base::scoped_nsobject<WebControllerSnapshotHelper> - webControllerSnapshotHelper_; + WebControllerSnapshotHelper* webControllerSnapshotHelper_; // Handles support for window.print JavaScript calls. std::unique_ptr<PrintObserver> printObserver_; // AutoReloadBridge for this tab. - base::scoped_nsobject<AutoReloadBridge> autoReloadBridge_; + AutoReloadBridge* autoReloadBridge_; // WebStateImpl for this tab. web::WebStateImpl* webStateImpl_; @@ -309,16 +289,13 @@ // Context used by history to scope the lifetime of navigation entry // references to Tab. - std::unique_ptr<TabHistoryContext> tabHistoryContext_; - - // The controller for everything related to reader mode. - base::scoped_nsobject<ReaderModeController> readerModeController_; + TabHistoryContext tabHistoryContext_; // C++ bridge that receives notifications from the FaviconDriver. std::unique_ptr<FaviconDriverObserverBridge> faviconDriverObserverBridge_; // U2F call controller object. - base::scoped_nsobject<U2FController> U2FController_; + U2FController* U2FController_; // C++ observer used to trigger snapshots after the removal of InfoBars. std::unique_ptr<TabInfoBarObserver> tabInfoBarObserver_; @@ -367,17 +344,6 @@ @end namespace { -// TabHistoryContext is used by history to scope the lifetime of navigation -// entry references to Tab. -class TabHistoryContext : public history::Context { - public: - TabHistoryContext() {} - ~TabHistoryContext() {} - - private: - DISALLOW_COPY_AND_ASSIGN(TabHistoryContext); -}; - class FaviconDriverObserverBridge : public favicon::FaviconDriverObserver { public: FaviconDriverObserverBridge(Tab* owner, @@ -392,7 +358,7 @@ const gfx::Image& image) override; private: - Tab* owner_; // Owns this instance. + __weak Tab* owner_; ScopedObserver<favicon::FaviconDriver, favicon::FaviconDriverObserver> scoped_observer_; DISALLOW_COPY_AND_ASSIGN(FaviconDriverObserverBridge); @@ -428,7 +394,7 @@ infobars::InfoBar* new_infobar) override; private: - Tab* owner_; // Owns this instance; + __weak Tab* owner_; ScopedObserver<infobars::InfoBarManager, TabInfoBarObserver> scoped_observer_; DISALLOW_COPY_AND_ASSIGN(TabInfoBarObserver); }; @@ -473,27 +439,33 @@ @implementation Tab @synthesize browserState = browserState_; +@synthesize tabId = tabId_; @synthesize useGreyImageCache = useGreyImageCache_; @synthesize isPrerenderTab = isPrerenderTab_; @synthesize isLinkLoadingPrerenderTab = isLinkLoadingPrerenderTab_; @synthesize isVoiceSearchResultsTab = isVoiceSearchResultsTab_; +@synthesize passwordController = passwordController_; +@synthesize overscrollActionsController = overscrollActionsController_; +@synthesize readerModeController = readerModeController_; +@synthesize overscrollActionsControllerDelegate = + overscrollActionsControllerDelegate_; +@synthesize passKitDialogProvider = passKitDialogProvider_; @synthesize delegate = delegate_; +@synthesize dialogDelegate = dialogDelegate_; +@synthesize snapshotOverlayProvider = snapshotOverlayProvider_; @synthesize tabSnapshottingDelegate = tabSnapshottingDelegate_; @synthesize tabHeadersDelegate = tabHeadersDelegate_; +@synthesize fullScreenControllerDelegate = fullScreenControllerDelegate_; - (instancetype)initWithWebState:(web::WebState*)webState { DCHECK(webState); self = [super init]; if (self) { - propertyReleaser_Tab_.Init(self, [Tab class]); - // TODO(crbug.com/620465): Tab should only use public API of WebState. // Remove this cast once this is the case. webStateImpl_ = static_cast<web::WebStateImpl*>(webState); browserState_ = ios::ChromeBrowserState::FromBrowserState(webState->GetBrowserState()); - - tabHistoryContext_ = base::MakeUnique<TabHistoryContext>(); webStateObserver_ = base::MakeUnique<web::WebStateObserverBridge>(webState, self); @@ -501,10 +473,10 @@ [[self webController] addObserver:self]; [[self webController] setDelegate:self]; - snapshotManager_.reset([[SnapshotManager alloc] init]); - webControllerSnapshotHelper_.reset([[WebControllerSnapshotHelper alloc] + snapshotManager_ = [[SnapshotManager alloc] init]; + webControllerSnapshotHelper_ = [[WebControllerSnapshotHelper alloc] initWithSnapshotManager:snapshotManager_ - tab:self]); + tab:self]; if (experimental_flags::IsNativeAppLauncherEnabled()) [self initNativeAppNavigationController]; @@ -519,40 +491,39 @@ } - (void)attachTabHelpers { - tabInfoBarObserver_.reset(new TabInfoBarObserver(self)); + tabInfoBarObserver_ = base::MakeUnique<TabInfoBarObserver>(self); tabInfoBarObserver_->SetShouldObserveInfoBarManager(true); - if (experimental_flags::IsAutoReloadEnabled()) { - autoReloadBridge_.reset([[AutoReloadBridge alloc] initWithTab:self]); - } + if (experimental_flags::IsAutoReloadEnabled()) + autoReloadBridge_ = [[AutoReloadBridge alloc] initWithTab:self]; printObserver_ = base::MakeUnique<PrintObserver>(self.webState); - base::scoped_nsprotocol<id<PasswordsUiDelegate>> passwordsUiDelegate( - [[PasswordsUiDelegateImpl alloc] init]); - passwordController_.reset([[PasswordController alloc] - initWithWebState:self.webState - passwordsUiDelegate:passwordsUiDelegate]); + id<PasswordsUiDelegate> passwordsUiDelegate = + [[PasswordsUiDelegateImpl alloc] init]; + passwordController_ = + [[PasswordController alloc] initWithWebState:self.webState + passwordsUiDelegate:passwordsUiDelegate]; password_manager::PasswordGenerationManager* passwordGenerationManager = [passwordController_ passwordGenerationManager]; - autofillController_.reset([[AutofillController alloc] - initWithBrowserState:browserState_ - passwordGenerationManager:passwordGenerationManager - webState:self.webState]); - suggestionController_.reset([[FormSuggestionController alloc] + autofillController_ = + [[AutofillController alloc] initWithBrowserState:browserState_ + passwordGenerationManager:passwordGenerationManager + webState:self.webState]; + suggestionController_ = [[FormSuggestionController alloc] initWithWebState:self.webState - providers:[self suggestionProviders]]); - inputAccessoryViewController_.reset([[FormInputAccessoryViewController alloc] + providers:[self suggestionProviders]]; + inputAccessoryViewController_ = [[FormInputAccessoryViewController alloc] initWithWebState:self.webState - providers:[self accessoryViewProviders]]); + providers:[self accessoryViewProviders]]; [self setShouldObserveFaviconChanges:YES]; // Create the ReaderModeController immediately so it can register for // WebState changes. if (experimental_flags::IsReaderModeEnabled()) { - readerModeController_.reset([[ReaderModeController alloc] - initWithWebState:self.webState - delegate:self]); + readerModeController_ = + [[ReaderModeController alloc] initWithWebState:self.webState + delegate:self]; } } @@ -604,10 +575,6 @@ return [self.webController loadPhase] == web::PAGE_LOADED; } -- (void)setDialogDelegate:(id<TabDialogDelegate>)dialogDelegate { - dialogDelegate_.reset(dialogDelegate); -} - - (void)setIsVoiceSearchResultsTab:(BOOL)isVoiceSearchResultsTab { // There is intentionally no equality check in this setter, as we want the // notificaiton to be sent regardless of whether the value has changed. @@ -615,10 +582,6 @@ [parentTabModel_ notifyTabChanged:self]; } -- (PasswordController*)passwordController { - return passwordController_.get(); -} - - (void)retrieveSnapshot:(void (^)(UIImage*))callback { [webControllerSnapshotHelper_ retrieveSnapshotForWebController:self.webController @@ -671,7 +634,7 @@ - (NSString*)tabId { if (tabId_) - return tabId_.get(); + return tabId_; DCHECK(self.webState); web::SerializableUserDataManager* userDataManager = @@ -684,8 +647,8 @@ userDataManager->AddSerializableData(tabId, kTabIDKey); } - tabId_.reset([tabId copy]); - return tabId_.get(); + tabId_ = [tabId copy]; + return tabId_; } - (web::WebState*)webState { @@ -699,9 +662,8 @@ favicon::FaviconDriver* faviconDriver = favicon::WebFaviconDriver::FromWebState(self.webState); - if (faviconDriver) { + if (faviconDriver) faviconDriver->FetchFavicon(url); - } } - (void)setFavicon:(const gfx::Image*)image { @@ -728,9 +690,8 @@ - (UIView*)view { // Record reload of previously-evicted tab. - if (![self.webController isViewAlive] && [parentTabModel_ tabUsageRecorder]) { + if (![self.webController isViewAlive] && [parentTabModel_ tabUsageRecorder]) [parentTabModel_ tabUsageRecorder]->RecordPageLoadStart(self); - } return self.webState ? self.webState->GetView() : nil; } @@ -770,10 +731,10 @@ if (fullScreenController_) { [fullScreenController_ invalidate]; [self.webController removeObserver:fullScreenController_]; - fullScreenController_.reset([[FullScreenController alloc] + fullScreenController_ = [[FullScreenController alloc] initWithDelegate:fullScreenControllerDelegate_ navigationManager:self.navigationManager - sessionID:self.tabId]); + sessionID:self.tabId]; [self.webController addObserver:fullScreenController_]; // If the content of the page was loaded without knowledge of the // toolbar position it will be misplaced under the toolbar instead of @@ -817,23 +778,18 @@ [self countMainFrameLoad]; } -- (id<FullScreenControllerDelegate>)fullScreenControllerDelegate { - return fullScreenControllerDelegate_.get(); -} - - (void)setFullScreenControllerDelegate: (id<FullScreenControllerDelegate>)fullScreenControllerDelegate { - if (fullScreenControllerDelegate == fullScreenControllerDelegate_) { + if (fullScreenControllerDelegate == fullScreenControllerDelegate_) return; - } // Lazily create a FullScreenController. // The check for fullScreenControllerDelegate is necessary to avoid recreating // a FullScreenController during teardown. if (!fullScreenController_ && fullScreenControllerDelegate) { - fullScreenController_.reset([[FullScreenController alloc] + fullScreenController_ = [[FullScreenController alloc] initWithDelegate:fullScreenControllerDelegate navigationManager:self.navigationManager - sessionID:self.tabId]); + sessionID:self.tabId]; [self.webController addObserver:fullScreenController_]; // If the content of the page was loaded without knowledge of the // toolbar position it will be misplaced under the toolbar instead of @@ -841,41 +797,31 @@ // sure the content is moved to the right place. [fullScreenController_ moveContentBelowHeader]; } - fullScreenControllerDelegate_.reset(fullScreenControllerDelegate); -} - -- (OverscrollActionsController*)overscrollActionsController { - return overscrollActionsController_.get(); -} - -- (id<OverscrollActionsControllerDelegate>)overscrollActionsControllerDelegate { - return overscrollActionsControllerDelegate_.get(); + fullScreenControllerDelegate_ = fullScreenControllerDelegate; } - (void)setOverscrollActionsControllerDelegate: (id<OverscrollActionsControllerDelegate>) overscrollActionsControllerDelegate { if (overscrollActionsControllerDelegate_ == - overscrollActionsControllerDelegate) + overscrollActionsControllerDelegate) { return; + } // Lazily create a OverscrollActionsController. // The check for overscrollActionsControllerDelegate is necessary to avoid // recreating a OverscrollActionsController during teardown. if (!overscrollActionsController_) { - overscrollActionsController_.reset( - [[OverscrollActionsController alloc] init]); + overscrollActionsController_ = [[OverscrollActionsController alloc] init]; [self.webController addObserver:overscrollActionsController_]; } OverscrollStyle style = OverscrollStyle::REGULAR_PAGE_NON_INCOGNITO; - if (browserState_->IsOffTheRecord()) { + if (browserState_->IsOffTheRecord()) style = OverscrollStyle::REGULAR_PAGE_INCOGNITO; - } [overscrollActionsController_ setStyle:style]; [overscrollActionsController_ setDelegate:overscrollActionsControllerDelegate]; - overscrollActionsControllerDelegate_.reset( - overscrollActionsControllerDelegate); + overscrollActionsControllerDelegate_ = overscrollActionsControllerDelegate; } - (void)saveTitleToHistoryDB { @@ -885,8 +831,9 @@ // Don't update the history if current entry has no title. NSString* title = [self title]; if (![title length] || - [title isEqualToString:l10n_util::GetNSString(IDS_DEFAULT_TAB_TITLE)]) + [title isEqualToString:l10n_util::GetNSString(IDS_DEFAULT_TAB_TITLE)]) { return; + } history::HistoryService* historyService = ios::HistoryServiceFactory::GetForBrowserState( @@ -952,12 +899,12 @@ referrer.url != GURL(kChromeContentSuggestionsReferrer); history::HistoryAddPageArgs args( - url, item->GetTimestamp(), tabHistoryContext_.get(), - item->GetUniqueID(), referrer.url, redirects, item->GetTransitionType(), + url, item->GetTimestamp(), &tabHistoryContext_, item->GetUniqueID(), + referrer.url, redirects, item->GetTransitionType(), history::SOURCE_BROWSED, false, consider_for_ntp_most_visited); addPageVector_.push_back(args); } else { - historyService->AddPage(url, item->GetTimestamp(), tabHistoryContext_.get(), + historyService->AddPage(url, item->GetTimestamp(), &tabHistoryContext_, item->GetUniqueID(), referrer.url, redirects, item->GetTransitionType(), history::SOURCE_BROWSED, false); @@ -1005,7 +952,7 @@ if (!initialNavigation && !isPrerenderTab_ && !PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_RELOAD) && (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) == 0) { - base::RecordAction(UserMetricsAction("MobileTabClobbered")); + base::RecordAction(base::UserMetricsAction("MobileTabClobbered")); } if ([parentTabModel_ tabUsageRecorder]) [parentTabModel_ tabUsageRecorder]->RecordPageLoadStart(self); @@ -1034,9 +981,8 @@ } - (void)webWillReload { - if ([parentTabModel_ tabUsageRecorder]) { + if ([parentTabModel_ tabUsageRecorder]) [parentTabModel_ tabUsageRecorder]->RecordReload(self); - } } // Halt the tab, which amounts to halting its webController. @@ -1054,24 +1000,24 @@ [[NSNotificationCenter defaultCenter] removeObserver:self]; [passwordController_ detach]; - passwordController_.reset(); + passwordController_ = nil; tabInfoBarObserver_.reset(); faviconDriverObserverBridge_.reset(); [openInController_ detachFromWebController]; - openInController_.reset(); + openInController_ = nil; [autofillController_ detachFromWebState]; [suggestionController_ detachFromWebState]; if (fullScreenController_) [self.webController removeObserver:fullScreenController_]; [fullScreenController_ invalidate]; - fullScreenController_.reset(); + fullScreenController_ = nil; if (overscrollActionsController_) [self.webController removeObserver:overscrollActionsController_]; [overscrollActionsController_ invalidate]; - overscrollActionsController_.reset(); + overscrollActionsController_ = nil; [readerModeController_ detachFromWebState]; - readerModeController_.reset(); + readerModeController_ = nil; // Invalidate any snapshot stored for this session. DCHECK(self.tabId); @@ -1100,8 +1046,8 @@ favicon::WebFaviconDriver::FromWebState(self.webState); // Some MockWebContents used in tests do not support the FaviconDriver. if (faviconDriver) { - faviconDriverObserverBridge_.reset( - new FaviconDriverObserverBridge(self, faviconDriver)); + faviconDriverObserverBridge_ = + base::MakeUnique<FaviconDriverObserverBridge>(self, faviconDriver); } } else { faviconDriverObserverBridge_.reset(); @@ -1111,7 +1057,7 @@ - (void)goBack { if (self.navigationManager) { DCHECK(self.navigationManager->CanGoBack()); - base::RecordAction(UserMetricsAction("Back")); + base::RecordAction(base::UserMetricsAction("Back")); self.navigationManager->GoBack(); } } @@ -1119,7 +1065,7 @@ - (void)goForward { if (self.navigationManager) { DCHECK(self.navigationManager->CanGoForward()); - base::RecordAction(UserMetricsAction("Forward")); + base::RecordAction(base::UserMetricsAction("Forward")); self.navigationManager->GoForward(); } } @@ -1147,21 +1093,16 @@ - (BOOL)openExternalURL:(const GURL&)url sourceURL:(const GURL&)sourceURL linkClicked:(BOOL)linkClicked { - if (!externalAppLauncher_.get()) - externalAppLauncher_.reset([[ExternalAppLauncher alloc] init]); - - // This method may release CRWWebController which may cause a crash - // (crbug.com/393949). - [[self.webController retain] autorelease]; + if (!externalAppLauncher_) + externalAppLauncher_ = [[ExternalAppLauncher alloc] init]; // Make a local url copy for possible modification. GURL finalURL = url; // Check if it's a direct FIDO U2F x-callback call. If so, do not open it, to // prevent pages from spoofing requests with different origins. - if (finalURL.SchemeIs("u2f-x-callback")) { + if (finalURL.SchemeIs("u2f-x-callback")) return NO; - } // Block attempts to open this application's settings in the native system // settings application. @@ -1171,9 +1112,8 @@ // Check if it's a FIDO U2F call. if (finalURL.SchemeIs("u2f")) { // Create U2FController object lazily. - if (!U2FController_) { - U2FController_.reset([[U2FController alloc] init]); - } + if (!U2FController_) + U2FController_ = [[U2FController alloc] init]; DCHECK([self navigationManager]); GURL origin = @@ -1185,9 +1125,8 @@ tabURL:self.url tabID:self.tabId]; - if (!finalURL.is_valid()) { + if (!finalURL.is_valid()) return NO; - } } if ([externalAppLauncher_ openURL:finalURL linkClicked:linkClicked]) { @@ -1202,9 +1141,8 @@ if (sourceURL.is_valid()) { ReadingListModel* model = ReadingListModelFactory::GetForBrowserState(browserState_); - if (model && model->loaded()) { + if (model && model->loaded()) model->SetReadStatus(sourceURL, true); - } } return YES; @@ -1215,11 +1153,10 @@ - (void)webState:(web::WebState*)webState didFinishNavigation:(web::NavigationContext*)navigation { if (navigation->IsSameDocument()) { + // Fetch the favicon for the new URL. auto* faviconDriver = favicon::WebFaviconDriver::FromWebState(webState); - if (faviconDriver) { - // Fetch the favicon for the new URL. + if (faviconDriver) faviconDriver->FetchFavicon(navigation->GetUrl()); - } } if (!navigation->IsErrorPage()) { @@ -1250,18 +1187,18 @@ - (OpenInController*)openInController { if (!openInController_) { - openInController_.reset([[OpenInController alloc] + openInController_ = [[OpenInController alloc] initWithRequestContext:browserState_->GetRequestContext() - webController:self.webController]); + webController:self.webController]; } - return openInController_.get(); + return openInController_; } - (id<CRWNativeContent>)controllerForUnhandledContentAtURL:(const GURL&)url { // Shows download manager UI for unhandled content. DownloadManagerController* downloadController = - [[[DownloadManagerController alloc] initWithWebState:self.webState - downloadURL:url] autorelease]; + [[DownloadManagerController alloc] initWithWebState:self.webState + downloadURL:url]; [downloadController start]; return downloadController; } @@ -1294,22 +1231,21 @@ } - (void)countMainFrameLoad { - if ([self isPrerenderTab] || [self url].SchemeIs(kChromeUIScheme)) { + if ([self isPrerenderTab] || [self url].SchemeIs(kChromeUIScheme)) return; - } - base::RecordAction(UserMetricsAction("MobilePageLoaded")); + base::RecordAction(base::UserMetricsAction("MobilePageLoaded")); } - (void)applicationDidBecomeActive { - if (requireReloadAfterBecomingActive_) { - if (visible_) { - self.navigationManager->Reload(web::ReloadType::NORMAL, - false /* check_for_repost */); - } else { - [self.webController requirePageReload]; - } - requireReloadAfterBecomingActive_ = NO; + if (!requireReloadAfterBecomingActive_) + return; + if (visible_) { + self.navigationManager->Reload(web::ReloadType::NORMAL, + false /* check_for_repost */); + } else { + [self.webController requirePageReload]; } + requireReloadAfterBecomingActive_ = NO; } #pragma mark - @@ -1335,10 +1271,6 @@ return self.view; } -- (ReaderModeController*)readerModeController { - return readerModeController_.get(); -} - - (BOOL)canSwitchToReaderMode { // Only if the page is loaded and the page passes suitability checks. ReaderModeController* controller = self.readerModeController; @@ -1416,15 +1348,6 @@ navigationManager->LoadURLWithParams(params); } -- (id<SnapshotOverlayProvider>)snapshotOverlayProvider { - return snapshotOverlayProvider_.get(); -} - -- (void)setSnapshotOverlayProvider: - (id<SnapshotOverlayProvider>)snapshotOverlayProvider { - snapshotOverlayProvider_.reset(snapshotOverlayProvider); -} - - (void)evaluateU2FResultFromURL:(const GURL&)URL { DCHECK(U2FController_); [U2FController_ evaluateU2FResultFromU2FURL:URL webState:self.webState]; @@ -1465,7 +1388,7 @@ // checked in several places. if (isUserNavigationEvent && !isPrerenderTab_ && ![self navigationManager]->GetPendingItem() && url != self.url) { - base::RecordAction(UserMetricsAction("MobileTabClobbered")); + base::RecordAction(base::UserMetricsAction("MobileTabClobbered")); if ([parentTabModel_ tabUsageRecorder]) [parentTabModel_ tabUsageRecorder]->RecordPageLoadStart(self); } @@ -1504,9 +1427,8 @@ } favicon::FaviconDriver* faviconDriver = favicon::WebFaviconDriver::FromWebState(webState); - if (faviconDriver) { + if (faviconDriver) faviconDriver->FetchFavicon(lastCommittedURL); - } [parentTabModel_ notifyTabChanged:self]; if (parentTabModel_) { [[NSNotificationCenter defaultCenter] @@ -1559,9 +1481,8 @@ else [autoReloadBridge_ loadFailedForURL:lastCommittedURL wasPost:wasPost]; [webControllerSnapshotHelper_ setSnapshotCoalescingEnabled:YES]; - if (!loadSuccess) { + if (!loadSuccess) [fullScreenController_ disableFullScreen]; - } [self recordInterfaceOrientation]; navigation_metrics::RecordMainFrameNavigation( lastCommittedURL, true, self.browserState->IsOffTheRecord()); @@ -1590,9 +1511,8 @@ finishPageLoadForTab:self loadSuccess:loadSuccess]; - if (loadSuccess) { + if (loadSuccess) [self updateSnapshotWithOverlay:YES visibleFrameOnly:YES]; - } [webControllerSnapshotHelper_ setSnapshotCoalescingEnabled:NO]; } @@ -1642,9 +1562,9 @@ if (isPrerenderTab_ || self.browserState->IsOffTheRecord()) return NO; - base::scoped_nsprotocol<id<NativeAppMetadata>> metadata( - [[ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager() - nativeAppForURL:url] retain]); + id<NativeAppMetadata> metadata = + [ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager() + nativeAppForURL:url]; if (![metadata shouldAutoOpenLinks]) return NO; @@ -1698,9 +1618,8 @@ // Always allow frame loads. BOOL isFrameLoad = (url != mainDocumentURL); - if (isFrameLoad) { + if (isFrameLoad) return YES; - } // TODO(crbug.com/546402): If this turns out to be useful, find a less hacky // hook point to send this from. @@ -1829,9 +1748,8 @@ } if (visible_) { - if (!applicationIsNotActive) { + if (!applicationIsNotActive) [fullScreenController_ disableFullScreen]; - } } else { [self.webController requirePageReload]; } @@ -1873,8 +1791,8 @@ signin_metrics::LogAccountReconcilorStateOnGaiaResponse( ios::AccountReconcilorFactory::GetForBrowserState(browserState_) ->GetState()); - base::scoped_nsobject<GenericChromeCommand> command( - [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_ACCOUNTS_SETTINGS]); + GenericChromeCommand* command = + [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_ACCOUNTS_SETTINGS]; [self.view chromeExecuteCommand:command]; } @@ -1889,8 +1807,8 @@ signin_metrics::LogAccountReconcilorStateOnGaiaResponse( ios::AccountReconcilorFactory::GetForBrowserState(browserState_) ->GetState()); - base::scoped_nsobject<GenericChromeCommand> command( - [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_ADD_ACCOUNT]); + GenericChromeCommand* command = + [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_ADD_ACCOUNT]; [self.view chromeExecuteCommand:command]; } @@ -1911,17 +1829,17 @@ [self goBack]; if (url.is_valid()) { - base::scoped_nsobject<OpenUrlCommand> command([[OpenUrlCommand alloc] + OpenUrlCommand* command = [[OpenUrlCommand alloc] initWithURL:url referrer:web::Referrer() // Strip referrer when switching modes. inIncognito:YES inBackground:NO - appendTo:kLastTab]); + appendTo:kLastTab]; [self.view chromeExecuteCommand:command]; } else { - base::scoped_nsobject<GenericChromeCommand> chromeCommand( - [[GenericChromeCommand alloc] initWithTag:IDC_NEW_INCOGNITO_TAB]); - [self.view chromeExecuteCommand:chromeCommand]; + GenericChromeCommand* command = + [[GenericChromeCommand alloc] initWithTag:IDC_NEW_INCOGNITO_TAB]; + [self.view chromeExecuteCommand:command]; } } @@ -1937,19 +1855,11 @@ if (browserState_->IsOffTheRecord()) return; DCHECK(!nativeAppNavigationController_); - nativeAppNavigationController_.reset( - [[NativeAppNavigationController alloc] initWithWebState:self.webState]); + nativeAppNavigationController_ = + [[NativeAppNavigationController alloc] initWithWebState:self.webState]; DCHECK(nativeAppNavigationController_); } -- (id<PassKitDialogProvider>)passKitDialogProvider { - return passKitDialogProvider_.get(); -} - -- (void)setPassKitDialogProvider:(id<PassKitDialogProvider>)provider { - passKitDialogProvider_.reset(provider); -} - - (void)wasShown { visible_ = YES; [self updateFullscreenWithToolbarVisible:YES]; @@ -1978,7 +1888,7 @@ @implementation Tab (TestingSupport) - (void)replaceExternalAppLauncher:(id)externalAppLauncher { - externalAppLauncher_.reset([externalAppLauncher retain]); + externalAppLauncher_ = externalAppLauncher; } - (TabModel*)parentTabModel { @@ -1986,7 +1896,7 @@ } - (FormInputAccessoryViewController*)inputAccessoryViewController { - return inputAccessoryViewController_.get(); + return inputAccessoryViewController_; } @end
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn index 42b2a02..49fc3a1 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
@@ -8,12 +8,8 @@ "content_suggestions_article_item.mm", "content_suggestions_footer_item.h", "content_suggestions_footer_item.mm", - "content_suggestions_most_visited.h", - "content_suggestions_most_visited.mm", "content_suggestions_most_visited_item.h", "content_suggestions_most_visited_item.mm", - "content_suggestions_most_visited_tile.h", - "content_suggestions_most_visited_tile.mm", "content_suggestions_reading_list_item.h", "content_suggestions_reading_list_item.mm", "content_suggestions_text_item.h", @@ -40,8 +36,6 @@ "content_suggestions_article_item_unittest.mm", "content_suggestions_footer_item_unittest.mm", "content_suggestions_most_visited_item_unittest.mm", - "content_suggestions_most_visited_tile_unittest.mm", - "content_suggestions_most_visited_unittest.mm", ] deps = [ ":cells",
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.h b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.h deleted file mode 100644 index 1914cc52..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.h +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MOST_VISITED_H_ -#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MOST_VISITED_H_ - -#import <Foundation/Foundation.h> - -@class FaviconAttributes; - -// Object representing a Most Visited suggestion. -@interface ContentSuggestionsMostVisited : NSObject - -// Title of the Most Visited suggestion. -@property(nonatomic, copy, nullable) NSString* title; -// Attributes used to display the favicon of the Most Visited suggestion. -// Setting this to nil displays an empty grey background. -@property(nonatomic, strong, nullable) FaviconAttributes* attributes; - -// Returns a Most Visited with the properties set. -+ (nullable ContentSuggestionsMostVisited*) -mostVisitedWithTitle:(nullable NSString*)title - attributes:(nullable FaviconAttributes*)attributes; - -@end - -#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MOST_VISITED_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.mm deleted file mode 100644 index 122367aa..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.mm +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.h" - -#import "ios/chrome/browser/ui/favicon/favicon_attributes.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation ContentSuggestionsMostVisited - -@synthesize title = _title; -@synthesize attributes = _attributes; - -+ (ContentSuggestionsMostVisited*)mostVisitedWithTitle:(NSString*)title - attributes: - (FaviconAttributes*)attributes { - ContentSuggestionsMostVisited* mostVisited = - [[ContentSuggestionsMostVisited alloc] init]; - mostVisited.title = title; - mostVisited.attributes = attributes; - return mostVisited; -} - -@end
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h index 1808434..f2f7f974 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h
@@ -9,31 +9,33 @@ #import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestion_identifier.h" #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" -@class ContentSuggestionsMostVisited; @class FaviconAttributes; +@class FaviconViewNew; -// Item containing the Most Visited suggestions. +// Item containing a Most Visited suggestion. @interface ContentSuggestionsMostVisitedItem : CollectionViewItem<ContentSuggestionIdentification> -// Most Visited suggestions for this item. -@property(nonatomic, copy, nonnull) - NSArray<ContentSuggestionsMostVisited*>* suggestions; +// Attributes to configure the favicon view. +@property(nonatomic, strong, nonnull) FaviconAttributes* attributes; + +// Text for the title and the accessibility label of the cell. +@property(nonatomic, copy, nonnull) NSString* title; @end -// Associated cell to display the Most Visited suggestions. -// This cell displays the most visited suggestions on two rows, vertically -// stacked. Each row is a horizontal stack of ContentSuggestionsTiles. The -// number of tiles per row depends of the available width. +// Associated cell to display a Most Visited tile based on the suggestion. +// It displays the favicon for this Most Visited suggestion and its title. @interface ContentSuggestionsMostVisitedCell : MDCCollectionViewCell -// Sets the Most Visited suggestions of this cell. -- (void)setSuggestions: - (nonnull NSArray<ContentSuggestionsMostVisited*>*)suggestions; +// FaviconView displaying the favicon. +@property(nonatomic, strong, readonly, nonnull) FaviconViewNew* faviconView; -// Returns the maximum number of tiles per line, limited to 4. -- (NSUInteger)numberOfTilesPerLine; +// Title of the Most Visited. +@property(nonatomic, strong, readonly, nonnull) UILabel* titleLabel; + +// Size for a Most Visited tile. ++ (CGSize)defaultSize; @end
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.mm index bdad43a9..0e121d4 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.mm
@@ -4,21 +4,23 @@ #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h" -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.h" -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile.h" #import "ios/chrome/browser/ui/favicon/favicon_attributes.h" #import "ios/chrome/browser/ui/favicon/favicon_view.h" -#include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" -#include "url/gurl.h" +#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif namespace { -const CGFloat kSpacingIPhone = 16; -const CGFloat kSpacingIPad = 24; +const CGFloat kLabelTextColor = 0.314; +const NSInteger kLabelNumLines = 2; +const CGFloat kFaviconSize = 48; +const CGFloat kSpaceFaviconTitle = 10; + +// Size of a Most Visited cell. +const CGSize kCellSize = {73, 100}; } #pragma mark - ContentSuggestionsMostVisitedItem @@ -26,7 +28,8 @@ @implementation ContentSuggestionsMostVisitedItem @synthesize suggestionIdentifier = _suggestionIdentifier; -@synthesize suggestions = _suggestions; +@synthesize attributes = _attributes; +@synthesize title = _title; - (instancetype)initWithType:(NSInteger)type { self = [super initWithType:type]; @@ -38,173 +41,66 @@ - (void)configureCell:(ContentSuggestionsMostVisitedCell*)cell { [super configureCell:cell]; - [cell setSuggestions:self.suggestions]; + cell.titleLabel.text = self.title; + cell.accessibilityLabel = self.title; + [cell.faviconView configureWithAttributes:self.attributes]; } @end #pragma mark - ContentSuggestionsMostVisitedCell -@interface ContentSuggestionsMostVisitedCell () - -// The Most Visited tiles to be displayed. -@property(nonatomic, strong) - NSMutableArray<ContentSuggestionsMostVisitedTile*>* tiles; - -// The first line of Most Visited tiles. -@property(nonatomic, strong) UIStackView* firstLine; - -// The second line of Most Visited tiles, displayed below the first one. -@property(nonatomic, strong) UIStackView* secondLine; - -// Contains both stack views. -@property(nonatomic, copy) NSArray<UIStackView*>* stackViews; - -// Superview for the stack views, used to center them. -@property(nonatomic, strong) UIView* stackContainer; - -// Width of the |stackContainer|, allowing resizing. -@property(nonatomic, strong) NSLayoutConstraint* containerWidth; - -// Number of tiles per line during the previous layout. -@property(nonatomic, assign) NSUInteger previousNumberOfTilesPerLine; - -@end - @implementation ContentSuggestionsMostVisitedCell : MDCCollectionViewCell -@synthesize tiles = _tiles; -@synthesize firstLine = _firstLine; -@synthesize secondLine = _secondLine; -@synthesize stackViews = _stackViews; -@synthesize stackContainer = _stackContainer; -@synthesize containerWidth = _containerWidth; -@synthesize previousNumberOfTilesPerLine = _previousNumberOfTilesPerLine; +@synthesize faviconView = _faviconView; +@synthesize titleLabel = _titleLabel; #pragma mark - Public - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - _tiles = [NSMutableArray array]; - _firstLine = [[UIStackView alloc] init]; - _secondLine = [[UIStackView alloc] init]; - _stackViews = @[ _firstLine, _secondLine ]; - _stackContainer = [[UIView alloc] init]; - _previousNumberOfTilesPerLine = 0; + _titleLabel = [[UILabel alloc] init]; + _titleLabel.textColor = [UIColor colorWithWhite:kLabelTextColor alpha:1.0]; + _titleLabel.font = [MDCTypography captionFont]; + _titleLabel.textAlignment = NSTextAlignmentCenter; + _titleLabel.preferredMaxLayoutWidth = [[self class] defaultSize].width; + _titleLabel.numberOfLines = kLabelNumLines; - for (UIStackView* row in self.stackViews) { - row.axis = UILayoutConstraintAxisHorizontal; - row.spacing = [self spacing]; - row.translatesAutoresizingMaskIntoConstraints = NO; - [_stackContainer addSubview:row]; - row.layoutMarginsRelativeArrangement = YES; - } + _faviconView = [[FaviconViewNew alloc] init]; + _faviconView.font = [MDCTypography headlineFont]; - _stackContainer.translatesAutoresizingMaskIntoConstraints = NO; + _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; + _faviconView.translatesAutoresizingMaskIntoConstraints = NO; - [self.contentView addSubview:_stackContainer]; + [self addSubview:_titleLabel]; + [self addSubview:_faviconView]; - [_stackContainer.centerXAnchor - constraintEqualToAnchor:self.contentView.centerXAnchor] - .active = YES; - _containerWidth = [_stackContainer.widthAnchor constraintEqualToConstant:0]; - _containerWidth.active = YES; + [NSLayoutConstraint activateConstraints:@[ + [_faviconView.widthAnchor constraintEqualToConstant:kFaviconSize], + [_faviconView.heightAnchor + constraintEqualToAnchor:_faviconView.widthAnchor], + [_faviconView.centerXAnchor + constraintEqualToAnchor:_titleLabel.centerXAnchor], + ]]; - ApplyVisualConstraints(@[ @"V:|[container]|" ], - @{ @"container" : _stackContainer }); - ApplyVisualConstraints( - @[ - @"V:|[first][second]|", @"H:|[first]-(>=0)-|", - @"H:|[second]-(>=0)-|" - ], - @{ @"first" : _firstLine, - @"second" : _secondLine }); + ApplyVisualConstraintsWithMetrics( + @[ @"V:|[favicon]-(space)-[title]", @"H:|[title]|" ], + @{ @"favicon" : _faviconView, + @"title" : _titleLabel }, + @{ @"space" : @(kSpaceFaviconTitle) }); + + self.isAccessibilityElement = YES; } return self; } -- (void)setSuggestions:(NSArray<ContentSuggestionsMostVisited*>*)suggestions { - [self.tiles removeAllObjects]; - for (ContentSuggestionsMostVisited* suggestion in suggestions) { - [self.tiles addObject:[ContentSuggestionsMostVisitedTile - tileWithTitle:suggestion.title - attributes:suggestion.attributes]]; - } ++ (CGSize)defaultSize { + return kCellSize; } -- (NSUInteger)numberOfTilesPerLine { - CGFloat availableWidth = self.contentView.bounds.size.width; - - if (availableWidth > [self widthForNumberOfItem:4]) - return 4; - if (availableWidth > [self widthForNumberOfItem:3]) - return 3; - if (availableWidth > [self widthForNumberOfItem:2]) - return 2; - - NOTREACHED(); - return 2; -} - -#pragma mark - UIView - -// Implements -layoutSubviews as per instructions in documentation for -// +[MDCCollectionViewCell cr_preferredHeightForWidth:forItem:]. -- (void)layoutSubviews { - [super layoutSubviews]; - - [self applyLayout]; - - [super layoutSubviews]; -} - -#pragma mark - Private - -// Layouts the tiles. The view is modified only if the number of tiles per line -// changes. -- (void)applyLayout { - NSUInteger numberOfTilesPerLine = [self numberOfTilesPerLine]; - - if (numberOfTilesPerLine == self.previousNumberOfTilesPerLine) { - return; - } - self.previousNumberOfTilesPerLine = numberOfTilesPerLine; - - for (UIStackView* row in self.stackViews) { - while (row.arrangedSubviews.count > 0) { - UIView* view = row.arrangedSubviews.firstObject; - [row removeArrangedSubview:view]; - [view removeFromSuperview]; - } - } - - NSUInteger numberOfTilesFirstLine = - MIN(numberOfTilesPerLine, self.tiles.count); - for (NSUInteger i = 0; i < numberOfTilesFirstLine; i++) { - [self.firstLine addArrangedSubview:self.tiles[i]]; - } - if (self.tiles.count > numberOfTilesPerLine) { - NSUInteger totalNumberOfTiles = - MIN(2 * numberOfTilesPerLine, self.tiles.count); - for (NSUInteger i = numberOfTilesPerLine; i < totalNumberOfTiles; i++) { - [self.secondLine addArrangedSubview:self.tiles[i]]; - } - } - - self.containerWidth.constant = - [self widthForNumberOfItem:numberOfTilesPerLine]; -} - -// Returns the spacing between tiles, based on the device. -- (CGFloat)spacing { - return IsIPadIdiom() ? kSpacingIPad : kSpacingIPhone; -} - -// Returns the width necessary to fit |numberOfItem| items. -- (CGFloat)widthForNumberOfItem:(NSUInteger)numberOfItem { - return (numberOfItem - 1) * [self spacing] + - numberOfItem * [ContentSuggestionsMostVisitedTile width]; +- (CGSize)intrinsicContentSize { + return [[self class] defaultSize]; } @end
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item_unittest.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item_unittest.mm index 50a147c..40357305 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item_unittest.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item_unittest.mm
@@ -4,8 +4,12 @@ #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h" +#import "ios/chrome/browser/ui/favicon/favicon_attributes.h" +#import "ios/chrome/browser/ui/favicon/favicon_view.h" #include "ios/chrome/browser/ui/ui_util.h" #include "testing/gtest/include/gtest/gtest.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#import "third_party/ocmock/gtest_support.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -13,7 +17,7 @@ namespace { -TEST(ContentSuggestionsMostVisitedItemTest, Configure) { +TEST(ContentSuggestionsMostVisitedItemTest, CellClass) { // Setup. ContentSuggestionsMostVisitedItem* item = [[ContentSuggestionsMostVisitedItem alloc] initWithType:0]; @@ -25,57 +29,25 @@ ASSERT_EQ([ContentSuggestionsMostVisitedCell class], [cell class]); } -TEST(ContentSuggestionsMostVisitedItemTest, SizeIPhone6) { +TEST(ContentSuggestionsMostVisitedItemTest, Configure) { // Setup. - if (IsIPadIdiom()) - return; + NSString* title = @"Test title."; + ContentSuggestionsMostVisitedItem* item = + [[ContentSuggestionsMostVisitedItem alloc] initWithType:0]; + item.title = title; + item.attributes = + [FaviconAttributes attributesWithMonogram:@"C" + textColor:[UIColor whiteColor] + backgroundColor:[UIColor blackColor]]; + ContentSuggestionsMostVisitedCell* cell = [[[item cellClass] alloc] init]; + id faviconViewMock = OCMPartialMock(cell.faviconView); + OCMExpect([faviconViewMock configureWithAttributes:item.attributes]); - ContentSuggestionsMostVisitedCell* cell = - [[ContentSuggestionsMostVisitedCell alloc] init]; - cell.frame = CGRectMake(0, 0, 360, 0); - [cell layoutIfNeeded]; + // Action. + [item configureCell:cell]; // Test. - EXPECT_EQ(4U, [cell numberOfTilesPerLine]); -} - -TEST(ContentSuggestionsMostVisitedItemTest, SizeIPhone5) { - // Setup. - if (IsIPadIdiom()) - return; - - ContentSuggestionsMostVisitedCell* cell = - [[ContentSuggestionsMostVisitedCell alloc] init]; - cell.frame = CGRectMake(0, 0, 320, 0); - [cell layoutIfNeeded]; - - // Test. - EXPECT_EQ(3U, [cell numberOfTilesPerLine]); -} - -// Test for iPad portrait and iPhone landscape. -TEST(ContentSuggestionsMostVisitedItemTest, SizeLarge) { - // Setup. - ContentSuggestionsMostVisitedCell* cell = - [[ContentSuggestionsMostVisitedCell alloc] init]; - cell.frame = CGRectMake(0, 0, 720, 0); - [cell layoutIfNeeded]; - - // Test. - EXPECT_EQ(4U, [cell numberOfTilesPerLine]); -} - -TEST(ContentSuggestionsMostVisitedItemTest, SizeIPadSplit) { - // Setup. - if (!IsIPadIdiom()) - return; - - ContentSuggestionsMostVisitedCell* cell = - [[ContentSuggestionsMostVisitedCell alloc] init]; - cell.frame = CGRectMake(0, 0, 360, 0); - [cell layoutIfNeeded]; - - // Test. - EXPECT_EQ(3U, [cell numberOfTilesPerLine]); + ASSERT_EQ(title, cell.titleLabel.text); + ASSERT_OCMOCK_VERIFY(faviconViewMock); } }
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile.h b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile.h deleted file mode 100644 index 478245df..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MOST_VISITED_TILE_H_ -#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MOST_VISITED_TILE_H_ - -#import <UIKit/UIKit.h> - -@class FaviconAttributes; -@class FaviconViewNew; - -// View used to display a Most Visited tile. -@interface ContentSuggestionsMostVisitedTile : UIView - -// Width of a Most Visited tile. -+ (CGFloat)width; - -// Creates a tile with a |title| and its favicon view configured with -// |attributes|. -+ (nullable ContentSuggestionsMostVisitedTile*) -tileWithTitle:(nullable NSString*)title - attributes:(nullable FaviconAttributes*)attributes; - -// FaviconView displaying the favicon. -@property(nonatomic, strong, readonly, nonnull) FaviconViewNew* faviconView; - -// Sets the text and the accessibility label of this view. -- (void)setTitle:(nullable NSString*)title; - -@end - -#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MOST_VISITED_TILE_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile.mm deleted file mode 100644 index 2ba638c..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile.mm +++ /dev/null
@@ -1,99 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile.h" - -#import "ios/chrome/browser/ui/favicon/favicon_attributes.h" -#import "ios/chrome/browser/ui/favicon/favicon_view.h" -#import "ios/chrome/browser/ui/uikit_ui_util.h" -#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -const CGFloat kLabelTextColor = 0.314; -const NSInteger kLabelNumLines = 2; -const CGFloat kFaviconSize = 48; -const CGFloat kSpaceFaviconTitle = 10; - -// Size of the tile. -const CGFloat kWidth = 73; -const CGFloat kHeight = 100; -} - -@interface ContentSuggestionsMostVisitedTile () - -@property(nonatomic, strong) UILabel* titleLabel; - -@end - -@implementation ContentSuggestionsMostVisitedTile - -@synthesize titleLabel = _titleLabel; -@synthesize faviconView = _faviconView; - -+ (CGFloat)width { - return kWidth; -} - -+ (ContentSuggestionsMostVisitedTile*)tileWithTitle:(NSString*)title - attributes: - (FaviconAttributes*)attributes { - ContentSuggestionsMostVisitedTile* tile = - [[ContentSuggestionsMostVisitedTile alloc] init]; - [tile.faviconView configureWithAttributes:attributes]; - [tile setTitle:title]; - return tile; -} - -- (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - _titleLabel = [[UILabel alloc] init]; - _titleLabel.textColor = [UIColor colorWithWhite:kLabelTextColor alpha:1.0]; - _titleLabel.font = [MDCTypography captionFont]; - _titleLabel.textAlignment = NSTextAlignmentCenter; - _titleLabel.preferredMaxLayoutWidth = [[self class] width]; - _titleLabel.numberOfLines = kLabelNumLines; - - _faviconView = [[FaviconViewNew alloc] init]; - _faviconView.font = [MDCTypography headlineFont]; - - _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; - _faviconView.translatesAutoresizingMaskIntoConstraints = NO; - - [self addSubview:_titleLabel]; - [self addSubview:_faviconView]; - - [NSLayoutConstraint activateConstraints:@[ - [_faviconView.widthAnchor constraintEqualToConstant:kFaviconSize], - [_faviconView.heightAnchor - constraintEqualToAnchor:_faviconView.widthAnchor], - [_faviconView.centerXAnchor - constraintEqualToAnchor:_titleLabel.centerXAnchor], - ]]; - - ApplyVisualConstraintsWithMetrics( - @[ @"V:|[favicon]-(space)-[title]", @"H:|[title]|" ], - @{ @"favicon" : _faviconView, - @"title" : _titleLabel }, - @{ @"space" : @(kSpaceFaviconTitle) }); - - self.isAccessibilityElement = YES; - } - return self; -} - -- (void)setTitle:(NSString*)title { - self.titleLabel.text = title; - self.accessibilityLabel = title; -} - -- (CGSize)intrinsicContentSize { - return CGSizeMake(kWidth, kHeight); -} - -@end
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile_unittest.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile_unittest.mm deleted file mode 100644 index 8ad6eb02..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile_unittest.mm +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile.h" - -#include "testing/gtest/include/gtest/gtest.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -TEST(ContentSuggestionsMostVisitedTileTest, Constructor) { - NSString* title = @"Test title"; - ContentSuggestionsMostVisitedTile* tile = - [ContentSuggestionsMostVisitedTile tileWithTitle:title attributes:nil]; - - ASSERT_TRUE([title isEqualToString:tile.accessibilityLabel]); -} -}
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_unittest.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_unittest.mm deleted file mode 100644 index a8f4ac3..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_unittest.mm +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.h" - -#import "ios/chrome/browser/ui/favicon/favicon_attributes.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -TEST(ContentSuggestionsMostVisitedTest, Constructor) { - NSString* title = @"Test title"; - FaviconAttributes* attributes = - [[FaviconAttributes alloc] initWithImage:[[UIImage alloc] init]]; - ContentSuggestionsMostVisited* mostVisited = - [ContentSuggestionsMostVisited mostVisitedWithTitle:title - attributes:attributes]; - - ASSERT_TRUE([title isEqualToString:mostVisited.title]); - ASSERT_EQ(attributes, mostVisited.attributes); -} -}
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm index cc7a811..a682c7c0 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
@@ -14,7 +14,6 @@ #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.h" -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_text_item.h" @@ -238,9 +237,6 @@ return [NSArray array]; } - NSMutableArray<ContentSuggestionsMostVisited*>* mostVisitedToAdd = - [NSMutableArray array]; - CSCollectionViewModel* model = self.collectionViewController.collectionViewModel; NSMutableArray<NSIndexPath*>* indexPaths = [NSMutableArray array]; @@ -293,37 +289,18 @@ break; } case ContentSuggestionTypeMostVisited: { - NSInteger section = - [model sectionForSectionIdentifier:SectionIdentifierMostVisited]; - NSIndexPath* indexPath = - [NSIndexPath indexPathForItem:0 inSection:section]; - - if ([model numberOfItemsInSection:section] == 0) { - [model addItem:[[ContentSuggestionsMostVisitedItem alloc] - initWithType:ItemTypeMostVisited] - toSectionWithIdentifier:SectionIdentifierMostVisited]; - [indexPaths addObject:indexPath]; - } - - ContentSuggestionsMostVisited* mostVisited = - [ContentSuggestionsMostVisited mostVisitedWithTitle:suggestion.title - attributes:nil]; - [mostVisitedToAdd addObject:mostVisited]; + ContentSuggestionsMostVisitedItem* mostVisitedItem = + [[ContentSuggestionsMostVisitedItem alloc] + initWithType:ItemTypeMostVisited]; + mostVisitedItem.title = suggestion.title; + [model addItem:mostVisitedItem + toSectionWithIdentifier:SectionIdentifierMostVisited]; + [indexPaths addObject:indexPath]; break; } } } - if ([model hasSectionForSectionIdentifier:SectionIdentifierMostVisited]) { - NSInteger section = - [model sectionForSectionIdentifier:SectionIdentifierMostVisited]; - NSIndexPath* indexPath = [NSIndexPath indexPathForItem:0 inSection:section]; - ContentSuggestionsMostVisitedItem* item = - base::mac::ObjCCast<ContentSuggestionsMostVisitedItem>( - [model itemAtIndexPath:indexPath]); - item.suggestions = mostVisitedToAdd; - } - return indexPaths; }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index c232f4b..80370081 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2025,7 +2025,7 @@ ] } ], - "PasswordProtectionLowReputationPing": [ + "PasswordProtectionPasswordFieldOnFocusPing": [ { "platforms": [ "chromeos", @@ -2042,7 +2042,7 @@ "incognito": "false" }, "enable_features": [ - "LowReputationPinging" + "PasswordFieldOnFocusPinging" ] } ] @@ -2113,46 +2113,40 @@ ], "experiments": [ { - "name": "ModalGestureEnabled", - "params": { - "require_gesture": "true" - }, + "name": "BlockPromptsEnabled", "enable_features": [ - "ModalPermissionPrompts" - ], - "disable_features": [ - "DisplayPersistenceToggleInPermissionPrompts" + "BlockPromptsIfDismissedOften" ] - }, + } + ] + } + ], + "PermissionPromptUIAndroidModal": [ + { + "platforms": [ + "android" + ], + "experiments": [ { - "name": "ModalNoGestureEnabled", - "params": { - "require_gesture": "false" - }, - "enable_features": [ - "ModalPermissionPrompts" - ], - "disable_features": [ - "DisplayPersistenceToggleInPermissionPrompts" - ] - }, - { - "name": "ModalAndToggleEnabled", - "params": { - "require_gesture": "false" - }, + "name": "ModalToggleEnabled", "enable_features": [ "DisplayPersistenceToggleInPermissionPrompts", "ModalPermissionPrompts" ] - }, + } + ] + } + ], + "PermissionPromptUICocoa": [ + { + "platforms": [ + "mac" + ], + "experiments": [ { - "name": "ToggleEnabled", + "name": "BlockPromptsEnabled", "enable_features": [ - "DisplayPersistenceToggleInPermissionPrompts" - ], - "disable_features": [ - "ModalPermissionPrompts" + "BlockPromptsIfDismissedOften" ] } ] @@ -2167,9 +2161,9 @@ ], "experiments": [ { - "name": "ToggleEnabled", + "name": "BlockPromptsEnabled", "enable_features": [ - "DisplayPersistenceToggleInPermissionPrompts" + "BlockPromptsIfDismissedOften" ] } ]
diff --git a/third_party/WebKit/LayoutTests/accessibility/aom.html b/third_party/WebKit/LayoutTests/accessibility/aom.html index 46c1043..cc22ccc5 100644 --- a/third_party/WebKit/LayoutTests/accessibility/aom.html +++ b/third_party/WebKit/LayoutTests/accessibility/aom.html
@@ -52,21 +52,9 @@ assert_equals(axButton.role, "AXRole: AXCheckBox"); assert_equals(axButton.name, "Check Me"); - assert_equals(aomButton.role, "checkbox"); - assert_equals(aomButton.label, "Check Me"); -}, "ARIA attributes are reflected into AOM properties"); - -test(function(t) { - var button = document.getElementById("button"); - var aomButton = button.accessibleNode; - var axButton = accessibilityController.accessibleElementById("button"); - - button.setAttribute("role", "beyonce"); - - assert_equals(axButton.role, "AXRole: AXButton"); - - assert_equals(aomButton.role, "beyonce"); -}, "Invalid ARIA roles are still reflected into AOM properties"); + assert_equals(aomButton.role, null); + assert_equals(aomButton.label, null); +}, "ARIA attributes are not reflected into AOM properties"); test(function(t) { var button = document.getElementById("button"); @@ -161,14 +149,9 @@ aomButton.role = null; aomButton.label = null; - assert_equals(axButton.role, "AXRole: AXButton"); - assert_equals(axButton.name, "Click Me"); - - button.setAttribute("role", "combobox"); - button.setAttribute("aria-label", "ARIA 2"); - assert_equals(axButton.role, "AXRole: AXButton"); - assert_equals(axButton.name, "Click Me"); -}, "Once an AOM property has been set, ARIA no longer has any effect"); + assert_equals(axButton.role, "AXRole: AXTextField"); + assert_equals(axButton.name, "ARIA"); +}, "Clearing an AOM property falls back on an ARIA attribute"); </script> <button id="button4">Click Me</button> @@ -178,9 +161,9 @@ var aomButton; (function() { var button = document.getElementById("button4"); - button.setAttribute("role", "checkbox"); - button.setAttribute("aria-label", "Check Me"); aomButton = button.accessibleNode; + aomButton.role = "checkbox"; + aomButton.label = "Check Me"; })(); assert_equals(aomButton.role, "checkbox"); assert_equals(aomButton.label, "Check Me");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-001-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-001-expected.txt index 3646c6d..a97e4e5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-001-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-001-expected.txt
@@ -1,20 +1,100 @@ This is a testharness.js-based test. -PASS testConstructor0 -PASS testConstructor1 -FAIL testConstructor2 Failed to construct 'DOMMatrix': Failed to parse '0,0'. -FAIL testConstructor3 Failed to construct 'DOMMatrix': Failed to parse '0,0'. -FAIL testConstructor4 Failed to construct 'DOMMatrix': Failed to parse '2,0,0,0,0,2,0,0,0,0,1,0,10,10,0,1'. -FAIL testConstructor5 Failed to construct 'DOMMatrix': Failed to parse '0,0'. -PASS testConstructor6 -FAIL testConstructor7 float64Array is not defined -FAIL testConstructor8 assert_equals: Expected value for is2D is false expected false but got true -FAIL testConstructor9 Failed to construct 'DOMMatrix': Failed to parse 'scale(2 2) translateX(5) translateY(5)'. -FAIL testConstructor10 Failed to construct 'DOMMatrix': Failed to parse 'scale(2, 2), translateX(5) ,translateY(5)'. -FAIL testConstructor11 assert_throws: function "function () { new DOMMatrix('scale(2)translateX(5px)'); }" did not throw -PASS testConstructor12 -PASS testConstructor13 -FAIL testConstructorIllegal0 assert_throws: function "function () { new DOMMatrixReadOnly(); }" did not throw -FAIL testConstructorIllegal1 assert_throws: function "function () { new DOMMatrixReadOnly(string); }" threw object "SyntaxError: Failed to construct 'DOMMatrixReadOnly': Failed to parse 'scale(2, 2), translateX(5px) translateY(5px)'." ("SyntaxError") expected object "TypeError" ("TypeError") -PASS testConstructorIllegal2 +Found 96 tests; 76 PASS, 20 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS new DOMMatrix() +FAIL new DOMMatrix(undefined) Failed to construct 'DOMMatrix': Failed to parse 'undefined'. +PASS new DOMMatrix(new DOMMatrix()) +PASS new DOMMatrix("none") +PASS new DOMMatrix(" none") +PASS new DOMMatrix("none ") +PASS new DOMMatrix("NONE") +PASS new DOMMatrix("none/**/") +PASS new DOMMatrix("/**/none") +PASS new DOMMatrix("") +FAIL new DOMMatrix(float32Array) 16 elements Failed to construct 'DOMMatrix': Failed to parse '0,0'. +FAIL new DOMMatrix(float32Array) 6 elements Failed to construct 'DOMMatrix': Failed to parse '0,0'. +FAIL new DOMMatrix(float64Array) 16 elements Failed to construct 'DOMMatrix': Failed to parse '2,0,0,0,0,2,0,0,0,0,1,0,10,10,0,1'. +FAIL new DOMMatrix((float64Array) 6 elements Failed to construct 'DOMMatrix': Failed to parse '0,0'. +PASS new DOMMatrix(sequence) 16 elements +FAIL new DOMMatrix(sequence) 6 elements assert_equals: Expected value for is2D is false expected false but got true +FAIL new DOMMatrix("scale(2) translateX(5px) translateY(5px)") assert_equals: Expected value for is2D is false expected false but got true +FAIL new DOMMatrix("scale(2 2) translateX(5) translateY(5)") Failed to construct 'DOMMatrix': Failed to parse 'scale(2 2) translateX(5) translateY(5)'. +FAIL new DOMMatrix("scale(2, 2), translateX(5) ,translateY(5)") Failed to construct 'DOMMatrix': Failed to parse 'scale(2, 2), translateX(5) ,translateY(5)'. +PASS new DOMMatrix("translateX (5px)") +FAIL new DOMMatrix("scale(2)translateX(5px)") assert_throws: function "function () { new self[constr](string); }" did not throw +PASS new DOMMatrix("translateX(5em)") +PASS new DOMMatrix("translateX(5ex)") +PASS new DOMMatrix("translateX(5ch)") +PASS new DOMMatrix("translateX(5rem)") +PASS new DOMMatrix("translateX(5vw)") +PASS new DOMMatrix("translateX(5vh)") +PASS new DOMMatrix("translateX(5vmin)") +PASS new DOMMatrix("translateX(5vmax)") +PASS new DOMMatrix("translateX(5%)") +PASS new DOMMatrix(" ") +PASS new DOMMatrix("/**/") +PASS new DOMMatrix("\0") +PASS new DOMMatrix(";") +PASS new DOMMatrix("none;") +PASS new DOMMatrix("null") +PASS new DOMMatrix(null) +PASS new DOMMatrix("undefined") +PASS new DOMMatrix("inherit") +PASS new DOMMatrix("initial") +PASS new DOMMatrix("unset") +PASS new DOMMatrix(sequence) +PASS new DOMMatrix(matrix) +PASS new DOMMatrix("scale(2, 2), translateX(5px) translateY(5px)") +PASS new DOMMatrix(sequence) 17 elements +PASS new DOMMatrix(sequence) 15 elements +PASS new DOMMatrix(sequence) 5 elements +PASS new DOMMatrix(sequence) 0 elements +PASS new DOMMatrixReadOnly() +FAIL new DOMMatrixReadOnly(undefined) Failed to construct 'DOMMatrixReadOnly': Failed to parse 'undefined'. +PASS new DOMMatrixReadOnly(new DOMMatrixReadOnly()) +PASS new DOMMatrixReadOnly("none") +PASS new DOMMatrixReadOnly(" none") +PASS new DOMMatrixReadOnly("none ") +PASS new DOMMatrixReadOnly("NONE") +PASS new DOMMatrixReadOnly("none/**/") +PASS new DOMMatrixReadOnly("/**/none") +PASS new DOMMatrixReadOnly("") +FAIL new DOMMatrixReadOnly(float32Array) 16 elements Failed to construct 'DOMMatrixReadOnly': Failed to parse '0,0'. +FAIL new DOMMatrixReadOnly(float32Array) 6 elements Failed to construct 'DOMMatrixReadOnly': Failed to parse '0,0'. +FAIL new DOMMatrixReadOnly(float64Array) 16 elements Failed to construct 'DOMMatrixReadOnly': Failed to parse '2,0,0,0,0,2,0,0,0,0,1,0,10,10,0,1'. +FAIL new DOMMatrixReadOnly((float64Array) 6 elements Failed to construct 'DOMMatrixReadOnly': Failed to parse '0,0'. +PASS new DOMMatrixReadOnly(sequence) 16 elements +FAIL new DOMMatrixReadOnly(sequence) 6 elements assert_equals: Expected value for is2D is false expected false but got true +FAIL new DOMMatrixReadOnly("scale(2) translateX(5px) translateY(5px)") assert_equals: Expected value for is2D is false expected false but got true +FAIL new DOMMatrixReadOnly("scale(2 2) translateX(5) translateY(5)") Failed to construct 'DOMMatrixReadOnly': Failed to parse 'scale(2 2) translateX(5) translateY(5)'. +FAIL new DOMMatrixReadOnly("scale(2, 2), translateX(5) ,translateY(5)") Failed to construct 'DOMMatrixReadOnly': Failed to parse 'scale(2, 2), translateX(5) ,translateY(5)'. +PASS new DOMMatrixReadOnly("translateX (5px)") +FAIL new DOMMatrixReadOnly("scale(2)translateX(5px)") assert_throws: function "function () { new self[constr](string); }" did not throw +PASS new DOMMatrixReadOnly("translateX(5em)") +PASS new DOMMatrixReadOnly("translateX(5ex)") +PASS new DOMMatrixReadOnly("translateX(5ch)") +PASS new DOMMatrixReadOnly("translateX(5rem)") +PASS new DOMMatrixReadOnly("translateX(5vw)") +PASS new DOMMatrixReadOnly("translateX(5vh)") +PASS new DOMMatrixReadOnly("translateX(5vmin)") +PASS new DOMMatrixReadOnly("translateX(5vmax)") +PASS new DOMMatrixReadOnly("translateX(5%)") +PASS new DOMMatrixReadOnly(" ") +PASS new DOMMatrixReadOnly("/**/") +PASS new DOMMatrixReadOnly("\0") +PASS new DOMMatrixReadOnly(";") +PASS new DOMMatrixReadOnly("none;") +PASS new DOMMatrixReadOnly("null") +PASS new DOMMatrixReadOnly(null) +PASS new DOMMatrixReadOnly("undefined") +PASS new DOMMatrixReadOnly("inherit") +PASS new DOMMatrixReadOnly("initial") +PASS new DOMMatrixReadOnly("unset") +PASS new DOMMatrixReadOnly(sequence) +PASS new DOMMatrixReadOnly(matrix) +PASS new DOMMatrixReadOnly("scale(2, 2), translateX(5px) translateY(5px)") +PASS new DOMMatrixReadOnly(sequence) 17 elements +PASS new DOMMatrixReadOnly(sequence) 15 elements +PASS new DOMMatrixReadOnly(sequence) 5 elements +PASS new DOMMatrixReadOnly(sequence) 0 elements Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-001.html index c054e89..1ff5a9b9 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-001.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-001.html
@@ -3,18 +3,17 @@ <head> <title>Geometry Interfaces: DOMMatrix and DOMMatrixReadOnly constructors</title> <link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com" /> - <link rel="help" href="http://www.w3.org/TR/geometry-1/#DOMMatrix"> - <link rel="help" href="http://www.w3.org/TR/geometry-1/#dommatrix-constructors"> - <link rel="help" href="http://www.w3.org/TR/geometry-1/#dom-dommatrix-dommatrix"> + <link rel="help" href="https://drafts.fxtf.org/geometry/#DOMMatrix"> + <link rel="help" href="https://drafts.fxtf.org/geometry/#dommatrix-constructors"> + <link rel="help" href="https://drafts.fxtf.org/geometry/#dom-dommatrix-dommatrix"> <script src="support/dommatrix-test-util.js"></script> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> <body> - <p>Test DOMMatrix and DOMMatrixReadOnly contructors</p> <div id="log"></div> <script> - initial = { + var initial = { m11: 1, m21: 0, m31: 0, m41: 0, m12: 0, m22: 1, m32: 0, m42: 0, m13: 0, m23: 0, m33: 1, m43: 0, @@ -22,7 +21,7 @@ is2D: true, isIdentity: true }; - scaleTranslate2D = { + var scaleTranslate2D = { m11: 2, m21: 0, m31: 0, m41: 10, m12: 0, m22: 2, m32: 0, m42: 10, m13: 0, m23: 0, m33: 1, m43: 0, @@ -30,116 +29,165 @@ is2D: false, isIdentity: false }; + ["DOMMatrix", "DOMMatrixReadOnly"].forEach(function(constr) { + test(function() { + checkDOMMatrix(new self[constr](), initial); + }, `new ${constr}()`); - test(function() { - checkDOMMatrix(new DOMMatrix(), initial); - },'testConstructor0'); - test(function() { - checkDOMMatrix(new DOMMatrix(new DOMMatrix()), initial); - },'testConstructor1'); - test(function() { - var float32Array = new Float32Array( - 2.0, 0.0, 0.0, 0.0, - 0.0, 2.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 10.0, 10.0, 0.0, 1.0); - checkDOMMatrix(new DOMMatrix(float32Array), scaleTranslate2D, false); - },'testConstructor2'); - test(function() { - var float32Array = new Float32Array(2.0, 0.0, 0.0, 2.0, 10.0, 10.0); - checkDOMMatrix(new DOMMatrix(float32Array), scaleTranslate2D); - },'testConstructor3'); - test(function() { - var float64Array = new Float64Array([ - 2.0, 0.0, 0.0, 0.0, - 0.0, 2.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 10.0, 10.0, 0.0, 1.0]); - checkDOMMatrix(new DOMMatrix(float64Array), scaleTranslate2D, false); - },'testConstructor4'); - test(function() { - var float64Array = new Float64Array(2.0, 0.0, 0.0, 2.0, 10.0, 10.0); - checkDOMMatrix(new DOMMatrix(float64Array), scaleTranslate2D); - },'testConstructor5'); - test(function() { - var sequence = [ - 2.0, 0.0, 0.0, 0.0, - 0.0, 2.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 10.0, 10.0, 0.0, 1.0]; - checkDOMMatrix(new DOMMatrix(sequence), scaleTranslate2D, false); - },'testConstructor6'); - test(function() { - var sequence = [ 2.0, 0.0, 0.0, 2.0, 10.0, 10.0]; - checkDOMMatrix(new DOMMatrix(float64Array), scaleTranslate2D); - },'testConstructor7'); - test(function() { - var string = 'scale(2) translateX(5px) translateY(5px)'; - checkDOMMatrix(new DOMMatrix(string), scaleTranslate2D); - },'testConstructor8'); - test(function() { - var string = 'scale(2 2) translateX(5) translateY(5)'; - checkDOMMatrix(new DOMMatrix(string), scaleTranslate2D); - },'testConstructor9'); - test(function() { - var string = 'scale(2, 2), translateX(5) ,translateY(5)'; - checkDOMMatrix(new DOMMatrix(string), scaleTranslate2D); - },'testConstructor10'); - test(function() { - assert_throws('SyntaxError', function() { new DOMMatrix('translateX (5px)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('scale(2)translateX(5px)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('translateX(5em)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('translateX(5ex)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('translateX(5ch)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('translateX(5rem)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('translateX(5vw)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('translateX(5vh)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('translateX(5vmin)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('translateX(5vmax)'); }); - assert_throws('SyntaxError', function() { new DOMMatrix('translateX(5%)'); }); - },'testConstructor11'); - test(function() { - var sequence = [ - 2.0, 1.0, 0.0, 0.0, - 1.0, 2.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 10.0, 10.0, 0.0, 1.0]; - checkDOMMatrix(new DOMMatrix(sequence), { - m11: 2, m21: 1, m31: 0, m41: 10, - m12: 1, m22: 2, m32: 0, m42: 10, - m13: 0, m23: 0, m33: 1, m43: 0, - m14: 0, m24: 0, m34: 0, m44: 1, - is2D: false, - isIdentity: false + test(function() { + checkDOMMatrix(new self[constr](undefined), initial); + }, `new ${constr}(undefined)`); + + test(function() { + checkDOMMatrix(new self[constr](new self[constr]()), initial); + }, `new ${constr}(new ${constr}())`); + + ['none', + ' none', + 'none ', + 'NONE', + 'none/**/', + '/**/none', + '', + ].forEach(function(string) { + test(function() { + checkDOMMatrix(new self[constr](string), initial); + }, `new ${constr}(${format_value(string)})`); }); - },'testConstructor12'); - test(function() { - var matrix = new DOMMatrix([ - 2.0, 1.0, 0.0, 0.0, - 1.0, 2.0, 0.0, 0.0, + + test(function() { + var float32Array = new Float32Array( + 2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 1.0); + checkDOMMatrix(new self[constr](float32Array), scaleTranslate2D, false); + }, `new ${constr}(float32Array) 16 elements`); + + test(function() { + var float32Array = new Float32Array(2.0, 0.0, 0.0, 2.0, 10.0, 10.0); + checkDOMMatrix(new self[constr](float32Array), scaleTranslate2D); + }, `new ${constr}(float32Array) 6 elements`); + + test(function() { + var float64Array = new Float64Array([ + 2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 1.0]); + checkDOMMatrix(new self[constr](float64Array), scaleTranslate2D, false); + }, `new ${constr}(float64Array) 16 elements`); + + test(function() { + var float64Array = new Float64Array(2.0, 0.0, 0.0, 2.0, 10.0, 10.0); + checkDOMMatrix(new self[constr](float64Array), scaleTranslate2D); + }, `new ${constr}((float64Array) 6 elements`); + + [ + [2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, - 10.0, 10.0, 0.0, 1.0]); - checkDOMMatrix(new DOMMatrix(matrix), { - m11: 2, m21: 1, m31: 0, m41: 10, - m12: 1, m22: 2, m32: 0, m42: 10, - m13: 0, m23: 0, m33: 1, m43: 0, - m14: 0, m24: 0, m34: 0, m44: 1, - is2D: false, - isIdentity: false + 10.0, 10.0, 0.0, 1.0], + [2.0, 0.0, 0.0, 2.0, 10.0, 10.0], + ].forEach(function(sequence) { + test(function() { + checkDOMMatrix(new self[constr](sequence), scaleTranslate2D, false); + }, `new ${constr}(sequence) ${sequence.length} elements`); }); - },'testConstructor13'); - test(function() { - assert_throws(new TypeError(), function() { new DOMMatrixReadOnly(); }); - },'testConstructorIllegal0'); - test(function() { - var string = 'scale(2, 2), translateX(5px) translateY(5px)'; - assert_throws(new TypeError(), function() { new DOMMatrixReadOnly(string); }); - },'testConstructorIllegal1'); - test(function() { - var sequence = [ 2.0, 0.0, 0.0, 2.0, 10.0]; - assert_throws(new TypeError(), function() { new DOMMatrixReadOnly(sequence); }); - },'testConstructorIllegal2'); - + + ['scale(2) translateX(5px) translateY(5px)', + 'scale(2 2) translateX(5) translateY(5)', + 'scale(2, 2), translateX(5) ,translateY(5)', + ].forEach(function(string) { + test(function() { + checkDOMMatrix(new self[constr](string), scaleTranslate2D); + }, `new ${constr}(${format_value(string)})`); + }); + + ['translateX (5px)', + 'scale(2)translateX(5px)', + 'translateX(5em)', + 'translateX(5ex)', + 'translateX(5ch)', + 'translateX(5rem)', + 'translateX(5vw)', + 'translateX(5vh)', + 'translateX(5vmin)', + 'translateX(5vmax)', + 'translateX(5%)', + ' ', + '/**/', + '\0', + ';', + 'none;', + 'null', + null, // is converted to 'null' by IDL + 'undefined', + 'inherit', + 'initial', + 'unset', + ].forEach(function(string) { + test(function() { + assert_throws('SyntaxError', function() { new self[constr](string); }); + }, `new ${constr}(${format_value(string)})`); + }); + + test(function() { + var sequence = [ + 2.0, 1.0, 0.0, 0.0, + 1.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 1.0]; + checkDOMMatrix(new self[constr](sequence), { + m11: 2, m21: 1, m31: 0, m41: 10, + m12: 1, m22: 2, m32: 0, m42: 10, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + is2D: false, + isIdentity: false + }); + }, `new ${constr}(sequence)`); + + test(function() { + var matrix = new self[constr]([ + 2.0, 1.0, 0.0, 0.0, + 1.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 1.0]); + checkDOMMatrix(new self[constr](matrix), { + m11: 2, m21: 1, m31: 0, m41: 10, + m12: 1, m22: 2, m32: 0, m42: 10, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + is2D: false, + isIdentity: false + }); + }, `new ${constr}(matrix)`); + + ['scale(2, 2), translateX(5px) translateY(5px)', + ].forEach(function(string) { + test(function() { + assert_throws("SyntaxError", function() { new self[constr](string); }); + }, `new ${constr}(${format_value(string)})`); + }); + + [ + [2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0, 2.0, 0.0], // 17 elements + [2.0, 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 10.0, 10.0, 0.0], // 15 elements + [2.0, 0.0, 0.0, 2.0, 10.0], // 5 elements + [], // 0 elements + ].forEach(function(sequence) { + test(function() { + assert_throws(new TypeError(), function() { new self[constr](sequence); }); + }, `new ${constr}(sequence) ${sequence.length} elements`); + }); + }); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-css-string.worker.js b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-css-string.worker.js new file mode 100644 index 0000000..2dd3eea --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/DOMMatrix-css-string.worker.js
@@ -0,0 +1,18 @@ +// https://drafts.fxtf.org/geometry/#DOMMatrix + +importScripts("/resources/testharness.js"); + +['DOMMatrix', 'DOMMatrixReadOnly'].forEach(constr => { + test(() => { + assert_true(constr in self, `${constr} should exist`); + assert_throws(new TypeError(), () => new self[constr]('matrix(1,0,0,1,0,0)') ); + }, `${constr} constructor with string argument in worker`); +}); + +test(() => { + assert_false('setMatrixValue' in DOMMatrix.prototype, 'on prototype'); + const matrix = new DOMMatrix(); + assert_false('setMatrixValue' in matrix, 'on instance'); +}, 'DOMMatrix setMatrixValue in worker'); + +done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/WebKitCSSMatrix-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/WebKitCSSMatrix-expected.txt new file mode 100644 index 0000000..dd0272a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/WebKitCSSMatrix-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +FAIL Equivalence test assert_equals: interface object expected function "function DOMMatrix() { [native code] }" but got function "function WebKitCSSMatrix() { [native code] }" +PASS Property descriptor for WebKitCSSMatrix +PASS Property descriptor for DOMMatrix +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/WebKitCSSMatrix.html b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/WebKitCSSMatrix.html new file mode 100644 index 0000000..7c28a5c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/WebKitCSSMatrix.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>Geometry Interfaces: WebKitCSSMatrix</title> +<link rel="help" href="https://drafts.fxtf.org/geometry/#DOMMatrix"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +test(() => { + assert_true('WebKitCSSMatrix' in self, 'WebKitCSSMatrix should exist'); + assert_true('DOMMatrix' in self, 'DOMMatrix should exist'); + assert_equals(WebKitCSSMatrix, DOMMatrix, 'interface object'); + assert_equals(WebKitCSSMatrix.prototype, DOMMatrix.prototype, 'prototype'); +}, 'Equivalence test'); + +['WebKitCSSMatrix', 'DOMMatrix'].forEach(interf => { + test(() => { + const desc = Object.getOwnPropertyDescriptor(self, interf); + assert_equals(desc.value, self[interf], 'value'); + assert_true(desc.writable, 'writable'); + assert_true(desc.configurable, 'configurable'); + assert_false(desc.enumerable, 'enumerable'); + assert_equals(desc.get, undefined, 'get'); + assert_equals(desc.set, undefined, 'set'); + }, `Property descriptor for ${interf}`); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/WebKitCSSMatrix.worker.js b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/WebKitCSSMatrix.worker.js new file mode 100644 index 0000000..71e2ecd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/WebKitCSSMatrix.worker.js
@@ -0,0 +1,9 @@ +// https://drafts.fxtf.org/geometry/#DOMMatrix + +importScripts('/resources/testharness.js'); + +test(() => { + assert_false('WebKitCSSMatrix' in self); +}, 'WebKitCSSMatrix in worker'); + +done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/historical.html b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/historical.html new file mode 100644 index 0000000..9d6864e6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/geometry-1/historical.html
@@ -0,0 +1,78 @@ +<!doctype html> +<title>Historical Geometry APIs</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<link rel=help href="https://drafts.fxtf.org/geometry/#changes"> +<script> +// Removed members +[ + // https://github.com/w3c/fxtf-drafts/commit/99e3212469026b2f2f50926a41912d110a1741b7 + ['DOMMatrixReadOnly', 'scaleNonUniform'], + ['DOMMatrix', 'scaleNonUniformSelf'], + // https://github.com/w3c/fxtf-drafts/commit/86da3dc961d442f9d8dc7ab59065a9804e109286 + ['DOMMatrix', 'multiplyBy'], + ['DOMMatrix', 'preMultiplyBy'], + ['DOMMatrix', 'translateBy'], + ['DOMMatrix', 'scaleBy'], + ['DOMMatrix', 'scale3dBy'], + ['DOMMatrix', 'scaleNonUniformBy'], + ['DOMMatrix', 'rotateBy'], + ['DOMMatrix', 'rotateFromVectorBy'], + ['DOMMatrix', 'rotateAxisAngleBy'], + ['DOMMatrix', 'skewXBy'], + ['DOMMatrix', 'skewYBy'], +].forEach(([interf, member]) => { + test(() => { + assert_true(interf in self, `${interf} should exist`); + assert_false(member in self[interf].prototype, 'on prototype'); + const instance = new self[interf](); + assert_false(member in instance, 'on instance'); + }, `${interf} ${member} must be nuked`); +}); + +// Removed static methods +// https://github.com/w3c/fxtf-drafts/commit/3c43462bcc857bb830f8af04532cdf33c5a634aa +['DOMMatrix', 'DOMMatrixReadOnly'].forEach(interf => { + test(() => { + assert_true(interf in self, `${interf} should exist`); + assert_false('fromString' in self[interf], 'on interface object'); + }, `${interf} fromString static member must be nuked`); +}); + +// Optional arguments +[ + // https://github.com/w3c/fxtf-drafts/commit/99e3212469026b2f2f50926a41912d110a1741b7 + ['DOMMatrixReadOnly', 'scale'], + ['DOMMatrix', 'scaleSelf'], + // https://github.com/w3c/fxtf-drafts/commit/8493a9c3d94da91ead5db6e05b51319494f5855f + ['DOMMatrixReadOnly', 'translate'], + ['DOMMatrixReadOnly', 'scale3d'], + ['DOMMatrixReadOnly', 'rotateFromVector'], + ['DOMMatrixReadOnly', 'rotateAxisAngle'], + ['DOMMatrixReadOnly', 'skewX'], + ['DOMMatrixReadOnly', 'skewY'], + ['DOMMatrix', 'translateSelf'], + ['DOMMatrix', 'scale3dSelf'], + ['DOMMatrix', 'rotateFromVectorSelf'], + ['DOMMatrix', 'rotateAxisAngleSelf'], + ['DOMMatrix', 'skewXSelf'], + ['DOMMatrix', 'skewYSelf'], + // https://github.com/w3c/fxtf-drafts/commit/62b9cb9d5be4982d2a9cbf314e3a59efb8a68dd6 + ['DOMPointReadOnly', 'matrixTransform'], + ['DOMMatrixReadOnly', 'multiply'], + ['DOMMatrix', 'multiplySelf'], + ['DOMMatrix', 'preMultiplySelf'], +].forEach(([interf, member]) => { + test(() => { + assert_equals(self[interf].prototype[member].length, 0, 'on prototype'); + const instance = new self[interf](); + assert_equals(instance[member].length, 0, 'on instance'); + }, `${interf} ${member} number of required arguments`); +}); + +// Renamed interfaces +// https://github.com/w3c/fxtf-drafts/commit/9031c94c8536cec7f7007c18d7be037a793e5ed5 +test(() => { + assert_false('CSSMatrix' in self); +}, 'CSSMatrix must be nuked'); +</script>
diff --git a/third_party/WebKit/Source/core/dom/AccessibleNode.cpp b/third_party/WebKit/Source/core/dom/AccessibleNode.cpp index 8e5437a..a8dd6c11 100644 --- a/third_party/WebKit/Source/core/dom/AccessibleNode.cpp +++ b/third_party/WebKit/Source/core/dom/AccessibleNode.cpp
@@ -32,6 +32,20 @@ } } + return g_null_atom; +} + +// static +const AtomicString& AccessibleNode::GetPropertyOrARIAAttribute( + Element* element, + AOMStringProperty property) { + if (!element) + return g_null_atom; + + const AtomicString& result = GetProperty(element, property); + if (!result.IsNull()) + return result; + // Fall back on the equivalent ARIA attribute. switch (property) { case AOMStringProperty::kAutocomplete:
diff --git a/third_party/WebKit/Source/core/dom/AccessibleNode.h b/third_party/WebKit/Source/core/dom/AccessibleNode.h index d082d34..333d5ef1 100644 --- a/third_party/WebKit/Source/core/dom/AccessibleNode.h +++ b/third_party/WebKit/Source/core/dom/AccessibleNode.h
@@ -49,9 +49,13 @@ explicit AccessibleNode(Element*); virtual ~AccessibleNode(); + // Returns the given string property if the Element has an AccessibleNode. + static const AtomicString& GetProperty(Element*, AOMStringProperty); + // Returns the given string property if the Element has an AccessibleNode, // otherwise returns the equivalent ARIA attribute. - static const AtomicString& GetProperty(Element*, AOMStringProperty); + static const AtomicString& GetPropertyOrARIAAttribute(Element*, + AOMStringProperty); AtomicString autocomplete() const; void setAutocomplete(const AtomicString&);
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index 88f37a8..53e007a 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1578,6 +1578,7 @@ kElementNameDOMValidHTMLParserInvalid = 1969, kGATTServerDisconnectedEvent = 1970, kAnchorClickDispatchForNonConnectedNode = 1971, + kHTMLParseErrorNestedForm = 1972, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp b/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp index 056c065..3b3c58b 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
@@ -618,6 +618,8 @@ if (token->GetName() == formTag) { if (tree_.IsFormElementPointerNonNull() && !IsParsingTemplateContents()) { ParseError(token); + UseCounter::Count(tree_.CurrentNode()->GetDocument(), + UseCounter::kHTMLParseErrorNestedForm); return; } ProcessFakePEndTagIfPInButtonScope();
diff --git a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp index 8d63c1de..2cae448c 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXObject.cpp
@@ -389,7 +389,7 @@ if (!node || !node->IsElementNode()) return g_null_atom; - return AccessibleNode::GetProperty(ToElement(node), property); + return AccessibleNode::GetPropertyOrARIAAttribute(ToElement(node), property); } bool AXObject::IsARIATextControl() const {
diff --git a/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp b/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp index 79c1ae70..8fbc26a 100644 --- a/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp +++ b/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp
@@ -222,4 +222,150 @@ FontFallbackPriority::kEmojiEmoji}}); } +// Extracted from http://unicode.org/emoji/charts/emoji-released.html for Emoji +// v5.0, except for the subdivision-flag section. Currently blocked on ICU 59 +// upgrade, TODO(jshin): crbug.com/699469 +// Before ICU 59 new emoji sequences and new single emoji are not detected as +// emoji type text and sequences get split up in the middle so that shaping +// cannot form the right glyph from the emoji font. Running this as one run in +// one test ensures that the new emoji form an unbroken emoji-type sequence. +TEST_F(SymbolsIteratorTest, DISABLED_Emoji5AdditionsExceptFlags) { + CHECK_RUNS( + {{"\xF0\x9F\xA7\x94\xF0\x9F\x8F\xBB\xF0\x9F\xA7\x94\xF0\x9F\x8F\xBC\xF0" + "\x9F\xA7\x94\xF0\x9F\x8F\xBD\xF0\x9F\xA7\x94\xF0\x9F\x8F\xBE\xF0\x9F" + "\xA7\x94\xF0\x9F\x8F\xBF\xF0\x9F\xA4\xB1\xF0\x9F\xA4\xB1\xF0\x9F\x8F" + "\xBB\xF0\x9F\xA4\xB1\xF0\x9F\x8F\xBC\xF0\x9F\xA4\xB1\xF0\x9F\x8F\xBD" + "\xF0\x9F\xA4\xB1\xF0\x9F\x8F\xBE\xF0\x9F\xA4\xB1\xF0\x9F\x8F\xBF\xF0" + "\x9F\xA7\x99\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBB\xF0\x9F\xA7\x99\xF0\x9F" + "\x8F\xBC\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBD\xF0\x9F\xA7\x99\xF0\x9F\x8F" + "\xBE\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBF\xF0\x9F\xA7\x99\xE2\x80\x8D\xE2" + "\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBB\xE2\x80\x8D\xE2" + "\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBC\xE2\x80\x8D\xE2" + "\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBD\xE2\x80\x8D\xE2" + "\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBE\xE2\x80\x8D\xE2" + "\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBF\xE2\x80\x8D\xE2" + "\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x99\xE2\x80\x8D\xE2\x99\x82\xEF\xB8" + "\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBB\xE2\x80\x8D\xE2\x99\x82\xEF\xB8" + "\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBC\xE2\x80\x8D\xE2\x99\x82\xEF\xB8" + "\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBD\xE2\x80\x8D\xE2\x99\x82\xEF\xB8" + "\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBE\xE2\x80\x8D\xE2\x99\x82\xEF\xB8" + "\x8F\xF0\x9F\xA7\x99\xF0\x9F\x8F\xBF\xE2\x80\x8D\xE2\x99\x82\xEF\xB8" + "\x8F\xF0\x9F\xA7\x9A\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBB\xF0\x9F\xA7\x9A" + "\xF0\x9F\x8F\xBC\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBD\xF0\x9F\xA7\x9A\xF0" + "\x9F\x8F\xBE\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBF\xF0\x9F\xA7\x9A\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBB\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBC\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBD\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBE\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBF\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBB\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBC\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBD\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBE\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x9A\xF0\x9F\x8F\xBF\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBB\xF0\x9F" + "\xA7\x9B\xF0\x9F\x8F\xBC\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBD\xF0\x9F\xA7" + "\x9B\xF0\x9F\x8F\xBE\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBF\xF0\x9F\xA7\x9B" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBB" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBC" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBD" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBE" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBF" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBB\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBC\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBD\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBE\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9B\xF0\x9F\x8F\xBF\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F\xA7\x9C\xF0\x9F\x8F\xBB" + "\xF0\x9F\xA7\x9C\xF0\x9F\x8F\xBC\xF0\x9F\xA7\x9C\xF0\x9F\x8F\xBD\xF0" + "\x9F\xA7\x9C\xF0\x9F\x8F\xBE\xF0\x9F\xA7\x9C\xF0\x9F\x8F\xBF\xF0\x9F" + "\xA7\x9C\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F" + "\x8F\xBB\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F" + "\x8F\xBC\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F" + "\x8F\xBD\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F" + "\x8F\xBE\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F" + "\x8F\xBF\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F\x8F\xBB\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F\x8F\xBC\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F\x8F\xBD\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F\x8F\xBE\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9C\xF0\x9F\x8F\xBF\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9D\xF0\x9F\xA7\x9D\xF0\x9F" + "\x8F\xBB\xF0\x9F\xA7\x9D\xF0\x9F\x8F\xBC\xF0\x9F\xA7\x9D\xF0\x9F\x8F" + "\xBD\xF0\x9F\xA7\x9D\xF0\x9F\x8F\xBE\xF0\x9F\xA7\x9D\xF0\x9F\x8F\xBF" + "\xF0\x9F\xA7\x9D\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9D" + "\xF0\x9F\x8F\xBB\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9D" + "\xF0\x9F\x8F\xBC\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9D" + "\xF0\x9F\x8F\xBD\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9D" + "\xF0\x9F\x8F\xBE\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9D" + "\xF0\x9F\x8F\xBF\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9D" + "\xE2\x80\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9D\xF0\x9F\x8F\xBB" + "\xE2\x80\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9D\xF0\x9F\x8F\xBC" + "\xE2\x80\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9D\xF0\x9F\x8F\xBD" + "\xE2\x80\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9D\xF0\x9F\x8F\xBE" + "\xE2\x80\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9D\xF0\x9F\x8F\xBF" + "\xE2\x80\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9E\xF0\x9F\xA7\x9E" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9E\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x9F\xF0\x9F\xA7\x9F\xE2\x80\x8D\xE2" + "\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x9F\xE2\x80\x8D\xE2\x99\x82\xEF\xB8" + "\x8F\xF0\x9F\xA7\x96\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBB\xF0\x9F\xA7\x96" + "\xF0\x9F\x8F\xBC\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBD\xF0\x9F\xA7\x96\xF0" + "\x9F\x8F\xBE\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBF\xF0\x9F\xA7\x96\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBB\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBC\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBD\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBE\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBF\xE2\x80" + "\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x96\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBB\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBC\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBD\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBE\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x96\xF0\x9F\x8F\xBF\xE2\x80\x8D\xE2\x99\x82" + "\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBB\xF0\x9F" + "\xA7\x97\xF0\x9F\x8F\xBC\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBD\xF0\x9F\xA7" + "\x97\xF0\x9F\x8F\xBE\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBF\xF0\x9F\xA7\x97" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBB" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBC" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBD" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBE" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBF" + "\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x97\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBB\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBC\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBD\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBE\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x97\xF0\x9F\x8F\xBF\xE2\x80\x8D\xE2" + "\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F\xA7\x98\xF0\x9F\x8F\xBB" + "\xF0\x9F\xA7\x98\xF0\x9F\x8F\xBC\xF0\x9F\xA7\x98\xF0\x9F\x8F\xBD\xF0" + "\x9F\xA7\x98\xF0\x9F\x8F\xBE\xF0\x9F\xA7\x98\xF0\x9F\x8F\xBF\xF0\x9F" + "\xA7\x98\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F" + "\x8F\xBB\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F" + "\x8F\xBC\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F" + "\x8F\xBD\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F" + "\x8F\xBE\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F" + "\x8F\xBF\xE2\x80\x8D\xE2\x99\x80\xEF\xB8\x8F\xF0\x9F\xA7\x98\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F\x8F\xBB\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F\x8F\xBC\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F\x8F\xBD\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F\x8F\xBE\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA7\x98\xF0\x9F\x8F\xBF\xE2\x80" + "\x8D\xE2\x99\x82\xEF\xB8\x8F\xF0\x9F\xA4\x9F\xF0\x9F\xA4\x9F\xF0\x9F" + "\x8F\xBB\xF0\x9F\xA4\x9F\xF0\x9F\x8F\xBC\xF0\x9F\xA4\x9F\xF0\x9F\x8F" + "\xBD\xF0\x9F\xA4\x9F\xF0\x9F\x8F\xBE\xF0\x9F\xA4\x9F\xF0\x9F\x8F\xBF" + "\xF0\x9F\xA4\xB2\xF0\x9F\xA4\xB2\xF0\x9F\x8F\xBB\xF0\x9F\xA4\xB2\xF0" + "\x9F\x8F\xBC\xF0\x9F\xA4\xB2\xF0\x9F\x8F\xBD\xF0\x9F\xA4\xB2\xF0\x9F" + "\x8F\xBE\xF0\x9F\xA4\xB2\xF0\x9F\x8F\xBF\xF0\x9F\xA7\xA0\xF0\x9F\xA7" + "\xA1\xF0\x9F\xA7\xA3\xF0\x9F\xA7\xA4\xF0\x9F\xA7\xA5\xF0\x9F\xA7\xA6" + "\xF0\x9F\xA7\xA2\xF0\x9F\xA6\x93\xF0\x9F\xA6\x92\xF0\x9F\xA6\x94\xF0" + "\x9F\xA6\x95\xF0\x9F\xA6\x96\xF0\x9F\xA6\x97\xF0\x9F\xA5\xA5\xF0\x9F" + "\xA5\xA6\xF0\x9F\xA5\xA8\xF0\x9F\xA5\xA9\xF0\x9F\xA5\xAA\xF0\x9F\xA5" + "\xA3\xF0\x9F\xA5\xAB\xF0\x9F\xA5\x9F\xF0\x9F\xA5\xA0\xF0\x9F\xA5\xA1" + "\xF0\x9F\xA5\xA7\xF0\x9F\xA5\xA4\xF0\x9F\xA5\xA2\xF0\x9F\x9B\xB8\xF0" + "\x9F\x9B\xB7\xF0\x9F\xA5\x8C", + FontFallbackPriority::kEmojiEmoji}}); +} + } // namespace blink
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 3036796..816d6b7 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -14847,6 +14847,7 @@ <int value="1969" label="ElementNameDOMValidHTMLParserInvalid"/> <int value="1970" label="GATTServerDisconnectedEvent"/> <int value="1971" label="AnchorClickDispatchForNonConnectedNode"/> + <int value="1972" label="HTMLParseErrorNestedForm"/> </enum> <enum name="FeedbackSource" type="int"> @@ -30740,6 +30741,8 @@ <int value="281" label="PPSX"/> <int value="282" label="SLDX"/> <int value="283" label="SLDM"/> + <int value="284" label="HTM"/> + <int value="285" label="HTML"/> </enum> <enum name="SBClientDownloadIsSignedBinary" type="int">
diff --git a/ui/base/ime/input_method.h b/ui/base/ime/input_method.h index 67010a3..6b1d526 100644 --- a/ui/base/ime/input_method.h +++ b/ui/base/ime/input_method.h
@@ -15,6 +15,7 @@ #include "build/build_config.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" +#include "ui/gfx/geometry/rect.h" namespace extensions { class InputImeApiTest; @@ -160,6 +161,9 @@ virtual void AddObserver(InputMethodObserver* observer) = 0; virtual void RemoveObserver(InputMethodObserver* observer) = 0; + // Set screen bounds of a on-screen keyboard. + virtual void SetOnScreenKeyboardBounds(const gfx::Rect& new_bounds) {} + protected: friend class extensions::InputImeApiTest;
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc index 492d7f9a..f436c5d5 100644 --- a/ui/base/ime/input_method_base.cc +++ b/ui/base/ime/input_method_base.cc
@@ -63,6 +63,12 @@ return text_input_client_; } +void InputMethodBase::SetOnScreenKeyboardBounds(const gfx::Rect& new_bounds) { + keyboard_bounds_ = new_bounds; + if (text_input_client_) + text_input_client_->EnsureCaretNotInRect(keyboard_bounds_); +} + void InputMethodBase::OnTextInputTypeChanged(const TextInputClient* client) { if (!IsTextInputClientFocused(client)) return; @@ -152,6 +158,10 @@ text_input_client_ = client; // nullptr allowed. OnDidChangeFocusedClient(old, client); NotifyTextInputStateChanged(text_input_client_); + + // Move new focused window if necessary. + if (text_input_client_) + text_input_client_->EnsureCaretNotInRect(keyboard_bounds_); } std::vector<gfx::Rect> InputMethodBase::GetCompositionBounds(
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h index 1daa0e9..aa16c6f 100644 --- a/ui/base/ime/input_method_base.h +++ b/ui/base/ime/input_method_base.h
@@ -43,6 +43,7 @@ void SetFocusedTextInputClient(TextInputClient* client) override; void DetachTextInputClient(TextInputClient* client) override; TextInputClient* GetTextInputClient() const override; + void SetOnScreenKeyboardBounds(const gfx::Rect& new_bounds) override; // If a derived class overrides this method, it should call parent's // implementation. @@ -124,6 +125,9 @@ std::vector<std::unique_ptr<ui::KeyEvent>> key_events_for_testing_; + // Screen bounds of a on-screen keyboard. + gfx::Rect keyboard_bounds_; + DISALLOW_COPY_AND_ASSIGN(InputMethodBase); };
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc index e07e020a..c5569e3 100644 --- a/ui/keyboard/keyboard_controller.cc +++ b/ui/keyboard/keyboard_controller.cc
@@ -520,6 +520,7 @@ ui_->HideKeyboardContainer(container_.get()); for (KeyboardControllerObserver& observer : observer_list_) observer.OnKeyboardHidden(); + ui_->EnsureCaretInWorkArea(); } void KeyboardController::AdjustKeyboardBounds() {
diff --git a/ui/keyboard/keyboard_ui.cc b/ui/keyboard/keyboard_ui.cc index 896add64..69b1f1e 100644 --- a/ui/keyboard/keyboard_ui.cc +++ b/ui/keyboard/keyboard_ui.cc
@@ -4,9 +4,11 @@ #include "ui/keyboard/keyboard_ui.h" +#include "base/command_line.h" #include "ui/aura/window.h" #include "ui/base/ime/input_method.h" #include "ui/base/ime/text_input_client.h" +#include "ui/base/ui_base_switches.h" #include "ui/keyboard/keyboard_controller.h" namespace keyboard { @@ -29,10 +31,26 @@ } void KeyboardUI::EnsureCaretInWorkArea() { - if (GetInputMethod()->GetTextInputClient()) { - aura::Window* keyboard_window = GetKeyboardWindow(); + if (!GetInputMethod()) + return; + + const aura::Window* keyboard_window = GetKeyboardWindow(); + const gfx::Rect keyboard_bounds_in_screen = + keyboard_window->IsVisible() ? keyboard_window->GetBoundsInScreen() + : gfx::Rect(); + + // Use new virtual keyboard behavior only if the flag enabled and in + // non-sticky mode. + const bool new_vk_behavior = + (base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kUseNewVirtualKeyboardBehavior) && + !keyboard::KeyboardController::GetInstance()->keyboard_locked()); + + if (new_vk_behavior) { + GetInputMethod()->SetOnScreenKeyboardBounds(keyboard_bounds_in_screen); + } else if (GetInputMethod()->GetTextInputClient()) { GetInputMethod()->GetTextInputClient()->EnsureCaretNotInRect( - keyboard_window->GetBoundsInScreen()); + keyboard_bounds_in_screen); } }
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 2c7c520d..147e648 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -7,12 +7,15 @@ #include <string> #include <utility> +#include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/window.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/cursor/cursor.h" #include "ui/base/default_style.h" @@ -21,6 +24,7 @@ #include "ui/base/ime/text_edit_commands.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches_util.h" #include "ui/compositor/canvas_painter.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" @@ -47,6 +51,7 @@ #include "ui/views/style/platform_style.h" #include "ui/views/views_delegate.h" #include "ui/views/widget/widget.h" +#include "ui/wm/core/coordinate_conversion.h" #if defined(OS_WIN) #include "base/win/win_util.h" @@ -63,6 +68,10 @@ #include "ui/base/x/x11_util_internal.h" // nogncheck #endif +#if defined(OS_CHROMEOS) +#include "ui/wm/core/ime_util_chromeos.h" +#endif + namespace views { namespace { @@ -1013,8 +1022,13 @@ void Textfield::OnBlur() { gfx::RenderText* render_text = GetRenderText(); render_text->set_focused(false); - if (GetInputMethod()) + if (GetInputMethod()) { GetInputMethod()->DetachTextInputClient(this); +#if defined(OS_CHROMEOS) + wm::RestoreWindowBoundsOnClientFocusLost( + GetNativeView()->GetToplevelWindow()); +#endif // defined(OS_CHROMEOS) + } StopBlinkingCursor(); cursor_view_.SetVisible(false); @@ -1485,7 +1499,12 @@ DeleteRange(range); } -void Textfield::EnsureCaretNotInRect(const gfx::Rect& rect) {} +void Textfield::EnsureCaretNotInRect(const gfx::Rect& rect_in_screen) { +#if defined(OS_CHROMEOS) + aura::Window* top_level_window = GetNativeView()->GetToplevelWindow(); + wm::EnsureWindowNotInRect(top_level_window, rect_in_screen); +#endif // defined(OS_CHROMEOS) +} bool Textfield::IsTextEditCommandEnabled(ui::TextEditCommand command) const { base::string16 result;
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index d712c65..c9e9d1c 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -21,6 +21,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/aura/window.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/dragdrop/drag_drop_types.h" @@ -62,6 +63,10 @@ #include "ui/events/event_utils.h" #endif +#if defined(OS_CHROMEOS) +#include "ui/wm/core/ime_util_chromeos.h" +#endif + using base::ASCIIToUTF16; using base::UTF8ToUTF16; using base::WideToUTF16; @@ -2953,6 +2958,48 @@ EXPECT_TRUE(test_api_->IsCursorBlinkTimerRunning()); } +#if defined(OS_CHROMEOS) +// Check that when accessibility virtual keyboard is enabled, windows are +// shifted up when focused and restored when focus is lost. +TEST_F(TextfieldTest, VirtualKeyboardFocusEnsureCaretNotInRect) { + InitTextfield(); + + // Enable new virtual keyboard behavior. + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(::switches::kUseNewVirtualKeyboardBehavior)) { + command_line->AppendSwitch(::switches::kUseNewVirtualKeyboardBehavior); + } + + aura::Window* root_window = widget_->GetNativeView()->GetRootWindow(); + int keyboard_height = 200; + gfx::Rect root_bounds = root_window->bounds(); + gfx::Rect orig_widget_bounds = gfx::Rect(0, 300, 400, 200); + gfx::Rect shifted_widget_bounds = gfx::Rect(0, 200, 400, 200); + gfx::Rect keyboard_view_bounds = + gfx::Rect(0, root_bounds.height() - keyboard_height, root_bounds.width(), + keyboard_height); + + // Focus the window. + widget_->SetBounds(orig_widget_bounds); + input_method_->SetFocusedTextInputClient(textfield_); + EXPECT_EQ(widget_->GetNativeView()->bounds(), orig_widget_bounds); + + // Simulate virtual keyboard. + input_method_->SetOnScreenKeyboardBounds(keyboard_view_bounds); + + // Window should be shifted. + EXPECT_EQ(widget_->GetNativeView()->bounds(), shifted_widget_bounds); + + // Detach the textfield from the IME + input_method_->DetachTextInputClient(textfield_); + wm::RestoreWindowBoundsOnClientFocusLost( + widget_->GetNativeView()->GetToplevelWindow()); + + // Window should be restored. + EXPECT_EQ(widget_->GetNativeView()->bounds(), orig_widget_bounds); +} +#endif // defined(OS_CHROMEOS) + class TextfieldTouchSelectionTest : public TextfieldTest { protected: // Simulates a complete tap.
diff --git a/ui/wm/BUILD.gn b/ui/wm/BUILD.gn index a490bbe2..16674713 100644 --- a/ui/wm/BUILD.gn +++ b/ui/wm/BUILD.gn
@@ -86,6 +86,13 @@ configs += [ "//build/config/linux:x11" ] deps += [ "//ui/events/devices/x11" ] } + + if (is_chromeos) { + sources += [ + "core/ime_util_chromeos.cc", + "core/ime_util_chromeos.h", + ] + } } static_library("test_support") { @@ -149,4 +156,8 @@ data_deps = [ "//ui/resources:ui_test_pak_data", ] + + if (is_chromeos) { + sources += [ "core/ime_util_chromeos_unittest.cc" ] + } }
diff --git a/ui/wm/core/ime_util_chromeos.cc b/ui/wm/core/ime_util_chromeos.cc new file mode 100644 index 0000000..4e57d2d4 --- /dev/null +++ b/ui/wm/core/ime_util_chromeos.cc
@@ -0,0 +1,100 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/wm/core/ime_util_chromeos.h" + +#include "base/command_line.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/base/ui_base_switches.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/wm/core/coordinate_conversion.h" + +namespace wm { +namespace { + +// Moves the window to ensure caret not in rect. +// Returns whether the window was moved or not. +void MoveWindowToEnsureCaretNotInRect(aura::Window* window, + const gfx::Rect& rect_in_screen) { + gfx::Rect original_window_bounds = window->GetBoundsInScreen(); + if (window->GetProperty(kVirtualKeyboardRestoreBoundsKey)) { + original_window_bounds = + *window->GetProperty(kVirtualKeyboardRestoreBoundsKey); + } + + // Calculate vertical window shift. + gfx::Rect rect_in_root_window = rect_in_screen; + ::wm::ConvertRectFromScreen(window->GetRootWindow(), &rect_in_root_window); + gfx::Rect bounds_in_root_window = original_window_bounds; + ::wm::ConvertRectFromScreen(window->GetRootWindow(), &bounds_in_root_window); + const int top_y = + std::max(rect_in_root_window.y() - bounds_in_root_window.height(), 0); + + // No need to move the window up. + if (top_y >= bounds_in_root_window.y()) + return; + + // Set restore bounds and move the window. + window->SetProperty(kVirtualKeyboardRestoreBoundsKey, + new gfx::Rect(original_window_bounds)); + + gfx::Rect new_bounds_in_root_window = bounds_in_root_window; + new_bounds_in_root_window.set_y(top_y); + window->SetBounds(new_bounds_in_root_window); +} + +} // namespace + +DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Rect, + kVirtualKeyboardRestoreBoundsKey, + nullptr); + +void RestoreWindowBoundsOnClientFocusLost(aura::Window* window) { + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kUseNewVirtualKeyboardBehavior)) + return; + + // Get restore bounds of the window + gfx::Rect* vk_restore_bounds = + window->GetProperty(kVirtualKeyboardRestoreBoundsKey); + + if (!vk_restore_bounds) + return; + + // Restore the window bounds + // TODO(yhanada): Don't move the window if a user has moved it while the + // keyboard is shown. + if (window->GetBoundsInScreen() != *vk_restore_bounds) { + gfx::Rect original_bounds = *vk_restore_bounds; + ::wm::ConvertRectFromScreen(window->GetRootWindow(), &original_bounds); + window->SetBounds(original_bounds); + } + window->ClearProperty(wm::kVirtualKeyboardRestoreBoundsKey); +} + +void EnsureWindowNotInRect(aura::Window* window, + const gfx::Rect& rect_in_screen) { + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kUseNewVirtualKeyboardBehavior)) + return; + + gfx::Rect original_window_bounds = window->GetBoundsInScreen(); + if (window->GetProperty(wm::kVirtualKeyboardRestoreBoundsKey)) { + original_window_bounds = + *window->GetProperty(wm::kVirtualKeyboardRestoreBoundsKey); + } + + gfx::Rect hidden_window_bounds_in_screen = + gfx::IntersectRects(rect_in_screen, original_window_bounds); + if (hidden_window_bounds_in_screen.IsEmpty()) { + // The window isn't covered by the keyboard, restore the window position if + // necessary. + RestoreWindowBoundsOnClientFocusLost(window); + return; + } + + MoveWindowToEnsureCaretNotInRect(window, rect_in_screen); +} + +} // namespace wm
diff --git a/ui/wm/core/ime_util_chromeos.h b/ui/wm/core/ime_util_chromeos.h new file mode 100644 index 0000000..39ed2228 --- /dev/null +++ b/ui/wm/core/ime_util_chromeos.h
@@ -0,0 +1,33 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_WM_CORE_IME_UTIL_CHROMEOS_H_ +#define UI_WM_CORE_IME_UTIL_CHROMEOS_H_ + +#include "ui/aura/window.h" +#include "ui/wm/wm_export.h" + +namespace gfx { +class Rect; +} + +namespace wm { + +// A property key to store the restore bounds for a window when moved by the +// virtual keyboard. +WM_EXPORT extern const aura::WindowProperty<gfx::Rect*>* const + kVirtualKeyboardRestoreBoundsKey; + +// Moves the window, if needed, to ensure it does not intersect with +// |rect_in_screen|. +WM_EXPORT void EnsureWindowNotInRect(aura::Window* window, + const gfx::Rect& rect_in_screen); + +// Restores the window bounds when input client loses the focus on the window. +WM_EXPORT void RestoreWindowBoundsOnClientFocusLost( + aura::Window* top_level_window); + +} // namespace wm + +#endif // UI_WM_CORE_IME_UTIL_CHROMEOS_H_
diff --git a/ui/wm/core/ime_util_chromeos_unittest.cc b/ui/wm/core/ime_util_chromeos_unittest.cc new file mode 100644 index 0000000..a0887bb --- /dev/null +++ b/ui/wm/core/ime_util_chromeos_unittest.cc
@@ -0,0 +1,143 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/wm/core/ime_util_chromeos.h" + +#include "base/command_line.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/aura/test/aura_test_base.h" +#include "ui/aura/test/test_windows.h" +#include "ui/base/ui_base_switches.h" +#include "ui/wm/core/default_screen_position_client.h" + +namespace wm { + +class ImeUtilChromeosTest : public aura::test::AuraTestBase { + public: + ImeUtilChromeosTest() = default; + ~ImeUtilChromeosTest() override = default; + + void SetUp() override { + AuraTestBase::SetUp(); + screen_position_client_ = base::MakeUnique<DefaultScreenPositionClient>(); + aura::client::SetScreenPositionClient(root_window(), + screen_position_client_.get()); + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(::switches::kUseNewVirtualKeyboardBehavior)) + command_line->AppendSwitch(::switches::kUseNewVirtualKeyboardBehavior); + } + + void TearDown() override { + aura::client::SetScreenPositionClient(root_window(), nullptr); + AuraTestBase::TearDown(); + } + + private: + std::unique_ptr<aura::client::ScreenPositionClient> screen_position_client_; + + DISALLOW_COPY_AND_ASSIGN(ImeUtilChromeosTest); +}; + +TEST_F(ImeUtilChromeosTest, RestoreWindowBounds) { + const gfx::Rect bounds(10, 20, 100, 200); + aura::Window* window = + aura::test::CreateTestWindowWithBounds(bounds, root_window()); + + EXPECT_EQ(nullptr, window->GetProperty(kVirtualKeyboardRestoreBoundsKey)); + EXPECT_EQ(bounds, window->bounds()); + + RestoreWindowBoundsOnClientFocusLost(window); + EXPECT_EQ(bounds, window->bounds()); + + gfx::Rect r1(40, 50, 150, 200); + window->SetProperty(kVirtualKeyboardRestoreBoundsKey, new gfx::Rect(r1)); + RestoreWindowBoundsOnClientFocusLost(window); + EXPECT_EQ(r1, window->bounds()); + EXPECT_EQ(nullptr, window->GetProperty(kVirtualKeyboardRestoreBoundsKey)); +} + +TEST_F(ImeUtilChromeosTest, EnsureWindowNotInRect_NotCovered) { + const gfx::Rect bounds(0, 0, 100, 200); + aura::Window* window = + aura::test::CreateTestWindowWithBounds(bounds, root_window()); + EXPECT_EQ(bounds, window->bounds()); + EXPECT_EQ(bounds, window->GetBoundsInScreen()); + + // The rect doesn't overlap on the window. + gfx::Rect rect(300, 300, 100, 100); + EXPECT_TRUE(gfx::IntersectRects(window->GetBoundsInScreen(), rect).IsEmpty()); + EnsureWindowNotInRect(window, rect); + // The bounds should not be changed. + EXPECT_EQ(bounds, window->bounds()); + EXPECT_EQ(bounds, window->GetBoundsInScreen()); +} + +TEST_F(ImeUtilChromeosTest, EnsureWindowNotInRect_MoveUp) { + const gfx::Rect original_bounds(10, 100, 100, 10); + aura::Window* window = + aura::test::CreateTestWindowWithBounds(original_bounds, root_window()); + EXPECT_EQ(original_bounds, window->bounds()); + EXPECT_EQ(original_bounds, window->GetBoundsInScreen()); + + // The rect overlaps the window. The window is moved up by + // EnsureWindowNotInRect. + gfx::Rect rect(50, 50, 200, 200); + EXPECT_FALSE( + gfx::IntersectRects(window->GetBoundsInScreen(), rect).IsEmpty()); + EnsureWindowNotInRect(window, rect); + EXPECT_EQ(gfx::Rect(10, 40, 100, 10), window->bounds()); + EXPECT_EQ(gfx::Rect(10, 40, 100, 10), window->GetBoundsInScreen()); +} + +TEST_F(ImeUtilChromeosTest, EnsureWindowNotInRect_MoveToTop) { + const gfx::Rect original_bounds(10, 10, 100, 100); + aura::Window* window = + aura::test::CreateTestWindowWithBounds(original_bounds, root_window()); + EXPECT_EQ(original_bounds, window->bounds()); + EXPECT_EQ(original_bounds, window->GetBoundsInScreen()); + + // The rect overlaps the window. The window is moved up by + // EnsureWinodwNotInRect, but there is not enough space above the window. + gfx::Rect rect(50, 50, 200, 200); + EXPECT_FALSE( + gfx::IntersectRects(window->GetBoundsInScreen(), rect).IsEmpty()); + EnsureWindowNotInRect(window, rect); + EXPECT_EQ(gfx::Rect(10, 0, 100, 100), window->bounds()); + EXPECT_EQ(gfx::Rect(10, 0, 100, 100), window->GetBoundsInScreen()); +} + +TEST_F(ImeUtilChromeosTest, MoveUpThenRestore) { + const gfx::Rect original_bounds(50, 50, 100, 100); + aura::Window* window = + aura::test::CreateTestWindowWithBounds(original_bounds, root_window()); + EXPECT_EQ(original_bounds, window->bounds()); + EXPECT_EQ(original_bounds, window->GetBoundsInScreen()); + + // EnsureWindowNotInRect moves up the window. + gfx::Rect rect(50, 50, 200, 200); + EXPECT_FALSE( + gfx::IntersectRects(window->GetBoundsInScreen(), rect).IsEmpty()); + EnsureWindowNotInRect(window, rect); + EXPECT_EQ(gfx::Rect(50, 0, 100, 100), window->bounds()); + EXPECT_EQ(gfx::Rect(50, 0, 100, 100), window->GetBoundsInScreen()); + + // The new rect doesn't overlap the moved window bounds, but still overlaps + // the original window bounds. + rect = gfx::Rect(50, 120, 200, 200); + EXPECT_FALSE(gfx::IntersectRects(rect, original_bounds).IsEmpty()); + EnsureWindowNotInRect(window, rect); + EXPECT_EQ(gfx::Rect(50, 20, 100, 100), window->bounds()); + EXPECT_EQ(gfx::Rect(50, 20, 100, 100), window->GetBoundsInScreen()); + + // Now the rect doesn't overlap the original window bounds. The original + // window bounds should be restored. + rect = gfx::Rect(200, 200, 200, 200); + EXPECT_TRUE(gfx::IntersectRects(rect, original_bounds).IsEmpty()); + EnsureWindowNotInRect(window, rect); + EXPECT_EQ(original_bounds, window->bounds()); + EXPECT_EQ(original_bounds, window->GetBoundsInScreen()); +} + +} // namespace wm