diff --git a/DEPS b/DEPS index 9baa217..78c96be 100644 --- a/DEPS +++ b/DEPS
@@ -175,11 +175,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'd99b64678d6a4a71323c3fe9693fc0a24d3fc4f4', + 'skia_revision': '1171d314efc7e131b039c94126d26575cfb9e70c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'd3ac36c81a08ec16adca1734830fe5d319a13dcb', + 'v8_revision': '633234050d9781560f814e4914c31954459aecd4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -187,11 +187,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'dadeffa315e7c95b36ebf30fd4094b3fae12c179', + 'angle_revision': '7daf31d8029b03d71f2e51288756c1f453fa429a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'bc98fbeec99b50d9843eef1cf58ad536f4678183', + 'swiftshader_revision': 'fb670f56acbdad6eed0a3faa126e9bbef177a66c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -246,7 +246,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '64e0899efa07a281ed44288cf6fab12e83e47f8a', + 'devtools_frontend_revision': '747295674924c671f86fe791f5ac81044dfeac12', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -286,11 +286,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': '25ede1ced6797f9a3689ae7dac5085ce8236c573', + 'spv_tools_revision': '18d3896a15fc90e71b9eb58901b2eb1728185115', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_headers_revision': 'a17e17e36da44d2cd1740132ecd7a8cb078f1d15', + 'spv_headers_revision': 'f8bf11a0253a32375c32cad92c841237b96696c0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -302,7 +302,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '1f9b5960d8b20a7aa82cbf1adebea8380f49c936', + 'dawn_revision': '81bcbbc20ee522b3039d981d5d24aa8e82f4b94c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -521,7 +521,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'ecb6de8a5a229721f761f13056c584c2b9208b6c', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '65758b73af4c97551fce65ae4f8bfedd39a360b3', 'condition': 'checkout_ios', }, @@ -852,7 +852,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '829a21222fe39a764a83bbe6eb8feb634ba2691b', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f845b816079e72207f8d8c6bab56896fb8e7a3ec', 'condition': 'checkout_linux', }, @@ -1448,7 +1448,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '84ee597cdeae08bb26e578fc66a35bcf35f633f4', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '93bcaae445243cde9d4cb500f7dfc1cd7210bf56', + Var('webrtc_git') + '/src.git' + '@' + 'dc5522b4bf4d729c2dfe269f84a5148212c57a88', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1523,7 +1523,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@53a925b3221aff550f0bea4e6ddab63df14ccd0b', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d0550b3138749715ace7875cf3618c19f5ae7e37', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index efde999e..d19b670 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1337,6 +1337,7 @@ 'build/android/gyp/merge_manifest.pydeps', 'build/android/gyp/prepare_resources.pydeps', 'build/android/gyp/proguard.pydeps', + 'build/android/gyp/turbine.pydeps', 'build/android/gyp/validate_static_library_dex_references.pydeps', 'build/android/gyp/write_build_config.pydeps', 'build/android/gyp/write_native_libraries_java.pydeps',
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index c78890b72..e12e002 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -983,6 +983,7 @@ ->overriding_factory.InitWithNewPipeAndPassReceiver(); (*factory_override)->overridden_factory_receiver = target_factory_remote.InitWithNewPipeAndPassReceiver(); + (*factory_override)->skip_cors_enabled_scheme_check = true; } else { // In this case, |factory_override| is not given. But all callers of // ContentBrowserClient::WillCreateURLLoaderFactory guarantee that
diff --git a/android_webview/docs/cors-and-webview-api.md b/android_webview/docs/cors-and-webview-api.md index 053a02f..d728e05 100644 --- a/android_webview/docs/cors-and-webview-api.md +++ b/android_webview/docs/cors-and-webview-api.md
@@ -53,4 +53,10 @@ TODO ### shouldInterceptRequest -TODO +Custom scheme should not be permitted for CORS-enabled requests usually. +However, when shouldInterceptRequest is used, the API allows developers to +handle CORS-enabled requests over custom schemes. + +When a custom scheme is used, `*` or `null` should appear in the +Access-Control-Allow-Origin response header as such custom scheme is processed +as an [opaque origin](https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque).
diff --git a/android_webview/nonembedded/BUILD.gn b/android_webview/nonembedded/BUILD.gn index 5f795bb..dfaedf7 100644 --- a/android_webview/nonembedded/BUILD.gn +++ b/android_webview/nonembedded/BUILD.gn
@@ -114,16 +114,34 @@ custom_package = "org.chromium.android_webview.devui" } -android_resources("devui_launcher_icon_resources") { - resource_dirs = [] - custom_package = "org.chromium.android_webview.devui.icon" - android_manifest = "java/DeveloperUiLauncherManifest.xml" +template("webview_devui_launcher") { + forward_variables_from(invoker, "*") + + _manifest_file = "$root_gen_dir/android_webview/DeveloperUiLauncherManifest__${target_name}.xml" + + jinja_template("${target_name}__manifest") { + input = "java/DeveloperUiLauncherManifest.xml" + output = _manifest_file + variables = [ "icon_enabled=$default_enabled_state" ] + } + + # Define an android resources target with an AndroidManifest and no actual resources to merge + # the activity alias defined in DeveloperUiLauncherManifest.xml to the final APK mainfest of the + # target that depends on it. + android_resources(target_name) { + resource_dirs = [] + custom_package = "org.chromium.android_webview.devui.icon" + android_manifest = _manifest_file + android_manifest_dep = ":${target_name}__manifest" + } } -android_resources("monochrome_devui_launcher_icon_resources") { - resource_dirs = [] - android_manifest = "java/MonochromeDeveloperUiLauncherManifest.xml" - custom_package = "org.chromium.android_webview.devui.icon" +webview_devui_launcher("system_webview_devui_launcher_icon_resources") { + default_enabled_state = standalone_or_trichrome_icon_default_enabled_state +} + +webview_devui_launcher("monochrome_devui_launcher_icon_resources") { + default_enabled_state = monochrome_launcher_icon_default_enabled_state } jinja_template("system_webview_manifest") {
diff --git a/android_webview/nonembedded/java/DeveloperUiLauncherManifest.xml b/android_webview/nonembedded/java/DeveloperUiLauncherManifest.xml index a1457e8..77533f6 100644 --- a/android_webview/nonembedded/java/DeveloperUiLauncherManifest.xml +++ b/android_webview/nonembedded/java/DeveloperUiLauncherManifest.xml
@@ -8,6 +8,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.chromium.android_webview.devui"> + <!-- required so Manifest merger doesn't add unused permissions see https://crbug.com/1046380 --> <uses-sdk android:minSdkVersion="21" /> <!--suppress HardcodedText --> @@ -15,7 +16,8 @@ <activity-alias android:name="org.chromium.android_webview.devui.LauncherActivity" android:targetActivity="org.chromium.android_webview.devui.MainActivity" android:label="WebView DevTools" - android:exported="true"> + android:exported="true" + android:enabled="{{ icon_enabled }}"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
diff --git a/android_webview/nonembedded/java/MonochromeDeveloperUiLauncherManifest.xml b/android_webview/nonembedded/java/MonochromeDeveloperUiLauncherManifest.xml deleted file mode 100644 index 1a156d9d..0000000 --- a/android_webview/nonembedded/java/MonochromeDeveloperUiLauncherManifest.xml +++ /dev/null
@@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright 2020 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. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.chromium.android_webview.devui"> - - <uses-sdk android:minSdkVersion="24" /> - - <!-- This should only be merged to Monochrome manifest --> - <!--suppress HardcodedText --> - <application> - <activity-alias android:name="org.chromium.android_webview.devui.MonochromeLauncherActivity" - android:targetActivity="org.chromium.android_webview.devui.MainActivity" - android:label="WebView DevTools" - android:exported="true" - android:enabled="false"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity-alias> - </application> -</manifest>
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java index 71e8715f..17e89e5b 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java
@@ -99,23 +99,18 @@ public static void postDeveloperUiLauncherIconTask() { PostTask.postTask(TaskTraits.BEST_EFFORT, () -> { Context context = ContextUtils.getApplicationContext(); - try { - ComponentName devToolsLauncherActivity = new ComponentName( - context, "org.chromium.android_webview.devui.MonochromeLauncherActivity"); - if (WebViewPackageHelper.isCurrentSystemWebViewImplementation(context)) { - // Enable the component to show the launcher icon. - context.getPackageManager().setComponentEnabledSetting(devToolsLauncherActivity, - PackageManager.COMPONENT_ENABLED_STATE_ENABLED, - PackageManager.DONT_KILL_APP); - } else { - // Disable the component to hide the launcher icon. - context.getPackageManager().setComponentEnabledSetting(devToolsLauncherActivity, - PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, - PackageManager.DONT_KILL_APP); - } - } catch (IllegalArgumentException e) { - // If MonochromeLauncherActivity doesn't exist, Dynamically showing/hiding DevTools - // launcher icon is not enabled in this package; e.g when it is a stable channel. + ComponentName devToolsLauncherActivity = new ComponentName( + context, "org.chromium.android_webview.devui.LauncherActivity"); + if (WebViewPackageHelper.isCurrentSystemWebViewImplementation(context)) { + // Enable the component to show the launcher icon. + context.getPackageManager().setComponentEnabledSetting(devToolsLauncherActivity, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + } else { + // Disable the component to hide the launcher icon. + context.getPackageManager().setComponentEnabledSetting(devToolsLauncherActivity, + PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, + PackageManager.DONT_KILL_APP); } }); }
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni index 8a13d74..6a28c2f 100644 --- a/android_webview/system_webview_apk_tmpl.gni +++ b/android_webview/system_webview_apk_tmpl.gni
@@ -44,6 +44,7 @@ deps += [ "//android_webview:locale_pak_assets", "//android_webview:pak_file_assets", + "//android_webview/nonembedded:system_webview_devui_launcher_icon_resources", ] if (_exclude_weblayer_java) { @@ -68,10 +69,6 @@ alternative_android_sdk_dep = webview_framework_dep } - if (webview_devui_show_icon) { - deps += [ "//android_webview/nonembedded:devui_launcher_icon_resources" ] - } - _use_trichrome_library = defined(use_trichrome_library) && use_trichrome_library assert(
diff --git a/android_webview/variables.gni b/android_webview/variables.gni index aaa4d94..946f84e 100644 --- a/android_webview/variables.gni +++ b/android_webview/variables.gni
@@ -6,13 +6,19 @@ import("//weblayer/variables.gni") declare_args() { - # Show a launcher icon to open WebView developer UI. This is enabled by - # default for all prestable builds. The icon for Monochrome is shown - # dynamically at runtime if Monochrome is the current selected system WebView - # implementation or hidden otherwise. - webview_devui_show_icon = android_channel != "stable" + # Always show a launcher icon to open WebView developer UI for all build variants and channels. + # When this is off, all prestable build variants will still show launcher icons except for + # Monochrome which will only show its launcher icon when it's the selected WebView provider. + webview_devui_always_show_icon = false } +# Used in standalone and trichrome, configures whether the launcher icon is on or off all the time +standalone_or_trichrome_icon_default_enabled_state = + android_channel != "stable" || webview_devui_always_show_icon + +# Used only in monochrome, configures whether the launcher icon is on all the time vs. on conditionally +monochrome_launcher_icon_default_enabled_state = webview_devui_always_show_icon + system_webview_android_manifest = "$root_gen_dir/android_webview/system_webview_apk/AndroidManifest.xml" trichrome_webview_android_manifest =
diff --git a/ash/login/ui/login_menu_view.cc b/ash/login/ui/login_menu_view.cc index e8c8b9f8..e9f059b 100644 --- a/ash/login/ui/login_menu_view.cc +++ b/ash/login/ui/login_menu_view.cc
@@ -135,7 +135,7 @@ SetFocusBehavior(views::View::FocusBehavior::ALWAYS); scroller_ = new views::ScrollView(); - scroller_->SetBackgroundColor(SK_ColorTRANSPARENT); + scroller_->SetBackgroundColor(base::nullopt); scroller_->SetDrawOverflowIndicator(false); scroller_->ClipHeightTo(kMenuItemHeightDp, kMenuItemHeightDp * 5); AddChildView(scroller_);
diff --git a/ash/media/media_notification_controller_impl.h b/ash/media/media_notification_controller_impl.h index 939e4d5..6170360 100644 --- a/ash/media/media_notification_controller_impl.h +++ b/ash/media/media_notification_controller_impl.h
@@ -50,7 +50,9 @@ void HideNotification(const std::string& id) override; void RemoveItem(const std::string& id) override; scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override; - void LogMediaSessionActionButtonPressed(const std::string& id) override {} + void LogMediaSessionActionButtonPressed( + const std::string& id, + media_session::mojom::MediaSessionAction action) override {} std::unique_ptr<MediaNotificationContainerImpl> CreateMediaNotification( const message_center::Notification& notification);
diff --git a/ash/system/tray/detailed_view_delegate.cc b/ash/system/tray/detailed_view_delegate.cc index ad6974e3..c8e4128 100644 --- a/ash/system/tray/detailed_view_delegate.cc +++ b/ash/system/tray/detailed_view_delegate.cc
@@ -114,8 +114,8 @@ tray_controller_->CloseBubble(); } -SkColor DetailedViewDelegate::GetBackgroundColor() { - return SK_ColorTRANSPARENT; +base::Optional<SkColor> DetailedViewDelegate::GetBackgroundColor() { + return base::nullopt; } bool DetailedViewDelegate::IsOverflowIndicatorEnabled() const {
diff --git a/ash/system/tray/detailed_view_delegate.h b/ash/system/tray/detailed_view_delegate.h index 799e3873..997844e 100644 --- a/ash/system/tray/detailed_view_delegate.h +++ b/ash/system/tray/detailed_view_delegate.h
@@ -7,6 +7,7 @@ #include "ash/ash_export.h" #include "base/macros.h" +#include "base/optional.h" #include "base/strings/string16.h" #include "third_party/skia/include/core/SkColor.h" @@ -44,7 +45,7 @@ virtual void CloseBubble(); // Get the background color of the detailed view. - virtual SkColor GetBackgroundColor(); + virtual base::Optional<SkColor> GetBackgroundColor(); // Return true if overflow indicator of ScrollView is enabled. virtual bool IsOverflowIndicatorEnabled() const;
diff --git a/ash/system/tray/tray_detailed_view.cc b/ash/system/tray/tray_detailed_view.cc index 335ea73..f7f43255 100644 --- a/ash/system/tray/tray_detailed_view.cc +++ b/ash/system/tray/tray_detailed_view.cc
@@ -268,16 +268,11 @@ // TrayDetailedView: TrayDetailedView::TrayDetailedView(DetailedViewDelegate* delegate) - : delegate_(delegate), - box_layout_(nullptr), - scroller_(nullptr), - scroll_content_(nullptr), - progress_bar_(nullptr), - tri_view_(nullptr), - back_button_(nullptr) { + : delegate_(delegate) { box_layout_ = SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); - SetBackground(views::CreateSolidBackground(delegate_->GetBackgroundColor())); + SetBackground(views::CreateSolidBackground( + delegate_->GetBackgroundColor().value_or(SK_ColorTRANSPARENT))); } TrayDetailedView::~TrayDetailedView() = default; @@ -314,13 +309,12 @@ void TrayDetailedView::CreateScrollableList() { DCHECK(!scroller_); auto scroll_content = std::make_unique<ScrollContentsView>(delegate_); - scroller_ = new views::ScrollView; + scroller_ = AddChildView(std::make_unique<views::ScrollView>()); scroller_->SetDrawOverflowIndicator(delegate_->IsOverflowIndicatorEnabled()); scroll_content_ = scroller_->SetContents(std::move(scroll_content)); // TODO(varkha): Make the sticky rows work with EnableViewPortLayer(). scroller_->SetBackgroundColor(delegate_->GetBackgroundColor()); - AddChildView(scroller_); box_layout_->SetFlexForView(scroller_, 1); } @@ -423,7 +417,9 @@ void TrayDetailedView::ShowProgress(double value, bool visible) { DCHECK(tri_view_); if (!progress_bar_) { - progress_bar_ = new views::ProgressBar(kTitleRowProgressBarHeight); + progress_bar_ = AddChildViewAt( + std::make_unique<views::ProgressBar>(kTitleRowProgressBarHeight), + kTitleRowSeparatorIndex + 1); progress_bar_->GetViewAccessibility().OverrideName( l10n_util::GetStringUTF16( IDS_ASH_STATUS_TRAY_NETWORK_PROGRESS_ACCESSIBLE_NAME)); @@ -432,7 +428,6 @@ AshColorProvider::Get()->GetContentLayerColor( AshColorProvider::ContentLayerType::kProminentIconButton, AshColorProvider::AshColorMode::kDark)); - AddChildViewAt(progress_bar_, kTitleRowSeparatorIndex + 1); } progress_bar_->SetValue(value);
diff --git a/ash/system/tray/tray_detailed_view.h b/ash/system/tray/tray_detailed_view.h index acc18935..265f132 100644 --- a/ash/system/tray/tray_detailed_view.h +++ b/ash/system/tray/tray_detailed_view.h
@@ -154,18 +154,18 @@ void TransitionToMainView(); DetailedViewDelegate* const delegate_; - views::BoxLayout* box_layout_; - views::ScrollView* scroller_; - views::View* scroll_content_; - views::ProgressBar* progress_bar_; + views::BoxLayout* box_layout_ = nullptr; + views::ScrollView* scroller_ = nullptr; + views::View* scroll_content_ = nullptr; + views::ProgressBar* progress_bar_ = nullptr; - ScrollBorder* scroll_border_; // Weak reference + ScrollBorder* scroll_border_ = nullptr; // Weak reference // The container view for the top-most title row in material design. - TriView* tri_view_; + TriView* tri_view_ = nullptr; // The back button that appears in the material design title row. Not owned. - views::Button* back_button_; + views::Button* back_button_ = nullptr; DISALLOW_COPY_AND_ASSIGN(TrayDetailedView); };
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index 07bb238..2da5339f 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -1987,7 +1987,7 @@ auto* overview_item = overview_session->GetOverviewItemForWindow(window.get()); DragItemToPoint(overview_item, window->GetBoundsInScreen().CenterPoint(), - GetEventGenerator(), /*drop=*/true); + GetEventGenerator(), /*by_touch_gestures=*/true); // Exit overview and add a new desk, then re-enter overview. Expect that now // the desks bar is visible.
diff --git a/ash/wm/splitview/split_view_drag_indicators_unittest.cc b/ash/wm/splitview/split_view_drag_indicators_unittest.cc index 8baa5467..460857c 100644 --- a/ash/wm/splitview/split_view_drag_indicators_unittest.cc +++ b/ash/wm/splitview/split_view_drag_indicators_unittest.cc
@@ -13,6 +13,7 @@ #include "ash/wm/overview/overview_grid.h" #include "ash/wm/overview/overview_item.h" #include "ash/wm/overview/overview_session.h" +#include "ash/wm/overview/overview_test_util.h" #include "ash/wm/splitview/split_view_constants.h" #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" @@ -82,19 +83,6 @@ SplitViewController::NONE; } - OverviewItem* GetOverviewItemForWindow(aura::Window* window, - int grid_index = 0) { - auto& windows = overview_session_->grid_list()[grid_index]->window_list(); - auto iter = - std::find_if(windows.cbegin(), windows.cend(), - [window](const std::unique_ptr<OverviewItem>& item) { - return item->Contains(window); - }); - if (iter == windows.end()) - return nullptr; - return iter->get(); - } - float GetEdgeInset(int screen_width) const { return screen_width * kHighlightScreenPrimaryAxisRatio + kHighlightScreenEdgePaddingDp; @@ -296,8 +284,7 @@ ToggleOverview(); // Start dragging from overview. - OverviewItem* item = - GetOverviewItemForWindow(window1.get(), /*is_touch_dragging=*/false); + OverviewItem* item = GetOverviewItemForWindow(window1.get()); gfx::PointF start_location(item->target_bounds().CenterPoint()); overview_session_->InitiateDrag(item, start_location, /*is_touch_dragging=*/false);
diff --git a/base/android/jni_array.cc b/base/android/jni_array.cc index c339c39..9626abe 100644 --- a/base/android/jni_array.cc +++ b/base/android/jni_array.cc
@@ -32,8 +32,8 @@ CheckException(env); DCHECK(byte_array); - env->SetByteArrayRegion( - byte_array, 0, len, reinterpret_cast<const jbyte*>(bytes)); + env->SetByteArrayRegion(byte_array, 0, len, + reinterpret_cast<const jbyte*>(bytes)); CheckException(env); return ScopedJavaLocalRef<jbyteArray>(env, byte_array); @@ -41,7 +41,7 @@ ScopedJavaLocalRef<jbyteArray> ToJavaByteArray( JNIEnv* env, - const std::vector<uint8_t>& bytes) { + base::span<const uint8_t> bytes) { return ToJavaByteArray(env, bytes.data(), bytes.size()); } @@ -65,21 +65,22 @@ return ScopedJavaLocalRef<jbooleanArray>(env, boolean_array); } -ScopedJavaLocalRef<jintArray> ToJavaIntArray( - JNIEnv* env, const int* ints, size_t len) { +ScopedJavaLocalRef<jintArray> ToJavaIntArray(JNIEnv* env, + const int* ints, + size_t len) { jintArray int_array = env->NewIntArray(len); CheckException(env); DCHECK(int_array); - env->SetIntArrayRegion( - int_array, 0, len, reinterpret_cast<const jint*>(ints)); + env->SetIntArrayRegion(int_array, 0, len, + reinterpret_cast<const jint*>(ints)); CheckException(env); return ScopedJavaLocalRef<jintArray>(env, int_array); } -ScopedJavaLocalRef<jintArray> ToJavaIntArray( - JNIEnv* env, const std::vector<int>& ints) { +ScopedJavaLocalRef<jintArray> ToJavaIntArray(JNIEnv* env, + base::span<const int> ints) { return ToJavaIntArray(env, ints.data(), ints.size()); } @@ -90,8 +91,8 @@ CheckException(env); DCHECK(long_array); - env->SetLongArrayRegion( - long_array, 0, len, reinterpret_cast<const jlong*>(longs)); + env->SetLongArrayRegion(long_array, 0, len, + reinterpret_cast<const jlong*>(longs)); CheckException(env); return ScopedJavaLocalRef<jlongArray>(env, long_array); @@ -100,19 +101,19 @@ // Returns a new Java long array converted from the given int64_t array. BASE_EXPORT ScopedJavaLocalRef<jlongArray> ToJavaLongArray( JNIEnv* env, - const std::vector<int64_t>& longs) { + base::span<const int64_t> longs) { return ToJavaLongArray(env, longs.data(), longs.size()); } // Returns a new Java float array converted from the given C++ float array. -BASE_EXPORT ScopedJavaLocalRef<jfloatArray> ToJavaFloatArray( - JNIEnv* env, const float* floats, size_t len) { +BASE_EXPORT ScopedJavaLocalRef<jfloatArray> +ToJavaFloatArray(JNIEnv* env, const float* floats, size_t len) { jfloatArray float_array = env->NewFloatArray(len); CheckException(env); DCHECK(float_array); - env->SetFloatArrayRegion( - float_array, 0, len, reinterpret_cast<const jfloat*>(floats)); + env->SetFloatArrayRegion(float_array, 0, len, + reinterpret_cast<const jfloat*>(floats)); CheckException(env); return ScopedJavaLocalRef<jfloatArray>(env, float_array); @@ -120,7 +121,7 @@ BASE_EXPORT ScopedJavaLocalRef<jfloatArray> ToJavaFloatArray( JNIEnv* env, - const std::vector<float>& floats) { + base::span<const float> floats) { return ToJavaFloatArray(env, floats.data(), floats.size()); } @@ -139,15 +140,16 @@ BASE_EXPORT ScopedJavaLocalRef<jdoubleArray> ToJavaDoubleArray( JNIEnv* env, - const std::vector<double>& doubles) { + base::span<const double> doubles) { return ToJavaDoubleArray(env, doubles.data(), doubles.size()); } ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray( - JNIEnv* env, const std::vector<std::string>& v) { + JNIEnv* env, + base::span<const std::string> v) { ScopedJavaLocalRef<jclass> byte_array_clazz = GetClass(env, "[B"); - jobjectArray joa = env->NewObjectArray(v.size(), - byte_array_clazz.obj(), NULL); + jobjectArray joa = + env->NewObjectArray(v.size(), byte_array_clazz.obj(), nullptr); CheckException(env); for (size_t i = 0; i < v.size(); ++i) { @@ -158,10 +160,27 @@ return ScopedJavaLocalRef<jobjectArray>(env, joa); } +ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray( + JNIEnv* env, + base::span<std::vector<uint8_t>> v) { + ScopedJavaLocalRef<jclass> byte_array_clazz = GetClass(env, "[B"); + jobjectArray joa = + env->NewObjectArray(v.size(), byte_array_clazz.obj(), nullptr); + CheckException(env); + + for (size_t i = 0; i < v.size(); ++i) { + ScopedJavaLocalRef<jbyteArray> byte_array = + ToJavaByteArray(env, v[i].data(), v[i].size()); + env->SetObjectArrayElement(joa, i, byte_array.obj()); + } + return ScopedJavaLocalRef<jobjectArray>(env, joa); +} + ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings( - JNIEnv* env, const std::vector<std::string>& v) { + JNIEnv* env, + base::span<const std::string> v) { ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String"); - jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL); + jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), nullptr); CheckException(env); for (size_t i = 0; i < v.size(); ++i) { @@ -173,12 +192,12 @@ ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStringArray( JNIEnv* env, - const std::vector<std::vector<string16>>& vec_outer) { + base::span<const std::vector<string16>> vec_outer) { ScopedJavaLocalRef<jclass> string_array_clazz = GetClass(env, "[Ljava/lang/String;"); jobjectArray joa = - env->NewObjectArray(vec_outer.size(), string_array_clazz.obj(), NULL); + env->NewObjectArray(vec_outer.size(), string_array_clazz.obj(), nullptr); CheckException(env); for (size_t i = 0; i < vec_outer.size(); ++i) { @@ -191,9 +210,10 @@ } ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings( - JNIEnv* env, const std::vector<string16>& v) { + JNIEnv* env, + base::span<const string16> v) { ScopedJavaLocalRef<jclass> string_clazz = GetClass(env, "java/lang/String"); - jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), NULL); + jobjectArray joa = env->NewObjectArray(v.size(), string_clazz.obj(), nullptr); CheckException(env); for (size_t i = 0; i < v.size(); ++i) {
diff --git a/base/android/jni_array.h b/base/android/jni_array.h index 2bb10379..a6a2ebe 100644 --- a/base/android/jni_array.h +++ b/base/android/jni_array.h
@@ -12,6 +12,7 @@ #include <vector> #include "base/android/scoped_java_ref.h" +#include "base/containers/span.h" #include "base/strings/string16.h" namespace base { @@ -24,7 +25,7 @@ BASE_EXPORT ScopedJavaLocalRef<jbyteArray> ToJavaByteArray( JNIEnv* env, - const std::vector<uint8_t>& bytes); + base::span<const uint8_t> bytes); // Returns a new Java byte array converted from the given string. No UTF-8 // conversion is performed. @@ -41,7 +42,8 @@ JNIEnv* env, const int* ints, size_t len); BASE_EXPORT ScopedJavaLocalRef<jintArray> ToJavaIntArray( - JNIEnv* env, const std::vector<int>& ints); + JNIEnv* env, + base::span<const int> ints); // Returns a new Java long array converted from the given int64_t array. BASE_EXPORT ScopedJavaLocalRef<jlongArray> ToJavaLongArray(JNIEnv* env, @@ -50,7 +52,7 @@ BASE_EXPORT ScopedJavaLocalRef<jlongArray> ToJavaLongArray( JNIEnv* env, - const std::vector<int64_t>& longs); + base::span<const int64_t> longs); // Returns a new Java float array converted from the given C++ float array. BASE_EXPORT ScopedJavaLocalRef<jfloatArray> ToJavaFloatArray( @@ -58,7 +60,7 @@ BASE_EXPORT ScopedJavaLocalRef<jfloatArray> ToJavaFloatArray( JNIEnv* env, - const std::vector<float>& floats); + base::span<const float> floats); // Returns a new Java double array converted from the given C++ double array. BASE_EXPORT ScopedJavaLocalRef<jdoubleArray> @@ -66,21 +68,28 @@ BASE_EXPORT ScopedJavaLocalRef<jdoubleArray> ToJavaDoubleArray( JNIEnv* env, - const std::vector<double>& doubles); + base::span<const double> doubles); // Returns a array of Java byte array converted from |v|. BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray( - JNIEnv* env, const std::vector<std::string>& v); + JNIEnv* env, + base::span<const std::string> v); + +BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfByteArray( + JNIEnv* env, + base::span<std::vector<uint8_t>> v); BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings( - JNIEnv* env, const std::vector<std::string>& v); + JNIEnv* env, + base::span<const std::string> v); BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStrings( - JNIEnv* env, const std::vector<string16>& v); + JNIEnv* env, + base::span<const string16> v); BASE_EXPORT ScopedJavaLocalRef<jobjectArray> ToJavaArrayOfStringArray( JNIEnv* env, - const std::vector<std::vector<string16>>& v); + base::span<const std::vector<string16>> v); // Converts a Java string array to a native array. BASE_EXPORT void AppendJavaStringArrayToStringVector(
diff --git a/base/fuchsia/time_zone_data_unittest.cc b/base/fuchsia/time_zone_data_unittest.cc index 5d078c4..bb6f4ae 100644 --- a/base/fuchsia/time_zone_data_unittest.cc +++ b/base/fuchsia/time_zone_data_unittest.cc
@@ -4,7 +4,6 @@ #include "base/i18n/icu_util.h" -#include "base/environment.h" #include "base/files/file_util.h" #include "base/strings/string_util.h" #include "build/build_config.h" @@ -28,8 +27,6 @@ class TimeZoneDataTest : public testing::Test { protected: - TimeZoneDataTest() : env_(base::Environment::Create()) {} - void SetUp() override { ResetIcu(); } void TearDown() override { ResetIcu(); } @@ -48,8 +45,6 @@ *icu_version = icu::TimeZone::getTZDataVersion(err); ASSERT_EQ(U_ZERO_ERROR, err) << u_errorName(err); } - - std::unique_ptr<base::Environment> env_; }; // Loads a file revision.txt from the actual underlying filesystem, which @@ -67,8 +62,7 @@ return; } - // Ensure that timezone data is loaded from the default location. - ASSERT_TRUE(env_->UnSetVar("ICU_TIMEZONE_FILES_DIR")); + // ResetIcu() ensures that time zone data is loaded from the default location. ASSERT_TRUE(InitializeICU()); std::string expected; @@ -87,7 +81,7 @@ // ICU library versions. TEST_F(TimeZoneDataTest, TestLoadingTimeZoneDataFromKnownConfigs) { ASSERT_TRUE(base::DirectoryExists(base::FilePath(kTzDataDirPath))); - ASSERT_TRUE(env_->SetVar("ICU_TIMEZONE_FILES_DIR", kTzDataDirPath)); + SetIcuTimeZoneDataDirForTesting(kTzDataDirPath); EXPECT_TRUE(InitializeICU()); std::string actual; @@ -97,7 +91,7 @@ } TEST_F(TimeZoneDataTest, DoesNotCrashWithInvalidPath) { - ASSERT_TRUE(env_->SetVar("ICU_TIMEZONE_FILES_DIR", "/some/nonexistent/path")); + SetIcuTimeZoneDataDirForTesting("/some/nonexistent/path"); EXPECT_TRUE(InitializeICU()); std::string actual;
diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc index 50b7faf..425a0b2 100644 --- a/base/i18n/icu_util.cc +++ b/base/i18n/icu_util.cc
@@ -89,7 +89,7 @@ // only implemented for OS_FUCHSIA. #if defined(OS_FUCHSIA) // The environment variable used to point the ICU data loader to the directory -// containing timezone data. This is available from ICU version 54. The env +// containing time zone data. This is available from ICU version 54. The env // variable approach is antiquated by today's standards (2019), but is the // recommended way to configure ICU. // @@ -120,6 +120,12 @@ MemoryMappedFile* g_icudtl_extra_mapped_file = nullptr; MemoryMappedFile::Region g_icudtl_extra_region; +#if defined(OS_FUCHSIA) +// The directory from which the ICU data loader will be configured to load time +// zone data. It is only changed by SetIcuTimeZoneDataDirForTesting(). +const char* g_icu_time_zone_data_dir = kIcuTimeZoneDataDir; +#endif // defined(OS_FUCHSIA) + struct PfRegion { public: PlatformFile pf; @@ -208,30 +214,20 @@ g_icudtl_region = pf_region->region; } -// Loads external timezone data, for configurations where it makes sense. -// If the timezone data directory is not set up properly, we continue but log -// appropriate information for debugging. +// Configures ICU to load external time zone data, if appropriate. void InitializeExternalTimeZoneData() { #if defined(OS_FUCHSIA) - std::unique_ptr<base::Environment> env = base::Environment::Create(); - - // We only set the variable if it was not already set by a test. Fuchsia - // normally does not otherwise set env variables in production code. - if (!env->HasVar(kIcuTimeZoneEnvVariable)) { - env->SetVar(kIcuTimeZoneEnvVariable, kIcuTimeZoneDataDir); - } - std::string tzdata_dir; - env->GetVar(kIcuTimeZoneEnvVariable, &tzdata_dir); - - // Try opening the path to check if present. No need to verify that it is a - // directory since ICU loading will return an error if the TimeZone data is - // wrong. - if (!base::DirectoryExists(base::FilePath(tzdata_dir))) { + if (!base::DirectoryExists(base::FilePath(g_icu_time_zone_data_dir))) { // TODO(https://crbug.com/1061262): Make this FATAL unless expected. - PLOG(WARNING) << "Could not open: '" << tzdata_dir + PLOG(WARNING) << "Could not open: '" << g_icu_time_zone_data_dir << "'. Using built-in timezone database"; return; } + + // Set the environment variable to override the location used by ICU. + // Loading can still fail if the directory is empty or its data is invalid. + std::unique_ptr<base::Environment> env = base::Environment::Create(); + env->SetVar(kIcuTimeZoneEnvVariable, g_icu_time_zone_data_dir); #endif // defined(OS_FUCHSIA) } @@ -323,10 +319,10 @@ // than relying on ICU's internal initialization. void InitializeIcuTimeZone() { #if defined(OS_ANDROID) - // On Android, we can't leave it up to ICU to set the default timezone - // because ICU's timezone detection does not work in many timezones (e.g. + // On Android, we can't leave it up to ICU to set the default time zone + // because ICU's time zone detection does not work in many time zones (e.g. // Australia/Sydney, Asia/Seoul, Europe/Paris ). Use JNI to detect the host - // timezone and set the ICU default timezone accordingly in advance of + // time zone and set the ICU default time zone accordingly in advance of // actual use. See crbug.com/722821 and // https://ssl.icu-project.org/trac/ticket/13208 . string16 zone_id = android::GetDefaultTimeZoneId(); @@ -334,7 +330,7 @@ icu::UnicodeString(FALSE, zone_id.data(), zone_id.length()))); #elif defined(OS_FUCHSIA) // The platform-specific mechanisms used by ICU's detectHostTimeZone() to - // determine the default timezone will not work on Fuchsia. Therefore, + // determine the default time zone will not work on Fuchsia. Therefore, // proactively set the default system. // This is also required by TimeZoneMonitorFuchsia::ProfileMayHaveChanged(), // which uses the current default to detect whether the time zone changed in @@ -346,7 +342,7 @@ icu::TimeZone::adoptDefault( icu::TimeZone::createTimeZone(icu::UnicodeString::fromUTF8(zone_id))); #elif defined(OS_LINUX) && !BUILDFLAG(IS_CHROMECAST) - // To respond to the timezone change properly, the default timezone + // To respond to the time zone change properly, the default time zone // cache in ICU has to be populated on starting up. // See TimeZoneMonitorLinux::NotifyClientsFromImpl(). std::unique_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault()); @@ -471,7 +467,17 @@ g_icudtl_mapped_file = nullptr; g_icudtl_extra_pf = kInvalidPlatformFile; g_icudtl_extra_mapped_file = nullptr; +#if defined(OS_FUCHSIA) + g_icu_time_zone_data_dir = kIcuTimeZoneDataDir; +#endif // defined(OS_FUCHSIA) } + +#if defined(OS_FUCHSIA) +// |dir| must remain valid until ResetGlobalsForTesting() is called. +void SetIcuTimeZoneDataDirForTesting(const char* dir) { + g_icu_time_zone_data_dir = dir; +} +#endif // defined(OS_FUCHSIA) #endif // (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE) bool InitializeICU() {
diff --git a/base/i18n/icu_util.h b/base/i18n/icu_util.h index 6a03863..cc133079 100644 --- a/base/i18n/icu_util.h +++ b/base/i18n/icu_util.h
@@ -49,6 +49,11 @@ const MemoryMappedFile::Region& data_region); BASE_I18N_EXPORT void ResetGlobalsForTesting(); + +#if defined(OS_FUCHSIA) +// Overrides the directory used by ICU for external time zone data. +BASE_I18N_EXPORT void SetIcuTimeZoneDataDirForTesting(const char* dir); +#endif // defined(OS_FUCHSIA) #endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE // In a test binary, initialize functions might be called twice.
diff --git a/base/process/process_unittest.cc b/base/process/process_unittest.cc index 8f449dd..465825f 100644 --- a/base/process/process_unittest.cc +++ b/base/process/process_unittest.cc
@@ -248,7 +248,6 @@ Process process(SpawnChild("FastSleepyChildProcess")); ASSERT_TRUE(process.IsValid()); - const int kDummyExitCode = 42; int exit_code = kDummyExitCode; EXPECT_TRUE(process.WaitForExit(&exit_code)); EXPECT_EQ(0, exit_code); @@ -258,7 +257,6 @@ Process process(SpawnChild("SleepyChildProcess")); ASSERT_TRUE(process.IsValid()); - const int kDummyExitCode = 42; int exit_code = kDummyExitCode; TimeDelta timeout = TestTimeouts::tiny_timeout(); EXPECT_FALSE(process.WaitForExitWithTimeout(timeout, &exit_code)); @@ -275,7 +273,6 @@ base::win::ScopedHandle stop_watching_handle( CreateEvent(nullptr, TRUE, FALSE, nullptr)); - const int kDummyExitCode = 42; int exit_code = kDummyExitCode; EXPECT_EQ(process.WaitForExitOrEvent(stop_watching_handle, &exit_code), base::Process::WaitExitStatus::PROCESS_EXITED); @@ -289,7 +286,6 @@ base::win::ScopedHandle stop_watching_handle( CreateEvent(nullptr, TRUE, TRUE, nullptr)); - const int kDummyExitCode = 42; int exit_code = kDummyExitCode; EXPECT_EQ(process.WaitForExitOrEvent(stop_watching_handle, &exit_code), base::Process::WaitExitStatus::STOP_EVENT_SIGNALED);
diff --git a/base/trace_event/trace_event_impl.h b/base/trace_event/trace_event_impl.h index 161cd6d..eb41386 100644 --- a/base/trace_event/trace_event_impl.h +++ b/base/trace_event/trace_event_impl.h
@@ -112,13 +112,6 @@ const ArgumentFilterPredicate& argument_filter_predicate) const; void AppendPrettyPrinted(std::ostringstream* out) const; - // TODO(898794): Remove once caller has been updated. - static void AppendValueAsJSON(unsigned char type, - TraceValue value, - std::string* out) { - value.AppendAsJSON(type, out); - } - TimeTicks timestamp() const { return timestamp_; } ThreadTicks thread_timestamp() const { return thread_timestamp_; } ThreadInstructionCount thread_instruction_count() const {
diff --git a/base/trace_event/traced_value.cc b/base/trace_event/traced_value.cc index 3dc5409c..152d9f2 100644 --- a/base/trace_event/traced_value.cc +++ b/base/trace_event/traced_value.cc
@@ -269,7 +269,7 @@ TraceEvent::TraceValue json_value; CHECK(it.ReadBool(&json_value.as_bool)); maybe_append_key_name(state_stack[current_state_index], &it, out); - TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_BOOL, json_value, out); + json_value.AppendAsJSON(TRACE_VALUE_TYPE_BOOL, out); break; } @@ -279,7 +279,7 @@ maybe_append_key_name(state_stack[current_state_index], &it, out); TraceEvent::TraceValue json_value; json_value.as_int = value; - TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_INT, json_value, out); + json_value.AppendAsJSON(TRACE_VALUE_TYPE_INT, out); break; } @@ -287,8 +287,7 @@ TraceEvent::TraceValue json_value; CHECK(it.ReadDouble(&json_value.as_double)); maybe_append_key_name(state_stack[current_state_index], &it, out); - TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_DOUBLE, json_value, - out); + json_value.AppendAsJSON(TRACE_VALUE_TYPE_DOUBLE, out); break; } @@ -298,8 +297,7 @@ maybe_append_key_name(state_stack[current_state_index], &it, out); TraceEvent::TraceValue json_value; json_value.as_string = value.c_str(); - TraceEvent::AppendValueAsJSON(TRACE_VALUE_TYPE_STRING, json_value, - out); + json_value.AppendAsJSON(TRACE_VALUE_TYPE_STRING, out); break; } @@ -399,12 +397,23 @@ } break; case kTypeDouble: { - double value; - CHECK(it.ReadDouble(&value)); - if (cur_dict) { - cur_dict->SetDoubleKey(ReadKeyName(it), value); + TraceEvent::TraceValue trace_value; + CHECK(it.ReadDouble(&trace_value.as_double)); + Value base_value; + if (!std::isfinite(trace_value.as_double)) { + // base::Value doesn't support nan and infinity values. Use strings + // for them instead. This follows the same convention in + // AppendAsTraceFormat(), supported by TraceValue::Append*(). + std::string value_string; + trace_value.AppendAsString(TRACE_VALUE_TYPE_DOUBLE, &value_string); + base_value = Value(value_string); } else { - cur_list->Append(value); + base_value = Value(trace_value.as_double); + } + if (cur_dict) { + cur_dict->SetKey(ReadKeyName(it), std::move(base_value)); + } else { + cur_list->Append(std::move(base_value)); } } break;
diff --git a/base/trace_event/traced_value_unittest.cc b/base/trace_event/traced_value_unittest.cc index 4278c453c..09b03d4 100644 --- a/base/trace_event/traced_value_unittest.cc +++ b/base/trace_event/traced_value_unittest.cc
@@ -8,6 +8,7 @@ #include <utility> +#include "base/strings/string_util.h" #include "base/values.h" #include "testing/gtest/include/gtest/gtest.h" @@ -126,5 +127,29 @@ EXPECT_EQ("{\"b\":2,\"c\":[\"foo\"],\"f\":3,\"g\":{}}", json); } +TEST(TraceEventArgumentTest, NanAndInfinityJSON) { + TracedValueJSON value; + value.SetDouble("nan", std::nan("")); + value.SetDouble("infinity", INFINITY); + value.SetDouble("negInfinity", -INFINITY); + std::string json; + value.AppendAsTraceFormat(&json); + EXPECT_EQ( + "{\"nan\":\"NaN\",\"infinity\":\"Infinity\"," + "\"negInfinity\":\"-Infinity\"}", + json); + + std::string formatted_json = value.ToFormattedJSON(); + // Remove CR and LF to make the result platform-independent. + ReplaceChars(formatted_json, "\n\r", "", &formatted_json); + EXPECT_EQ( + "{" + " \"infinity\": \"Infinity\"," + " \"nan\": \"NaN\"," + " \"negInfinity\": \"-Infinity\"" + "}", + formatted_json); +} + } // namespace trace_event } // namespace base
diff --git a/build/android/BUILD.gn b/build/android/BUILD.gn index 503d6ea..f796e8f 100644 --- a/build/android/BUILD.gn +++ b/build/android/BUILD.gn
@@ -76,7 +76,7 @@ # Proguard is needed only when using apks (rather than native executables). if (enable_java_templates) { - deps = [ "//third_party/proguard:proguard603_java" ] + deps = [ "//build/android/stacktrace:java_deobfuscate" ] } }
diff --git a/build/android/apk_operations.py b/build/android/apk_operations.py index 8ed169f..8bd8390 100755 --- a/build/android/apk_operations.py +++ b/build/android/apk_operations.py
@@ -1460,12 +1460,7 @@ def Run(self): deobfuscate = None if self.args.proguard_mapping_path and not self.args.no_deobfuscate: - try: - deobfuscate = deobfuscator.Deobfuscator(self.args.proguard_mapping_path) - except OSError: - sys.stderr.write('Error executing "bin/java_deobfuscate". ' - 'Did you forget to build it?\n') - sys.exit(1) + deobfuscate = deobfuscator.Deobfuscator(self.args.proguard_mapping_path) stack_script_context = _StackScriptContext( self.args.output_directory,
diff --git a/build/android/docs/java_optimization.md b/build/android/docs/java_optimization.md index e0f0ec7..ec3df1df 100644 --- a/build/android/docs/java_optimization.md +++ b/build/android/docs/java_optimization.md
@@ -82,7 +82,7 @@ * `$OUT/bin/chrome_public_apk run` # Launch chrome and run adb logcat 2. Using `java_deobfuscate` - * `$OUT/bin/java_deobfuscate $OUT/apks/ChromePublic.apk.mapping < logcat.txt` + * build/android/stacktrace/java_deobfuscate.py $OUT/apks/ChromePublic.apk.mapping < logcat.txt` * ProGuard mapping files are located beside APKs (ex. `$OUT/apks/ChromePublic.apk` and `$OUT/apks/ChromePublic.apk.mapping`)
diff --git a/build/android/gyp/turbine.py b/build/android/gyp/turbine.py new file mode 100755 index 0000000..1b0f0a22 --- /dev/null +++ b/build/android/gyp/turbine.py
@@ -0,0 +1,167 @@ +#!/usr/bin/env python +# Copyright 2020 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. +"""Wraps bin/helper/turbine and expands @FileArgs.""" + +import argparse +import logging +import os +import shutil +import subprocess +import sys +import time + +from util import build_utils +from util import md5_check + + +def _OnStaleMd5(options, cmd, javac_cmd, files, classpath): + if classpath: + cmd += ['--classpath'] + cmd += classpath + + if options.java_srcjars: + cmd += ['--source_jars'] + cmd += options.java_srcjars + + if files: + # Use jar_path to ensure paths are relative (needed for goma). + files_rsp_path = options.jar_path + '.files_list.txt' + with open(files_rsp_path, 'w') as f: + f.write(' '.join(files)) + # Pass source paths as response files to avoid extremely long command lines + # that are tedius to debug. + cmd += ['--sources'] + cmd += ['@' + files_rsp_path] + + if javac_cmd: + cmd.append('--javacopts') + cmd += javac_cmd + cmd.append('--') # Terminate javacopts + + # Use AtomicOutput so that output timestamps are not updated when outputs + # are not changed. + with build_utils.AtomicOutput(options.jar_path) as f: + cmd += ['--output', f.name] + logging.info('Command: %s' % ' '.join(cmd)) + start = time.time() + subprocess.check_call(cmd) + end = time.time() - start + logging.info('Header compilation took %ss', end) + + logging.info('Completed all steps in _OnStaleMd5') + + +def main(argv): + build_utils.InitLogging('TURBINE_DEBUG') + argv = build_utils.ExpandFileArgs(argv[1:]) + parser = argparse.ArgumentParser() + build_utils.AddDepfileOption(parser) + parser.add_argument( + '--turbine-jar-path', required=True, help='Path to the turbine jar file.') + parser.add_argument( + '--java-srcjars', + action='append', + default=[], + help='List of srcjars to include in compilation.') + parser.add_argument( + '--bootclasspath', + action='append', + default=[], + help='Boot classpath for javac. If this is specified multiple times, ' + 'they will all be appended to construct the classpath.') + parser.add_argument( + '--java-version', + help='Java language version to use in -source and -target args to javac.') + parser.add_argument('--classpath', action='append', help='Classpath to use.') + parser.add_argument( + '--processors', + action='append', + help='GN list of annotation processor main classes.') + parser.add_argument( + '--processorpath', + action='append', + help='GN list of jars that comprise the classpath used for Annotation ' + 'Processors.') + parser.add_argument( + '--processor-args', + action='append', + help='key=value arguments for the annotation processors.') + parser.add_argument('--jar-path', help='Jar output path.', required=True) + options, unknown_args = parser.parse_known_args(argv) + + options.bootclasspath = build_utils.ParseGnList(options.bootclasspath) + options.classpath = build_utils.ParseGnList(options.classpath) + options.processorpath = build_utils.ParseGnList(options.processorpath) + options.processors = build_utils.ParseGnList(options.processors) + options.java_srcjars = build_utils.ParseGnList(options.java_srcjars) + + files = [] + for arg in unknown_args: + # Interpret a path prefixed with @ as a file containing a list of sources. + if arg.startswith('@'): + files.extend(build_utils.ReadSourcesList(arg[1:])) + + cmd = [ + build_utils.JAVA_PATH, '-classpath', options.turbine_jar_path, + 'com.google.turbine.main.Main' + ] + javac_cmd = [] + + # Turbine reads lists from command line args by consuming args until one + # starts with double dash (--). Thus command line args should be grouped + # together and passed in together. + if options.processors: + cmd += ['--processors'] + cmd += options.processors + + if options.java_version: + javac_cmd.extend([ + '-source', + options.java_version, + '-target', + options.java_version, + ]) + if options.java_version == '1.8': + # Android's boot jar doesn't contain all java 8 classes. + options.bootclasspath.append(build_utils.RT_JAR_PATH) + + if options.bootclasspath: + cmd += ['--bootclasspath'] + for bootclasspath in options.bootclasspath: + cmd += bootclasspath.split(':') + + if options.processorpath: + cmd += ['--processorpath'] + cmd += options.processorpath + + if options.processor_args: + for arg in options.processor_args: + javac_cmd.extend(['-A%s' % arg]) + + classpath_inputs = ( + options.bootclasspath + options.classpath + options.processorpath) + + # GN already knows of the java files, so avoid listing individual java files + # in the depfile. + depfile_deps = classpath_inputs + options.java_srcjars + input_paths = depfile_deps + files + + output_paths = [ + options.jar_path, + ] + + input_strings = cmd + options.classpath + files + + md5_check.CallAndWriteDepfileIfStale( + lambda: _OnStaleMd5(options, cmd, javac_cmd, files, options.classpath), + options, + depfile_deps=depfile_deps, + input_paths=input_paths, + input_strings=input_strings, + output_paths=output_paths) + + +if __name__ == '__main__': + sys.exit(main(sys.argv))
diff --git a/build/android/gyp/turbine.pydeps b/build/android/gyp/turbine.pydeps new file mode 100644 index 0000000..1939645 --- /dev/null +++ b/build/android/gyp/turbine.pydeps
@@ -0,0 +1,7 @@ +# Generated by running: +# build/print_python_deps.py --root build/android/gyp --output build/android/gyp/turbine.pydeps build/android/gyp/turbine.py +../../gn_helpers.py +turbine.py +util/__init__.py +util/build_utils.py +util/md5_check.py
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py index 03607d5..f96e3292 100755 --- a/build/android/gyp/write_build_config.py +++ b/build/android/gyp/write_build_config.py
@@ -248,8 +248,8 @@ * `deps_info['interface_jar_path']: Path to the interface jar generated for this library. This corresponds to -a jar file that only contains declarations. Generated by running the `ijar` -tool on `deps_info['jar_path']` +a jar file that only contains declarations. Generated by running the `ijar` on +`deps_info['jar_path']` or the `turbine` tool on source files. * `deps_info['dex_path']`: Path to the `.dex` file generated for this target, from `deps_info['jar_path']`
diff --git a/build/android/pylib/symbols/deobfuscator.py b/build/android/pylib/symbols/deobfuscator.py index ac4ff7e4..9eb62060 100644 --- a/build/android/pylib/symbols/deobfuscator.py +++ b/build/android/pylib/symbols/deobfuscator.py
@@ -20,8 +20,8 @@ class Deobfuscator(object): def __init__(self, mapping_path): - script_path = os.path.join( - constants.GetOutDirectory(), 'bin', 'java_deobfuscate') + script_path = os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'android', + 'stacktrace', 'java_deobfuscate.py') cmd = [script_path, mapping_path] # Allow only one thread to call TransformLines() at a time. self._lock = threading.Lock() @@ -134,7 +134,7 @@ class DeobfuscatorPool(object): # As of Sep 2017, each instance requires about 500MB of RAM, as measured by: - # /usr/bin/time -v out/Release/bin/java_deobfuscate \ + # /usr/bin/time -v build/android/stacktrace/java_deobfuscate.py \ # out/Release/apks/ChromePublic.apk.mapping def __init__(self, mapping_path, pool_size=4): self._mapping_path = mapping_path
diff --git a/build/android/pylib/utils/device_dependencies.py b/build/android/pylib/utils/device_dependencies.py index f20d3b3..a6470da 100644 --- a/build/android/pylib/utils/device_dependencies.py +++ b/build/android/pylib/utils/device_dependencies.py
@@ -8,7 +8,7 @@ from pylib import constants -_BLACKLIST = [ +_EXCLUSIONS = [ re.compile(r'.*OWNERS'), # Should never be included. re.compile(r'.*\.crx'), # Chrome extension zip files. re.compile(os.path.join('.*', @@ -36,15 +36,17 @@ re.compile(os.path.join('.*', 'development', 'scripts', 'stack')), # Required for java deobfuscation on the host: + re.compile(r'.*build/android/stacktrace/.*'), re.compile(r'.*third_party/jdk/.*'), + re.compile(r'.*third_party/proguard/.*'), ] def _FilterDataDeps(abs_host_files): - blacklist = _BLACKLIST + [ - re.compile(os.path.join(constants.GetOutDirectory(), 'bin'))] - return [p for p in abs_host_files - if not any(r.match(p) for r in blacklist)] + exclusions = _EXCLUSIONS + [ + re.compile(os.path.join(constants.GetOutDirectory(), 'bin')) + ] + return [p for p in abs_host_files if not any(r.match(p) for r in exclusions)] def DevicePathComponentsFor(host_path, output_directory):
diff --git a/build/android/pylib/utils/proguard.py b/build/android/pylib/utils/proguard.py index 2d439a5..9d5bae28 100644 --- a/build/android/pylib/utils/proguard.py +++ b/build/android/pylib/utils/proguard.py
@@ -33,11 +33,8 @@ def _GetProguardPath(): - # Use the one in lib.java rather than source tree because it is the one that - # is added to swarming .isolate files. - return os.path.join( - constants.GetOutDirectory(), 'lib.java', 'third_party', 'proguard', - 'proguard603.jar') + return os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', 'proguard', + 'lib', 'proguard603.jar') def Dump(jar_path):
diff --git a/build/android/stacktrace/BUILD.gn b/build/android/stacktrace/BUILD.gn index 978dcba..d6c5ffb 100644 --- a/build/android/stacktrace/BUILD.gn +++ b/build/android/stacktrace/BUILD.gn
@@ -4,12 +4,24 @@ import("//build/config/android/rules.gni") -java_binary("java_deobfuscate") { - main_class = "org.chromium.build.FlushingReTrace" +java_library("java_deobfuscate_java") { sources = [ "java/org/chromium/build/FlushingReTrace.java" ] - deps = [ "//third_party/proguard:retrace_java" ] + + # Avoid using java_prebuilt() to ensure all uses go through the checked-in + # wrapper script. + input_jars_paths = [ + "//third_party/proguard/lib/proguard603.jar", + "//third_party/proguard/lib/retrace603.jar", + ] +} + +# Use the checked-in copy of the wrapper script & .jar rather than the built +# one to simplify usage of the tool. +group("java_deobfuscate") { data = [ - "$root_build_dir/lib.java/build/android/stacktrace/java_deobfuscate.jar", - "$root_build_dir/bin/java_deobfuscate", + "java_deobfuscate.py", + "java_deobfuscate.jar", + "//third_party/proguard/lib/proguard603.jar", + "//third_party/proguard/lib/retrace603.jar", ] }
diff --git a/build/android/stacktrace/README.md b/build/android/stacktrace/README.md index bfa537c5..58ea94b 100644 --- a/build/android/stacktrace/README.md +++ b/build/android/stacktrace/README.md
@@ -1,4 +1,4 @@ -# java_deobfuscate +# java_deobfuscate.py A wrapper around ProGuard's ReTrace tool, which: @@ -7,11 +7,16 @@ The second point here is what allows you to run: - adb logcat | out/Default/bin/java_deobfuscate out/Default/apks/ChromePublic.apk.mapping + adb logcat | build/android/stacktrace/java_deobfuscate.py out/Default/apks/ChromePublic.apk.mapping And have it actually show output without logcat terminating. +## Update Instructions: + + ninja -C out/Release java_deobfuscate + cp out/Release/lib.java/build/android/stacktrace/java_deobfuscate.jar build/android/stacktrace + # stackwalker.py Extracts Breakpad microdumps from a log file and uses `stackwalker` to symbolize
diff --git a/build/android/stacktrace/java_deobfuscate.jar b/build/android/stacktrace/java_deobfuscate.jar new file mode 100644 index 0000000..36a1b70 --- /dev/null +++ b/build/android/stacktrace/java_deobfuscate.jar Binary files differ
diff --git a/build/android/stacktrace/java_deobfuscate.py b/build/android/stacktrace/java_deobfuscate.py new file mode 100755 index 0000000..8c231ecf --- /dev/null +++ b/build/android/stacktrace/java_deobfuscate.py
@@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# +# Copyright 2020 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. +"""Wrapper script for java_deobfuscate. + +This is also a buildable target, but having it pre-built here simplifies usage. +""" + +import os +import sys + +DIR_SOURCE_ROOT = os.path.normpath( + os.path.join(os.path.dirname(__file__), '../../../')) + + +def main(): + classpath = [ + os.path.join(DIR_SOURCE_ROOT, 'build', 'android', 'stacktrace', + 'java_deobfuscate.jar'), + os.path.join(DIR_SOURCE_ROOT, 'third_party', 'proguard', 'lib', + 'proguard603.jar'), + os.path.join(DIR_SOURCE_ROOT, 'third_party', 'proguard', 'lib', + 'retrace603.jar'), + ] + java_path = os.path.join(DIR_SOURCE_ROOT, 'third_party', 'jdk', 'current', + 'bin', 'java') + + cmd = [ + java_path, '-classpath', ':'.join(classpath), + 'org.chromium.build.FlushingReTrace' + ] + cmd.extend(sys.argv[1:]) + os.execvp(cmd[0], cmd) + + +if __name__ == '__main__': + main()
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 2c3b380..8afa139 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -17,8 +17,7 @@ assert(is_android) # These identify targets that have .build_config files (except for android_apk, -# java_binary, android_app_bundle since we never need to -# depend on these). +# java_binary, android_app_bundle since we never need to depend on these). _java_target_patterns = [ "*:*_java", "*:*_javalib", @@ -44,6 +43,13 @@ # Targets that match the patterns but are not actually java targets. _java_target_exceptions = [ "*:*_unpack_aar" ] +# Targets that should be replace by their headers during javac. +_java_header_target_patterns = [ + "*:*_java", + "*:*_javalib", + "*:java", +] + _r8_path = "//third_party/r8/lib/r8.jar" _dexdump_path = "$android_sdk_build_tools/dexdump" @@ -2688,10 +2694,11 @@ # additional_jar_files: Optional list of files to copy into the resulting # .jar file (by default, only .class files are put there). Each entry # has the 'srcPath:dstPath' format. - # enable_errorprone: Optional. If True, use the errorprone compiler to - # check for error-prone constructs in the language. If not provided, - # whether this is enabled depends on chromium_code and the global + # enable_errorprone: If True, use the errorprone compiler to check for + # error-prone constructs in the language. If not provided, whether this is + # enabled depends on chromium_code and the global # use_errorprone_java_compiler variable. + # use_turbine: If True, compile headers using turbine.py. # apk_name: Optional APK name. If provided, will tell compile_java.py to also # generate an .apk.jar.info file under size-info/${apk_name}.apk.jar.info # provider_configurations: Optional list of paths to Java service @@ -2743,16 +2750,20 @@ } action_with_pydeps(target_name) { - script = "//build/android/gyp/compile_java.py" + if (invoker.use_turbine) { + script = "//build/android/gyp/turbine.py" + } else { + script = "//build/android/gyp/compile_java.py" + } depfile = "$target_gen_dir/$target_name.d" deps = _srcjar_deps if (defined(invoker.deps)) { deps += invoker.deps } - outputs = [ invoker.javac_jar_path ] - if (!invoker.enable_errorprone) { - outputs += [ invoker.javac_jar_path + ".info" ] + outputs = [ invoker.output_jar_path ] + if (!invoker.enable_errorprone && !invoker.use_turbine) { + outputs += [ invoker.output_jar_path + ".info" ] } inputs = invoker.java_files + _java_srcjars + [ _build_config ] if (invoker.java_files != []) { @@ -2760,8 +2771,8 @@ } _rebased_build_config = rebase_path(_build_config, root_build_dir) - _rebased_javac_jar_path = - rebase_path(invoker.javac_jar_path, root_build_dir) + _rebased_output_jar_path = + rebase_path(invoker.output_jar_path, root_build_dir) _rebased_java_srcjars = rebase_path(_java_srcjars, root_build_dir) _rebased_depfile = rebase_path(depfile, root_build_dir) _rebased_generated_dir = rebase_path( @@ -2770,13 +2781,23 @@ args = [ "--depfile=$_rebased_depfile", "--generated-dir=$_rebased_generated_dir", - "--jar-path=$_rebased_javac_jar_path", + "--jar-path=$_rebased_output_jar_path", "--java-srcjars=$_rebased_java_srcjars", "--classpath=@FileArg($_rebased_build_config:deps_info:javac_full_interface_classpath)", "--processorpath=@FileArg($_rebased_build_config:javac:processor_classpath)", "--processors=@FileArg($_rebased_build_config:javac:processor_classes)", ] - if (invoker.supports_android) { + if (invoker.use_turbine) { + _turbine_jar_path = "//third_party/turbine/turbine.jar" + inputs += [ _turbine_jar_path ] + args += [ + "--turbine-jar-path", + rebase_path(_turbine_jar_path, root_build_dir), + ] + } + + # Currently turbine does not support JDK11. + if (invoker.supports_android || invoker.use_turbine) { args += [ "--java-version=1.8" ] } if ((!defined(invoker.never_goma) || !invoker.never_goma) && @@ -2846,6 +2867,27 @@ } } + template("java_header_group") { + forward_variables_from(invoker, [ "testonly" ]) + group(target_name) { + if (defined(invoker.deps)) { + deps = [] + foreach(_dep, invoker.deps) { + set_sources_assignment_filter(_java_header_target_patterns) + _target_label = get_label_info(_dep, "label_no_toolchain") + sources = [ _target_label ] + if (sources == []) { + # This is a java dep, so replace it with its header. + deps += [ "${_target_label}__header" ] + } else { + deps += [ _dep ] + } + sources = [] + } + } + } + } + # Create an interface jar from a normal jar. # # Variables @@ -2935,6 +2977,9 @@ # testonly: True iff target should only be used for tests. # no_build_hooks: Disables bytecode rewriting of asserts and android # resources methods. + # enable_turbine: If exists then will be used to determine whether to run + # turbine or not. Useful for disabling turbine headers for problematic + # targets. # chromium_code: Optional. Whether this is Chromium-specific code. If not # provided, this is determined automatically, based on the location of # the source files (i.e. anything under third_party/ is not @@ -3113,15 +3158,32 @@ _accumulated_public_deps = [] _accumulated_deps = [] + _java_header_deps = [] + _java_full_deps = [] if (defined(invoker.deps)) { - _accumulated_deps = invoker.deps + foreach(_dep, invoker.deps) { + set_sources_assignment_filter(_java_header_target_patterns) + _target_label = get_label_info(_dep, "label_no_toolchain") + sources = [ _target_label ] + if (sources == []) { + # This is a java header dep, so replace it with its header. + _java_header_deps += [ "${_target_label}__header" ] + _java_full_deps += [ _dep ] + } else { + # Not a java header dep, so no need to replace it with its header. + _accumulated_deps += [ _dep ] + } + sources = [] + } } _enable_build_hooks = _supports_android && (!defined(invoker.no_build_hooks) || !invoker.no_build_hooks) if (_enable_build_hooks) { - _accumulated_deps += [ "//build/android/buildhooks:build_hooks_java" ] + _java_full_deps += [ "//build/android/buildhooks:build_hooks_java" ] + _java_header_deps += + [ "//build/android/buildhooks:build_hooks_java__header" ] } # Some testonly targets use their own resources and the code being @@ -3131,7 +3193,9 @@ _enable_build_hooks && _requires_android && (!defined(invoker.testonly) || !invoker.testonly) if (_enable_build_hooks_android) { - _accumulated_deps += + # This is only needed for the process_java_prebuilt step, so no header + # necessary. + _java_full_deps += [ "//build/android/buildhooks:build_hooks_android_java" ] } @@ -3161,7 +3225,8 @@ !invoker.jacoco_never_instrument && _jacoco_instrument } if (_jacoco_instrument) { - _accumulated_deps += [ "//third_party/jacoco:jacocoagent_java" ] + _java_header_deps += [ "//third_party/jacoco:jacocoagent_java__header" ] + _java_full_deps += [ "//third_party/jacoco:jacocoagent_java" ] } } @@ -3178,11 +3243,13 @@ _include_android_sdk = invoker.include_android_sdk } if (_include_android_sdk) { + _sdk_java_dep = "//third_party/android_sdk:android_sdk_java" if (defined(invoker.alternative_android_sdk_dep)) { - _accumulated_deps += [ invoker.alternative_android_sdk_dep ] - } else { - _accumulated_deps += [ "//third_party/android_sdk:android_sdk_java" ] + _sdk_java_dep = invoker.alternative_android_sdk_dep } + + # This is an android_system_java_prebuilt target, so no headers. + _accumulated_deps += [ _sdk_java_dep ] } _jetified_jar_path = "$target_out_dir/${target_name}__process_prebuilt-jetified.jar" @@ -3246,7 +3313,7 @@ build_config = _build_config is_prebuilt = _is_prebuilt jetified_jar_path = _jetified_jar_path - possible_config_deps = _accumulated_deps + possible_config_deps = _java_full_deps + _accumulated_deps skip_jetify = defined(invoker.skip_jetify) && invoker.skip_jetify if (defined(apk_under_test)) { possible_config_deps += [ apk_under_test ] @@ -3289,12 +3356,14 @@ # Don't need to depend on the apk-under-test to be packaged. if (defined(invoker.apk_under_test)) { - _accumulated_deps += [ "${invoker.apk_under_test}__java" ] + _java_full_deps += [ "${invoker.apk_under_test}__java" ] + _java_header_deps += [ "${invoker.apk_under_test}__java__header" ] } if (defined(invoker.android_manifest_dep)) { _accumulated_deps += [ invoker.android_manifest_dep ] } if (defined(invoker.annotation_processor_deps)) { + # We need the full annotation processors rather than just the headers. _accumulated_deps += invoker.annotation_processor_deps } @@ -3321,8 +3390,10 @@ template("compile_java_helper") { compile_java(target_name) { forward_variables_from(invoker, "*") - enable_errorprone = invoker.enable_errorprone - javac_jar_path = invoker.javac_jar_path + output_jar_path = invoker.output_jar_path + enable_errorprone = + defined(invoker.enable_errorprone) && invoker.enable_errorprone + use_turbine = defined(invoker.use_turbine) && invoker.use_turbine main_target_name = _main_target_name build_config = _build_config @@ -3334,7 +3405,8 @@ chromium_code = _chromium_code supports_android = _supports_android requires_android = _requires_android - deps = _accumulated_deps + _accumulated_public_deps + deps = + _java_header_deps + _accumulated_deps + _accumulated_public_deps # android_apk and junit_binary pass R.java srcjars via srcjar_deps. if (_type == "java_library" && _requires_android) { @@ -3343,8 +3415,6 @@ } } } - _analysis_public_deps = [] - _compile_java_target = "${_main_target_name}__compile_java" _compile_java_forward_variables = [ "additional_jar_files", "apk_name", @@ -3354,10 +3424,11 @@ "jar_excluded_patterns", "never_goma", ] + _analysis_public_deps = [] + _compile_java_target = "${_main_target_name}__compile_java" compile_java_helper(_compile_java_target) { forward_variables_from(invoker, _compile_java_forward_variables) - enable_errorprone = false - javac_jar_path = _javac_jar_path + output_jar_path = _javac_jar_path } if (_enable_errorprone) { _compile_java_errorprone_target = @@ -3371,7 +3442,7 @@ } javac_args += invoker.errorprone_args } - javac_jar_path = _javac_jar_path + ".errorprone_stamp" + output_jar_path = _javac_jar_path + ".errorprone_stamp" } _analysis_public_deps += [ ":$_compile_java_errorprone_target" ] } @@ -3421,6 +3492,36 @@ _accumulated_public_deps += [ ":$_compile_java_target" ] } # _has_sources + if (_is_prebuilt || _has_sources) { + _header_target_name = "${target_name}__header" + _enable_turbine = _has_sources && _chromium_code + if (defined(invoker.enable_turbine)) { + _enable_turbine = invoker.enable_turbine + } + if (_enable_turbine) { + compile_java_helper(_header_target_name) { + forward_variables_from(invoker, _compile_java_forward_variables) + use_turbine = true + output_jar_path = _final_ijar_path + } + } else { + generate_interface_jar(_header_target_name) { + # Always used the unfiltered .jar to create the interface jar so that + # other targets will resolve filtered classes when depending on + # BuildConfig, NativeLibraries, etc. + input_jar = _unprocessed_jar_path + output_jar = _final_ijar_path + + # Some prebuilts have java deps (e.g. //third_party/proguard:retrace_java). + deps = _accumulated_deps + _java_header_deps + if (_has_sources) { + deps += [ ":$_compile_java_target" ] + } + } + } + _accumulated_public_deps += [ ":$_header_target_name" ] + } # _is_prebuilt || _has_sources + if (defined(_final_jar_path)) { if (_is_system_library) { _copy_system_library_target_name = "${target_name}__copy_system_library" @@ -3456,7 +3557,20 @@ java_sources_file = _java_sources_file } output_jar_path = _final_jar_path - deps = _accumulated_deps + _accumulated_public_deps + deps = _java_full_deps + _accumulated_deps + _accumulated_public_deps + + # proguard_configs listed on java_library targets need to be marked + # as inputs to at least one action so that "gn analyze" will know + # about them. Although ijar doesn't use them, it's a convenient spot + # to list them. + # https://crbug.com/827197 + if (defined(invoker.proguard_configs)) { + inputs = invoker.proguard_configs + if (!defined(deps)) { + deps = [] + } + deps += _srcjar_deps # For the aapt-generated proguard rules. + } } _accumulated_public_deps += [ ":$_process_prebuilt_target_name" ] @@ -3480,12 +3594,7 @@ } if (!_is_java_binary) { - # Export the interface jar as the main target (rather than a group) - # so that ninja will notice when the output is unchanged and not rebuild - # reverse-dependencies. Targets that should be rebuilt when the - # non-interface .jar changes use a depfile to indicate that they should - # be rebuilt even when the interface jar does not change. - generate_interface_jar(target_name) { + group(target_name) { forward_variables_from(invoker, [ "assert_no_deps", @@ -3499,30 +3608,12 @@ # as inputs to other targets. public_deps = _accumulated_public_deps - # Always used the unfiltered .jar to create the interface jar so that - # other targets will resolve filtered classes when depending on - # BuildConfig, NativeLibraries, etc. - input_jar = _unprocessed_jar_path - output_jar = _final_ijar_path if (_lint_enabled || _enable_errorprone) { if (!defined(data_deps)) { data_deps = [] } data_deps += [ ":${_main_target_name}__analysis" ] } - - # proguard_configs listed on java_library targets need to be marked - # as inputs to at least one action so that "gn analyze" will know - # about them. Although ijar doesn't use them, it's a convenient spot - # to list them. - # https://crbug.com/827197 - if (defined(invoker.proguard_configs)) { - inputs = invoker.proguard_configs - if (!defined(deps)) { - deps = [] - } - deps += _srcjar_deps # For the aapt-generated proguard rules. - } } } }
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 379844e..899444d3 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1130,6 +1130,9 @@ possible_config_deps = invoker.deps } } + java_header_group("${target_name}__header") { + forward_variables_from(invoker, [ "deps" ]) + } group(target_name) { forward_variables_from(invoker, "*") if (!defined(deps)) { @@ -3753,7 +3756,6 @@ _final_apk_path = "$root_build_dir/apks/${apk_name}.apk" } data = [ "$_final_apk_path.mapping" ] - data_deps += [ "//build/android/stacktrace:java_deobfuscate" ] } dist_ijar_path = "$root_build_dir/test.lib.java/${invoker.apk_name}.jar" @@ -4891,6 +4893,8 @@ "--proguard-mapping-path", rebase_path(_proguard_mapping_path, root_build_dir), ] + + # Required by logcat command. data_deps += [ "//build/android/stacktrace:java_deobfuscate" ] data += [ _proguard_mapping_path ] }
diff --git a/build/config/ios/ios_test_runner_wrapper.gni b/build/config/ios/ios_test_runner_wrapper.gni index 3985dc6..1f2ca0f1 100644 --- a/build/config/ios/ios_test_runner_wrapper.gni +++ b/build/config/ios/ios_test_runner_wrapper.gni
@@ -118,7 +118,12 @@ } else { _wrapper_output_name = wrapper_output_name } - wrapper_script = "${root_build_dir}/bin/${_wrapper_output_name}" + + # Test targets may attempt to generate multiple wrappers for a suite with + # multiple different toolchains when running with additional_target_cpus. + # Generate the wrapper script into root_out_dir rather than root_build_dir + # to ensure those wrappers are distinct. + wrapper_script = "${root_out_dir}/bin/${_wrapper_output_name}" # ios/build/bot/scripts/*.py needs to be present for test runner if (!defined(data)) {
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 24b0039..c5df5ad 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200318.3.1 \ No newline at end of file +0.20200319.1.1 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 24b0039..c5df5ad 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200318.3.1 \ No newline at end of file +0.20200319.1.1 \ No newline at end of file
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index a305bf6..58fdec5 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2801,6 +2801,7 @@ "java/src/org/chromium/chrome/browser/password_manager/Credential.java", "java/src/org/chromium/chrome/browser/password_manager/CredentialLeakDialogBridge.java", "java/src/org/chromium/chrome/browser/password_manager/OnboardingDialogBridge.java", + "java/src/org/chromium/chrome/browser/password_manager/PasswordChangeLauncher.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupLauncher.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogBridge.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationPopupBridge.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 08a3a98..ac76225b 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -802,10 +802,6 @@ "java/src/org/chromium/chrome/browser/historyreport/SearchJniBridge.java", "java/src/org/chromium/chrome/browser/historyreport/UsageReport.java", "java/src/org/chromium/chrome/browser/homepage/HomepagePolicyManager.java", - "java/src/org/chromium/chrome/browser/homepage/settings/HomepageEditor.java", - "java/src/org/chromium/chrome/browser/homepage/settings/HomepageMetricsEnums.java", - "java/src/org/chromium/chrome/browser/homepage/settings/HomepageSettings.java", - "java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java", "java/src/org/chromium/chrome/browser/identity/SettingsSecureBasedIdentificationGenerator.java", "java/src/org/chromium/chrome/browser/identity/UniqueIdentificationGenerator.java", "java/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactory.java", @@ -1240,6 +1236,7 @@ "java/src/org/chromium/chrome/browser/password_manager/CredentialLeakDialogBridge.java", "java/src/org/chromium/chrome/browser/password_manager/GooglePasswordManagerUIProvider.java", "java/src/org/chromium/chrome/browser/password_manager/OnboardingDialogBridge.java", + "java/src/org/chromium/chrome/browser/password_manager/PasswordChangeLauncher.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordCheckupLauncher.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogBridge.java", "java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogCoordinator.java", @@ -1419,6 +1416,10 @@ "java/src/org/chromium/chrome/browser/settings/MainSettings.java", "java/src/org/chromium/chrome/browser/settings/SettingsActivity.java", "java/src/org/chromium/chrome/browser/settings/SettingsLauncher.java", + "java/src/org/chromium/chrome/browser/settings/homepage/HomepageEditor.java", + "java/src/org/chromium/chrome/browser/settings/homepage/HomepageMetricsEnums.java", + "java/src/org/chromium/chrome/browser/settings/homepage/HomepageSettings.java", + "java/src/org/chromium/chrome/browser/settings/homepage/RadioButtonGroupHomepagePreference.java", "java/src/org/chromium/chrome/browser/share/LensUtils.java", "java/src/org/chromium/chrome/browser/share/OptionalShareTargetsManager.java", "java/src/org/chromium/chrome/browser/share/ShareActivity.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 1345ad2..8e39afd 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -202,8 +202,6 @@ "javatests/src/org/chromium/chrome/browser/history/HistoryActivityTest.java", "javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/homepage/HomepageTestRule.java", - "javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentTest.java", - "javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentWithEditorTest.java", "javatests/src/org/chromium/chrome/browser/identity/SettingsSecureBasedIdentificationGeneratorTest.java", "javatests/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactoryTest.java", "javatests/src/org/chromium/chrome/browser/identity/UuidBasedUniqueIdentificationGeneratorTest.java", @@ -425,6 +423,9 @@ "javatests/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProviderTest.java", "javatests/src/org/chromium/chrome/browser/services/GoogleServicesManagerIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/settings/SettingsActivityTest.java", + "javatests/src/org/chromium/chrome/browser/settings/homepage/HomepageSettingsFragmentTest.java", + "javatests/src/org/chromium/chrome/browser/settings/homepage/HomepageSettingsFragmentWithEditorTest.java", + "javatests/src/org/chromium/chrome/browser/shape_detection/ShapeDetectionTest.java", "javatests/src/org/chromium/chrome/browser/share/LensUtilsTest.java", "javatests/src/org/chromium/chrome/browser/share/ShareButtonControllerTest.java", "javatests/src/org/chromium/chrome/browser/share/ShareDelegateImplIntegrationTest.java",
diff --git a/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java b/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java index 9176386..9369c76 100644 --- a/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java +++ b/chrome/android/features/autofill_assistant/public/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java
@@ -37,7 +37,7 @@ * <p>Intent starting with this prefix are reported to the controller as parameters, except for * the ones starting with {@code INTENT_SPECIAL_PREFIX}. */ - private static final String INTENT_EXTRA_PREFIX = + public static final String INTENT_EXTRA_PREFIX = "org.chromium.chrome.browser.autofill_assistant."; /** Prefix for intent extras which are not parameters. */
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java index 2707a3d..f3224b5 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -38,7 +38,6 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeTabbedActivity; @@ -231,7 +230,6 @@ @MediumTest @Feature({"StartSurface"}) @CommandLineFlags.Add({BASE_PARAMS + "/single"}) - @DisabledTest(message = "crbug.com/1051643") public void testSearchInSingleSurface() { // TODO(crbug.com/1025296): Set cached flag before starting the activity and mimic clicking // the 'home' button to show the single start surface home page. @@ -258,8 +256,13 @@ assertThat( mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount(), equalTo(2)); + } - // Search in incognito mode. + @Test + @MediumTest + @Feature({"StartSurface"}) + @CommandLineFlags.Add({BASE_PARAMS + "/single"}) + public void testSearchInIncognitoSingleSurface() { TestThreadUtils.runOnUiThreadBlocking( () -> mActivityTestRule.getActivity() @@ -268,10 +271,12 @@ .setOverviewState(OverviewModeState.SHOWING_HOMEPAGE)); TestThreadUtils.runOnUiThreadBlocking( () -> mActivityTestRule.getActivity().getLayoutManager().showOverview(false)); + assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); onView(withId(org.chromium.chrome.start_surface.R.id.incognito_switch)).perform(click()); assertTrue(mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected()); - hideWatcher = TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity()); + OverviewModeBehaviorWatcher hideWatcher = + TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity()); onView(allOf(withId(org.chromium.chrome.start_surface.R.id.search_box_text), isDisplayed())) .perform(typeText(mUrl)); onView(withId(org.chromium.chrome.start_surface.R.id.url_bar))
diff --git a/chrome/android/features/tab_ui/java/res/layout/selectable_tab_list_card_item.xml b/chrome/android/features/tab_ui/java/res/layout/selectable_tab_list_card_item.xml deleted file mode 100644 index b7e6cd6..0000000 --- a/chrome/android/features/tab_ui/java/res/layout/selectable_tab_list_card_item.xml +++ /dev/null
@@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2020 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. --> -<!-- TODO(crbug.com/1023557): Rename SelectableTabGridView to SelectableTabView. --> -<org.chromium.chrome.browser.tasks.tab_management.SelectableTabGridView - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/selectable_tab_list_card_item" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <include layout="@layout/tab_list_card_item"/> - -</org.chromium.chrome.browser.tasks.tab_management.SelectableTabGridView> \ No newline at end of file
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java index 614b113..3dddfae 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java
@@ -47,20 +47,14 @@ mComponentName = animationSourceViewProvider == null ? "TabGridDialogFromStrip" : "TabGridDialogInSwitcher"; - @TabListCoordinator.TabListMode - int mode = TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled() - && SysUtils.isLowEndDevice() - ? TabListCoordinator.TabListMode.LIST - : TabListCoordinator.TabListMode.GRID; - mToolbarPropertyModel = new PropertyModel(TabGridPanelProperties.ALL_KEYS); mParentLayout = new TabGridDialogParent(context, containerView); TabSelectionEditorCoordinator.TabSelectionEditorController controller = null; if (TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled()) { - mTabSelectionEditorCoordinator = new TabSelectionEditorCoordinator(context, - containerView, tabModelSelector, tabContentManager, mParentLayout, mode); + mTabSelectionEditorCoordinator = new TabSelectionEditorCoordinator( + context, containerView, tabModelSelector, tabContentManager, mParentLayout); controller = mTabSelectionEditorCoordinator.getController(); } else { @@ -71,9 +65,15 @@ tabModelSelector, tabCreatorManager, resetHandler, animationSourceViewProvider, controller, tabGroupTitleEditor, shareDelegateSupplier, mComponentName); - mTabListCoordinator = new TabListCoordinator(mode, context, tabModelSelector, - tabContentManager::getTabThumbnailWithCallback, null, false, - gridCardOnClickListenerProvider, mMediator.getTabGridDialogHandler(), + // TODO(crbug.com/1031349) : Remove the inline mode logic here, make the constructor to take + // in a mode parameter instead. + mTabListCoordinator = new TabListCoordinator( + TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled() + && SysUtils.isLowEndDevice() + ? TabListCoordinator.TabListMode.LIST + : TabListCoordinator.TabListMode.GRID, + context, tabModelSelector, tabContentManager::getTabThumbnailWithCallback, null, + false, gridCardOnClickListenerProvider, mMediator.getTabGridDialogHandler(), TabProperties.UiType.CLOSABLE, null, containerView, null, false, mComponentName); TabListRecyclerView recyclerView = mTabListCoordinator.getContainerView();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java index 81305e2..15a3ccf 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -184,13 +184,6 @@ return group; }, TabListViewBinder::bindListTab); - - mAdapter.registerType(UiType.SELECTABLE, parent -> { - ViewGroup group = (ViewGroup) LayoutInflater.from(context).inflate( - R.layout.selectable_tab_list_card_item, parentView, false); - group.setClickable(true); - return group; - }, TabListViewBinder::bindSelectableListTab); } else { throw new IllegalArgumentException( "Attempting to create a tab list UI with invalid mode");
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index 9bd2472..41caf5ffd7 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -1185,9 +1185,13 @@ tab.isIncognito())) .with(TabProperties.IS_SELECTED, isSelected) .with(TabProperties.IPH_PROVIDER, showIPH ? mIphProvider : null) + .with(TabProperties.TAB_SELECTED_LISTENER, tabSelectedListener) + .with(TabProperties.TAB_CLOSED_LISTENER, mTabClosedListener) .with(CARD_ALPHA, 1f) .with(TabProperties.CARD_ANIMATION_STATUS, ClosableTabGridView.AnimationStatus.CARD_RESTORE) + .with(TabProperties.SELECTABLE_TAB_CLICKED_LISTENER, + mSelectableTabOnClickListener) .with(TabProperties.TAB_SELECTION_DELEGATE, getTabSelectionDelegate()) .with(TabProperties.IS_INCOGNITO, tab.isIncognito()) .with(TabProperties.SELECTED_TAB_BACKGROUND_DRAWABLE_ID, @@ -1228,11 +1232,6 @@ actionButtonBackgroundColorList); tabInfo.set(TabProperties.SELECTABLE_TAB_ACTION_BUTTON_SELECTED_BACKGROUND, actionbuttonSelectedBackgroundColorList); - tabInfo.set( - TabProperties.SELECTABLE_TAB_CLICKED_LISTENER, mSelectableTabOnClickListener); - } else { - tabInfo.set(TabProperties.TAB_SELECTED_LISTENER, tabSelectedListener); - tabInfo.set(TabProperties.TAB_CLOSED_LISTENER, mTabClosedListener); } if (index >= mModel.size()) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java index a775583f..6da5fae 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java
@@ -8,8 +8,6 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.InsetDrawable; import android.os.Build; -import android.support.graphics.drawable.AnimatedVectorDrawableCompat; -import android.support.v4.graphics.drawable.DrawableCompat; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -18,7 +16,6 @@ import androidx.annotation.Nullable; import androidx.core.content.res.ResourcesCompat; -import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.tab_ui.R; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -79,51 +76,4 @@ ((TextView) fastView.findViewById(R.id.description)).setText(title); } } - - /** - * Bind a selectable tab to view. - * @param model The model to bind. - * @param view The view to bind to. - * @param propertyKey The property that changed. - */ - public static void bindSelectableListTab( - PropertyModel model, ViewGroup view, @Nullable PropertyKey propertyKey) { - bindListTab(model, view, propertyKey); - - final int tabId = model.get(TabProperties.TAB_ID); - final int defaultLevel = view.getResources().getInteger(R.integer.list_item_level_default); - final int selectedLevel = - view.getResources().getInteger(R.integer.list_item_level_selected); - - if (TabProperties.SELECTABLE_TAB_CLICKED_LISTENER == propertyKey) { - view.setOnClickListener(v -> { - model.get(TabProperties.SELECTABLE_TAB_CLICKED_LISTENER).run(tabId); - ((SelectableTabGridView) view).onClick(); - }); - view.setOnLongClickListener(v -> { - model.get(TabProperties.SELECTABLE_TAB_CLICKED_LISTENER).run(tabId); - return ((SelectableTabGridView) view).onLongClick(view); - }); - } else if (TabProperties.TAB_SELECTION_DELEGATE == propertyKey) { - assert model.get(TabProperties.TAB_SELECTION_DELEGATE) != null; - - ((SelectableTabGridView) view) - .setSelectionDelegate(model.get(TabProperties.TAB_SELECTION_DELEGATE)); - ((SelectableTabGridView) view).setItem(tabId); - } else if (TabProperties.IS_SELECTED == propertyKey) { - boolean isSelected = model.get(TabProperties.IS_SELECTED); - ImageView actionButton = (ImageView) view.findViewById(R.id.action_button); - actionButton.getBackground().setLevel(isSelected ? selectedLevel : defaultLevel); - DrawableCompat.setTintList(actionButton.getBackground().mutate(), - isSelected ? model.get( - TabProperties.SELECTABLE_TAB_ACTION_BUTTON_SELECTED_BACKGROUND) - : model.get(TabProperties.SELECTABLE_TAB_ACTION_BUTTON_BACKGROUND)); - - // The check should be invisible if not selected. - actionButton.getDrawable().setAlpha(isSelected ? 255 : 0); - ApiCompatibilityUtils.setImageTintList(actionButton, - isSelected ? model.get(TabProperties.CHECKED_DRAWABLE_STATE_LIST) : null); - if (isSelected) ((AnimatedVectorDrawableCompat) actionButton.getDrawable()).start(); - } - } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java index c5b8844..ce58e59e 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorCoordinator.java
@@ -9,10 +9,9 @@ import android.content.Context; import android.view.LayoutInflater; -import android.view.ViewGroup; +import android.view.View; import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -102,7 +101,7 @@ } private final Context mContext; - private final ViewGroup mParentView; + private final View mParentView; private final TabModelSelector mTabModelSelector; private final TabSelectionEditorLayout mTabSelectionEditorLayout; private final TabListCoordinator mTabListCoordinator; @@ -111,18 +110,19 @@ private final PropertyModelChangeProcessor mTabSelectionEditorLayoutChangeProcessor; private final TabSelectionEditorMediator mTabSelectionEditorMediator; - public TabSelectionEditorCoordinator(Context context, ViewGroup parentView, + public TabSelectionEditorCoordinator(Context context, View parentView, TabModelSelector tabModelSelector, TabContentManager tabContentManager, @Nullable TabSelectionEditorMediator - .TabSelectionEditorPositionProvider positionProvider, - @TabListCoordinator.TabListMode int mode) { + .TabSelectionEditorPositionProvider positionProvider) { mContext = context; mParentView = parentView; mTabModelSelector = tabModelSelector; - mTabListCoordinator = new TabListCoordinator(mode, context, mTabModelSelector, - tabContentManager::getTabThumbnailWithCallback, null, false, null, null, - TabProperties.UiType.SELECTABLE, this::getSelectionDelegate, mParentView, null, + // TODO(crbug.com/1007598): construct TabListCoordinator with List mode if it's a low end + // device, and TabGroupContinuation is turned on. + mTabListCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.GRID, context, + mTabModelSelector, tabContentManager::getTabThumbnailWithCallback, null, false, + null, null, TabProperties.UiType.SELECTABLE, this::getSelectionDelegate, null, null, false, COMPONENT_NAME); mTabListCoordinator.registerItemType(TabProperties.UiType.DIVIDER, new LayoutViewBuilder(R.layout.divider_preference), @@ -197,12 +197,4 @@ mTabSelectionEditorMediator.destroy(); mTabSelectionEditorLayoutChangeProcessor.destroy(); } - - /** - * @return The {@link TabSelectionEditorLayout} for testing. - */ - @VisibleForTesting - public TabSelectionEditorLayout getTabSelectionEditorLayoutForTesting() { - return mTabSelectionEditorLayout; - } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java index ebad219..65c81609 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherCoordinator.java
@@ -103,7 +103,7 @@ PropertyModel containerViewModel = new PropertyModel(TabListContainerProperties.ALL_KEYS); mTabSelectionEditorCoordinator = new TabSelectionEditorCoordinator( - context, container, tabModelSelector, tabContentManager, null, mode); + context, container, tabModelSelector, tabContentManager, null); mMediator = new TabSwitcherMediator(this, containerViewModel, tabModelSelector, fullscreenManager, container, mTabSelectionEditorCoordinator.getController(),
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java index 4935097..2adc3c0 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
@@ -68,9 +68,6 @@ private SelectionDelegate<Integer> mSelectionDelegate; private int mSelectedTabBackgroundDrawableId = R.drawable.selected_tab_background; - private ViewGroup mSelectableTabListView; - private PropertyModelChangeProcessor mSelectableListMCP; - private TabListMediator.ThumbnailFetcher mMockThumbnailProvider = new TabListMediator.ThumbnailFetcher(new TabListMediator.ThumbnailProvider() { @Override @@ -137,13 +134,10 @@ R.layout.tab_strip_item, null); mSelectableTabGridView = (ViewGroup) getActivity().getLayoutInflater().inflate( R.layout.selectable_tab_grid_card_item, null); - mSelectableTabListView = (ViewGroup) getActivity().getLayoutInflater().inflate( - R.layout.selectable_tab_list_card_item, null); view.addView(mTabGridView); view.addView(mTabStripView); view.addView(mSelectableTabGridView); - view.addView(mSelectableTabListView); }); mSelectionDelegate = new SelectionDelegate<>(); @@ -174,8 +168,6 @@ mStripModel, mTabStripView, TabStripViewBinder::bind); mSelectableMCP = PropertyModelChangeProcessor.create( mSelectableModel, mSelectableTabGridView, TabGridViewBinder::bindSelectableTab); - mSelectableListMCP = PropertyModelChangeProcessor.create(mSelectableModel, - mSelectableTabListView, TabListViewBinder::bindSelectableListTab); }); } @@ -192,26 +184,10 @@ model.set(TabProperties.IS_SELECTED, false); Assert.assertTrue(selectedView.getVisibility() == View.GONE); } - } - - private void testSelectableTabClickToSelect( - ViewGroup view, PropertyModel model, boolean isLongClick) { - Runnable clickTask = () -> { - if (isLongClick) { - view.performLongClick(); - } else { - view.performClick(); - } - }; - - model.set(TabProperties.IS_SELECTED, false); - clickTask.run(); - Assert.assertTrue(mSelectClicked.get()); - mSelectClicked.set(false); - - model.set(TabProperties.IS_SELECTED, true); - clickTask.run(); - Assert.assertTrue(mSelectClicked.get()); + mStripModel.set(TabProperties.IS_SELECTED, true); + Assert.assertTrue(((FrameLayout) mTabStripView).getForeground() != null); + mStripModel.set(TabProperties.IS_SELECTED, false); + Assert.assertFalse(((FrameLayout) mTabStripView).getForeground() != null); } @Test @@ -235,17 +211,6 @@ mSelectableModel.set(TabProperties.IS_SELECTED, false); Assert.assertTrue(actionButton.getBackground().getLevel() == 0); Assert.assertEquals(0, actionButton.getDrawable().getAlpha()); - - testGridSelected(mSelectableTabListView, mSelectableModel); - mSelectableModel.set(TabProperties.IS_SELECTED, true); - ImageView actionButtonList = mSelectableTabListView.findViewById(R.id.action_button); - Assert.assertTrue(actionButtonList.getBackground().getLevel() == 1); - Assert.assertTrue(actionButtonList.getDrawable() != null); - Assert.assertEquals(255, actionButton.getDrawable().getAlpha()); - - mSelectableModel.set(TabProperties.IS_SELECTED, false); - Assert.assertTrue(actionButtonList.getBackground().getLevel() == 0); - Assert.assertEquals(0, actionButtonList.getDrawable().getAlpha()); } @Test @@ -300,9 +265,6 @@ mSelectableModel.set(TabProperties.TITLE, title); textView = mSelectableTabGridView.findViewById(R.id.tab_title); Assert.assertEquals(textView.getText(), title); - - textView = mSelectableTabListView.findViewById(R.id.title); - Assert.assertEquals(textView.getText(), title); } @Test @@ -447,11 +409,14 @@ Assert.assertFalse(mSelectClicked.get()); mSelectClicked.set(false); - testSelectableTabClickToSelect(mSelectableTabGridView, mSelectableModel, false); - testSelectableTabClickToSelect(mSelectableTabGridView, mSelectableModel, true); + mSelectableModel.set(TabProperties.IS_SELECTED, false); + mSelectableTabGridView.performClick(); + Assert.assertTrue(mSelectClicked.get()); + mSelectClicked.set(false); - testSelectableTabClickToSelect(mSelectableTabListView, mSelectableModel, false); - testSelectableTabClickToSelect(mSelectableTabListView, mSelectableModel, true); + mSelectableModel.set(TabProperties.IS_SELECTED, true); + mSelectableTabGridView.performClick(); + Assert.assertTrue(mSelectClicked.get()); } @Test
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java index c9e3e78..95859098 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java
@@ -6,7 +6,6 @@ import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; -import android.view.ViewGroup; import org.junit.After; import org.junit.Before; @@ -15,10 +14,7 @@ import org.junit.rules.TestRule; import org.junit.runner.RunWith; -import org.chromium.base.BaseSwitches; -import org.chromium.base.SysUtils; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -29,14 +25,11 @@ import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.browser.Features; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.UiRestriction; -import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -53,15 +46,11 @@ @Rule public TestRule mProcessor = new Features.InstrumentationProcessor(); - @Rule - public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule(); - private TabSelectionEditorTestingRobot mRobot = new TabSelectionEditorTestingRobot(); private TabModelSelector mTabModelSelector; private TabSelectionEditorCoordinator .TabSelectionEditorController mTabSelectionEditorController; - private TabSelectionEditorLayout mTabSelectionEditorLayout; @Before public void setUp() throws Exception { @@ -75,14 +64,10 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { TabSelectionEditorCoordinator tabSelectionEditorCoordinator = new TabSelectionEditorCoordinator(mActivityTestRule.getActivity(), - (ViewGroup) mActivityTestRule.getActivity().getCurrentFocus(), - mTabModelSelector, - mActivityTestRule.getActivity().getTabContentManager(), null, - getMode()); + mActivityTestRule.getActivity().getCurrentFocus(), mTabModelSelector, + mActivityTestRule.getActivity().getTabContentManager(), null); mTabSelectionEditorController = tabSelectionEditorCoordinator.getController(); - mTabSelectionEditorLayout = - tabSelectionEditorCoordinator.getTabSelectionEditorLayoutForTesting(); }); } @@ -91,13 +76,6 @@ CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GROUPS_ANDROID, null); } - private @TabListCoordinator.TabListMode int getMode() { - return TabUiFeatureUtilities.isTabGroupsAndroidContinuationEnabled() - && SysUtils.isLowEndDevice() - ? TabListCoordinator.TabListMode.LIST - : TabListCoordinator.TabListMode.GRID; - } - @Test @MediumTest public void testShowTabs() { @@ -262,34 +240,6 @@ mRobot.resultRobot.verifyDividerNotClickableNotFocusable(); } - @Test - @MediumTest - @Feature({"RenderTest"}) - @CommandLineFlags.Add(BaseSwitches.ENABLE_LOW_END_DEVICE_MODE) - @EnableFeatures({ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID}) - public void testListViewAppearance() throws IOException { - List<Tab> tabs = getTabsInCurrentTabModel(); - - TestThreadUtils.runOnUiThreadBlocking(() -> { mTabSelectionEditorController.show(tabs); }); - - mRenderTestRule.render(mTabSelectionEditorLayout, "list_view"); - } - - @Test - @MediumTest - @Feature({"RenderTest"}) - @CommandLineFlags.Add(BaseSwitches.ENABLE_LOW_END_DEVICE_MODE) - @EnableFeatures({ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID}) - public void testListViewAppearance_oneSelectedTab() throws IOException { - List<Tab> tabs = getTabsInCurrentTabModel(); - - TestThreadUtils.runOnUiThreadBlocking(() -> { mTabSelectionEditorController.show(tabs); }); - - mRobot.actionRobot.clickItemAtAdapterPosition(0); - - mRenderTestRule.render(mTabSelectionEditorLayout, "list_view_one_selected_tab"); - } - private List<Tab> getTabsInCurrentTabModel() { List<Tab> tabs = new ArrayList<>();
diff --git a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected index 4647d7d8..299da1c 100644 --- a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected +++ b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected
@@ -1058,7 +1058,7 @@ android:exported="true" android:label="WebView DevTools" - android:name="org.chromium.android_webview.devui.MonochromeLauncherActivity" + android:name="org.chromium.android_webview.devui.LauncherActivity" android:targetActivity="org.chromium.android_webview.devui.MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/>
diff --git a/chrome/android/java/res/xml/homepage_preferences.xml b/chrome/android/java/res/xml/homepage_preferences.xml index f641eb2..14f411fc 100644 --- a/chrome/android/java/res/xml/homepage_preferences.xml +++ b/chrome/android/java/res/xml/homepage_preferences.xml
@@ -18,7 +18,7 @@ android:visibility="gone" android:fragment="org.chromium.chrome.browser.settings.homepage.HomepageEditor" /> - <org.chromium.chrome.browser.homepage.settings.RadioButtonGroupHomepagePreference + <org.chromium.chrome.browser.settings.homepage.RadioButtonGroupHomepagePreference android:key="homepage_radio_group" android:visibility="gone" android:selectable="false"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeCachedFlags.java index 2b96d30..cf8b1610 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeCachedFlags.java
@@ -57,7 +57,6 @@ ChromeFeatureList.PAINT_PREVIEW_DEMO, ChromeFeatureList.PRIORITIZE_BOOTSTRAP_TASKS, ChromeFeatureList.INSTANT_START, - ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR, ChromeFeatureList.START_SURFACE_ANDROID, ChromeFeatureList.SWAP_PIXEL_FORMAT_TO_FIX_CONVERT_FROM_TRANSLUCENT, ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java index 4b5bfce6..7bd82a7f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java
@@ -87,7 +87,7 @@ } @CalledByNative - public static long getMainEntryPointTicks() { + public static long getApplicationStartTime() { return sApplicationStartTimeMs; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java index 469eb7a..b161fde 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
@@ -235,7 +235,7 @@ mActivity = activity; mUiConfig = uiConfig; - Profile profile = Profile.getLastUsedProfile(); + Profile profile = Profile.getLastUsedRegularProfile(); OfflinePageBridge offlinePageBridge = SuggestionsDependencyFactory.getInstance().getOfflinePageBridge(profile); TileRenderer tileRenderer =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/HomepageManager.java b/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/HomepageManager.java index c749d8a..8aa58321 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/HomepageManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/HomepageManager.java
@@ -15,11 +15,11 @@ import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.homepage.HomepagePolicyManager; -import org.chromium.chrome.browser.homepage.settings.HomepageMetricsEnums.HomeButtonPreferenceState; -import org.chromium.chrome.browser.homepage.settings.HomepageMetricsEnums.HomepageLocationType; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; +import org.chromium.chrome.browser.settings.homepage.HomepageMetricsEnums.HomeButtonPreferenceState; +import org.chromium.chrome.browser.settings.homepage.HomepageMetricsEnums.HomepageLocationType; import org.chromium.components.embedder_support.util.UrlConstants; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordChangeLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordChangeLauncher.java new file mode 100644 index 0000000..f539775e --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordChangeLauncher.java
@@ -0,0 +1,38 @@ +// Copyright 2020 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. + +package org.chromium.chrome.browser.password_manager; + +import android.os.Bundle; + +import org.chromium.base.Log; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.autofill_assistant.AutofillAssistantFacade; +import org.chromium.ui.base.WindowAndroid; + +/** Class for starting a password change flow in Autofill Assistant. */ +public class PasswordChangeLauncher { + private static final String TAG = "AutofillAssistant"; + + /** + * Name for the parameter that stores session username. Should be synced with + * |kSessionUsernameParameterName| from components/autofill_assistant/browser/controller.cc + * TODO(b/151401974): Eliminate duplicate parameter definitions. + */ + private static final String PASSWORD_CHANGE_USERNAME_PARAMETER = + AutofillAssistantFacade.INTENT_EXTRA_PREFIX + "PASSWORD_CHANGE_USERNAME"; + + @CalledByNative + public static void start(WindowAndroid windowAndroid, String origin, String username) { + ChromeActivity activity = (ChromeActivity) windowAndroid.getActivity().get(); + if (activity == null) { + Log.v(TAG, "Failed to retrieve ChromeActivity."); + return; + } + Bundle bundleExtras = new Bundle(); + bundleExtras.putString(PASSWORD_CHANGE_USERNAME_PARAMETER, username); + AutofillAssistantFacade.start(activity, bundleExtras, origin); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/DecoderServiceHost.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/DecoderServiceHost.java index 15d711b..e12cdcd5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/DecoderServiceHost.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/DecoderServiceHost.java
@@ -86,7 +86,7 @@ @Override public void onServiceConnected(ComponentName className, IBinder service) { mIRemoteService = IDecoderService.Stub.asInterface(service); - mBound = true; + assert mIRemoteService != null; for (DecoderStatusCallback callback : mCallbacks) { callback.serviceReady(); } @@ -96,7 +96,6 @@ public void onServiceDisconnected(ComponentName className) { Log.e(TAG, "Service has unexpectedly disconnected"); mIRemoteService = null; - mBound = false; } }; @@ -204,9 +203,6 @@ // The callbacks used to notify the clients when the service is ready. private final List<DecoderStatusCallback> mCallbacks = new ArrayList<DecoderStatusCallback>(); - // Flag indicating whether we are bound to the service. - private boolean mBound; - private final Context mContext; /** @@ -237,9 +233,9 @@ * @param context The context to use. */ public void unbind(Context context) { - if (mBound) { + if (mIRemoteService != null) { context.unbindService(mConnection); - mBound = false; + mIRemoteService = null; } } @@ -506,6 +502,15 @@ * @param params The information about the decoding request. */ private void dispatchDecodeImageRequest(DecoderServiceParams params) { + if (mIRemoteService == null) { + // If the connection is lost, ignore the request and continue. Further still image + // decoding requests will likely be dropped but note that there may be video requests + // remaining (which don't require this connection to be open). + Log.e(TAG, "Connection to decoder service unexpectedly terminated."); + closeRequestWithError(mProcessingRequest.mUri.getPath()); + return; + } + // Obtain a file descriptor to send over to the sandboxed process. ParcelFileDescriptor pfd = null; Bundle bundle = new Bundle();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/HomepageEditor.java similarity index 98% rename from chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageEditor.java rename to chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/HomepageEditor.java index 5efd4a5..b8def92c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/HomepageEditor.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.homepage.settings; +package org.chromium.chrome.browser.settings.homepage; import android.os.Bundle; import android.text.Editable;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageMetricsEnums.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/HomepageMetricsEnums.java similarity index 97% rename from chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageMetricsEnums.java rename to chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/HomepageMetricsEnums.java index 2d95728..3084079 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageMetricsEnums.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/HomepageMetricsEnums.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.homepage.settings; +package org.chromium.chrome.browser.settings.homepage; import androidx.annotation.IntDef;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/HomepageSettings.java similarity index 97% rename from chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageSettings.java rename to chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/HomepageSettings.java index 6b98884..92505ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/HomepageSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/HomepageSettings.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.homepage.settings; +package org.chromium.chrome.browser.settings.homepage; import android.os.Bundle; @@ -14,14 +14,14 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.homepage.HomepagePolicyManager; -import org.chromium.chrome.browser.homepage.settings.RadioButtonGroupHomepagePreference.HomepageOption; -import org.chromium.chrome.browser.homepage.settings.RadioButtonGroupHomepagePreference.PreferenceValues; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.settings.ChromeSwitchPreference; import org.chromium.chrome.browser.settings.ManagedPreferenceDelegate; import org.chromium.chrome.browser.settings.SettingsUtils; import org.chromium.chrome.browser.settings.TextMessagePreference; +import org.chromium.chrome.browser.settings.homepage.RadioButtonGroupHomepagePreference.HomepageOption; +import org.chromium.chrome.browser.settings.homepage.RadioButtonGroupHomepagePreference.PreferenceValues; import org.chromium.chrome.browser.toolbar.bottom.BottomToolbarVariationManager; import org.chromium.components.url_formatter.UrlFormatter;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/RadioButtonGroupHomepagePreference.java similarity index 99% rename from chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java rename to chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/RadioButtonGroupHomepagePreference.java index a30c301..6ea4c0eb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/settings/RadioButtonGroupHomepagePreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/homepage/RadioButtonGroupHomepagePreference.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.homepage.settings; +package org.chromium.chrome.browser.settings.homepage; import android.content.Context; import android.util.AttributeSet;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java index 8da6e2a3..a1aeb8e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java
@@ -14,7 +14,6 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabProvider; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.toolbar.ButtonData; @@ -26,6 +25,11 @@ * whether NTP is shown). */ public class ShareButtonController implements ButtonDataProvider { + /** + * Default minimum width to show share button. + */ + private static final int MIN_WIDTH = 360; + // Context is used for fetching resources and launching preferences page. private final Context mContext; @@ -41,6 +45,8 @@ private final ObservableSupplier<Boolean> mBottomToolbarVisibilitySupplier; private OnClickListener mOnClickListener; + private Integer mMinimumWidthDp; + /** * Creates ShareButtonController object. * @param context The Context for retrieving resources, etc. @@ -99,11 +105,26 @@ } private void updateButtonState(Tab tab) { - // TODO(crbug.com/1036023) add width constraints. - if (!CachedFeatureFlags.isEnabled(ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR) - || (mBottomToolbarVisibilitySupplier.get() - && BottomToolbarVariationManager.isShareButtonOnBottom()) - || mShareDelegateSupplier.get() == null) { + if (tab == null || tab.getWebContents() == null + || !ChromeFeatureList.isEnabled(ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR)) { + mButtonData.canShow = false; + return; + } + + if (mMinimumWidthDp == null) { + mMinimumWidthDp = ChromeFeatureList.getFieldTrialParamByFeatureAsInt( + ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR, "minimum_width", MIN_WIDTH); + } + + float deviceWidthPX = mContext.getResources().getDisplayMetrics().widthPixels; + int deviceWidth = + (int) (deviceWidthPX / (mContext.getResources().getDisplayMetrics().density)); + + boolean isDeviceWideEnough = deviceWidth > mMinimumWidthDp; + + if ((mBottomToolbarVisibilitySupplier.get() + && BottomToolbarVariationManager.isShareButtonOnBottom()) + || mShareDelegateSupplier.get() == null || !isDeviceWideEnough) { mButtonData.canShow = false; return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java index 0b9ef9e..74c5fde 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/HomeButton.java
@@ -28,10 +28,10 @@ import org.chromium.chrome.browser.compositor.layouts.OverviewModeState; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.homepage.HomepagePolicyManager; -import org.chromium.chrome.browser.homepage.settings.HomepageSettings; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.settings.SettingsLauncher; +import org.chromium.chrome.browser.settings.homepage.HomepageSettings; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.toolbar.bottom.BottomToolbarConfiguration; import org.chromium.ui.widget.ChromeImageButton;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java index d2935fd..a14d9b8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinatorPhone.java
@@ -11,10 +11,8 @@ import androidx.annotation.Nullable; -import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.incognito.IncognitoUtils; -import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; @@ -25,15 +23,13 @@ import org.chromium.chrome.browser.toolbar.IncognitoStateProvider; import org.chromium.chrome.browser.toolbar.TabCountProvider; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; -import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; -import org.chromium.components.search_engines.TemplateUrlService.TemplateUrlServiceObserver; /** * The coordinator for the tab switcher mode top toolbar shown on phones, responsible for * communication with other UI components and lifecycle. Lazily creates the tab * switcher mode top toolbar the first time it's needed. */ -class TabSwitcherModeTTCoordinatorPhone implements TemplateUrlServiceObserver { +class TabSwitcherModeTTCoordinatorPhone { private final ViewStub mTabSwitcherToolbarStub; // TODO(twellington): Create a model to hold all of these properties. Consider using @@ -51,10 +47,6 @@ private TabSwitcherModeTTPhone mTabSwitcherModeToolbar; @Nullable - private IncognitoSwitchCoordinator mIncognitoSwitchCoordinator; - @Nullable - private View mLogo; - @Nullable private TabModelObserver mTabModelObserver; TabSwitcherModeTTCoordinatorPhone(ViewStub tabSwitcherToolbarStub) { @@ -69,25 +61,11 @@ mTabSwitcherModeToolbar.destroy(); mTabSwitcherModeToolbar = null; } - if (mIncognitoSwitchCoordinator != null) { - mIncognitoSwitchCoordinator.destroy(); - mIncognitoSwitchCoordinator = null; - } - if (StartSurfaceConfiguration.isStartSurfaceEnabled()) { - TemplateUrlServiceFactory.get().removeObserver(this); - } if (mTabModelSelector != null && mTabModelObserver != null) { mTabModelSelector.getModel(true).removeObserver(mTabModelObserver); } } - @Override - public void onTemplateURLServiceChanged() { - mLogo.setVisibility( - (TemplateUrlServiceFactory.get().isDefaultSearchEngineGoogle() ? View.VISIBLE - : View.GONE)); - } - /** * Called when tab switcher mode is entered or exited. * @param inTabSwitcherMode Whether or not tab switcher mode should be shown or hidden. @@ -264,15 +242,6 @@ incognitoTabModel.addObserver(mTabModelObserver); mTabSwitcherModeToolbar.onIncognitoTabsCountChanged(incognitoTabModel.getCount()); } - if (StartSurfaceConfiguration.isStartSurfaceEnabled()) { - mIncognitoSwitchCoordinator = - new IncognitoSwitchCoordinator(mTabSwitcherModeToolbar, mTabModelSelector); - mLogo = mTabSwitcherModeToolbar.findViewById(R.id.logo); - if (TemplateUrlServiceFactory.get().isDefaultSearchEngineGoogle()) { - mLogo.setVisibility(View.VISIBLE); - } - TemplateUrlServiceFactory.get().addObserver(this); - } assert mIncognitoStateProvider != null; mTabSwitcherModeToolbar.setIncognitoStateProvider(mIncognitoStateProvider);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java index 31d7f4fb..8c96d220 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTPhone.java
@@ -32,7 +32,6 @@ import org.chromium.chrome.browser.toolbar.bottom.BottomToolbarConfiguration; import org.chromium.chrome.browser.toolbar.bottom.BottomToolbarVariationManager; import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper; -import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.browser_ui.widget.animation.CancelAwareAnimatorListener; import org.chromium.components.browser_ui.widget.animation.Interpolators; @@ -385,11 +384,6 @@ } private void setIncognitoToggleVisibility(boolean showIncognitoToggle) { - // If StartSurface is enabled, the incognito switch is shown and handled - // by the IncognitoSwitchCoordinator in the - // TabSwitcherModeTTCoordinatorPhone. - if (StartSurfaceConfiguration.isStartSurfaceEnabled()) return; - if (mIncognitoToggleTabLayout == null) { if (showIncognitoToggle) inflateIncognitoToggle(); } else {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java index be1605e..625f9ef 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/HomepagePolicyIntegrationTest.java
@@ -27,14 +27,14 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.homepage.settings.HomepageMetricsEnums.HomeButtonPreferenceState; -import org.chromium.chrome.browser.homepage.settings.HomepageMetricsEnums.HomepageLocationType; -import org.chromium.chrome.browser.homepage.settings.HomepageSettings; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.settings.ChromeSwitchPreference; import org.chromium.chrome.browser.settings.SettingsActivity; +import org.chromium.chrome.browser.settings.homepage.HomepageMetricsEnums.HomeButtonPreferenceState; +import org.chromium.chrome.browser.settings.homepage.HomepageMetricsEnums.HomepageLocationType; +import org.chromium.chrome.browser.settings.homepage.HomepageSettings; import org.chromium.chrome.browser.toolbar.HomeButton; import org.chromium.chrome.browser.toolbar.ToolbarManager; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java index 8fef4631..a52504c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/partnercustomizations/PartnerHomepageIntegrationTest.java
@@ -27,10 +27,10 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.flags.ChromeSwitches; -import org.chromium.chrome.browser.homepage.settings.HomepageEditor; -import org.chromium.chrome.browser.homepage.settings.HomepageSettings; import org.chromium.chrome.browser.settings.ChromeSwitchPreference; import org.chromium.chrome.browser.settings.SettingsActivity; +import org.chromium.chrome.browser.settings.homepage.HomepageEditor; +import org.chromium.chrome.browser.settings.homepage.HomepageSettings; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabList; import org.chromium.chrome.browser.tabmodel.TabModel;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/homepage/HomepageSettingsFragmentTest.java similarity index 99% rename from chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentTest.java rename to chrome/android/javatests/src/org/chromium/chrome/browser/settings/homepage/HomepageSettingsFragmentTest.java index ae2a5ed7..616f7e6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/homepage/HomepageSettingsFragmentTest.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.homepage.settings; +package org.chromium.chrome.browser.settings.homepage; import android.support.test.filters.SmallTest; import android.view.View; @@ -21,13 +21,13 @@ import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.homepage.HomepageTestRule; -import org.chromium.chrome.browser.homepage.settings.HomepageMetricsEnums.HomepageLocationType; import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; import org.chromium.chrome.browser.settings.ChromeSwitchPreference; import org.chromium.chrome.browser.settings.SettingsActivity; import org.chromium.chrome.browser.settings.TextMessagePreference; +import org.chromium.chrome.browser.settings.homepage.HomepageMetricsEnums.HomepageLocationType; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.browser.Features;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentWithEditorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/homepage/HomepageSettingsFragmentWithEditorTest.java similarity index 98% rename from chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentWithEditorTest.java rename to chrome/android/javatests/src/org/chromium/chrome/browser/settings/homepage/HomepageSettingsFragmentWithEditorTest.java index 5879902..a7acb9d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/homepage/settings/HomepageSettingsFragmentWithEditorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/homepage/HomepageSettingsFragmentWithEditorTest.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.homepage.settings; +package org.chromium.chrome.browser.settings.homepage; import android.support.test.filters.SmallTest;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/HomeButtonTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/HomeButtonTest.java index fa6e726..500f103 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/HomeButtonTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/HomeButtonTest.java
@@ -28,9 +28,9 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.homepage.HomepageTestRule; -import org.chromium.chrome.browser.homepage.settings.HomepageSettings; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.settings.SettingsLauncher; +import org.chromium.chrome.browser.settings.homepage.HomepageSettings; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
diff --git a/chrome/android/third_party/compositor_animator/BUILD.gn b/chrome/android/third_party/compositor_animator/BUILD.gn index d1b467310..1fe69c9 100644 --- a/chrome/android/third_party/compositor_animator/BUILD.gn +++ b/chrome/android/third_party/compositor_animator/BUILD.gn
@@ -6,5 +6,11 @@ import("//build/config/android/rules.gni") android_library("compositor_animator_java") { + # Turbine does not generate bridge methods in the parent class. Thus each + # child class generates its own bridge methods and adds a number of methods. + # This target would add about 30 methods if it enabled turbine. We are + # hoping to turn this back on once r8 can mitigate these extra methods. + enable_turbine = false + sources = [ "java/src/org/chromium/chrome/browser/compositor/animation/FloatProperty.java" ] }
diff --git a/chrome/app/android/chrome_main_delegate_android.cc b/chrome/app/android/chrome_main_delegate_android.cc index fe6940b6..7631584 100644 --- a/chrome/app/android/chrome_main_delegate_android.cc +++ b/chrome/app/android/chrome_main_delegate_android.cc
@@ -87,8 +87,8 @@ // Also only record the start time the first time round, since this is the // start time of the application, and will be same for all requests. if (!browser_runner_) { - startup_metric_utils::RecordMainEntryPointTime( - chrome::android::GetMainEntryPointTimeTicks()); + startup_metric_utils::RecordApplicationStartTime( + chrome::android::GetApplicationStartTime()); browser_runner_ = content::BrowserMainRunner::Create(); }
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 80de4b7..d6f0e7d 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -490,23 +490,31 @@ #endif #if !defined(CHROME_MULTIPLE_DLL_CHILD) -void RecordMainStartupMetrics(base::TimeTicks exe_entry_point_ticks) { - if (!exe_entry_point_ticks.is_null()) - startup_metric_utils::RecordExeMainEntryPointTicks(exe_entry_point_ticks); +void RecordMainStartupMetrics(base::TimeTicks application_start_time) { + const base::TimeTicks now = base::TimeTicks::Now(); + +#if defined(OS_WIN) + DCHECK(!application_start_time.is_null()); + startup_metric_utils::RecordApplicationStartTime(application_start_time); +#elif defined(OS_ANDROID) + // On Android the main entry point time is the time when the Java code starts. + // This happens before the shared library containing this code is even loaded. + // The Java startup code has recorded that time, but the C++ code can't fetch + // it from the Java side until it has initialized the JNI. See + // ChromeMainDelegateAndroid. +#else + // On other platforms, |application_start_time| == |now| since the application + // starts with ChromeMain(). + startup_metric_utils::RecordApplicationStartTime(now); +#endif + #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) // Record the startup process creation time on supported platforms. startup_metric_utils::RecordStartupProcessCreationTime( base::Process::Current().CreationTime()); #endif -// On Android the main entry point time is the time when the Java code starts. -// This happens before the shared library containing this code is even loaded. -// The Java startup code has recorded that time, but the C++ code can't fetch it -// from the Java side until it has initialized the JNI. See -// ChromeMainDelegateAndroid. -#if !defined(OS_ANDROID) - startup_metric_utils::RecordMainEntryPointTime(base::TimeTicks::Now()); -#endif + startup_metric_utils::RecordChromeMainEntryTime(now); } #endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index d3a7a843..a82a850 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -4525,6 +4525,12 @@ <message name="IDS_EDU_LOGIN_WELCOME_REAUTH_BODY" desc="Text on the reauthentication screen in EDU account addition flow informing user to ask their parent for permission to reauthenticate the account."> To sign in again for access to educational resources, ask a parent to give you permission </message> + <message name="IDS_EDU_LOGIN_PARENTS_LIST_TITLE" desc="Title for the parent sign-in screen asking the user to ask a parent to sign-in to approve EDU account addition."> + Parent sign-in + </message> + <message name="IDS_EDU_LOGIN_PARENTS_LIST_BODY" desc="Text on the parent sign-in screen asking the user to ask a parent to sign-in to approve EDU account addition."> + Ask a parent to sign in to grant permission to add a school account + </message> <!-- TPM firmware auto-update notifications --> <message name="IDS_TPM_AUTO_UPDATE_PLANNED_NOTIFICATION_TITLE" desc="Title for the notification informing the user that local data will be deleted.">
diff --git a/chrome/app/chromeos_strings_grdp/IDS_EDU_LOGIN_PARENTS_LIST_BODY.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_EDU_LOGIN_PARENTS_LIST_BODY.png.sha1 new file mode 100644 index 0000000..33e63e37 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_EDU_LOGIN_PARENTS_LIST_BODY.png.sha1
@@ -0,0 +1 @@ +c1c3e7b4e108aaf5e6cbf7881343710e490b8ac9 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_EDU_LOGIN_PARENTS_LIST_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_EDU_LOGIN_PARENTS_LIST_TITLE.png.sha1 new file mode 100644 index 0000000..33e63e37 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_EDU_LOGIN_PARENTS_LIST_TITLE.png.sha1
@@ -0,0 +1 @@ +c1c3e7b4e108aaf5e6cbf7881343710e490b8ac9 \ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index d59a6297..8075306 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -2729,7 +2729,7 @@ Some sites use third-party cookies to load their pages. If a site isn't working, you can try allowing cookies. </message> <message name="IDS_COOKIE_CONTROLS_BLOCKED_MESSAGE" desc="Text shown in the dialog that allows users to control cookie blocking."> - Sites can’t use your browsing activity across different sites to personalize ads + Sites can't use cookies that track you across the web </message> <message name="IDS_COOKIE_CONTROLS_TOOLTIP" desc="Tooltip shown on a page action icon that is shown when cookie blocking is enabled."> Third-party cookie blocking
diff --git a/chrome/app/generated_resources_grd/IDS_COOKIE_CONTROLS_BLOCKED_MESSAGE.png.sha1 b/chrome/app/generated_resources_grd/IDS_COOKIE_CONTROLS_BLOCKED_MESSAGE.png.sha1 index cedf0d2..1e54feb 100644 --- a/chrome/app/generated_resources_grd/IDS_COOKIE_CONTROLS_BLOCKED_MESSAGE.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_COOKIE_CONTROLS_BLOCKED_MESSAGE.png.sha1
@@ -1 +1 @@ -35cf61169272da7e8e35f0b4cc77bf41082baf48 \ No newline at end of file +c0b6ced9a266ce54265096caeef818742a2ed5ac \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 9a31a3b..7269580 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -2997,24 +2997,6 @@ <message name="IDS_SETTINGS_PERSONALIZE_GOOGLE_SERVICES_TITLE" desc="Title of the personalize Google services section. When clicked, takes the user to the Google Activity Controls."> Control how your browsing history is used to personalize Search, ads, and more </message> - <message name="IDS_SETTINGS_USE_HISTORY_TO_PERSONALIZE_GOOGLE_SERVICES_TITLE" desc="Title of the use your history to personalize Google services section. When clicked, takes the user to the Google Activity Controls."> - Use your Chrome browsing history to personalize Search, ads and other Google services - </message> - <message name="IDS_SETTINGS_SWAA_ON" desc="The sWAA state that shows in the use history to personalize google services row"> - On - </message> - <message name="IDS_SETTINGS_SWAA_OFF" desc="The sWAA state that shows in the use history to personalize google services row"> - Off - </message> - <message name="IDS_SETTINGS_DATA_ENCRYPTED_HINT" desc="Hint that shows when sWAA is off in the use history to personalize google services row because data is encrypted with custom passphrase"> - Turned off because you encrypted your sync data with a passphrase - </message> - <message name="IDS_SETTINGS_HISTORY_SYNC_OFF_HINT" desc="Hint that shows when sWAA is off in the use history to personalize google services row because history sync is off"> - Turned off because you disabled history sync - </message> - <message name="IDS_SETTINGS_SWAA_OFF_HINT" desc="Hint that shows when sWAA is off in the use history to personalize google services row because history recording is disabled in Web and App Activity" translateable="false"> - The usage of Chrome history for personalization is turned off in your Activity controls - </message> <if expr="not chromeos"> <!-- Import Settings Dialog -->
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index afa8676b..dc5ab97 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -222,8 +222,6 @@ "browsing_data/browsing_data_important_sites_util.h", "browsing_data/browsing_data_indexed_db_helper.cc", "browsing_data/browsing_data_indexed_db_helper.h", - "browsing_data/browsing_data_local_storage_helper.cc", - "browsing_data/browsing_data_local_storage_helper.h", "browsing_data/browsing_data_media_license_helper.cc", "browsing_data/browsing_data_media_license_helper.h", "browsing_data/browsing_data_quota_helper.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 433b4da..7d0aafa 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1371,9 +1371,6 @@ const FeatureEntry::FeatureParam kStartSurfaceAndroid_TwoPanesSurface[] = { {"start_surface_variation", "twopanes"}}; -const FeatureEntry::FeatureParam kStartSurfaceAndroid_Toolbar[] = { - {"start_surface_variation", "toolbar"}}; - const FeatureEntry::FeatureParam kStartSurfaceAndroid_TasksOnly[] = { {"start_surface_variation", "tasksonly"}}; @@ -1385,8 +1382,6 @@ base::size(kStartSurfaceAndroid_SingleSurface), nullptr}, {"Two Panes Surface", kStartSurfaceAndroid_TwoPanesSurface, base::size(kStartSurfaceAndroid_TwoPanesSurface), nullptr}, - {"Start Surface Toolbar", kStartSurfaceAndroid_Toolbar, - base::size(kStartSurfaceAndroid_Toolbar), nullptr}, {"Tasks Only", kStartSurfaceAndroid_TasksOnly, base::size(kStartSurfaceAndroid_TasksOnly), nullptr}, {"Omnibox Only", kStartSurfaceAndroid_OmniboxOnly, @@ -3980,6 +3975,10 @@ {"remote-copy-receiver", flag_descriptions::kRemoteCopyReceiverName, flag_descriptions::kRemoteCopyReceiverDescription, kOsDesktop, FEATURE_VALUE_TYPE(kRemoteCopyReceiver)}, + {"remote-copy-image-notification", + flag_descriptions::kRemoteCopyImageNotificationName, + flag_descriptions::kRemoteCopyImageNotificationDescription, kOsDesktop, + FEATURE_VALUE_TYPE(kRemoteCopyImageNotification)}, {"remote-copy-progress-notification", flag_descriptions::kRemoteCopyProgressNotificationName, flag_descriptions::kRemoteCopyProgressNotificationDescription, kOsDesktop,
diff --git a/chrome/browser/android/metrics/uma_utils.cc b/chrome/browser/android/metrics/uma_utils.cc index 767e0894..2583ad0 100644 --- a/chrome/browser/android/metrics/uma_utils.cc +++ b/chrome/browser/android/metrics/uma_utils.cc
@@ -18,10 +18,10 @@ namespace chrome { namespace android { -base::TimeTicks GetMainEntryPointTimeTicks() { +base::TimeTicks GetApplicationStartTime() { JNIEnv* env = base::android::AttachCurrentThread(); return base::TimeTicks::FromUptimeMillis( - Java_UmaUtils_getMainEntryPointTicks(env)); + Java_UmaUtils_getApplicationStartTime(env)); } static jboolean JNI_UmaUtils_IsClientInMetricsReportingSample(JNIEnv* env) {
diff --git a/chrome/browser/android/metrics/uma_utils.h b/chrome/browser/android/metrics/uma_utils.h index 7822aea7..2c51140 100644 --- a/chrome/browser/android/metrics/uma_utils.h +++ b/chrome/browser/android/metrics/uma_utils.h
@@ -12,7 +12,7 @@ namespace chrome { namespace android { -base::TimeTicks GetMainEntryPointTimeTicks(); +base::TimeTicks GetApplicationStartTime(); // Sets whether UMA reporting is enabled. This will call to Java to update // the shared preference that is the source of truth for UMA reporting.
diff --git a/chrome/browser/android/preferences/website_preference_bridge.cc b/chrome/browser/android/preferences/website_preference_bridge.cc index c82ea0c..9b3b618 100644 --- a/chrome/browser/android/preferences/website_preference_bridge.cc +++ b/chrome/browser/android/preferences/website_preference_bridge.cc
@@ -21,7 +21,6 @@ #include "base/stl_util.h" #include "chrome/android/chrome_jni_headers/WebsitePreferenceBridge_jni.h" #include "chrome/browser/android/search_permissions/search_permissions_service.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/engagement/important_sites_util.h" #include "chrome/browser/media/android/cdm/media_drm_license_manager.h" #include "chrome/browser/notifications/notification_permission_context.h" @@ -34,6 +33,7 @@ #include "chrome/browser/usb/usb_chooser_context.h" #include "chrome/browser/usb/usb_chooser_context_factory.h" #include "chrome/common/pref_names.h" +#include "components/browsing_data/content/local_storage_helper.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/browser/uma_util.h" @@ -787,7 +787,7 @@ jboolean fetch_important) { Profile* profile = ProfileManager::GetActiveUserProfile(); auto local_storage_helper = - base::MakeRefCounted<BrowsingDataLocalStorageHelper>(profile); + base::MakeRefCounted<browsing_data::LocalStorageHelper>(profile); local_storage_helper->StartFetching( base::Bind(&OnLocalStorageModelInfoLoaded, profile, fetch_important, ScopedJavaGlobalRef<jobject>(java_callback))); @@ -809,7 +809,7 @@ const JavaParamRef<jobject>& java_callback) { Profile* profile = ProfileManager::GetActiveUserProfile(); auto local_storage_helper = - base::MakeRefCounted<BrowsingDataLocalStorageHelper>(profile); + base::MakeRefCounted<browsing_data::LocalStorageHelper>(profile); auto origin = url::Origin::Create(GURL(ConvertJavaStringToUTF8(env, jorigin))); local_storage_helper->DeleteOrigin(
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index c7beb54..ce8fa86 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -225,6 +225,7 @@ <include name="IDR_EDU_LOGIN_EDU_LOGIN_TEMPLATE_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_template.js" use_base_dir="false" type="BINDATA" compress="gzip" /> <include name="IDR_EDU_LOGIN_EDU_LOGIN_CSS_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_css.js" use_base_dir="false" type ="BINDATA" /> <include name="IDR_EDU_LOGIN_EDU_LOGIN_WELCOME_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_welcome.js" use_base_dir="false" type ="BINDATA" compress="gzip" preprocess="true" /> + <include name="IDR_EDU_LOGIN_EDU_LOGIN_PARENTS_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_login\edu_login_parents.js" use_base_dir="false" type ="BINDATA" compress="gzip" preprocess="true" /> <include name="IDR_FAMILY_LINK_LOGO_SVG" file="resources\chromeos\family_link_logo.svg" type="BINDATA" compress="gzip" /> <!-- Chrome OS Account Manager welcome screen resources -->
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc b/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc deleted file mode 100644 index e43cc4b..0000000 --- a/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc +++ /dev/null
@@ -1,125 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" - -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/location.h" -#include "base/task/post_task.h" -#include "chrome/browser/browsing_data/browsing_data_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/browser/storage_usage_info.h" -#include "url/gurl.h" -#include "url/origin.h" -#include "url/url_constants.h" - -using content::BrowserContext; -using content::BrowserThread; -using content::DOMStorageContext; - -namespace { - -// Only websafe state is considered browsing data. -bool HasStorageScheme(const GURL& origin_url) { - return BrowsingDataHelper::HasWebScheme(origin_url); -} - -void GetUsageInfoCallback( - BrowsingDataLocalStorageHelper::FetchCallback callback, - const std::vector<content::StorageUsageInfo>& infos) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!callback.is_null()); - - std::list<content::StorageUsageInfo> result; - for (const content::StorageUsageInfo& info : infos) { - if (!HasStorageScheme(info.origin.GetURL())) - continue; - result.push_back(info); - } - - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(callback), result)); -} - -} // namespace - -BrowsingDataLocalStorageHelper::BrowsingDataLocalStorageHelper(Profile* profile) - : dom_storage_context_(BrowserContext::GetDefaultStoragePartition(profile) - ->GetDOMStorageContext()) { - DCHECK(dom_storage_context_); -} - -BrowsingDataLocalStorageHelper::~BrowsingDataLocalStorageHelper() { -} - -void BrowsingDataLocalStorageHelper::StartFetching(FetchCallback callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!callback.is_null()); - dom_storage_context_->GetLocalStorageUsage( - base::BindOnce(&GetUsageInfoCallback, std::move(callback))); -} - -void BrowsingDataLocalStorageHelper::DeleteOrigin(const url::Origin& origin, - base::OnceClosure callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - dom_storage_context_->DeleteLocalStorage(origin, std::move(callback)); -} - -//--------------------------------------------------------- - -CannedBrowsingDataLocalStorageHelper::CannedBrowsingDataLocalStorageHelper( - Profile* profile) - : BrowsingDataLocalStorageHelper(profile) { -} - -void CannedBrowsingDataLocalStorageHelper::Add(const url::Origin& origin) { - if (!HasStorageScheme(origin.GetURL())) - return; - pending_origins_.insert(origin); -} - -void CannedBrowsingDataLocalStorageHelper::Reset() { - pending_origins_.clear(); -} - -bool CannedBrowsingDataLocalStorageHelper::empty() const { - return pending_origins_.empty(); -} - -size_t CannedBrowsingDataLocalStorageHelper::GetCount() const { - return pending_origins_.size(); -} - -const std::set<url::Origin>& CannedBrowsingDataLocalStorageHelper::GetOrigins() - const { - return pending_origins_; -} - -void CannedBrowsingDataLocalStorageHelper::StartFetching( - FetchCallback callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!callback.is_null()); - - std::list<content::StorageUsageInfo> result; - for (const auto& origin : pending_origins_) - result.emplace_back(origin, 0, base::Time()); - - base::PostTask(FROM_HERE, {BrowserThread::UI}, - base::BindOnce(std::move(callback), result)); -} - -void CannedBrowsingDataLocalStorageHelper::DeleteOrigin( - const url::Origin& origin, - base::OnceClosure callback) { - pending_origins_.erase(origin); - BrowsingDataLocalStorageHelper::DeleteOrigin(origin, std::move(callback)); -} - -CannedBrowsingDataLocalStorageHelper::~CannedBrowsingDataLocalStorageHelper() {}
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc b/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc index e81fc275..5b04922e 100644 --- a/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.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 "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" +#include "components/browsing_data/content/local_storage_helper.h" #include <stddef.h> @@ -74,12 +74,12 @@ } }; -// This class is notified by BrowsingDataLocalStorageHelper on the UI thread +// This class is notified by browsing_data::LocalStorageHelper on the UI thread // once it finishes fetching the local storage data. class StopTestOnCallback { public: explicit StopTestOnCallback( - BrowsingDataLocalStorageHelper* local_storage_helper) + browsing_data::LocalStorageHelper* local_storage_helper) : local_storage_helper_(local_storage_helper) { DCHECK(local_storage_helper_); } @@ -107,12 +107,12 @@ } private: - BrowsingDataLocalStorageHelper* local_storage_helper_; + browsing_data::LocalStorageHelper* local_storage_helper_; }; IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, CallbackCompletes) { - scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper( - new BrowsingDataLocalStorageHelper(browser()->profile())); + scoped_refptr<browsing_data::LocalStorageHelper> local_storage_helper( + new browsing_data::LocalStorageHelper(browser()->profile())); CreateLocalStorageFilesForTest(); StopTestOnCallback stop_test_on_callback(local_storage_helper.get()); local_storage_helper->StartFetching(base::Bind( @@ -129,8 +129,8 @@ #endif IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, MAYBE_DeleteSingleFile) { - scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper( - new BrowsingDataLocalStorageHelper(browser()->profile())); + scoped_refptr<browsing_data::LocalStorageHelper> local_storage_helper( + new browsing_data::LocalStorageHelper(browser()->profile())); CreateLocalStorageFilesForTest(); base::RunLoop run_loop; local_storage_helper->DeleteOrigin( @@ -158,8 +158,8 @@ const GURL origin1("http://host1:1/"); const GURL origin2("http://host2:1/"); - scoped_refptr<CannedBrowsingDataLocalStorageHelper> helper( - new CannedBrowsingDataLocalStorageHelper(browser()->profile())); + scoped_refptr<browsing_data::CannedLocalStorageHelper> helper( + new browsing_data::CannedLocalStorageHelper(browser()->profile())); helper->Add(url::Origin::Create(origin1)); helper->Add(url::Origin::Create(origin2)); @@ -180,8 +180,8 @@ IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, CannedUnique) { const GURL origin("http://host1:1/"); - scoped_refptr<CannedBrowsingDataLocalStorageHelper> helper( - new CannedBrowsingDataLocalStorageHelper(browser()->profile())); + scoped_refptr<browsing_data::CannedLocalStorageHelper> helper( + new browsing_data::CannedLocalStorageHelper(browser()->profile())); helper->Add(url::Origin::Create(origin)); helper->Add(url::Origin::Create(origin));
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index f2b831c..9bca9c55 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -530,7 +530,7 @@ auto container = std::make_unique<LocalDataContainer>( new BrowsingDataCookieHelper(storage_partition), new BrowsingDataDatabaseHelper(profile), - new BrowsingDataLocalStorageHelper(profile), + new browsing_data::LocalStorageHelper(profile), /*session_storage_helper=*/nullptr, new BrowsingDataAppCacheHelper(storage_partition->GetAppCacheService()), new BrowsingDataIndexedDBHelper(storage_partition),
diff --git a/chrome/browser/browsing_data/cookies_tree_model.cc b/chrome/browser/browsing_data/cookies_tree_model.cc index eab62d5..2656597 100644 --- a/chrome/browser/browsing_data/cookies_tree_model.cc +++ b/chrome/browser/browsing_data/cookies_tree_model.cc
@@ -28,7 +28,6 @@ #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/browsing_data/browsing_data_quota_helper.h" #include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h" #include "chrome/browser/browsing_data/browsing_data_shared_worker_helper.h" @@ -36,6 +35,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" +#include "components/browsing_data/content/local_storage_helper.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/vector_icons/vector_icons.h" #include "content/public/browser/storage_partition.h" @@ -1960,7 +1960,7 @@ auto container = std::make_unique<LocalDataContainer>( new BrowsingDataCookieHelper(storage_partition), new BrowsingDataDatabaseHelper(profile), - new BrowsingDataLocalStorageHelper(profile), + new browsing_data::LocalStorageHelper(profile), /*session_storage_helper=*/nullptr, new BrowsingDataAppCacheHelper(storage_partition->GetAppCacheService()), new BrowsingDataIndexedDBHelper(storage_partition),
diff --git a/chrome/browser/browsing_data/local_data_container.cc b/chrome/browser/browsing_data/local_data_container.cc index 6954591..b0113be 100644 --- a/chrome/browser/browsing_data/local_data_container.cc +++ b/chrome/browser/browsing_data/local_data_container.cc
@@ -18,8 +18,8 @@ LocalDataContainer::LocalDataContainer( scoped_refptr<BrowsingDataCookieHelper> cookie_helper, scoped_refptr<BrowsingDataDatabaseHelper> database_helper, - scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper, - scoped_refptr<BrowsingDataLocalStorageHelper> session_storage_helper, + scoped_refptr<browsing_data::LocalStorageHelper> local_storage_helper, + scoped_refptr<browsing_data::LocalStorageHelper> session_storage_helper, scoped_refptr<BrowsingDataAppCacheHelper> appcache_helper, scoped_refptr<BrowsingDataIndexedDBHelper> indexed_db_helper, scoped_refptr<BrowsingDataFileSystemHelper> file_system_helper,
diff --git a/chrome/browser/browsing_data/local_data_container.h b/chrome/browser/browsing_data/local_data_container.h index 7a722c8..d727893 100644 --- a/chrome/browser/browsing_data/local_data_container.h +++ b/chrome/browser/browsing_data/local_data_container.h
@@ -20,11 +20,11 @@ #include "chrome/browser/browsing_data/browsing_data_database_helper.h" #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/browsing_data/browsing_data_media_license_helper.h" #include "chrome/browser/browsing_data/browsing_data_quota_helper.h" #include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h" #include "chrome/browser/browsing_data/browsing_data_shared_worker_helper.h" +#include "components/browsing_data/content/local_storage_helper.h" class BrowsingDataFlashLSOHelper; class CookiesTreeModel; @@ -67,8 +67,8 @@ LocalDataContainer( scoped_refptr<BrowsingDataCookieHelper> cookie_helper, scoped_refptr<BrowsingDataDatabaseHelper> database_helper, - scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper, - scoped_refptr<BrowsingDataLocalStorageHelper> session_storage_helper, + scoped_refptr<browsing_data::LocalStorageHelper> local_storage_helper, + scoped_refptr<browsing_data::LocalStorageHelper> session_storage_helper, scoped_refptr<BrowsingDataAppCacheHelper> appcache_helper, scoped_refptr<BrowsingDataIndexedDBHelper> indexed_db_helper, scoped_refptr<BrowsingDataFileSystemHelper> file_system_helper, @@ -126,8 +126,8 @@ scoped_refptr<BrowsingDataAppCacheHelper> appcache_helper_; scoped_refptr<BrowsingDataCookieHelper> cookie_helper_; scoped_refptr<BrowsingDataDatabaseHelper> database_helper_; - scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper_; - scoped_refptr<BrowsingDataLocalStorageHelper> session_storage_helper_; + scoped_refptr<browsing_data::LocalStorageHelper> local_storage_helper_; + scoped_refptr<browsing_data::LocalStorageHelper> session_storage_helper_; scoped_refptr<BrowsingDataIndexedDBHelper> indexed_db_helper_; scoped_refptr<BrowsingDataFileSystemHelper> file_system_helper_; scoped_refptr<BrowsingDataQuotaHelper> quota_helper_;
diff --git a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc index 3fa6511..14fc9479 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc
@@ -13,12 +13,11 @@ #include "url/gurl.h" MockBrowsingDataLocalStorageHelper::MockBrowsingDataLocalStorageHelper( - Profile* profile) - : BrowsingDataLocalStorageHelper(profile) { -} + content::BrowserContext* context) + : browsing_data::LocalStorageHelper(context) {} -MockBrowsingDataLocalStorageHelper::~MockBrowsingDataLocalStorageHelper() { -} +MockBrowsingDataLocalStorageHelper::~MockBrowsingDataLocalStorageHelper() = + default; void MockBrowsingDataLocalStorageHelper::StartFetching(FetchCallback callback) { ASSERT_FALSE(callback.is_null());
diff --git a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h index c01d22b..c5189fa 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h +++ b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h
@@ -10,17 +10,17 @@ #include "base/callback.h" #include "base/macros.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" +#include "components/browsing_data/content/local_storage_helper.h" -// Mock for BrowsingDataLocalStorageHelper. +// Mock for browsing_data::LocalStorageHelper. // Use AddLocalStorageSamples() or add directly to response_ list, then // call Notify(). class MockBrowsingDataLocalStorageHelper - : public BrowsingDataLocalStorageHelper { + : public browsing_data::LocalStorageHelper { public: - explicit MockBrowsingDataLocalStorageHelper(Profile* profile); + explicit MockBrowsingDataLocalStorageHelper(content::BrowserContext* context); - // BrowsingDataLocalStorageHelper implementation. + // browsing_data::LocalStorageHelper implementation. void StartFetching(FetchCallback callback) override; void DeleteOrigin(const url::Origin& origin, base::OnceClosure callback) override;
diff --git a/chrome/browser/browsing_data/site_data_size_collector.cc b/chrome/browser/browsing_data/site_data_size_collector.cc index 5cf3f93..e6f5290 100644 --- a/chrome/browser/browsing_data/site_data_size_collector.cc +++ b/chrome/browser/browsing_data/site_data_size_collector.cc
@@ -30,7 +30,7 @@ const base::FilePath& default_storage_partition_path, BrowsingDataCookieHelper* cookie_helper, BrowsingDataDatabaseHelper* database_helper, - BrowsingDataLocalStorageHelper* local_storage_helper, + browsing_data::LocalStorageHelper* local_storage_helper, BrowsingDataAppCacheHelper* appcache_helper, BrowsingDataIndexedDBHelper* indexed_db_helper, BrowsingDataFileSystemHelper* file_system_helper,
diff --git a/chrome/browser/browsing_data/site_data_size_collector.h b/chrome/browser/browsing_data/site_data_size_collector.h index fa2af8ed..2a39767 100644 --- a/chrome/browser/browsing_data/site_data_size_collector.h +++ b/chrome/browser/browsing_data/site_data_size_collector.h
@@ -17,9 +17,9 @@ #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h" #include "chrome/browser/profiles/profile.h" +#include "components/browsing_data/content/local_storage_helper.h" #include "content/public/browser/storage_partition.h" class SiteDataSizeCollector { @@ -37,7 +37,7 @@ SiteDataSizeCollector(const base::FilePath& default_storage_partition_path, BrowsingDataCookieHelper* cookie_helper, BrowsingDataDatabaseHelper* database_helper, - BrowsingDataLocalStorageHelper* local_storage_helper, + browsing_data::LocalStorageHelper* local_storage_helper, BrowsingDataAppCacheHelper* appcache_helper, BrowsingDataIndexedDBHelper* indexed_db_helper, BrowsingDataFileSystemHelper* file_system_helper, @@ -80,7 +80,7 @@ scoped_refptr<BrowsingDataAppCacheHelper> appcache_helper_; scoped_refptr<BrowsingDataCookieHelper> cookie_helper_; scoped_refptr<BrowsingDataDatabaseHelper> database_helper_; - scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper_; + scoped_refptr<browsing_data::LocalStorageHelper> local_storage_helper_; scoped_refptr<BrowsingDataIndexedDBHelper> indexed_db_helper_; scoped_refptr<BrowsingDataFileSystemHelper> file_system_helper_; scoped_refptr<BrowsingDataServiceWorkerHelper> service_worker_helper_;
diff --git a/chrome/browser/content_settings/local_shared_objects_container.cc b/chrome/browser/content_settings/local_shared_objects_container.cc index 5988a53a..dec265b 100644 --- a/chrome/browser/content_settings/local_shared_objects_container.cc +++ b/chrome/browser/content_settings/local_shared_objects_container.cc
@@ -16,12 +16,12 @@ #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h" #include "chrome/browser/browsing_data/browsing_data_shared_worker_helper.h" #include "chrome/browser/browsing_data/canonical_cookie_hash.h" #include "chrome/browser/browsing_data/cookies_tree_model.h" #include "chrome/browser/profiles/profile.h" +#include "components/browsing_data/content/local_storage_helper.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/url_constants.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" @@ -52,7 +52,7 @@ ->GetFileSystemContext())), indexed_dbs_(new CannedBrowsingDataIndexedDBHelper( content::BrowserContext::GetDefaultStoragePartition(profile))), - local_storages_(new CannedBrowsingDataLocalStorageHelper(profile)), + local_storages_(new browsing_data::CannedLocalStorageHelper(profile)), service_workers_(new CannedBrowsingDataServiceWorkerHelper( content::BrowserContext::GetDefaultStoragePartition(profile) ->GetServiceWorkerContext())), @@ -62,10 +62,9 @@ cache_storages_(new CannedBrowsingDataCacheStorageHelper( content::BrowserContext::GetDefaultStoragePartition(profile) ->GetCacheStorageContext())), - session_storages_(new CannedBrowsingDataLocalStorageHelper(profile)) {} + session_storages_(new browsing_data::CannedLocalStorageHelper(profile)) {} -LocalSharedObjectsContainer::~LocalSharedObjectsContainer() { -} +LocalSharedObjectsContainer::~LocalSharedObjectsContainer() = default; size_t LocalSharedObjectsContainer::GetObjectCount() const { size_t count = 0;
diff --git a/chrome/browser/content_settings/local_shared_objects_container.h b/chrome/browser/content_settings/local_shared_objects_container.h index 4c7f957..9a801cbe 100644 --- a/chrome/browser/content_settings/local_shared_objects_container.h +++ b/chrome/browser/content_settings/local_shared_objects_container.h
@@ -17,7 +17,6 @@ class CannedBrowsingDataDatabaseHelper; class CannedBrowsingDataFileSystemHelper; class CannedBrowsingDataIndexedDBHelper; -class CannedBrowsingDataLocalStorageHelper; class CannedBrowsingDataServiceWorkerHelper; class CannedBrowsingDataSharedWorkerHelper; class CannedBrowsingDataCacheStorageHelper; @@ -25,6 +24,10 @@ class GURL; class Profile; +namespace browsing_data { +class CannedLocalStorageHelper; +} + class LocalSharedObjectsContainer { public: explicit LocalSharedObjectsContainer(Profile* profile); @@ -59,7 +62,7 @@ CannedBrowsingDataIndexedDBHelper* indexed_dbs() const { return indexed_dbs_.get(); } - CannedBrowsingDataLocalStorageHelper* local_storages() const { + browsing_data::CannedLocalStorageHelper* local_storages() const { return local_storages_.get(); } CannedBrowsingDataServiceWorkerHelper* service_workers() const { @@ -71,7 +74,7 @@ CannedBrowsingDataCacheStorageHelper* cache_storages() const { return cache_storages_.get(); } - CannedBrowsingDataLocalStorageHelper* session_storages() const { + browsing_data::CannedLocalStorageHelper* session_storages() const { return session_storages_.get(); } @@ -81,11 +84,11 @@ scoped_refptr<CannedBrowsingDataDatabaseHelper> databases_; scoped_refptr<CannedBrowsingDataFileSystemHelper> file_systems_; scoped_refptr<CannedBrowsingDataIndexedDBHelper> indexed_dbs_; - scoped_refptr<CannedBrowsingDataLocalStorageHelper> local_storages_; + scoped_refptr<browsing_data::CannedLocalStorageHelper> local_storages_; scoped_refptr<CannedBrowsingDataServiceWorkerHelper> service_workers_; scoped_refptr<CannedBrowsingDataSharedWorkerHelper> shared_workers_; scoped_refptr<CannedBrowsingDataCacheStorageHelper> cache_storages_; - scoped_refptr<CannedBrowsingDataLocalStorageHelper> session_storages_; + scoped_refptr<browsing_data::CannedLocalStorageHelper> session_storages_; DISALLOW_COPY_AND_ASSIGN(LocalSharedObjectsContainer); };
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc index bad544c..d6735849 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.cc +++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/browsing_data/browsing_data_database_helper.h" #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/browsing_data/cookies_tree_model.h" #include "chrome/browser/content_settings/chrome_content_settings_utils.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -30,6 +29,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" #include "chrome/common/renderer_configuration.mojom.h" +#include "components/browsing_data/content/local_storage_helper.h" #include "components/content_settings/core/browser/content_settings_details.h" #include "components/content_settings/core/browser/content_settings_info.h" #include "components/content_settings/core/browser/content_settings_registry.h" @@ -348,7 +348,7 @@ LocalSharedObjectsContainer& container = blocked_by_policy ? blocked_local_shared_objects_ : allowed_local_shared_objects_; - CannedBrowsingDataLocalStorageHelper* helper = + browsing_data::CannedLocalStorageHelper* helper = local ? container.local_storages() : container.session_storages(); helper->Add(url::Origin::Create(url));
diff --git a/chrome/browser/dom_distiller/tab_utils.cc b/chrome/browser/dom_distiller/tab_utils.cc index 363029c3..1f3e6c2 100644 --- a/chrome/browser/dom_distiller/tab_utils.cc +++ b/chrome/browser/dom_distiller/tab_utils.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" #include "chrome/browser/ui/tab_contents/core_tab_helper.h" #include "components/dom_distiller/content/browser/distiller_page_web_contents.h" +#include "components/dom_distiller/content/browser/uma_helper.h" #include "components/dom_distiller/core/distiller_page.h" #include "components/dom_distiller/core/dom_distiller_service.h" #include "components/dom_distiller/core/task_tracker.h" @@ -173,6 +174,8 @@ new SourcePageHandleWebContents(old_web_contents_owned.release(), true)); MaybeStartDistillation(std::move(source_page_handle)); + + dom_distiller::UMAHelper::LogTimeOnDistillablePage(old_web_contents); } void DistillCurrentPage(content::WebContents* source_web_contents) {
diff --git a/chrome/browser/dom_distiller/tab_utils.h b/chrome/browser/dom_distiller/tab_utils.h index 7200d8a..09d470e6 100644 --- a/chrome/browser/dom_distiller/tab_utils.h +++ b/chrome/browser/dom_distiller/tab_utils.h
@@ -15,7 +15,7 @@ void DistillCurrentPageAndView(content::WebContents* old_web_contents); // Starts distillation in the |source_web_contents|. The viewer needs to be -// created separatly. +// created separately. void DistillCurrentPage(content::WebContents* source_web_contents); // Starts distillation in the |source_web_contents| while navigating the
diff --git a/chrome/browser/dom_distiller/tab_utils_browsertest.cc b/chrome/browser/dom_distiller/tab_utils_browsertest.cc index a1f6794..7109f9f6 100644 --- a/chrome/browser/dom_distiller/tab_utils_browsertest.cc +++ b/chrome/browser/dom_distiller/tab_utils_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" #include "build/build_config.h" #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" #include "chrome/browser/dom_distiller/tab_utils.h" @@ -43,6 +44,10 @@ #else // Desktop. This test is in chrome/ and is not run on iOS. const char* kExpectedArticleTitle = "Test Page Title - Reader Mode"; #endif // defined(OS_ANDROID) +const char* kDistillablePageHistogram = + "DomDistiller.Time.ActivelyViewingArticleBeforeDistilling"; +const char* kDistilledPageHistogram = + "DomDistiller.Time.ActivelyViewingReaderModePage"; std::unique_ptr<content::WebContents> NewContentsWithSameParamsAs( content::WebContents* source_web_contents) { @@ -177,6 +182,37 @@ EXPECT_EQ(kExpectedArticleTitle, GetPageTitle(after_web_contents)); } +// TODO(1061928): Make this test more robust by using a TestMockTimeTaskRunner +// and a test TickClock. This would require having UMAHelper be an object +// so that it can hold a TickClock reference. +IN_PROC_BROWSER_TEST_F(DomDistillerTabUtilsBrowserTest, UMATimesAreLogged) { + base::HistogramTester histogram_tester; + + content::WebContents* initial_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + // This blocks until the navigation has completely finished. + ui_test_utils::NavigateToURL(browser(), article_url()); + + // No UMA logged for distillable or distilled yet. + histogram_tester.ExpectTotalCount(kDistillablePageHistogram, 0); + histogram_tester.ExpectTotalCount(kDistilledPageHistogram, 0); + + DistillCurrentPageAndView(initial_web_contents); + + // UMA should now exist for the distillable page because we distilled it. + histogram_tester.ExpectTotalCount(kDistillablePageHistogram, 1); + + // Distilled page UMA isn't logged until we leave that page. + histogram_tester.ExpectTotalCount(kDistilledPageHistogram, 0); + + // Go back to the article, check UMA exists for distilled page now. + ui_test_utils::NavigateToURL(browser(), article_url()); + histogram_tester.ExpectTotalCount(kDistilledPageHistogram, 1); + // However, there should not be a second distillable histogram. + histogram_tester.ExpectTotalCount(kDistillablePageHistogram, 1); +} + IN_PROC_BROWSER_TEST_F(DomDistillerTabUtilsBrowserTest, DistillAndViewCreatesNewWebContentsAndPreservesOld) { content::WebContents* source_web_contents =
diff --git a/chrome/browser/downgrade/user_data_downgrade_unittest.cc b/chrome/browser/downgrade/user_data_downgrade_unittest.cc index ccaf6db..de0225e 100644 --- a/chrome/browser/downgrade/user_data_downgrade_unittest.cc +++ b/chrome/browser/downgrade/user_data_downgrade_unittest.cc
@@ -139,11 +139,12 @@ base::File::Info snapshot_info; ASSERT_TRUE(base::GetFileInfo(snapshot_dir, &snapshot_info)); - // Test that data is deleted only if it was created after the deletion time - // range start. - RemoveDataForProfile(base::Time::Now(), profile_path_default, + // Nothing should be deleted from |profile_path_default| since delete_begin + // is after the snapshot has been created. + RemoveDataForProfile(base::Time::Max(), profile_path_default, ChromeBrowsingDataRemoverDelegate::DATA_TYPE_BOOKMARKS); - RemoveDataForProfile(snapshot_info.creation_time, profile_path_1, + // Only the bookmarks should be deleted. + RemoveDataForProfile(base::Time::Min(), profile_path_1, ChromeBrowsingDataRemoverDelegate::DATA_TYPE_BOOKMARKS); EXPECT_TRUE(base::PathExists( snapshot_profile_path_default.Append(chrome::kPreferencesFilename))); @@ -171,8 +172,7 @@ ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA; // Delete some data from default profile. - RemoveDataForProfile(snapshot_info.creation_time, profile_path_default, - remove_mask); + RemoveDataForProfile(base::Time::Min(), profile_path_default, remove_mask); for (const auto& item : profile_items) { EXPECT_EQ( (item.data_types & remove_mask) == 0,
diff --git a/chrome/browser/downgrade/user_data_snapshot_browsertest.cc b/chrome/browser/downgrade/user_data_snapshot_browsertest.cc index 74177a28..d5270b7 100644 --- a/chrome/browser/downgrade/user_data_snapshot_browsertest.cc +++ b/chrome/browser/downgrade/user_data_snapshot_browsertest.cc
@@ -394,15 +394,16 @@ browser()->profile()->GetPrefs()->GetInteger(prefs::kRestoreOnStartup), 1); auto* tab_strip = browser()->tab_strip_model(); - // There are 2 tabs that need to be preserved, however in the test, there - // will be another about:blank tab. - if (IsInitialVersion()) { - ASSERT_EQ(tab_strip->count(), 2); - } else { - ASSERT_EQ(tab_strip->count(), 3); + // There are 2 tabs that need to be preserved. There might be a 3rd tab, + // about:blank that is opened by the test itself. That 3rd tab may or may + // not have been opened at this time. + ASSERT_GE(tab_strip->count(), 2); + ASSERT_LE(tab_strip->count(), 3); + if (tab_strip->count() == 3) { content::WaitForLoadStop(tab_strip->GetWebContentsAt(2)); EXPECT_EQ(tab_strip->GetWebContentsAt(2)->GetURL(), GURL("about:blank")); } + // embedded_test_server() might return a different hostname. content::WaitForLoadStop(tab_strip->GetWebContentsAt(0)); EXPECT_EQ(tab_strip->GetWebContentsAt(0)->GetURL().path(), "/title1.html");
diff --git a/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc b/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc index 9479c4e..64f0eafb 100644 --- a/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc +++ b/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc
@@ -7,15 +7,16 @@ #include <stddef.h> #include <algorithm> +#include <map> #include <memory> -#include "base/containers/flat_map.h" #include "base/containers/flat_set.h" #include "base/memory/ref_counted.h" #include "base/numerics/safe_conversions.h" #include "base/optional.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h" @@ -105,7 +106,7 @@ // canonicalized credential corresponds to. size_t already_processed_ = 0; size_t remaining_in_queue_ = 0; - base::flat_map<CanonicalizedCredential, size_t> counts_; + std::map<CanonicalizedCredential, size_t> counts_; base::WeakPtrFactory<PasswordCheckProgress> weak_ptr_factory_{this}; }; @@ -466,6 +467,16 @@ profile_->GetPrefs()->SetDouble( password_manager::prefs::kLastTimePasswordCheckCompleted, base::Time::Now().ToDoubleT()); + + // In case the check run to completion delay the last Check Status update by + // a second. This avoids flickering of the UI if the full check ran from + // start to finish almost immediately. + base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&PasswordCheckDelegate::NotifyPasswordCheckStatusChanged, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromSeconds(1)); + return; } // NotifyPasswordCheckStatusChanged() invokes GetPasswordCheckStatus() @@ -502,9 +513,12 @@ if (password_check_progress_) password_check_progress_->OnProcessed(credential); - // Trigger an update of the check status, considering that the progress has - // changed. - NotifyPasswordCheckStatusChanged(); + // While the check is still running trigger an update of the check status, + // considering that the progress has changed. + if (bulk_leak_check_service_adapter_.GetBulkLeakCheckState() == + BulkLeakCheckService::State::kRunning) { + NotifyPasswordCheckStatusChanged(); + } } const CredentialWithPassword*
diff --git a/chrome/browser/extensions/api/passwords_private/password_check_delegate.h b/chrome/browser/extensions/api/passwords_private/password_check_delegate.h index 45820b20..4b14e0d 100644 --- a/chrome/browser/extensions/api/passwords_private/password_check_delegate.h +++ b/chrome/browser/extensions/api/passwords_private/password_check_delegate.h
@@ -169,6 +169,8 @@ int, password_manager::PasswordCredentialLess> compromised_credential_id_generator_; + + base::WeakPtrFactory<PasswordCheckDelegate> weak_ptr_factory_{this}; }; } // namespace extensions
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc index cec4ffd..c5a36f8 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc
@@ -220,6 +220,17 @@ GetDelegate(browser_context())->IsOptedInForAccountStorage()))); } +// PasswordsPrivateOptInForAccountStorageFunction +ResponseAction PasswordsPrivateOptInForAccountStorageFunction::Run() { + auto parameters = + api::passwords_private::OptInForAccountStorage::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(parameters.get()); + + GetDelegate(browser_context()) + ->SetAccountStorageOptIn(parameters->opt_in, GetSenderWebContents()); + return RespondNow(NoArguments()); +} + // PasswordsPrivateGetCompromisedCredentialsFunction: PasswordsPrivateGetCompromisedCredentialsFunction:: ~PasswordsPrivateGetCompromisedCredentialsFunction() = default;
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_api.h b/chrome/browser/extensions/api/passwords_private/passwords_private_api.h index f143cac..48e1bb6 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_api.h +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_api.h
@@ -195,6 +195,19 @@ ResponseAction Run() override; }; +class PasswordsPrivateOptInForAccountStorageFunction + : public ExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("passwordsPrivate.optInForAccountStorage", + PASSWORDSPRIVATE_OPTINFORACCOUNTSTORAGE) + + protected: + ~PasswordsPrivateOptInForAccountStorageFunction() override = default; + + // ExtensionFunction overrides. + ResponseAction Run() override; +}; + class PasswordsPrivateGetCompromisedCredentialsFunction : public ExtensionFunction { public:
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_apitest.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_apitest.cc index 58e1819..04f9b2f1 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_apitest.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_apitest.cc
@@ -92,8 +92,12 @@ s_test_delegate_->SetStartPasswordCheckReturnSuccess(result); } + bool IsOptedInForAccountStorage() { + return s_test_delegate_->IsOptedInForAccountStorage(); + } + void SetOptedInForAccountStorage(bool opted_in) { - s_test_delegate_->SetOptedInForAccountStorage(opted_in); + s_test_delegate_->SetAccountStorageOptIn(opted_in, nullptr); } void ResetPlaintextPassword() { s_test_delegate_->ResetPlaintextPassword(); } @@ -204,6 +208,16 @@ << message_; } +IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest, OptInForAccountStorage) { + SetOptedInForAccountStorage(false); + EXPECT_TRUE(RunPasswordsSubtest("optInForAccountStorage")) << message_; +} + +IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest, OptOutForAccountStorage) { + SetOptedInForAccountStorage(true); + EXPECT_TRUE(RunPasswordsSubtest("optOutForAccountStorage")) << message_; +} + IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest, RemoveCompromisedCredentialFails) { EXPECT_TRUE(RunPasswordsSubtest("removeCompromisedCredentialFails"))
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h index 510918e5..ca14d66 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h
@@ -111,6 +111,12 @@ // local/profile storage). virtual bool IsOptedInForAccountStorage() = 0; + // Sets whether the user is opted in to use the Google account storage for + // passwords. If |opt_in| is true and the user is not currently opted in, + // will trigger a reauth flow. + virtual void SetAccountStorageOptIn(bool opt_in, + content::WebContents* web_contents) = 0; + // Obtains information about compromised credentials. This includes the last // time a check was run, as well as all compromised credentials that are // present in the password store.
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc index 1e78fd8e..f254b749f 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
@@ -14,6 +14,7 @@ #include "build/build_config.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h" +#include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" @@ -28,6 +29,7 @@ #include "components/password_manager/core/browser/ui/plaintext_reason.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/prefs/pref_service.h" +#include "components/signin/public/identity_manager/identity_manager.h" #include "content/public/browser/web_contents.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/l10n/l10n_util.h" @@ -137,6 +139,9 @@ password_access_authenticator_( base::BindRepeating(&PasswordsPrivateDelegateImpl::OsReauthCall, base::Unretained(this))), + account_storage_opt_in_reauthenticator_( + base::BindRepeating(&PasswordsPrivateDelegateImpl::InvokeGoogleReauth, + base::Unretained(this))), password_account_storage_opt_in_watcher_( std::make_unique< password_manager::PasswordAccountStorageOptInWatcher>( @@ -309,6 +314,21 @@ #endif } +void PasswordsPrivateDelegateImpl::InvokeGoogleReauth( + content::WebContents* web_contents, + PasswordsPrivateDelegateImpl::GoogleReauthCallback callback) { + if (auto* client = + ChromePasswordManagerClient::FromWebContents(web_contents)) { + client->TriggerReauthForAccount( + IdentityManagerFactory::GetForProfile(profile_)->GetPrimaryAccountId( + signin::ConsentLevel::kNotRequired), + std::move(callback)); + return; + } + std::move(callback).Run( + password_manager::PasswordManagerClient::ReauthSucceeded(false)); +} + Profile* PasswordsPrivateDelegateImpl::GetProfile() { return profile_; } @@ -418,6 +438,33 @@ profile_->GetPrefs(), ProfileSyncServiceFactory::GetForProfile(profile_)); } +void PasswordsPrivateDelegateImpl::SetAccountStorageOptIn( + bool opt_in, + content::WebContents* web_contents) { + if (opt_in == IsOptedInForAccountStorage()) + return; + if (!opt_in) { + password_manager_util::SetAccountStorageOptIn( + profile_->GetPrefs(), + ProfileSyncServiceFactory::GetForProfile(profile_), false); + return; + } + account_storage_opt_in_reauthenticator_.Run( + web_contents, + base::BindOnce( + &PasswordsPrivateDelegateImpl::SetAccountStorageOptInCallback, + weak_ptr_factory_.GetWeakPtr())); +} + +void PasswordsPrivateDelegateImpl::SetAccountStorageOptInCallback( + password_manager::PasswordManagerClient::ReauthSucceeded reauth_succeeded) { + if (reauth_succeeded) { + password_manager_util::SetAccountStorageOptIn( + profile_->GetPrefs(), + ProfileSyncServiceFactory::GetForProfile(profile_), true); + } +} + std::vector<api::passwords_private::CompromisedCredential> PasswordsPrivateDelegateImpl::GetCompromisedCredentials() { return password_check_delegate_.GetCompromisedCredentials();
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h index b437b46..dd1cdf25 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h
@@ -13,6 +13,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/strings/string16.h" #include "build/build_config.h" @@ -26,6 +27,7 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/password_manager/core/browser/password_access_authenticator.h" #include "components/password_manager/core/browser/password_account_storage_opt_in_watcher.h" +#include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/reauth_purpose.h" #include "components/password_manager/core/browser/ui/export_progress_status.h" #include "extensions/browser/extension_function.h" @@ -66,6 +68,8 @@ api::passwords_private::ExportProgressStatus GetExportProgressStatus() override; bool IsOptedInForAccountStorage() override; + void SetAccountStorageOptIn(bool opt_in, + content::WebContents* web_contents) override; std::vector<api::passwords_private::CompromisedCredential> GetCompromisedCredentials() override; void GetPlaintextCompromisedPassword( @@ -96,6 +100,14 @@ IdGenerator<std::string>& GetPasswordIdGeneratorForTesting(); + // TODO(crbug.com/1049141): Move the strong alias out of PasswordManagerClient + // to avoid leaking implementation details here. + using GoogleReauthCallback = base::OnceCallback<void( + password_manager::PasswordManagerClient::ReauthSucceeded)>; + using GoogleAccountAuthenticator = + base::RepeatingCallback<void(content::WebContents*, + GoogleReauthCallback)>; + #if defined(UNIT_TEST) // Use this in tests to mock the OS-level reauthentication. void set_os_reauth_call( @@ -104,6 +116,12 @@ password_access_authenticator_.set_os_reauth_call( std::move(os_reauth_call)); } + // Use this in tests to mock the Google account reauthentication. + void set_account_storage_opt_in_reauthenticator( + GoogleAccountAuthenticator account_storage_opt_in_reauthenticator) { + account_storage_opt_in_reauthenticator_ = + std::move(account_storage_opt_in_reauthenticator); + } #endif // defined(UNIT_TEST) private: @@ -129,10 +147,20 @@ void OnAccountStorageOptInStateChanged(); + // Callback for the reauth flow that is triggered upon the user opting in to + // account password storage. Will opt in the user if the reauth succeeded. + void SetAccountStorageOptInCallback( + password_manager::PasswordManagerClient::ReauthSucceeded + reauth_succeeded); + // Triggers an OS-dependent UI to present OS account login challenge and // returns true if the user passed that challenge. bool OsReauthCall(password_manager::ReauthPurpose purpose); + // Triggers a Google account reauthentication UI. + void InvokeGoogleReauth(content::WebContents* web_contents, + GoogleReauthCallback callback); + // Not owned by this class. Profile* profile_; @@ -144,6 +172,8 @@ password_manager::PasswordAccessAuthenticator password_access_authenticator_; + GoogleAccountAuthenticator account_storage_opt_in_reauthenticator_; + std::unique_ptr<password_manager::PasswordAccountStorageOptInWatcher> password_account_storage_opt_in_watcher_; @@ -178,6 +208,8 @@ // NativeWindow for the window where the API was called. content::WebContents* web_contents_; + base::WeakPtrFactory<PasswordsPrivateDelegateImpl> weak_ptr_factory_{this}; + DISALLOW_COPY_AND_ASSIGN(PasswordsPrivateDelegateImpl); };
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc index 20cb0b0..64de82d2 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc
@@ -18,12 +18,14 @@ #include "base/test/gmock_move_support.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" +#include "base/test/scoped_feature_list.h" #include "base/values.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h" #include "chrome/browser/password_manager/password_store_factory.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/common/extensions/api/passwords_private.h" #include "chrome/test/base/testing_profile.h" #include "components/autofill/core/common/password_form.h" @@ -31,8 +33,12 @@ #include "components/password_manager/core/browser/password_list_sorter.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/password_manager/core/browser/password_manager_test_utils.h" +#include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/browser/reauth_purpose.h" #include "components/password_manager/core/browser/test_password_store.h" +#include "components/password_manager/core/common/password_manager_features.h" +#include "components/sync/driver/test_sync_service.h" +#include "content/public/browser/browser_context.h" #include "content/public/test/browser_task_environment.h" #include "extensions/browser/test_event_router.h" #include "testing/gtest/include/gtest/gtest.h" @@ -122,6 +128,16 @@ return form; } +std::unique_ptr<KeyedService> BuildTestSyncService(content::BrowserContext*) { + auto sync_service = std::make_unique<syncer::TestSyncService>(); + CoreAccountInfo fake_info; + fake_info.account_id = CoreAccountId("id"); + fake_info.gaia = "gaia"; + fake_info.email = "foo@bar.com"; + sync_service->SetAuthenticatedAccountInfo(fake_info); + return sync_service; +} + } // namespace class PasswordsPrivateDelegateImplTest : public testing::Test { @@ -136,6 +152,9 @@ // PasswordsPrivateEventRouter. void SetUpRouters(); + void SetGoogleReauthResponse(PasswordsPrivateDelegateImpl* delegate, + bool should_succeed); + base::HistogramTester& histogram_tester() { return histogram_tester_; } protected: @@ -146,6 +165,8 @@ CreateAndUseTestPasswordStore(&profile_); ui::TestClipboard* test_clipboard_ = ui::TestClipboard::CreateForCurrentThread(); + base::MockCallback<PasswordsPrivateDelegateImpl::GoogleAccountAuthenticator> + mock_google_authenticator_; private: base::HistogramTester histogram_tester_; @@ -178,6 +199,22 @@ &profile_, base::BindRepeating(&BuildPasswordsPrivateEventRouter)); } +void PasswordsPrivateDelegateImplTest::SetGoogleReauthResponse( + PasswordsPrivateDelegateImpl* delegate, + bool should_succeed) { + ON_CALL(mock_google_authenticator_, Run) + .WillByDefault( + [should_succeed]( + content::WebContents*, + PasswordsPrivateDelegateImpl::GoogleReauthCallback callback) { + std::move(callback).Run( + password_manager::PasswordManagerClient::ReauthSucceeded( + should_succeed)); + }); + delegate->set_account_storage_opt_in_reauthenticator( + mock_google_authenticator_.Get()); +} + TEST_F(PasswordsPrivateDelegateImplTest, GetSavedPasswordsList) { PasswordsPrivateDelegateImpl delegate(&profile_); @@ -289,6 +326,47 @@ 1); } +TEST_F(PasswordsPrivateDelegateImplTest, TestShouldOptInIfReauthSucceeds) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + password_manager::features::kEnablePasswordsAccountStorage); + + PasswordsPrivateDelegateImpl delegate(&profile_); + + SetGoogleReauthResponse(&delegate, true); + + auto* test_sync_service = static_cast<syncer::SyncService*>( + ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( + &profile_, base::BindRepeating(&BuildTestSyncService))); + + password_manager_util::SetAccountStorageOptIn(profile_.GetPrefs(), + test_sync_service, false); + delegate.SetAccountStorageOptIn(true, nullptr); + + EXPECT_TRUE(password_manager_util::IsOptedInForAccountStorage( + profile_.GetPrefs(), test_sync_service)); +} + +TEST_F(PasswordsPrivateDelegateImplTest, TestShouldOptOut) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + password_manager::features::kEnablePasswordsAccountStorage); + + PasswordsPrivateDelegateImpl delegate(&profile_); + + auto* test_sync_service = static_cast<syncer::SyncService*>( + ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( + &profile_, base::BindRepeating(&BuildTestSyncService))); + + password_manager_util::SetAccountStorageOptIn(profile_.GetPrefs(), + test_sync_service, true); + delegate.SetAccountStorageOptIn(false, nullptr); + + EXPECT_CALL(mock_google_authenticator_, Run).Times(0); + EXPECT_FALSE(password_manager_util::IsOptedInForAccountStorage( + profile_.GetPrefs(), test_sync_service)); +} + TEST_F(PasswordsPrivateDelegateImplTest, TestCopyPasswordCallbackResultFail) { SetUpPasswordStore({CreateSampleForm()});
diff --git a/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.cc b/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.cc index 3d72c27..7412ecd 100644 --- a/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.cc +++ b/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.cc
@@ -151,6 +151,12 @@ return is_opted_in_for_account_storage_; } +void TestPasswordsPrivateDelegate::SetAccountStorageOptIn( + bool opt_in, + content::WebContents* web_contents) { + is_opted_in_for_account_storage_ = opt_in; +} + std::vector<api::passwords_private::CompromisedCredential> TestPasswordsPrivateDelegate::GetCompromisedCredentials() { api::passwords_private::CompromisedCredential credential;
diff --git a/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.h b/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.h index 17b26e2..f3c27bd 100644 --- a/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.h +++ b/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.h
@@ -40,6 +40,8 @@ api::passwords_private::ExportProgressStatus GetExportProgressStatus() override; bool IsOptedInForAccountStorage() override; + void SetAccountStorageOptIn(bool opt_in, + content::WebContents* web_contents) override; std::vector<api::passwords_private::CompromisedCredential> GetCompromisedCredentials() override; void GetPlaintextCompromisedPassword(
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 9a7ee97..6e337da 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -3393,6 +3393,11 @@ "expiry_milestone": 84 }, { + "name": "remote-copy-image-notification", + "owners": [ "//chrome/browser/sharing/OWNERS" ], + "expiry_milestone": 85 + }, + { "name": "remote-copy-progress-notification", "owners": [ "//chrome/browser/sharing/OWNERS" ], "expiry_milestone": 85 @@ -3418,6 +3423,11 @@ "expiry_milestone": 90 }, { + "name": "safe-browsing-available", + "owners": [ "//ios/chrome/browser/safe_browsing/OWNERS" ], + "expiry_milestone": 85 + }, + { "name": "safety-tips", "owners": [ "jdeblasio", "estark", "meacer" ], "expiry_milestone": 84
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index c5724aa..47544d0 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3738,6 +3738,12 @@ "Enables the remote copy feature to handle messages by writing content to " "the clipboard and showing a notification to the user."; +const char kRemoteCopyImageNotificationName[] = + "Enables image notifications for the remote copy feature"; +const char kRemoteCopyImageNotificationDescription[] = + "Enables image notifications to be shown for the remote copy feature " + "when receiving a message."; + const char kRemoteCopyProgressNotificationName[] = "Enables progress notifications for the remote copy feature"; const char kRemoteCopyProgressNotificationDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 034cb3c..f905ee2 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2184,6 +2184,9 @@ extern const char kRemoteCopyReceiverName[]; extern const char kRemoteCopyReceiverDescription[]; +extern const char kRemoteCopyImageNotificationName[]; +extern const char kRemoteCopyImageNotificationDescription[]; + extern const char kRemoteCopyProgressNotificationName[]; extern const char kRemoteCopyProgressNotificationDescription[];
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java index c832fcc..d14c61c 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -65,7 +65,6 @@ put(ChromeFeatureList.TAB_GROUPS_ANDROID, false); put(ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID, false); put(ChromeFeatureList.DUET_TABSTRIP_INTEGRATION_ANDROID, false); - put(ChromeFeatureList.SHARE_BUTTON_IN_TOP_TOOLBAR, false); put(ChromeFeatureList.CLOSE_TAB_SUGGESTIONS, false); put(ChromeFeatureList.INSTANT_START, false); put(ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID, false);
diff --git a/chrome/browser/media/feeds/media_feeds_contents_observer.cc b/chrome/browser/media/feeds/media_feeds_contents_observer.cc index 98e561b..aee74b2 100644 --- a/chrome/browser/media/feeds/media_feeds_contents_observer.cc +++ b/chrome/browser/media/feeds/media_feeds_contents_observer.cc
@@ -61,7 +61,7 @@ return; } - service->SaveMediaFeed(*url); + service->DiscoverMediaFeed(*url); } if (test_closure_)
diff --git a/chrome/browser/media/feeds/media_feeds_store.mojom b/chrome/browser/media/feeds/media_feeds_store.mojom index 6b2abaa..7eaa7fa 100644 --- a/chrome/browser/media/feeds/media_feeds_store.mojom +++ b/chrome/browser/media/feeds/media_feeds_store.mojom
@@ -14,6 +14,9 @@ // The URL for the discovered feed. url.mojom.Url url; + + // The last time this feed was discovered. + mojo_base.mojom.Time last_discovery_time; }; // The type of the feed item. This enum is committed to storage so do not
diff --git a/chrome/browser/media/history/media_history_feeds_table.cc b/chrome/browser/media/history/media_history_feeds_table.cc index 0c14b44..212c878 100644 --- a/chrome/browser/media/history/media_history_feeds_table.cc +++ b/chrome/browser/media/history/media_history_feeds_table.cc
@@ -29,6 +29,7 @@ "id INTEGER PRIMARY KEY AUTOINCREMENT," "origin_id INTEGER NOT NULL UNIQUE," "url TEXT NOT NULL, " + "last_discovery_time_s INTEGER, " "CONSTRAINT fk_origin " "FOREIGN KEY (origin_id) " "REFERENCES origin(id) " @@ -55,23 +56,57 @@ return sql::INIT_OK; } -bool MediaHistoryFeedsTable::SaveFeed(const GURL& url) { +bool MediaHistoryFeedsTable::DiscoverFeed(const GURL& url) { DCHECK_LT(0, DB()->transaction_nesting()); if (!CanAccessDatabase()) return false; - sql::Statement statement(DB()->GetCachedStatement( - SQL_FROM_HERE, - base::StringPrintf("INSERT OR REPLACE INTO %s " - "(origin_id, url) VALUES " - "((SELECT id FROM origin WHERE origin = ?), ?)", - kTableName) - .c_str())); - statement.BindString(0, MediaHistoryOriginTable::GetOriginForStorage( - url::Origin::Create(url))); - statement.BindString(1, url.spec()); + const auto origin = + MediaHistoryOriginTable::GetOriginForStorage(url::Origin::Create(url)); + const auto now = base::Time::Now().ToDeltaSinceWindowsEpoch().InSeconds(); - return statement.Run(); + base::Optional<GURL> feed_url; + base::Optional<int64_t> feed_id; + + { + // Check if we already have a feed for the current origin; + sql::Statement statement(DB()->GetCachedStatement( + SQL_FROM_HERE, + "SELECT id, url FROM mediaFeed WHERE origin_id = (SELECT id FROM " + "origin WHERE origin = ?)")); + statement.BindString(0, origin); + + while (statement.Step()) { + DCHECK(!feed_id); + DCHECK(!feed_url); + + feed_id = statement.ColumnInt64(0); + feed_url = GURL(statement.ColumnString(1)); + } + } + + if (!feed_url || url != feed_url) { + // If the feed does not exist or exists and has a different URL then we + // should replace the feed. + sql::Statement statement(DB()->GetCachedStatement( + SQL_FROM_HERE, + "INSERT OR REPLACE INTO mediaFeed " + "(origin_id, url, last_discovery_time_s) VALUES " + "((SELECT id FROM origin WHERE origin = ?), ?, ?)")); + statement.BindString(0, origin); + statement.BindString(1, url.spec()); + statement.BindInt64(2, now); + return statement.Run() && DB()->GetLastChangeCount() == 1; + } else { + // If the feed already exists in the database with the same URL we should + // just update the last discovery time so we don't delete the old entry. + sql::Statement statement(DB()->GetCachedStatement( + SQL_FROM_HERE, + "UPDATE mediaFeed SET last_discovery_time_s = ? WHERE id = ?")); + statement.BindInt64(0, now); + statement.BindInt64(1, *feed_id); + return statement.Run() && DB()->GetLastChangeCount() == 1; + } } std::vector<media_feeds::mojom::MediaFeedPtr> @@ -80,17 +115,19 @@ if (!CanAccessDatabase()) return feeds; - sql::Statement statement( - DB()->GetUniqueStatement(base::StringPrintf("SELECT id, url " - "FROM %s", - kTableName) - .c_str())); + sql::Statement statement(DB()->GetUniqueStatement( + base::StringPrintf("SELECT id, url, last_discovery_time_s " + "FROM %s", + kTableName) + .c_str())); while (statement.Step()) { media_feeds::mojom::MediaFeedPtr feed(media_feeds::mojom::MediaFeed::New()); feed->id = statement.ColumnInt64(0); feed->url = GURL(statement.ColumnString(1)); + feed->last_discovery_time = base::Time::FromDeltaSinceWindowsEpoch( + base::TimeDelta::FromSeconds(statement.ColumnInt64(2))); feeds.push_back(std::move(feed)); }
diff --git a/chrome/browser/media/history/media_history_feeds_table.h b/chrome/browser/media/history/media_history_feeds_table.h index a48381c..9840388 100644 --- a/chrome/browser/media/history/media_history_feeds_table.h +++ b/chrome/browser/media/history/media_history_feeds_table.h
@@ -35,7 +35,7 @@ sql::InitStatus CreateTableIfNonExistent() override; // Saves a newly discovered feed in the database. - bool SaveFeed(const GURL& url); + bool DiscoverFeed(const GURL& url); // Returns the feed rows in the database. std::vector<media_feeds::mojom::MediaFeedPtr> GetRows();
diff --git a/chrome/browser/media/history/media_history_keyed_service.cc b/chrome/browser/media/history/media_history_keyed_service.cc index 669cd2b..f3233cc 100644 --- a/chrome/browser/media/history/media_history_keyed_service.cc +++ b/chrome/browser/media/history/media_history_keyed_service.cc
@@ -207,9 +207,9 @@ store_->GetForRead()->GetURLsInTableForTest(table, std::move(callback)); } -void MediaHistoryKeyedService::SaveMediaFeed(const GURL& url) { +void MediaHistoryKeyedService::DiscoverMediaFeed(const GURL& url) { if (auto* store = store_->GetForWrite()) - store->SaveMediaFeed(url); + store->DiscoverMediaFeed(url); } void MediaHistoryKeyedService::PostTaskToDBForTest(base::OnceClosure callback) {
diff --git a/chrome/browser/media/history/media_history_keyed_service.h b/chrome/browser/media/history/media_history_keyed_service.h index bdbf2d8..14e3d99 100644 --- a/chrome/browser/media/history/media_history_keyed_service.h +++ b/chrome/browser/media/history/media_history_keyed_service.h
@@ -81,7 +81,7 @@ const std::vector<media_session::MediaImage>& artwork); // Saves a newly discovered media feed in the media history store. - void SaveMediaFeed(const GURL& url); + void DiscoverMediaFeed(const GURL& url); // Gets the media items in |feed_id|. void GetItemsForMediaFeedForDebug(
diff --git a/chrome/browser/media/history/media_history_store.cc b/chrome/browser/media/history/media_history_store.cc index 137de2d2..6ea7f716 100644 --- a/chrome/browser/media/history/media_history_store.cc +++ b/chrome/browser/media/history/media_history_store.cc
@@ -91,7 +91,7 @@ std::set<GURL> GetURLsInTableForTest(const std::string& table); - void SaveMediaFeed(const GURL& url); + void DiscoverMediaFeed(const GURL& url); void ReplaceMediaFeedItems( const int64_t feed_id, @@ -472,7 +472,7 @@ return urls; } -void MediaHistoryStoreInternal::SaveMediaFeed(const GURL& url) { +void MediaHistoryStoreInternal::DiscoverMediaFeed(const GURL& url) { DCHECK(db_task_runner_->RunsTasksInCurrentSequence()); if (!initialization_successful_) return; @@ -486,7 +486,7 @@ return; if (!(CreateOriginId(url::Origin::Create(url)) && - feeds_table_->SaveFeed(url))) { + feeds_table_->DiscoverFeed(url))) { DB()->RollbackTransaction(); return; } @@ -661,10 +661,10 @@ std::move(callback)); } -void MediaHistoryStore::SaveMediaFeed(const GURL& url) { +void MediaHistoryStore::DiscoverMediaFeed(const GURL& url) { db_->db_task_runner_->PostTask( FROM_HERE, - base::BindOnce(&MediaHistoryStoreInternal::SaveMediaFeed, db_, url)); + base::BindOnce(&MediaHistoryStoreInternal::DiscoverMediaFeed, db_, url)); } void MediaHistoryStore::PostTaskToDBForTest(base::OnceClosure callback) {
diff --git a/chrome/browser/media/history/media_history_store.h b/chrome/browser/media/history/media_history_store.h index f1461740..ad83536 100644 --- a/chrome/browser/media/history/media_history_store.h +++ b/chrome/browser/media/history/media_history_store.h
@@ -101,7 +101,7 @@ const std::vector<media_session::MediaImage>& artwork); // Saves a newly discovered media feed in the media history store. - void SaveMediaFeed(const GURL& url); + void DiscoverMediaFeed(const GURL& url); void ReplaceMediaFeedItems( const int64_t feed_id,
diff --git a/chrome/browser/media/history/media_history_store_unittest.cc b/chrome/browser/media/history/media_history_store_unittest.cc index 84faf22..e942074 100644 --- a/chrome/browser/media/history/media_history_store_unittest.cc +++ b/chrome/browser/media/history/media_history_store_unittest.cc
@@ -523,8 +523,8 @@ EXPECT_EQ(origins, GetOriginRowsSync(otr_service())); } -TEST_P(MediaHistoryStoreUnitTest, SaveMediaFeed_Noop) { - service()->SaveMediaFeed(GURL("https://www.google.com/feed")); +TEST_P(MediaHistoryStoreUnitTest, DiscoverMediaFeed_Noop) { + service()->DiscoverMediaFeed(GURL("https://www.google.com/feed")); WaitForDB(); { @@ -698,13 +698,13 @@ ASSERT_TRUE(GetDB().DoesTableExist("mediaFeedItem")); } -TEST_P(MediaHistoryStoreFeedsTest, SaveMediaFeed) { +TEST_P(MediaHistoryStoreFeedsTest, DiscoverMediaFeed) { GURL url_a("https://www.google.com/feed"); GURL url_b("https://www.google.co.uk/feed"); GURL url_c("https://www.google.com/feed2"); - service()->SaveMediaFeed(url_a); - service()->SaveMediaFeed(url_b); + service()->DiscoverMediaFeed(url_a); + service()->DiscoverMediaFeed(url_b); WaitForDB(); { @@ -727,7 +727,7 @@ EXPECT_EQ(feeds, GetMediaFeedsSync(otr_service())); } - service()->SaveMediaFeed(url_c); + service()->DiscoverMediaFeed(url_c); WaitForDB(); { @@ -752,7 +752,7 @@ } TEST_P(MediaHistoryStoreFeedsTest, ReplaceMediaFeedItems) { - service()->SaveMediaFeed(GURL("https://www.google.com/feed")); + service()->DiscoverMediaFeed(GURL("https://www.google.com/feed")); WaitForDB(); // If we are read only we should use -1 as a placeholder feed id because the @@ -796,7 +796,7 @@ } TEST_P(MediaHistoryStoreFeedsTest, ReplaceMediaFeedItems_WithEmpty) { - service()->SaveMediaFeed(GURL("https://www.google.com/feed")); + service()->DiscoverMediaFeed(GURL("https://www.google.com/feed")); WaitForDB(); // If we are read only we should use -1 as a placeholder feed id because the @@ -836,8 +836,8 @@ } TEST_P(MediaHistoryStoreFeedsTest, ReplaceMediaFeedItems_MultipleFeeds) { - service()->SaveMediaFeed(GURL("https://www.google.com/feed")); - service()->SaveMediaFeed(GURL("https://www.google.co.uk/feed")); + service()->DiscoverMediaFeed(GURL("https://www.google.com/feed")); + service()->DiscoverMediaFeed(GURL("https://www.google.co.uk/feed")); WaitForDB(); // If we are read only we should use -1 as a placeholder feed id because the @@ -882,7 +882,7 @@ } TEST_P(MediaHistoryStoreFeedsTest, ReplaceMediaFeedItems_BadType) { - service()->SaveMediaFeed(GURL("https://www.google.com/feed")); + service()->DiscoverMediaFeed(GURL("https://www.google.com/feed")); WaitForDB(); // If we are read only we should use -1 as a placeholder feed id because the @@ -921,4 +921,91 @@ } } +TEST_P(MediaHistoryStoreFeedsTest, RediscoverMediaFeed) { + GURL feed_url("https://www.google.com/feed"); + service()->DiscoverMediaFeed(feed_url); + WaitForDB(); + + // If we are read only we should use -1 as a placeholder feed id because the + // feed will not have been stored. This is so we can run the rest of the test + // to ensure a no-op. + int feed_id = -1; + base::Time feed_last_time; + + if (!IsReadOnly()) { + auto feeds = GetMediaFeedsSync(service()); + feed_id = feeds[0]->id; + feed_last_time = feeds[0]->last_discovery_time; + + EXPECT_LT(base::Time(), feed_last_time); + EXPECT_GT(base::Time::Now(), feed_last_time); + EXPECT_EQ(feed_url, feeds[0]->url); + } + + service()->ReplaceMediaFeedItems(feed_id, GetExpectedItems()); + WaitForDB(); + + { + // The media items should be stored. + auto items = GetItemsForMediaFeedSync(service(), feed_id); + + if (IsReadOnly()) { + EXPECT_TRUE(items.empty()); + } else { + EXPECT_EQ(GetExpectedItems(), items); + } + + // The OTR service should have the same data. + EXPECT_EQ(items, GetItemsForMediaFeedSync(otr_service(), feed_id)); + } + + // Rediscovering the same feed should not replace the feed. + service()->DiscoverMediaFeed(feed_url); + WaitForDB(); + + if (!IsReadOnly()) { + auto feeds = GetMediaFeedsSync(service()); + + EXPECT_LE(feed_last_time, feeds[0]->last_discovery_time); + EXPECT_EQ(feed_id, feeds[0]->id); + EXPECT_EQ(feed_url, feeds[0]->url); + } + + { + // The media items should be stored. + auto items = GetItemsForMediaFeedSync(service(), feed_id); + + if (IsReadOnly()) { + EXPECT_TRUE(items.empty()); + } else { + EXPECT_EQ(GetExpectedItems(), items); + } + + // The OTR service should have the same data. + EXPECT_EQ(items, GetItemsForMediaFeedSync(otr_service(), feed_id)); + } + + // Finding a new URL should replace the feed. + GURL new_url("https://www.google.com/feed2"); + service()->DiscoverMediaFeed(new_url); + WaitForDB(); + + if (!IsReadOnly()) { + auto feeds = GetMediaFeedsSync(service()); + + EXPECT_LE(feed_last_time, feeds[0]->last_discovery_time); + EXPECT_LT(feed_id, feeds[0]->id); + EXPECT_EQ(new_url, feeds[0]->url); + } + + { + // The media items should be deleted. + auto items = GetItemsForMediaFeedSync(service(), feed_id); + EXPECT_TRUE(items.empty()); + + // The OTR service should have the same data. + EXPECT_EQ(items, GetItemsForMediaFeedSync(otr_service(), feed_id)); + } +} + } // namespace media_history
diff --git a/chrome/browser/metrics/startup_metrics_browsertest.cc b/chrome/browser/metrics/startup_metrics_browsertest.cc index f93a345..32ced89 100644 --- a/chrome/browser/metrics/startup_metrics_browsertest.cc +++ b/chrome/browser/metrics/startup_metrics_browsertest.cc
@@ -23,10 +23,10 @@ "Startup.FirstWebContents.MainNavigationFinished", "Startup.FirstWebContents.MainNavigationStart", "Startup.FirstWebContents.NonEmptyPaint2", + "Startup.FirstWebContents.NonEmptyPaint3", "Startup.FirstWebContents.RenderProcessHostInit.ToNonEmptyPaint", - "Startup.LoadTime.ExeMainToDllMain2", - "Startup.LoadTime.ProcessCreateToDllMain2", - "Startup.LoadTime.ProcessCreateToExeMain2", + "Startup.LoadTime.ApplicationStartToChromeMain", + "Startup.LoadTime.ProcessCreateToApplicationStart", #if defined(OS_WIN) "Startup.BrowserMessageLoopStartHardFaultCount", @@ -38,9 +38,6 @@ // Verify that startup histograms are logged on browser startup. IN_PROC_BROWSER_TEST_F(StartupMetricsTest, ReportsValues) { - // This is usually done from the constructor of ChromeMainDelegate. - startup_metric_utils::RecordExeMainEntryPointTicks(base::TimeTicks::Now()); - // This is usually done from ChromeBrowserMainParts::MainMessageLoopRun(). startup_metric_utils::RecordBrowserMainMessageLoopStart( base::TimeTicks::Now(), false /* is_first_run */);
diff --git a/chrome/browser/password_manager/credential_leak_password_change_controller_android.cc b/chrome/browser/password_manager/credential_leak_password_change_controller_android.cc index 22a4401..bc117eca 100644 --- a/chrome/browser/password_manager/credential_leak_password_change_controller_android.cc +++ b/chrome/browser/password_manager/credential_leak_password_change_controller_android.cc
@@ -6,6 +6,7 @@ #include "base/android/jni_android.h" #include "base/android/jni_string.h" +#include "chrome/android/chrome_jni_headers/PasswordChangeLauncher_jni.h" #include "chrome/browser/ui/android/passwords/credential_leak_dialog_password_change_view_android.h" #include "chrome/common/url_constants.h" #include "components/password_manager/core/browser/leak_detection_dialog_utils.h" @@ -47,6 +48,13 @@ password_manager::GetLeakDialogType(leak_type_), ShouldCheckPasswords() ? LeakDialogDismissalReason::kClickedCheckPasswords : LeakDialogDismissalReason::kClickedOk); + if (window_android_) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_PasswordChangeLauncher_start( + env, window_android_->GetJavaObject(), + base::android::ConvertUTF8ToJavaString(env, origin_.spec()), + base::android::ConvertUTF16ToJavaString(env, username_)); + } delete this; }
diff --git a/chrome/browser/password_manager/credential_manager_browsertest.cc b/chrome/browser/password_manager/credential_manager_browsertest.cc index 7f35db1..c9b4530 100644 --- a/chrome/browser/password_manager/credential_manager_browsertest.cc +++ b/chrome/browser/password_manager/credential_manager_browsertest.cc
@@ -30,6 +30,8 @@ namespace { +using password_manager::MatchesFormExceptStore; + class CredentialManagerBrowserTest : public PasswordManagerBrowserTestBase { public: CredentialManagerBrowserTest() {} @@ -980,7 +982,8 @@ // Now make them equal to be able to check the equality of other fields. signin_form.date_last_used = stored[signin_form.signon_realm][0].date_last_used; - EXPECT_EQ(signin_form, stored[signin_form.signon_realm][0]); + EXPECT_THAT(signin_form, + MatchesFormExceptStore(stored[signin_form.signon_realm][0])); } IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest, CredentialsAutofilled) {
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 6a3973b..b141005 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -466,8 +466,14 @@ // TODO(wjmaclean): Are there any attributes we can/should test with respect to // the extension's loaded html? // TODO(https://crbug.com/1034972): Re-enable. Flaky on all platforms. +// Temporarily re-enabling on Linux to collect diagnostic data. +#if defined(OS_LINUX) +#define MAYBE_PdfExtensionLoadedInGuest PdfExtensionLoadedInGuest +#else +#define MAYBE_PdfExtensionLoadedInGuest DISABLED_PdfExtensionLoadedInGuest +#endif IN_PROC_BROWSER_TEST_F(PDFExtensionTestWithTestGuestViewManager, - DISABLED_PdfExtensionLoadedInGuest) { + MAYBE_PdfExtensionLoadedInGuest) { // Load test HTML, and verify the text area has focus. GURL main_url(embedded_test_server()->GetURL("/pdf/test.pdf")); ui_test_utils::NavigateToURL(browser(), main_url);
diff --git a/chrome/browser/resources/chromeos/edu_login/BUILD.gn b/chrome/browser/resources/chromeos/edu_login/BUILD.gn index b890332..c3c2c25 100644 --- a/chrome/browser/resources/chromeos/edu_login/BUILD.gn +++ b/chrome/browser/resources/chromeos/edu_login/BUILD.gn
@@ -11,6 +11,7 @@ ":app", ":browser_proxy", ":edu_login_button", + ":edu_login_parents", ":edu_login_template", ":edu_login_util", ":edu_login_welcome", @@ -19,9 +20,12 @@ js_library("app") { deps = [ + ":edu_login_parents", + ":edu_login_util", ":edu_login_welcome", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_view_manager:cr_view_manager.m", + "//ui/webui/resources/js:assert.m", ] } @@ -59,6 +63,15 @@ ] } +js_library("edu_login_parents") { + deps = [ + ":edu_login_button", + ":edu_login_template", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:icon.m", + ] +} + polymer_modulizer("app") { js_file = "app.js" html_file = "app.html" @@ -89,11 +102,18 @@ html_type = "v3-ready" } +polymer_modulizer("edu_login_parents") { + js_file = "edu_login_parents.js" + html_file = "edu_login_parents.html" + html_type = "v3-ready" +} + group("polymer3_elements") { public_deps = [ ":app_module", ":edu_login_button_module", ":edu_login_css_module", + ":edu_login_parents_module", ":edu_login_template_module", ":edu_login_welcome_module", ]
diff --git a/chrome/browser/resources/chromeos/edu_login/app.html b/chrome/browser/resources/chromeos/edu_login/app.html index c37a6a5e..0aa2bb5 100644 --- a/chrome/browser/resources/chromeos/edu_login/app.html +++ b/chrome/browser/resources/chromeos/edu_login/app.html
@@ -1,4 +1,7 @@ <cr-view-manager id="viewManager"> <edu-login-welcome id="[[Steps.WELCOME]]" slot="view"> </edu-login-welcome> + <edu-login-parents id="[[Steps.PARENTS]]" slot="view" + selected-parent="{{selectedParent_}}"> + </edu-login-parents> </cr-view-manager>
diff --git a/chrome/browser/resources/chromeos/edu_login/app.js b/chrome/browser/resources/chromeos/edu_login/app.js index 7056d1a..450f5816 100644 --- a/chrome/browser/resources/chromeos/edu_login/app.js +++ b/chrome/browser/resources/chromeos/edu_login/app.js
@@ -3,9 +3,12 @@ // found in the LICENSE file. import './edu_login_welcome.js'; +import './edu_login_parents.js'; import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.m.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {ParentAccount} from './edu_login_util.js'; /** @enum {string} */ const Steps = { @@ -39,10 +42,17 @@ type: Number, value: 0, }, + + /** + * Selected parent account for approving EDU login flow. + * @type {?ParentAccount} + */ + selectedParent_: Object, }, listeners: { 'go-next': 'onGoNext_', + 'go-back': 'onGoBack_', }, /** @override */ @@ -52,9 +62,15 @@ /** Switches to the next view. */ onGoNext_() { - if (this.stepIndex_ < stepsArray.length - 1) { - ++this.stepIndex_; - } + assert(this.stepIndex_ < stepsArray.length - 1); + ++this.stepIndex_; + this.switchViewAtIndex_(this.stepIndex_); + }, + + /** Switches to the previous view. */ + onGoBack_() { + assert(this.stepIndex_ > 0); + --this.stepIndex_; this.switchViewAtIndex_(this.stepIndex_); },
diff --git a/chrome/browser/resources/chromeos/edu_login/edu_login_parents.html b/chrome/browser/resources/chromeos/edu_login/edu_login_parents.html new file mode 100644 index 0000000..b2023136 --- /dev/null +++ b/chrome/browser/resources/chromeos/edu_login/edu_login_parents.html
@@ -0,0 +1,76 @@ +<style include="edu-login-css"> + .account-list-item { + align-items: center; + cursor: pointer; + display: flex; + min-height: 64px; + outline: none; + transition: background 200ms; + } + + .main-padding.account-list-item { + padding-bottom: 0; + padding-top: 0; + } + + .account-list-item:hover, + .account-list-item:focus { + background: var(--google-grey-100); + } + + .account-list-item.selected { + background: var(--google-grey-200); + } + + .account-info { + padding-inline-start: 24px; + } + + .profile-icon { + --profile-icon-size: 36px; + background: center / cover no-repeat; + border-radius: 50%; + flex-shrink: 0; + height: var(--profile-icon-size); + width: var(--profile-icon-size); + } +</style> + +<edu-login-template> + <span slot="main"> + <div class="main-padding"> + <if expr="_google_chrome"> + <img class="google-full-logo" + src="chrome://theme/IDR_LOGO_GOOGLE_COLOR_90" alt=""> + </if> + <h1>$i18n{parentsListTitle}</h1> + <p id="parentsListBody" aria-hidden="true" class="secondary"> + $i18n{parentsListBody} + </p> + </div> + <div tabindex="0" role="listbox" aria-labelledby="parentsListBody"> + <template is="dom-repeat" items="[[parents_]]"> + <div role="option" tabindex="0" aria-selected="false" + id="account-list-item-[[index]]" + aria-label$="[[item.displayName]] [[item.email]]" + class$="account-list-item main-padding + [[getSelectedClass_(selectedParent, item)]]" + on-tap="selectParent_" on-keydown="onParentSelectionKeydown_"> + <div class="profile-icon" style="background-image: + [[getIconImageSet_(item.profileImage)]]"> + </div> + <div class="account-info text-elide"> + <span>[[item.displayName]]</span> + <div class="secondary">[[item.email]]</div> + </div> + </div> + </template> + </div> + </span> + <span slot="buttons"> + <edu-login-button button-type="back"></edu-login-button> + <edu-login-button button-type="next" + disabled="[[isNextDisabled_(selectedParent)]]"> + </edu-login-button> + </span> +</edu-login-template>
diff --git a/chrome/browser/resources/chromeos/edu_login/edu_login_parents.js b/chrome/browser/resources/chromeos/edu_login/edu_login_parents.js new file mode 100644 index 0000000..f0210ec --- /dev/null +++ b/chrome/browser/resources/chromeos/edu_login/edu_login_parents.js
@@ -0,0 +1,103 @@ +// Copyright 2020 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 './edu_login_css.js'; +import './edu_login_template.js'; +import './edu_login_button.js'; + +import {getImage} from 'chrome://resources/js/icon.m.js'; +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {EduAccountLoginBrowserProxyImpl} from './browser_proxy.js'; +import {ParentAccount} from './edu_login_util.js'; + +Polymer({ + is: 'edu-login-parents', + + _template: html`{__html_template__}`, + + properties: { + /** + * Selected parent account for approving EDU login flow. + * @type {?ParentAccount} + */ + selectedParent: { + type: Object, + value: null, + notify: true, + }, + + /** + * Array of user's parents. + * @private {!Array<!ParentAccount>} + */ + parents_: { + type: Array, + value() { + return []; + }, + }, + }, + + /** @override */ + ready() { + // TODO(anastasiian): handle fetching error. + EduAccountLoginBrowserProxyImpl.getInstance().getParents().then(result => { + this.parents_ = result; + }); + }, + + /** + * @param {ParentAccount} selectedParent + * @param {ParentAccount} item + * @return {string} class name + * @private + */ + getSelectedClass_(selectedParent, item) { + return item === selectedParent ? 'selected' : ''; + }, + + /** + * @param {string} iconUrl + * @return {string} A CSS image-set for multiple scale factors. + * @private + */ + getIconImageSet_(iconUrl) { + return getImage(iconUrl); + }, + + /** + * @param {ParentAccount} selectedParent + * @return {boolean} + * @private + */ + isNextDisabled_(selectedParent) { + return selectedParent === null; + }, + + /** + * Sets selected parent. + * @param {Event} e + * @private + */ + onParentSelectionKeydown_(e) { + if (e.key === 'Enter' || e.key === ' ') { // Enter or Space key + this.selectParent_(e); + } + }, + + /** + * @param {Event} e + * @private + */ + selectParent_(e) { + this.shadowRoot.querySelectorAll('.account-list-item') + .forEach(el => el.setAttribute('aria-selected', false)); + this.$$(`#account-list-item-${e.model.index}`) + .setAttribute('aria-selected', true); + + this.selectedParent = e.model.item; + this.fire('go-next'); + }, +});
diff --git a/chrome/browser/resources/chromeos/edu_login/edu_login_util.js b/chrome/browser/resources/chromeos/edu_login/edu_login_util.js index 03c93f00..7260eaf 100644 --- a/chrome/browser/resources/chromeos/edu_login/edu_login_util.js +++ b/chrome/browser/resources/chromeos/edu_login/edu_login_util.js
@@ -7,7 +7,7 @@ * @typedef {{ * email: string, * displayName: string, - * profileImageUrl: string, + * profileImage: string, * obfuscatedGaiaId: string * }} */
diff --git a/chrome/browser/resources/media/media_feeds.html b/chrome/browser/resources/media/media_feeds.html index c4fb7d7..faeee94 100644 --- a/chrome/browser/resources/media/media_feeds.html +++ b/chrome/browser/resources/media/media_feeds.html
@@ -86,6 +86,9 @@ <th sort-key="url"> Url </th> + <th sort-key="lastDiscoveryTime"> + Last Discovery Time + </th> </tr> </thead> <tbody id="feed-table-body"> @@ -96,6 +99,7 @@ <tr> <td class="id-cell"></td> <td class="url-cell"></td> + <td class="last-discovery-time-cell"></td> </tr> </template> </body>
diff --git a/chrome/browser/resources/media/media_feeds.js b/chrome/browser/resources/media/media_feeds.js index e174ec5..e1d8ed23 100644 --- a/chrome/browser/resources/media/media_feeds.js +++ b/chrome/browser/resources/media/media_feeds.js
@@ -32,11 +32,32 @@ td[0].textContent = rowInfo.id; td[1].textContent = rowInfo.url.url; + td[2].textContent = convertMojoTimeToJS(rowInfo.lastDiscoveryTime).toString(); return document.importNode(template.content, true); } /** + * Converts a mojo time to a JS time. + * @param {!mojoBase.mojom.Time} mojoTime + * @return {Date} + */ +function convertMojoTimeToJS(mojoTime) { + // The new Date().getTime() returns the number of milliseconds since the + // UNIX epoch (1970-01-01 00::00:00 UTC), while |internalValue| of the + // device.mojom.Geoposition represents the value of microseconds since the + // Windows FILETIME epoch (1601-01-01 00:00:00 UTC). So add the delta when + // sets the |internalValue|. See more info in //base/time/time.h. + const windowsEpoch = Date.UTC(1601, 0, 1, 0, 0, 0, 0); + const unixEpoch = Date.UTC(1970, 0, 1, 0, 0, 0, 0); + // |epochDeltaInMs| equals to base::Time::kTimeTToMicrosecondsOffset. + const epochDeltaInMs = unixEpoch - windowsEpoch; + const timeInMs = Number(mojoTime.internalValue) / 1000; + + return new Date(timeInMs - epochDeltaInMs); +} + +/** * Remove all rows from the feeds table. */ function clearTable() { @@ -65,6 +86,9 @@ return a.url.url > b.url.url ? 1 : -1; } else if (sortKey == 'id') { return a.id > b.id; + } else if (sortKey == 'lastDiscoveryTime') { + return ( + a.lastDiscoveryTime.internalValue > b.lastDiscoveryTime.internalValue); } assertNotReached('Unsupported sort key: ' + sortKey);
diff --git a/chrome/browser/resources/settings/autofill_page/BUILD.gn b/chrome/browser/resources/settings/autofill_page/BUILD.gn index 2acf1d8..a6d0bdf 100644 --- a/chrome/browser/resources/settings/autofill_page/BUILD.gn +++ b/chrome/browser/resources/settings/autofill_page/BUILD.gn
@@ -99,6 +99,7 @@ deps = [ ":password_manager_proxy", "..:plural_string_proxy", + "../prefs:prefs_behavior", "//ui/webui/resources/js:i18n_behavior", ] } @@ -291,6 +292,7 @@ deps = [ ":password_manager_proxy.m", "..:plural_string_proxy.m", + "../prefs:prefs_behavior.m", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:i18n_behavior.m", ] @@ -523,12 +525,12 @@ js_file = "password_check.js" html_file = "password_check.html" html_type = "dom-module" - auto_imports = [ - "chrome/browser/resources/settings/autofill_page/password_manager_proxy.html|PasswordManagerImpl,PasswordManagerProxy", - "chrome/browser/resources/settings/people_page/sync_browser_proxy.html|SyncBrowserProxyImpl,SyncPrefs,SyncStatus", - "chrome/browser/resources/settings/plural_string_proxy.html|PluralStringProxyImpl", - "ui/webui/resources/html/assert.html|assert", - ] + auto_imports = settings_auto_imports + [ + "chrome/browser/resources/settings/autofill_page/password_manager_proxy.html|PasswordManagerImpl,PasswordManagerProxy", + "chrome/browser/resources/settings/people_page/sync_browser_proxy.html|SyncBrowserProxyImpl,SyncPrefs,SyncStatus", + "chrome/browser/resources/settings/plural_string_proxy.html|PluralStringProxyImpl", + "ui/webui/resources/html/assert.html|assert", + ] namespace_rewrites = settings_namespace_rewrites }
diff --git a/chrome/browser/resources/settings/autofill_page/autofill_page.html b/chrome/browser/resources/settings/autofill_page/autofill_page.html index 30f4dbf..f8faf55 100644 --- a/chrome/browser/resources/settings/autofill_page/autofill_page.html +++ b/chrome/browser/resources/settings/autofill_page/autofill_page.html
@@ -56,7 +56,7 @@ associated-control="[[$$('#passwordManagerButton')]]" page-title="$i18n{checkPasswords}" learn-more-url="$i18n{passwordCheckLearnMoreURL}"> - <settings-password-check></settings-password-check> + <settings-password-check prefs="{{prefs}}"></settings-password-check> </settings-subpage> </template> <template is="dom-if" route-path="/payments">
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.html b/chrome/browser/resources/settings/autofill_page/password_check.html index bae8450..e58224f 100644 --- a/chrome/browser/resources/settings/autofill_page/password_check.html +++ b/chrome/browser/resources/settings/autofill_page/password_check.html
@@ -14,6 +14,8 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html"> <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> +<link rel="import" href="../prefs/prefs.html"> +<link rel="import" href="../prefs/prefs_behavior.html"> <link rel="import" href="password_check_edit_dialog.html"> <link rel="import" href="password_check_list_item.html"> <link rel="import" href="password_manager_proxy.html"> @@ -106,7 +108,7 @@ </cr-button> </div> <div id="noCompromisedCredentials" - hidden$="[[hasLeakedCredentials_(leakedPasswords)]]"> + hidden$="[[!showNoCompromisedPasswordsLabel_]]"> <div class="settings-box secondary"> $i18n{noCompromisedCredentials} </div>
diff --git a/chrome/browser/resources/settings/autofill_page/password_check.js b/chrome/browser/resources/settings/autofill_page/password_check.js index 85b53f7f..af0b38c 100644 --- a/chrome/browser/resources/settings/autofill_page/password_check.js +++ b/chrome/browser/resources/settings/autofill_page/password_check.js
@@ -11,6 +11,7 @@ behaviors: [ I18nBehavior, + PrefsBehavior, WebUIListenerBehavior, ], @@ -79,6 +80,13 @@ * @private {?PasswordManagerProxy.CompromisedCredential} */ activePassword_: Object, + + /** @private */ + showNoCompromisedPasswordsLabel_: { + type: Boolean, + computed: + 'computeShowNoCompromisedPasswordsLabel(syncStatus_, prefs.*, status_, leakedPasswords)', + } }, /** @@ -281,9 +289,13 @@ case CheckState.CANCELED: return this.i18n('checkPasswordsCanceled'); case CheckState.RUNNING: + // Returns the progress of a running check. Ensures that both numbers + // are at least 1. return this.i18n( - 'checkPasswordsProgress', this.status_.alreadyProcessed || 0, - this.status_.remainingInQueue + this.status_.alreadyProcessed); + 'checkPasswordsProgress', (this.status_.alreadyProcessed || 0) + 1, + Math.max( + this.status_.remainingInQueue + this.status_.alreadyProcessed, + 1)); case CheckState.OFFLINE: return this.i18n('checkPasswordsErrorOffline'); case CheckState.SIGNED_OUT: @@ -520,5 +532,26 @@ this.leakedPasswords = resultList.concat(addedResults); }, + /** + * @return {boolean} + * @private + */ + computeShowNoCompromisedPasswordsLabel() { + // Check if user isn't signed in. + if (!this.syncStatus_ || !this.syncStatus_.signedIn) { + return false; + } + + // Check if breach detection is turned off in settings. + if (!this.prefs || + !this.getPref('profile.password_manager_leak_detection').value) { + return false; + } + + // Return true if there was a successful check and no compromised passwords + // were found. + return !this.hasLeakedCredentials_(this.leakedPasswords) && + this.showsTimestamp_(this.status_); + }, }); })();
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.html b/chrome/browser/resources/settings/autofill_page/passwords_section.html index cf97434..031a935 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_section.html +++ b/chrome/browser/resources/settings/autofill_page/passwords_section.html
@@ -111,7 +111,7 @@ </settings-toggle-button> <template is="dom-if" if="[[enablePasswordCheck_]]"> <div id="checkPasswordsBannerContainer" class="settings-box" - hidden$="[[haveCheckedPasswordsBefore_]]"> + hidden$="[[!shouldShowBanner_]]"> <picture> <source srcset="chrome://settings/images/password_check_neutral_dark.svg" @@ -121,7 +121,7 @@ </picture> </div> <div id="checkPasswordsButton" class="settings-box continuation" - hidden$="[[haveCheckedPasswordsBefore_]]"> + hidden$="[[!shouldShowBanner_]]"> <div class="start settings-box-text"> <div>$i18n{checkPasswords}</div> <div class="secondary">$i18n{checkPasswordsDescription}</div> @@ -132,7 +132,7 @@ </div> <div class="settings-box two-line" id="checkPasswordsLinkRow" on-click="onCheckPasswordsClick_" actionable - hidden$="[[!haveCheckedPasswordsBefore_]]"> + hidden$="[[shouldShowBanner_]]"> <iron-icon icon="cr:warning" id="checkPasswordWarningIcon" hidden$="[[!hasLeakedCredentials_]]"></iron-icon> <div class="start settings-box-text">
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.js b/chrome/browser/resources/settings/autofill_page/passwords_section.js index 729664ec..7f97f2c4 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_section.js +++ b/chrome/browser/resources/settings/autofill_page/passwords_section.js
@@ -94,7 +94,30 @@ }, /** @private */ - haveCheckedPasswordsBefore_: Boolean, + signedIn_: { + type: Boolean, + value: true, + computed: 'computeSignedIn_(syncStatus_.signedIn)', + }, + + /** @private */ + hasNeverCheckedPasswords_: { + type: Boolean, + value: false, + }, + + /** @private */ + hasStoredPasswords_: { + type: Boolean, + value: false, + }, + + shouldShowBanner_: { + type: Boolean, + value: true, + computed: 'computeShouldShowBanner_(' + + 'signedIn_, hasNeverCheckedPasswords_, hasStoredPasswords_)', + }, /** @private */ hasLeakedCredentials_: { @@ -234,6 +257,7 @@ // given entry and is stable with regard to mutations to the list, it is // sufficient to just use this id to create a item uid. this.updateList('savedPasswords', item => item.entry.id, newList); + this.hasStoredPasswords_ = list.length > 0; }; const setPasswordExceptionsListener = list => { @@ -254,7 +278,7 @@ // TODO(https://crbug.com/1047726) Remove code duplication with // password_check.js const statusChangeListener = status => { - this.haveCheckedPasswordsBefore_ = !!status.elapsedTimeSinceLastCheck; + this.hasNeverCheckedPasswords_ = !status.elapsedTimeSinceLastCheck; }; this.setIsOptedInForAccountStorageListener_ = @@ -412,6 +436,23 @@ * @return {boolean} * @private */ + computeSignedIn_() { + return !!this.syncStatus_ && !!this.syncStatus_.signedIn; + }, + + /** + * @return {boolean} + * @private + */ + computeShouldShowBanner_() { + return this.signedIn_ && this.hasStoredPasswords_ && + this.hasNeverCheckedPasswords_; + }, + + /** + * @return {boolean} + * @private + */ computeHidePasswordsLink_() { return !!this.syncStatus_ && !!this.syncStatus_.signedIn && !!this.syncPrefs_ && !!this.syncPrefs_.encryptAllData;
diff --git a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js index 9cb6cb1..05544df 100644 --- a/chrome/browser/resources/settings/people_page/sync_browser_proxy.js +++ b/chrome/browser/resources/settings/people_page/sync_browser_proxy.js
@@ -100,11 +100,6 @@ }; /** - * @typedef {{requestSucceeded: boolean, historyRecordingEnabled: boolean}} - */ - let HistoryRecordingEnabled; - - /** * Key to be used with localStorage. * @type {string} */ @@ -224,13 +219,6 @@ * manager in passwords section on page load. */ sendSyncPrefsChanged() {} - - /** - * Fetches if history recording is enabled and can be used to provide - * personalized experience. - * @return {!Promise<!HistoryRecordingEnabled>} - */ - queryIsHistoryRecordingEnabled() {} } /** @@ -338,11 +326,6 @@ sendSyncPrefsChanged() { chrome.send('SyncPrefsDispatch'); } - - /** @override */ - queryIsHistoryRecordingEnabled() { - return cr.sendWithPromise('GetIsHistoryRecordingEnabledAndCanBeUsed'); - } } cr.addSingletonGetter(SyncBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html index 1e6482ea..963f2d5 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.html +++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -16,7 +16,6 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="sync_account_control.html"> <link rel="import" href="sync_encryption_options.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html"> <link rel="import" href="sync_browser_proxy.html"> <link rel="import" href="../privacy_page/personalization_options.html"> <link rel="import" href="../router.html"> @@ -84,32 +83,6 @@ width: 40px; } - #history-usage-state { - text-align: end; - vertical-align: middle; - width: 36px; - } - - #history-usage-row[disabled] { - pointer-events: none; - } - - #history-usage-row[disabled] > #history-usage-state { - text-align: center; - } - - #history-usage-row > cr-icon-button.icon-external { - margin-inline-start: 1px; - } - - #history-usage-state paper-spinner-lite { - --paper-spinner-color: var(--google-grey-500); - --paper-spinner-stroke-width: 2px; - height: var(--cr-icon-size); - vertical-align: middle; - width: var(--cr-icon-size); - } - #toast { left: 0; z-index: 1; @@ -193,31 +166,13 @@ </cr-icon-button> </div> - <a id="history-usage-row" - class="inherit-color no-outline list-item" tabindex="-1" + <a class="inherit-color no-outline list-item" tabindex="-1" target="_blank" href="$i18n{activityControlsUrl}" - on-click="onActivityControlsTap_" - disabled$="[[hideActivityControlsUrl_]]"> + on-click="onActivityControlsTap_"> <div class="start settings-box-text"> $i18n{personalizeGoogleServicesTitle} - <div id="history-usage-off-hint" - class="secondary" hidden$="[[!isSwaaOff_(Swaa_)]]"> - [[getHistoryUsageOffHint_(Swaa_, syncPrefs.encryptAllData, - syncPrefs.typedUrlsSynced)]] - </div> </div> - <div id="history-usage-state" - hidden$="[[!syncSetupFriendlySettings_]]"> - <paper-spinner-lite - class="last" hidden$="[[!isSwaaFetching_(Swaa_)]]" active> - </paper-spinner-lite> - <div class="secondary" hidden$="[[!isSwaaFetched_(Swaa_)]]"> - [[getSwaaStateText_(Swaa_)]] - </div> - </div> - <cr-icon-button class="icon-external" - hidden$="[[hideActivityControlsUrl_]]"> - </cr-icon-button> + <cr-icon-button class="icon-external"></cr-icon-button> </a> <a id="syncDashboardLink"
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js index 2be922e3..2f2ebe0e 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -5,32 +5,6 @@ (function() { /** - * These values are persisted to logs and should not be renumbered or re-used. - * See SyncSetupSettignsDisplayedSwaaState in - * tools/metrics/histograms/enums.xml. - * @enum {number} - */ -const displayedSwaaState = { - ON: 0, - OFF_ENCRYPTION_ON: 1, - OFF_HISTORY_SYNC_OFF: 2, - OFF_WEB_AND_APP_ACTIVITY: 3, - NONE: 4, -}; - -/** - * All possible states for the sWAA bit. - * @enum {string} - */ -const SwaaState = { - NOT_FETCHED: 'not-fetched', - FETCHING: 'fetching', - FAILED: 'failed', - ON: 'On', - OFF: 'Off', -}; - -/** * @fileoverview * 'settings-sync-page' is the settings page containing sync settings. */ @@ -40,7 +14,6 @@ behaviors: [ WebUIListenerBehavior, settings.RouteObserverBehavior, - I18nBehavior, ], properties: { @@ -142,47 +115,15 @@ syncSetupFriendlySettings_: { type: Boolean, value() { - return loadTimeData.valueExists('syncSetupFriendlySettings') && - loadTimeData.getBoolean('syncSetupFriendlySettings'); + return loadTimeData.getBoolean('syncSetupFriendlySettings'); } }, - - /** - * Whether history is not synced or data is encrypted. - * @private - */ - historyNotSyncedOrEncrypted_: { - type: Boolean, - computed: 'computeHistoryNotSyncedOrEncrypted_(' + - 'syncPrefs.encryptAllData, syncPrefs.typedUrlsSynced)', - }, - - /** @private */ - hideActivityControlsUrl_: { - type: Boolean, - computed: 'computeHideActivityControlsUrl_(historyNotSyncedOrEncrypted_)', - }, - - /** @private */ - Swaa_: { - type: String, - value: SwaaState.NOT_FETCHED, - }, }, - observers: ['fetchSwaa_(syncSectionDisabled_, historyNotSyncedOrEncrypted_)'], - /** @private {?settings.SyncBrowserProxy} */ browserProxy_: null, /** - * The visibility changed callback is used to refetch the |Swaa_| bit when - * the page is foregrounded. - * @private {?Function} - */ - visibilityChangedCallback_: null, - - /** * The beforeunload callback is used to show the 'Leave site' dialog. This * makes sure that the user has the chance to go back and confirm the sync * opt-in before leaving. @@ -282,134 +223,6 @@ }, /** - * @return {boolean} Returns true if History sync is off or data is encrypted. - * @private - */ - computeHistoryNotSyncedOrEncrypted_() { - return !!(this.syncPrefs) && - (!this.syncPrefs.typedUrlsSynced || this.syncPrefs.encryptAllData); - }, - - /** - * @return {boolean} - * @private - */ - computeHideActivityControlsUrl_() { - return !!this.syncSetupFriendlySettings_ && - !!this.historyNotSyncedOrEncrypted_; - }, - - - /** - * Compute and fetch the sWAA bit for sync users. sWAA is 'OFF' if sync - * history is off or data is encrypted with custom passphrase. Otherwise, - * a query to |Web and App Activity| is needed. - * @private - */ - fetchSwaa_() { - const router = settings.Router.getInstance(); - if (router.getCurrentRoute() !== router.getRoutes().SYNC) { - return; - } - - if (!this.syncSetupFriendlySettings_) { - return; - } - - if (!this.syncPrefs || this.syncPrefs.encryptAllData === undefined || - this.syncPrefs.typedUrlsSynced === undefined) { - return; - } - - if (this.syncSectionDisabled_) { - this.Swaa_ = SwaaState.NOT_FETCHED; - return; - } - - if (this.historyNotSyncedOrEncrypted_) { - this.Swaa_ = SwaaState.OFF; - this.recordDisplayedSwaa(); - return; - } - - if (this.Swaa_ === SwaaState.FETCHING) { - return; - } - - this.Swaa_ = SwaaState.FETCHING; - const updateSwaa = historyRecordingEnabled => { - this.Swaa_ = historyRecordingEnabled.requestSucceeded ? - (historyRecordingEnabled.historyRecordingEnabled ? SwaaState.ON : - SwaaState.OFF) : - SwaaState.FAILED; - this.recordDisplayedSwaa(); - }; - this.browserProxy_.queryIsHistoryRecordingEnabled().then(updateSwaa); - }, - - /** @private */ - recordDisplayedSwaa() { - let currentDisplayedSwaa; - if (this.Swaa_ === SwaaState.FAILED) { - currentDisplayedSwaa = displayedSwaaState.NONE; - } else if (this.Swaa_ === SwaaState.ON) { - currentDisplayedSwaa = displayedSwaaState.ON; - } else { - assert(this.Swaa_ === SwaaState.OFF); - if (this.syncPrefs.encryptAllData) { - currentDisplayedSwaa = displayedSwaaState.OFF_ENCRYPTION_ON; - } else if (!this.syncPrefs.typedUrlsSynced) { - currentDisplayedSwaa = displayedSwaaState.OFF_HISTORY_SYNC_OFF; - } else { - currentDisplayedSwaa = displayedSwaaState.OFF_WEB_AND_APP_ACTIVITY; - } - } - chrome.metricsPrivate.recordEnumerationValue( - 'Settings.SyncSetup.DisplayedSwaaState', currentDisplayedSwaa, - Object.keys(displayedSwaaState).length); - }, - - /** - * Refetch sWAA when the page is forgrounded, to guarantee the value shown is - * most up-to-date. - * @private - */ - visibilityHandler_() { - if (document.visibilityState === 'visible') { - this.fetchSwaa_(); - } - }, - - /** - * Return hint to explain the sWAA state. It is displayed as secondary text in - * the history usage row. - * @private - */ - getHistoryUsageOffHint_() { - if (this.Swaa_ === SwaaState.OFF) { - if (this.syncPrefs.encryptAllData) { - return this.i18n('dataEncryptedHint'); - } - - if (!this.syncPrefs.typedUrlsSynced) { - return this.i18n('historySyncOffHint'); - } - return this.i18n('SwaaOffHint'); - } - return ''; - }, - - /** - * @private - */ - getSwaaStateText_() { - if (!this.isSwaaFetched_()) { - return ''; - } - return this.i18n(this.Swaa_ === SwaaState.ON ? 'SwaaOn' : 'SwaaOff'); - }, - - /** * @return {boolean} * @private */ @@ -495,36 +308,10 @@ return expectedPageStatus == this.pageStatus_; }, - /** - * @return {boolean} - * @private - */ - isSwaaFetching_() { - return this.Swaa_ === SwaaState.FETCHING; - }, - - /** - * @return {boolean} - * @private - */ - isSwaaFetched_() { - return this.Swaa_ === SwaaState.ON || this.Swaa_ === SwaaState.OFF; - }, - - /** - * @return {boolean} - * @private - */ - isSwaaOff_() { - return this.Swaa_ === SwaaState.OFF; - }, - /** @private */ onNavigateToPage_() { const router = settings.Router.getInstance(); assert(router.getCurrentRoute() == router.getRoutes().SYNC); - this.Swaa_ = SwaaState.NOT_FETCHED; - this.fetchSwaa_(); if (this.beforeunloadCallback_) { return; } @@ -551,11 +338,6 @@ this.unloadCallback_ = this.onNavigateAwayFromPage_.bind(this); window.addEventListener('unload', this.unloadCallback_); - - this.visibilityChangedCallback_ = this.visibilityHandler_.bind(this); - window.addEventListener('focus', this.visibilityChangedCallback_); - document.addEventListener( - 'visibilitychange', this.visibilityChangedCallback_); }, /** @private */ @@ -577,13 +359,6 @@ window.removeEventListener('unload', this.unloadCallback_); this.unloadCallback_ = null; } - - if (this.visibilityChangedCallback_) { - window.removeEventListener('focus', this.visibilityChangedCallback_); - document.removeEventListener( - 'visibilitychange', this.visibilityChangedCallback_); - this.visibilityChangedCallback_ = null; - } }, /** @@ -594,8 +369,13 @@ this.syncPrefs = syncPrefs; this.pageStatus_ = settings.PageStatus.CONFIGURE; - if (this.Swaa_ === SwaaState.FAILED) { - this.fetchSwaa_(); + // Hide the new passphrase box if (a) full data encryption is enabled, + // (b) encrypting all data is not allowed (so far, only applies to + // supervised accounts), or (c) the user is a supervised account. + if (this.syncPrefs.encryptAllData || + !this.syncPrefs.encryptAllDataAllowed || + (this.syncStatus && this.syncStatus.supervisedUser)) { + this.creatingNewPassphrase_ = false; } },
diff --git a/chrome/browser/resources/settings/privacy_page/BUILD.gn b/chrome/browser/resources/settings/privacy_page/BUILD.gn index a644d11..679803a 100644 --- a/chrome/browser/resources/settings/privacy_page/BUILD.gn +++ b/chrome/browser/resources/settings/privacy_page/BUILD.gn
@@ -27,6 +27,7 @@ js_library("collapse_radio_button") { deps = [ "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button_behavior", + "//ui/webui/resources/cr_elements/policy:cr_policy_indicator", ] }
diff --git a/chrome/browser/resources/settings/privacy_page/collapse_radio_button.html b/chrome/browser/resources/settings/privacy_page/collapse_radio_button.html index cb861aca..3820469 100644 --- a/chrome/browser/resources/settings/privacy_page/collapse_radio_button.html +++ b/chrome/browser/resources/settings/privacy_page/collapse_radio_button.html
@@ -3,6 +3,8 @@ <link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html"> <link rel="import" href="../settings_shared_css.html"> @@ -13,9 +15,17 @@ display: block; } - #radioCollapse { - display: flex; - padding: 0; + :host([disabled]) { + opacity: 1; + } + + cr-policy-indicator, + :host([disabled]) cr-expand-button { + pointer-events: auto; + } + + :host([disabled]) .disc-wrapper { + opacity: var(--cr-disabled-opacity); } iron-collapse { @@ -23,13 +33,21 @@ margin-inline-start: var(--cr-section-indent-width); } + .separator { + margin-inline-end: 0; + } + #labelWrapper { padding-bottom: 6px; padding-top: 6px; } - </style> - <div id="radioCollapse" class="settings-box first"> + #radioCollapse { + align-items: center; + display: flex; + } + </style> + <div id="radioCollapse"> <div aria-checked$="[[getAriaChecked_(checked)]]" aria-disabled$="[[getAriaDisabled_(disabled)]]" aria-labelledby="label" @@ -51,8 +69,14 @@ <slot name="sub-label"></slot> </div> </div> - <div class="separator"></div> - <cr-expand-button expanded="{{expanded}}"></cr-expand-button> + <cr-policy-indicator id="policyIndicator" + on-click="onIndicatorClick_" + on-aria-label="[[label]]" + indicator-type="[[policyIndicatorType]]"> + </cr-policy-indicator> + <div hidden$="[[noCollapse]]" class="separator"></div> + <cr-expand-button hidden$="[[noCollapse]]" expanded="{{expanded}}"> + </cr-expand-button> </div> <iron-collapse opened="[[expanded]]">
diff --git a/chrome/browser/resources/settings/privacy_page/collapse_radio_button.js b/chrome/browser/resources/settings/privacy_page/collapse_radio_button.js index d717320..0e33605 100644 --- a/chrome/browser/resources/settings/privacy_page/collapse_radio_button.js +++ b/chrome/browser/resources/settings/privacy_page/collapse_radio_button.js
@@ -16,6 +16,17 @@ value: false, }, + /** + * Which indicator type to show (or NONE). + * @type {CrPolicyIndicatorType} + */ + policyIndicatorType: { + type: String, + value: CrPolicyIndicatorType.NONE, + }, + + noCollapse: Boolean, + label: String, subLabel: { @@ -30,4 +41,14 @@ onCheckedChanged_() { this.expanded = this.checked; }, + + /** + * @param {!Event} e + * @private + */ + onIndicatorClick_(e) { + // Prevent interacting with the indicator changing anything when disabled. + e.preventDefault(); + e.stopPropagation(); + }, });
diff --git a/chrome/browser/sharing/shared_clipboard/feature_flags.cc b/chrome/browser/sharing/shared_clipboard/feature_flags.cc index eb7a304..6bc97a07 100644 --- a/chrome/browser/sharing/shared_clipboard/feature_flags.cc +++ b/chrome/browser/sharing/shared_clipboard/feature_flags.cc
@@ -15,6 +15,9 @@ const base::FeatureParam<std::string> kRemoteCopyAllowedOrigins = { &kRemoteCopyReceiver, "RemoteCopyAllowedOrigins", ""}; +const base::Feature kRemoteCopyImageNotification{ + "RemoteCopyImageNotification", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kRemoteCopyProgressNotification{ "RemoteCopyProgressNotification", base::FEATURE_DISABLED_BY_DEFAULT}; #endif // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) ||
diff --git a/chrome/browser/sharing/shared_clipboard/feature_flags.h b/chrome/browser/sharing/shared_clipboard/feature_flags.h index ad317c4..c07172a 100644 --- a/chrome/browser/sharing/shared_clipboard/feature_flags.h +++ b/chrome/browser/sharing/shared_clipboard/feature_flags.h
@@ -22,6 +22,9 @@ // List of allowed origins to fetch images from, comma separated. extern const base::FeatureParam<std::string> kRemoteCopyAllowedOrigins; +// Feature to enable image notifications for remote copy messages. +extern const base::Feature kRemoteCopyImageNotification; + // Feature to enable progress notifications for remote copy messages. extern const base::Feature kRemoteCopyProgressNotification; #endif // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) ||
diff --git a/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc b/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc index 5869167..d7eb9d9 100644 --- a/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc +++ b/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc
@@ -440,6 +440,11 @@ LogRemoteCopyDecodeImageTime(timer_.Elapsed()); LogRemoteCopyReceivedImageSizeAfterDecode(image.computeByteSize()); + if (!base::FeatureList::IsEnabled(kRemoteCopyImageNotification)) { + WriteImageAndShowNotification(image, image); + return; + } + double scale = std::min( static_cast<double>(kNotificationImageMaxWidthPx) / image.width(), static_cast<double>(kNotificationImageMaxHeightPx) / image.height()); @@ -518,14 +523,18 @@ const std::string& notification_id) { TRACE_EVENT0("sharing", "RemoteCopyMessageHandler::ShowNotification"); + bool use_image_notification = + base::FeatureList::IsEnabled(kRemoteCopyImageNotification) && + !image.drawsNothing(); + message_center::RichNotificationData rich_notification_data; - if (!image.drawsNothing()) + if (use_image_notification) rich_notification_data.image = gfx::Image::CreateFrom1xBitmap(image); rich_notification_data.vector_small_image = &kSendTabToSelfIcon; message_center::NotificationType type = - image.drawsNothing() ? message_center::NOTIFICATION_TYPE_SIMPLE - : message_center::NOTIFICATION_TYPE_IMAGE; + use_image_notification ? message_center::NOTIFICATION_TYPE_IMAGE + : message_center::NOTIFICATION_TYPE_SIMPLE; ui::Accelerator paste_accelerator(ui::VKEY_V, ui::EF_PLATFORM_ACCELERATOR);
diff --git a/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler_unittest.cc b/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler_unittest.cc index b2cf72ec..329ac4fb 100644 --- a/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler_unittest.cc +++ b/chrome/browser/sharing/shared_clipboard/remote_copy_message_handler_unittest.cc
@@ -235,8 +235,8 @@ TEST_F(RemoteCopyMessageHandlerTest, ImageNotificationWithoutProgressFlag) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeaturesAndParameters( - {{kRemoteCopyReceiver, - {{kRemoteCopyAllowedOrigins.name, kTestImageUrl}}}}, + {{kRemoteCopyReceiver, {{kRemoteCopyAllowedOrigins.name, kTestImageUrl}}}, + {kRemoteCopyImageNotification, {}}}, {kRemoteCopyProgressNotification}); base::RunLoop run_loop; @@ -267,10 +267,50 @@ task_environment_.RunUntilIdle(); } +TEST_F(RemoteCopyMessageHandlerTest, + NoImageAndNoProgressNotificationWhenDisabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeaturesAndParameters( + {{kRemoteCopyReceiver, + {{kRemoteCopyAllowedOrigins.name, kTestImageUrl}}}}, + {kRemoteCopyImageNotification, kRemoteCopyProgressNotification}); + + base::RunLoop run_loop; + ClipboardObserver observer(run_loop.QuitClosure()); + ui::ClipboardMonitor::GetInstance()->AddObserver(&observer); + + message_handler_->OnMessage(CreateMessageWithImage(kTestImageUrl), + base::DoNothing()); + + // There should be no progress notification with the flag disabled. + EXPECT_FALSE(HasProgressNotification()); + + // Let tasks run until the image is decoded, written to the clipboard and the + // simple notification is shown (the image notification feature is disabled). + run_loop.Run(); + ui::ClipboardMonitor::GetInstance()->RemoveObserver(&observer); + + // After finishing the transfer there should be no progress notification. + EXPECT_FALSE(HasProgressNotification()); + + // Expect the image to be in the clipboard now. + SkBitmap image = GetClipboardImage(); + EXPECT_TRUE(gfx::BitmapsAreEqual(*image_, image)); + + // Expect a simple notification. + auto notification = GetNotification(); + EXPECT_TRUE(notification.image().IsEmpty()); + + // Calling GetDefaultStoragePartition creates tasks that need to run before + // the ScopedFeatureList is destroyed. See crbug.com/1060869 + task_environment_.RunUntilIdle(); +} + TEST_F(RemoteCopyMessageHandlerTest, ImageNotificationWithProgressFlag) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeaturesAndParameters( {{kRemoteCopyReceiver, {{kRemoteCopyAllowedOrigins.name, kTestImageUrl}}}, + {kRemoteCopyImageNotification, {}}, {kRemoteCopyProgressNotification, {}}}, {}); @@ -335,6 +375,7 @@ base::test::ScopedFeatureList feature_list; feature_list.InitWithFeaturesAndParameters( {{kRemoteCopyReceiver, {{kRemoteCopyAllowedOrigins.name, kTestImageUrl}}}, + {kRemoteCopyImageNotification, {}}, {kRemoteCopyProgressNotification, {}}}, {});
diff --git a/chrome/browser/sync/test/integration/password_manager_sync_test.cc b/chrome/browser/sync/test/integration/password_manager_sync_test.cc index 5361f2b..2373b2dd 100644 --- a/chrome/browser/sync/test/integration/password_manager_sync_test.cc +++ b/chrome/browser/sync/test/integration/password_manager_sync_test.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/password_manager/account_storage/account_password_store_factory.h" #include "chrome/browser/password_manager/password_manager_test_base.h" #include "chrome/browser/password_manager/password_store_factory.h" +#include "chrome/browser/sync/test/integration/encryption_helper.h" #include "chrome/browser/sync/test/integration/passwords_helper.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" #include "chrome/browser/sync/test/integration/secondary_account_helper.h" @@ -34,6 +35,7 @@ namespace { using testing::ElementsAre; +using testing::IsEmpty; MATCHER_P2(MatchesLogin, username, password, "") { return arg->username_value == base::UTF8ToUTF16(username) && @@ -103,6 +105,8 @@ ASSERT_TRUE(embedded_test_server()->Start()); host_resolver()->AddRule("*", "127.0.0.1"); + + encryption_helper::SetKeystoreNigoriInFakeServer(GetFakeServer()); } void TearDownOnMainThread() override { @@ -110,6 +114,46 @@ SyncTest::TearDownOnMainThread(); } + void SetupSyncTransportWithPasswordAccountStorage() { + // Setup Sync for a secondary account (i.e. in transport mode). + secondary_account_helper::SignInSecondaryAccount( + GetProfile(0), &test_url_loader_factory_, "user@email.com"); + ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); + ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); + + // Let the user opt in to the passwords account storage, and wait for it to + // become active. + password_manager_util::SetAccountStorageOptIn(GetProfile(0)->GetPrefs(), + GetSyncService(0), true); + PasswordSyncActiveChecker(GetSyncService(0)).Wait(); + ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::PASSWORDS)); + } + + autofill::PasswordForm CreateTestPasswordForm(const std::string& username, + const std::string& password) { + GURL origin = embedded_test_server()->GetURL("/"); + autofill::PasswordForm form; + form.signon_realm = origin.spec(); + form.origin = origin; + form.username_value = base::UTF8ToUTF16(username); + form.password_value = base::UTF8ToUTF16(password); + form.date_created = base::Time::Now(); + return form; + } + + void AddPasswordToFakeServer(const std::string& username, + const std::string& password) { + passwords_helper::InjectKeystoreEncryptedServerPassword( + CreateTestPasswordForm(username, password), GetFakeServer()); + } + + void AddLocalPassword(const std::string& username, + const std::string& password) { + scoped_refptr<password_manager::PasswordStore> password_store = + passwords_helper::GetPasswordStore(0); + password_store->AddLogin(CreateTestPasswordForm(username, password)); + } + // Synchronously reads all credentials from the profile password store and // returns them. std::vector<std::unique_ptr<autofill::PasswordForm>> @@ -142,6 +186,19 @@ observer.Wait(); } + void FillAndSubmitPasswordForm(content::WebContents* web_contents, + const std::string& username, + const std::string& password) { + NavigationObserver observer(web_contents); + std::string fill_and_submit = base::StringPrintf( + "document.getElementById('username_field').value = '%s';" + "document.getElementById('password_field').value = '%s';" + "document.getElementById('input_submit_button').click()", + username.c_str(), password.c_str()); + ASSERT_TRUE(content::ExecJs(web_contents, fill_and_submit)); + observer.Wait(); + } + private: base::test::ScopedFeatureList feature_list_; @@ -159,32 +216,13 @@ content::WebContents* web_contents = nullptr; GetNewTab(GetBrowser(0), &web_contents); - // Setup Sync for a secondary account (i.e. in transport mode). - secondary_account_helper::SignInSecondaryAccount( - GetProfile(0), &test_url_loader_factory_, "user@email.com"); - ASSERT_TRUE(GetClient(0)->AwaitSyncTransportActive()); - ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureEnabled()); - - // Let the user opt in to the passwords account storage, and wait for it to - // become active. - password_manager_util::SetAccountStorageOptIn(GetProfile(0)->GetPrefs(), - GetSyncService(0), true); - PasswordSyncActiveChecker(GetSyncService(0)).Wait(); - ASSERT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::PASSWORDS)); + SetupSyncTransportWithPasswordAccountStorage(); // Part 1: Save a password; it should go into the account store by default. { - // Navigate to a page with a password form. + // Navigate to a page with a password form, fill it out, and submit it. NavigateToFile(web_contents, "/password/password_form.html"); - - // Fill out and submit the password form. - NavigationObserver observer(web_contents); - std::string fill_and_submit = - "document.getElementById('username_field').value = 'accountuser';" - "document.getElementById('password_field').value = 'accountpass';" - "document.getElementById('input_submit_button').click()"; - ASSERT_TRUE(content::ExecJs(web_contents, fill_and_submit)); - observer.Wait(); + FillAndSubmitPasswordForm(web_contents, "accountuser", "accountpass"); // Save the password and check the store. BubbleObserver bubble_observer(web_contents); @@ -203,7 +241,7 @@ GetProfile(0)->GetPrefs(), GetSyncService(0), autofill::PasswordForm::Store::kProfileStore); { - // Navigate to a page with a password form. + // Navigate to a page with a password form, fill it out, and submit it. // TODO(crbug.com/1058339): If we use the same URL as in part 1 here, then // the test fails because the *account* data gets filled and submitted // again. This is because the password manager is "smart" and prefers @@ -216,15 +254,7 @@ // autofill on pageload, see PasswordManagerBrowserTestWithAutofillDisabled. // NavigateToFile(web_contents, "/password/password_form.html"); NavigateToFile(web_contents, "/password/simple_password.html"); - - // Fill out and submit the password form. - NavigationObserver observer(web_contents); - std::string fill_and_submit = - "document.getElementById('username_field').value = 'localuser';" - "document.getElementById('password_field').value = 'localpass';" - "document.getElementById('input_submit_button').click()"; - ASSERT_TRUE(content::ExecJs(web_contents, fill_and_submit)); - observer.Wait(); + FillAndSubmitPasswordForm(web_contents, "localuser", "localpass"); // Save the password and check the store. BubbleObserver bubble_observer(web_contents); @@ -237,6 +267,189 @@ ElementsAre(MatchesLogin("localuser", "localpass"))); } } + +IN_PROC_BROWSER_TEST_F(PasswordManagerSyncTest, UpdateInProfileStore) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + + AddLocalPassword("user", "localpass"); + + SetupSyncTransportWithPasswordAccountStorage(); + + content::WebContents* web_contents = nullptr; + GetNewTab(GetBrowser(0), &web_contents); + + // Go to a form and submit a different password. + NavigateToFile(web_contents, "/password/simple_password.html"); + FillAndSubmitPasswordForm(web_contents, "user", "newpass"); + + // There should be an update bubble; accept it. + BubbleObserver bubble_observer(web_contents); + ASSERT_TRUE(bubble_observer.IsUpdatePromptShownAutomatically()); + bubble_observer.AcceptUpdatePrompt(); + + // The updated password should be in the profile store, while the account + // store should still be empty. + EXPECT_THAT(GetAllLoginsFromProfilePasswordStore(), + ElementsAre(MatchesLogin("user", "newpass"))); + EXPECT_THAT(GetAllLoginsFromAccountPasswordStore(), IsEmpty()); +} + +IN_PROC_BROWSER_TEST_F(PasswordManagerSyncTest, UpdateInAccountStore) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + + AddPasswordToFakeServer("user", "accountpass"); + + SetupSyncTransportWithPasswordAccountStorage(); + + content::WebContents* web_contents = nullptr; + GetNewTab(GetBrowser(0), &web_contents); + + // Go to a form and submit a different password. + NavigateToFile(web_contents, "/password/simple_password.html"); + FillAndSubmitPasswordForm(web_contents, "user", "newpass"); + + // There should be an update bubble; accept it. + BubbleObserver bubble_observer(web_contents); + ASSERT_TRUE(bubble_observer.IsUpdatePromptShownAutomatically()); + bubble_observer.AcceptUpdatePrompt(); + + // The updated password should be in the account store, while the profile + // store should still be empty. + EXPECT_THAT(GetAllLoginsFromAccountPasswordStore(), + ElementsAre(MatchesLogin("user", "newpass"))); + EXPECT_THAT(GetAllLoginsFromProfilePasswordStore(), IsEmpty()); +} + +IN_PROC_BROWSER_TEST_F(PasswordManagerSyncTest, + UpdateMatchingCredentialInBothStores) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + + AddPasswordToFakeServer("user", "pass"); + AddLocalPassword("user", "pass"); + + SetupSyncTransportWithPasswordAccountStorage(); + + content::WebContents* web_contents = nullptr; + GetNewTab(GetBrowser(0), &web_contents); + + // Go to a form and submit a different password. + NavigateToFile(web_contents, "/password/simple_password.html"); + FillAndSubmitPasswordForm(web_contents, "user", "newpass"); + + // There should be an update bubble; accept it. + BubbleObserver bubble_observer(web_contents); + ASSERT_TRUE(bubble_observer.IsUpdatePromptShownAutomatically()); + bubble_observer.AcceptUpdatePrompt(); + + // The updated password should be in both stores. + EXPECT_THAT(GetAllLoginsFromAccountPasswordStore(), + ElementsAre(MatchesLogin("user", "newpass"))); + EXPECT_THAT(GetAllLoginsFromProfilePasswordStore(), + ElementsAre(MatchesLogin("user", "newpass"))); +} + +IN_PROC_BROWSER_TEST_F(PasswordManagerSyncTest, + UpdateMismatchingCredentialInBothStores) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + + AddPasswordToFakeServer("user", "accountpass"); + AddLocalPassword("user", "localpass"); + + SetupSyncTransportWithPasswordAccountStorage(); + + content::WebContents* web_contents = nullptr; + GetNewTab(GetBrowser(0), &web_contents); + + // Go to a form and submit a different password. + NavigateToFile(web_contents, "/password/simple_password.html"); + FillAndSubmitPasswordForm(web_contents, "user", "newpass"); + + // There should be an update bubble; accept it. + BubbleObserver bubble_observer(web_contents); + ASSERT_TRUE(bubble_observer.IsUpdatePromptShownAutomatically()); + bubble_observer.AcceptUpdatePrompt(); + + // The updated password should be in both stores. + EXPECT_THAT(GetAllLoginsFromAccountPasswordStore(), + ElementsAre(MatchesLogin("user", "newpass"))); + EXPECT_THAT(GetAllLoginsFromProfilePasswordStore(), + ElementsAre(MatchesLogin("user", "newpass"))); +} + +// Tests that if credentials for the same username, but with different passwords +// exist in the two stores, and one of them is used to successfully log in, the +// other one is silently updated to match. +IN_PROC_BROWSER_TEST_F(PasswordManagerSyncTest, + AutoUpdateFromAccountToProfileOnSuccessfulUse) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + + // Add credentials for the same username, but with different passwords, to the + // two stores. + AddPasswordToFakeServer("user", "accountpass"); + AddLocalPassword("user", "localpass"); + + SetupSyncTransportWithPasswordAccountStorage(); + + // Now we have credentials for the same user, but with different passwords, in + // the two stores. + ASSERT_THAT(GetAllLoginsFromProfilePasswordStore(), + ElementsAre(MatchesLogin("user", "localpass"))); + ASSERT_THAT(GetAllLoginsFromAccountPasswordStore(), + ElementsAre(MatchesLogin("user", "accountpass"))); + + content::WebContents* web_contents = nullptr; + GetNewTab(GetBrowser(0), &web_contents); + + // Go to a form and submit the version of the credentials from the profile + // store. + NavigateToFile(web_contents, "/password/simple_password.html"); + FillAndSubmitPasswordForm(web_contents, "user", "localpass"); + + // Now the credential should of course still be in the profile store... + ASSERT_THAT(GetAllLoginsFromProfilePasswordStore(), + ElementsAre(MatchesLogin("user", "localpass"))); + // ...but also the one in the account store should have been silently updated + // to match. + EXPECT_THAT(GetAllLoginsFromAccountPasswordStore(), + ElementsAre(MatchesLogin("user", "localpass"))); +} + +// Tests that if credentials for the same username, but with different passwords +// exist in the two stores, and one of them is used to successfully log in, the +// other one is silently updated to match. +IN_PROC_BROWSER_TEST_F(PasswordManagerSyncTest, + AutoUpdateFromProfileToAccountOnSuccessfulUse) { + ASSERT_TRUE(SetupClients()) << "SetupClients() failed."; + + // Add credentials for the same username, but with different passwords, to the + // two stores. + AddPasswordToFakeServer("user", "accountpass"); + AddLocalPassword("user", "localpass"); + + SetupSyncTransportWithPasswordAccountStorage(); + + // Now we have credentials for the same user, but with different passwords, in + // the two stores. + ASSERT_THAT(GetAllLoginsFromProfilePasswordStore(), + ElementsAre(MatchesLogin("user", "localpass"))); + ASSERT_THAT(GetAllLoginsFromAccountPasswordStore(), + ElementsAre(MatchesLogin("user", "accountpass"))); + + content::WebContents* web_contents = nullptr; + GetNewTab(GetBrowser(0), &web_contents); + + // Go to a form and submit the version of the credentials from the account + // store. + NavigateToFile(web_contents, "/password/simple_password.html"); + FillAndSubmitPasswordForm(web_contents, "user", "accountpass"); + + // Now the credential should of course still be in the account store... + ASSERT_THAT(GetAllLoginsFromAccountPasswordStore(), + ElementsAre(MatchesLogin("user", "accountpass"))); + // ...but also the one in the profile store should have been updated to match. + EXPECT_THAT(GetAllLoginsFromProfilePasswordStore(), + ElementsAre(MatchesLogin("user", "accountpass"))); +} #endif // !defined(OS_CHROMEOS) } // namespace
diff --git a/chrome/browser/sync/test/integration/passwords_helper.cc b/chrome/browser/sync/test/integration/passwords_helper.cc index 99af7e98..f4117f09 100644 --- a/chrome/browser/sync/test/integration/passwords_helper.cc +++ b/chrome/browser/sync/test/integration/passwords_helper.cc
@@ -333,6 +333,13 @@ } void InjectKeystoreEncryptedServerPassword( + const autofill::PasswordForm& form, + fake_server::FakeServer* fake_server) { + InjectKeystoreEncryptedServerPassword(SpecificsDataFromPasswordForm(form), + fake_server); +} + +void InjectKeystoreEncryptedServerPassword( const sync_pb::PasswordSpecificsData& password_data, fake_server::FakeServer* fake_server) { InjectEncryptedServerPassword(
diff --git a/chrome/browser/sync/test/integration/passwords_helper.h b/chrome/browser/sync/test/integration/passwords_helper.h index 52be73e0..56fc0c2c 100644 --- a/chrome/browser/sync/test/integration/passwords_helper.h +++ b/chrome/browser/sync/test/integration/passwords_helper.h
@@ -116,6 +116,10 @@ fake_server::FakeServer* fake_server); // As above, but using standard Keystore encryption. void InjectKeystoreEncryptedServerPassword( + const autofill::PasswordForm& form, + fake_server::FakeServer* fake_server); +// As above, but using standard Keystore encryption and PasswordSpecificsData. +void InjectKeystoreEncryptedServerPassword( const sync_pb::PasswordSpecificsData& password_data, fake_server::FakeServer* fake_server);
diff --git a/chrome/browser/ui/global_media_controls/cast_media_notification_item_unittest.cc b/chrome/browser/ui/global_media_controls/cast_media_notification_item_unittest.cc index eeb2a13..dec75f3 100644 --- a/chrome/browser/ui/global_media_controls/cast_media_notification_item_unittest.cc +++ b/chrome/browser/ui/global_media_controls/cast_media_notification_item_unittest.cc
@@ -60,7 +60,8 @@ MOCK_METHOD1(HideNotification, void(const std::string&)); MOCK_METHOD1(RemoveItem, void(const std::string&)); MOCK_CONST_METHOD0(GetTaskRunner, scoped_refptr<base::SequencedTaskRunner>()); - MOCK_METHOD1(LogMediaSessionActionButtonPressed, void(const std::string&)); + MOCK_METHOD2(LogMediaSessionActionButtonPressed, + void(const std::string&, MediaSessionAction)); }; class MockMediaNotificationView
diff --git a/chrome/browser/ui/global_media_controls/cast_media_notification_provider_unittest.cc b/chrome/browser/ui/global_media_controls/cast_media_notification_provider_unittest.cc index 3fe7349..7207356 100644 --- a/chrome/browser/ui/global_media_controls/cast_media_notification_provider_unittest.cc +++ b/chrome/browser/ui/global_media_controls/cast_media_notification_provider_unittest.cc
@@ -38,7 +38,9 @@ scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override { return nullptr; } - MOCK_METHOD1(LogMediaSessionActionButtonPressed, void(const std::string& id)); + MOCK_METHOD2(LogMediaSessionActionButtonPressed, + void(const std::string& id, + media_session::mojom::MediaSessionAction action)); }; class MockMediaNotificationView
diff --git a/chrome/browser/ui/global_media_controls/media_notification_service.cc b/chrome/browser/ui/global_media_controls/media_notification_service.cc index 7d812c7..46818e97 100644 --- a/chrome/browser/ui/global_media_controls/media_notification_service.cc +++ b/chrome/browser/ui/global_media_controls/media_notification_service.cc
@@ -19,13 +19,19 @@ #include "components/media_message_center/media_notification_item.h" #include "components/media_message_center/media_notification_util.h" #include "components/media_message_center/media_session_notification_item.h" +#include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/media_session.h" #include "content/public/browser/media_session_service.h" #include "media/base/media_switches.h" #include "services/media_session/public/mojom/media_session.mojom.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "services/metrics/public/cpp/ukm_recorder.h" namespace { +// The maximum number of actions we will record to UKM for a specific source. +constexpr int kMaxActionsRecordedToUKM = 100; + constexpr int kAutoDismissTimerInMinutesDefault = 60; // minutes constexpr const char kAutoDismissTimerInMinutesParamName[] = "timer_in_minutes"; @@ -427,7 +433,8 @@ } void MediaNotificationService::LogMediaSessionActionButtonPressed( - const std::string& id) { + const std::string& id, + media_session::mojom::MediaSessionAction action) { auto it = sessions_.find(id); if (it == sessions_.end()) return; @@ -438,6 +445,17 @@ base::UmaHistogramBoolean("Media.GlobalMediaControls.UserActionFocus", IsWebContentsFocused(web_contents)); + + ukm::UkmRecorder* recorder = ukm::UkmRecorder::Get(); + ukm::SourceId source_id = + ukm::GetSourceIdForWebContentsDocument(web_contents); + + if (++actions_recorded_to_ukm_[source_id] > kMaxActionsRecordedToUKM) + return; + + ukm::builders::Media_GlobalMediaControls_ActionButtonPressed(source_id) + .SetMediaSessionAction(static_cast<int64_t>(action)) + .Record(recorder); } void MediaNotificationService::OnContainerClicked(const std::string& id) {
diff --git a/chrome/browser/ui/global_media_controls/media_notification_service.h b/chrome/browser/ui/global_media_controls/media_notification_service.h index c72036aa..1c3c1a3d 100644 --- a/chrome/browser/ui/global_media_controls/media_notification_service.h +++ b/chrome/browser/ui/global_media_controls/media_notification_service.h
@@ -25,6 +25,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "services/media_session/public/mojom/audio_focus.mojom.h" #include "services/media_session/public/mojom/media_controller.mojom-forward.h" +#include "services/metrics/public/cpp/ukm_source_id.h" namespace content { class WebContents; @@ -63,7 +64,9 @@ void HideNotification(const std::string& id) override; void RemoveItem(const std::string& id) override; scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override; - void LogMediaSessionActionButtonPressed(const std::string& id) override; + void LogMediaSessionActionButtonPressed( + const std::string& id, + media_session::mojom::MediaSessionAction action) override; // MediaNotificationContainerObserver implementation. void OnContainerExpanded(bool expanded) override {} @@ -270,6 +273,10 @@ base::ObserverList<MediaNotificationServiceObserver> observers_; + // Tracks the number of times we have recorded an action for a specific + // source. We use this to cap the number of UKM recordings per site. + std::map<ukm::SourceId, int> actions_recorded_to_ukm_; + base::WeakPtrFactory<MediaNotificationService> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index b193efe6..698151c8 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -30,7 +30,6 @@ #include "chrome/browser/browsing_data/browsing_data_database_helper.h" #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/content_settings/local_shared_objects_container.h" #include "chrome/browser/history/history_service_factory.h" @@ -48,6 +47,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "chrome/grit/theme_resources.h" +#include "components/browsing_data/content/local_storage_helper.h" #include "components/content_settings/core/browser/content_settings_registry.h" #include "components/content_settings/core/browser/content_settings_utils.h" #include "components/content_settings/core/browser/host_content_settings_map.h"
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc index bc10974..e2bc74f 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.cc +++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -56,8 +56,8 @@ #include "chrome/grit/theme_resources.h" #include "components/bookmarks/common/bookmark_pref_names.h" #include "components/dom_distiller/content/browser/distillable_page_utils.h" +#include "components/dom_distiller/content/browser/uma_helper.h" #include "components/dom_distiller/core/dom_distiller_features.h" -#include "components/dom_distiller/core/uma_helper.h" #include "components/dom_distiller/core/url_utils.h" #include "components/prefs/pref_service.h" #include "components/signin/public/base/signin_metrics.h"
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc index 87d6a35..adfbdf3 100644 --- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -1163,7 +1163,9 @@ case autofill::PopupItemId::POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO: case autofill::PopupItemId::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY: case autofill::PopupItemId::POPUP_ITEM_ID_HIDE_AUTOFILL_SUGGESTIONS: - case autofill::PopupItemId::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN: + case autofill::PopupItemId::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN: + case autofill::PopupItemId:: + POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE: case autofill::PopupItemId::POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS: case autofill::PopupItemId::POPUP_ITEM_ID_USE_VIRTUAL_CARD: // This is a footer, so this suggestion will be processed later. Don't
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc index 6abfaca..eb923bf 100644 --- a/chrome/browser/ui/views/collected_cookies_views.cc +++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -13,7 +13,6 @@ #include "chrome/browser/browsing_data/browsing_data_database_helper.h" #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/browsing_data/cookies_tree_model.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/content_settings/local_shared_objects_container.h" @@ -26,6 +25,7 @@ #include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/cookie_info_view.h" #include "chrome/grit/generated_resources.h" +#include "components/browsing_data/content/local_storage_helper.h" #include "components/constrained_window/constrained_window_views.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc index 00a8452..35a95ca 100644 --- a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc +++ b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.cc
@@ -7,19 +7,39 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/grit/generated_resources.h" +#include "components/dom_distiller/content/browser/uma_helper.h" #include "components/dom_distiller/core/dom_distiller_features.h" -#include "components/dom_distiller/core/uma_helper.h" #include "components/dom_distiller/core/url_utils.h" #include "components/prefs/pref_service.h" #include "components/ukm/content/source_url_recorder.h" +#include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "ui/base/l10n/l10n_util.h" +using dom_distiller::UMAHelper; using dom_distiller::url_utils::IsDistilledPage; +namespace { +UMAHelper::ReaderModePageType GetPageType(content::WebContents* contents) { + // Determine if the current web contents is a distilled page. + UMAHelper::ReaderModePageType page_type = + UMAHelper::ReaderModePageType::kNone; + if (IsDistilledPage(contents->GetLastCommittedURL())) { + page_type = UMAHelper::ReaderModePageType::kDistilled; + } else { + base::Optional<dom_distiller::DistillabilityResult> distillability = + dom_distiller::GetLatestResult(contents); + if (distillability && distillability.value().is_distillable) + page_type = UMAHelper::ReaderModePageType::kDistillable; + } + return page_type; +} + +} // namespace + ReaderModeIconView::ReaderModeIconView( CommandUpdater* command_updater, IconLabelBubbleView::Delegate* icon_label_bubble_delegate, @@ -44,14 +64,37 @@ AnimateInkDrop(views::InkDropState::HIDDEN, nullptr); } +void ReaderModeIconView::ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame()) + return; + // When navigation is about to happen, ensure timers are appropriately stopped + // and reset. + UMAHelper::UpdateTimersOnNavigation(GetWebContents(), + GetPageType(GetWebContents())); +} + +void ReaderModeIconView::DocumentAvailableInMainFrame() { + UMAHelper::StartTimerIfNeeded(GetWebContents(), + GetPageType(GetWebContents())); +} + void ReaderModeIconView::UpdateImpl() { content::WebContents* contents = GetWebContents(); if (!contents) { SetVisible(false); return; } + UMAHelper::ReaderModePageType page_type = GetPageType(contents); - if (IsDistilledPage(contents->GetLastCommittedURL())) { + // WebContentsObserver::web_contents() is not updated until the call to + // Observe() below, so it should still contain the old contents. This will + // be used to ensure the timers for UMA are updated for the old web contents. + content::WebContents* old_contents = web_contents(); + if (contents != old_contents) + UMAHelper::UpdateTimersOnContentsChange(contents, old_contents); + + if (page_type == UMAHelper::ReaderModePageType::kDistilled) { SetVisible(true); SetActive(true); } else { @@ -65,17 +108,12 @@ } // If the currently active web contents has changed since last time, stop // observing the old web contents and start observing the new one. - // (WebContentsObserver::web_contents() is not updated until the call to - // Observe() below, so it should still contain the old contents.) - content::WebContents* old_contents = web_contents(); if (old_contents != contents) { if (old_contents) dom_distiller::RemoveObserver(old_contents, this); dom_distiller::AddObserver(contents, this); } - base::Optional<dom_distiller::DistillabilityResult> distillability = - dom_distiller::GetLatestResult(contents); - SetVisible(distillability && distillability.value().is_distillable); + SetVisible(page_type == UMAHelper::ReaderModePageType::kDistillable); SetActive(false); } @@ -131,4 +169,8 @@ .Record(ukm::UkmRecorder::Get()); } Update(); + // Once we know the type of page we are on (distillable or not), we can + // update the timers. + UMAHelper::ReaderModePageType page_type = GetPageType(contents); + UMAHelper::StartTimerIfNeeded(contents, page_type); }
diff --git a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.h b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.h index 8e69531c..fe21e93 100644 --- a/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.h +++ b/chrome/browser/ui/views/reader_mode/reader_mode_icon_view.h
@@ -33,11 +33,16 @@ ~ReaderModeIconView() override; protected: + // content:WebContentsObserver overrides: // Detect when navigation to the distilled page completes. This is required to // correctly update the icon's inkdrop. void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; + void ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) override; + void DocumentAvailableInMainFrame() override; + // PageActionIconView overrides: void UpdateImpl() override; const gfx::VectorIcon& GetVectorIcon() const override; base::string16 GetTextForTooltipAndAccessibleName() const override; @@ -48,6 +53,7 @@ // intentionally does not display a bubble when activated. views::BubbleDialogDelegateView* GetBubble() const override; + // dom_distiller::DistillabilityObserver overrides: void OnResult(const dom_distiller::DistillabilityResult& result) override; private:
diff --git a/chrome/browser/ui/views/sharing/remote_copy_browsertest.cc b/chrome/browser/ui/views/sharing/remote_copy_browsertest.cc index f05a199..d8291d2 100644 --- a/chrome/browser/ui/views/sharing/remote_copy_browsertest.cc +++ b/chrome/browser/ui/views/sharing/remote_copy_browsertest.cc
@@ -184,9 +184,11 @@ EXPECT_TRUE(server_->Start()); url::Origin allowlist_origin = url::Origin::Create(server_->base_url()); - feature_list_.InitAndEnableFeatureWithParameters( - kRemoteCopyReceiver, - {{kRemoteCopyAllowedOrigins.name, allowlist_origin.Serialize()}}); + feature_list_.InitWithFeaturesAndParameters( + {{kRemoteCopyReceiver, + {{kRemoteCopyAllowedOrigins.name, allowlist_origin.Serialize()}}}, + {kRemoteCopyImageNotification, {}}}, + {}); } };
diff --git a/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc b/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc index 70c961a..c9cfb83 100644 --- a/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc +++ b/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc
@@ -17,7 +17,6 @@ #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h" #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h" #include "chrome/browser/chromeos/crostini/crostini_features.h" #include "chrome/browser/chromeos/file_manager/path_util.h" @@ -28,6 +27,7 @@ #include "components/arc/session/arc_bridge_service.h" #include "components/arc/storage_manager/arc_storage_manager.h" #include "components/browsing_data/content/conditional_cache_counting_helper.h" +#include "components/browsing_data/content/local_storage_helper.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/storage_partition.h" @@ -172,7 +172,7 @@ storage_partition->GetPath(), new BrowsingDataCookieHelper(storage_partition), new BrowsingDataDatabaseHelper(profile_), - new BrowsingDataLocalStorageHelper(profile_), + new browsing_data::LocalStorageHelper(profile_), new BrowsingDataAppCacheHelper(storage_partition->GetAppCacheService()), new BrowsingDataIndexedDBHelper(storage_partition), BrowsingDataFileSystemHelper::Create(
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index aaed3dc..57cd1e34 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -16,7 +16,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "build/build_config.h" -#include "chrome/browser/history/web_history_service_factory.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_avatar_icon_util.h" @@ -32,14 +31,12 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/singleton_tabs.h" -#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/common/url_constants.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h" #include "components/autofill/core/common/autofill_prefs.h" -#include "components/browsing_data/core/history_notice_utils.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/signin_error_controller.h" #include "components/signin/public/base/signin_metrics.h" @@ -54,9 +51,7 @@ #include "components/sync/driver/sync_service_utils.h" #include "components/sync/driver/sync_user_settings.h" #include "components/unified_consent/unified_consent_metrics.h" -#include "content/public/browser/browser_context.h" #include "content/public/browser/render_view_host.h" -#include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "google_apis/gaia/gaia_auth_util.h" @@ -300,11 +295,6 @@ "SyncPrefsDispatch", base::BindRepeating(&PeopleHandler::HandleSyncPrefsDispatch, base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "GetIsHistoryRecordingEnabledAndCanBeUsed", - base::BindRepeating( - &PeopleHandler::HandleGetIsHistoryRecordingEnabledAndCanBeUsed, - base::Unretained(this))); #if defined(OS_CHROMEOS) web_ui()->RegisterMessageCallback( "AttemptUserExit", @@ -470,61 +460,6 @@ ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CHOOSE); } -void PeopleHandler::HandleGetIsHistoryRecordingEnabledAndCanBeUsed( - const base::ListValue* args) { - AllowJavascript(); - std::string webui_callback_id; - CHECK(args->GetString(0, &webui_callback_id)); - - DCHECK(base::FeatureList::IsEnabled(features::kSyncSetupFriendlySettings)); - syncer::SyncService* sync_service = GetSyncService(); - if (!sync_service) { - OnQueryHistoryRecordingCompletion(webui_callback_id, nullptr, - base::nullopt); - return; - } - - if (sync_service->GetUserSettings()->IsUsingSecondaryPassphrase()) { - OnQueryHistoryRecordingCompletion(webui_callback_id, nullptr, false); - return; - } - - std::unique_ptr<history::WebHistoryService::Request> request = - browsing_data::CreateQueryWebAndAppActivityRequest( - IdentityManagerFactory::GetForProfile(profile_), - content::BrowserContext::GetDefaultStoragePartition(profile_) - ->GetURLLoaderFactoryForBrowserProcess(), - base::BindOnce(&PeopleHandler::OnQueryHistoryRecordingCompletion, - weak_factory_.GetWeakPtr(), webui_callback_id)); - DCHECK(request); - auto* request_ptr = request.get(); - web_and_app_activity_requests_.insert(std::move(request)); - request_ptr->Start(); -} - -void PeopleHandler::OnQueryHistoryRecordingCompletion( - const std::string& webui_callback_id, - history::WebHistoryService::Request* request, - const base::Optional<bool>& history_recording_enabled) { - if (request) { - auto it = - std::find_if(web_and_app_activity_requests_.begin(), - web_and_app_activity_requests_.end(), - [request](const auto& r) { return r.get() == request; }); - DCHECK(web_and_app_activity_requests_.end() != it); - web_and_app_activity_requests_.erase(it); - } - - if (!IsJavascriptAllowed()) - return; - - std::unique_ptr<base::DictionaryValue> status(new base::DictionaryValue); - status->SetBoolean("requestSucceeded", history_recording_enabled.has_value()); - status->SetBoolean("historyRecordingEnabled", - history_recording_enabled.value_or(false)); - ResolveJavascriptCallback(base::Value(webui_callback_id), *status); -} - void PeopleHandler::HandleGetStoredAccounts(const base::ListValue* args) { AllowJavascript(); CHECK_EQ(1U, args->GetSize());
diff --git a/chrome/browser/ui/webui/settings/people_handler.h b/chrome/browser/ui/webui/settings/people_handler.h index 84ec3ce..50093e1 100644 --- a/chrome/browser/ui/webui/settings/people_handler.h +++ b/chrome/browser/ui/webui/settings/people_handler.h
@@ -16,7 +16,6 @@ #include "build/buildflag.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" -#include "components/history/core/browser/web_history_service.h" #include "components/prefs/pref_change_registrar.h" #include "components/signin/public/base/signin_buildflags.h" #include "components/signin/public/identity_manager/identity_manager.h" @@ -155,8 +154,6 @@ void HandleSetEncryption(const base::ListValue* args); void HandleShowSetupUI(const base::ListValue* args); void HandleSyncPrefsDispatch(const base::ListValue* args); - void HandleGetIsHistoryRecordingEnabledAndCanBeUsed( - const base::ListValue* args); #if defined(OS_CHROMEOS) void HandleAttemptUserExit(const base::ListValue* args); void HandleTurnOnSync(const base::ListValue* args); @@ -180,11 +177,6 @@ signin_metrics::AccessPoint access_point); #endif - void OnQueryHistoryRecordingCompletion( - const std::string& webui_callback_id, - history::WebHistoryService::Request* request, - const base::Optional<bool>& history_recording_enabled); - void HandleGetStoredAccounts(const base::ListValue* args); void HandleStartSyncingWithEmail(const base::ListValue* args); base::Value GetStoredAccountsList(); @@ -228,11 +220,6 @@ // Used to listen for pref changes to allow or disallow signin. PrefChangeRegistrar profile_pref_registrar_; - // Pending web and app activity requests to query whether history recording - // is enabled or not. - std::set<std::unique_ptr<history::WebHistoryService::Request>> - web_and_app_activity_requests_; - // Manages observer lifetimes. ScopedObserver<signin::IdentityManager, signin::IdentityManager::Observer> identity_manager_observer_{this};
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 50546fbd..b808956 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -25,7 +25,6 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h" -#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/webui/management_ui.h" #include "chrome/browser/ui/webui/policy_indicator_localized_strings_provider.h" #include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
diff --git a/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc index 9cf16c5d6..9a461686 100644 --- a/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc
@@ -194,6 +194,8 @@ {"syncSetupCancelDialogTitle", IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_TITLE}, {"syncSetupCancelDialogBody", IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_BODY}, + {"personalizeGoogleServicesTitle", + IDS_SETTINGS_PERSONALIZE_GOOGLE_SERVICES_TITLE}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); @@ -228,23 +230,10 @@ base::ASCIIToUTF16(chrome::kSyncEncryptionHelpURL))); #endif if (base::FeatureList::IsEnabled(features::kSyncSetupFriendlySettings)) { - static constexpr webui::LocalizedString - kSyncSetupFriendlySettingsStrings[] = { - {"personalizeGoogleServicesTitle", - IDS_SETTINGS_USE_HISTORY_TO_PERSONALIZE_GOOGLE_SERVICES_TITLE}, - {"SwaaOn", IDS_SETTINGS_SWAA_ON}, - {"SwaaOff", IDS_SETTINGS_SWAA_OFF}, - {"dataEncryptedHint", IDS_SETTINGS_DATA_ENCRYPTED_HINT}, - {"historySyncOffHint", IDS_SETTINGS_HISTORY_SYNC_OFF_HINT}, - {"SwaaOffHint", IDS_SETTINGS_SWAA_OFF_HINT}, - {"manageSyncedDataTitle", - IDS_SETTINGS_NEW_MANAGE_SYNCED_DATA_TITLE_UNIFIED_CONSENT}, - }; - AddLocalizedStringsBulk(html_source, kSyncSetupFriendlySettingsStrings); - } else { html_source->AddLocalizedString( - "personalizeGoogleServicesTitle", - IDS_SETTINGS_PERSONALIZE_GOOGLE_SERVICES_TITLE); + "manageSyncedDataTitle", + IDS_SETTINGS_NEW_MANAGE_SYNCED_DATA_TITLE_UNIFIED_CONSENT); + } else { html_source->AddLocalizedString( "manageSyncedDataTitle", IDS_SETTINGS_MANAGE_SYNCED_DATA_TITLE_UNIFIED_CONSENT);
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc index 5b77ab9..1827416b 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -735,8 +735,8 @@ } // Each call to HandleGetAllSites() above added a callback to the profile's - // BrowsingDataLocalStorageHelper, so make sure these aren't stuck waiting to - // run at the end of the test. + // browsing_data::LocalStorageHelper, so make sure these aren't stuck waiting + // to run at the end of the test. base::RunLoop run_loop; run_loop.RunUntilIdle(); }
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui.cc b/chrome/browser/ui/webui/signin/inline_login_ui.cc index 2cd45a5..69f57dde 100644 --- a/chrome/browser/ui/webui/signin/inline_login_ui.cc +++ b/chrome/browser/ui/webui/signin/inline_login_ui.cc
@@ -49,6 +49,10 @@ IDS_EDU_LOGIN_WELCOME_REAUTH_TITLE); source->AddLocalizedString("welcomeReauthBody", IDS_EDU_LOGIN_WELCOME_REAUTH_BODY); + source->AddLocalizedString("parentsListTitle", + IDS_EDU_LOGIN_PARENTS_LIST_TITLE); + source->AddLocalizedString("parentsListBody", + IDS_EDU_LOGIN_PARENTS_LIST_BODY); } #endif // defined(OS_CHROMEOS) @@ -88,6 +92,8 @@ source->AddResourcePath("edu_login_util.js", IDR_EDU_LOGIN_EDU_LOGIN_UTIL_JS); source->AddResourcePath("edu_login_welcome.js", IDR_EDU_LOGIN_EDU_LOGIN_WELCOME_JS); + source->AddResourcePath("edu_login_parents.js", + IDR_EDU_LOGIN_EDU_LOGIN_PARENTS_JS); source->AddResourcePath("test_loader.js", IDR_WEBUI_JS_TEST_LOADER); source->AddResourcePath("test_loader.html", IDR_WEBUI_HTML_TEST_LOADER);
diff --git a/chrome/browser/upboarding/query_tiles/internal/BUILD.gn b/chrome/browser/upboarding/query_tiles/internal/BUILD.gn index 716370d..6ad84b2 100644 --- a/chrome/browser/upboarding/query_tiles/internal/BUILD.gn +++ b/chrome/browser/upboarding/query_tiles/internal/BUILD.gn
@@ -9,8 +9,12 @@ source_set("internal") { sources = [ + "image_data_store.cc", + "image_data_store.h", "image_decoder.cc", "image_decoder.h", + "image_info_store.cc", + "image_info_store.h", "image_loader.cc", "image_loader.h", "proto_conversion.cc",
diff --git a/chrome/browser/upboarding/query_tiles/internal/image_data_store.cc b/chrome/browser/upboarding/query_tiles/internal/image_data_store.cc new file mode 100644 index 0000000..579bd37 --- /dev/null +++ b/chrome/browser/upboarding/query_tiles/internal/image_data_store.cc
@@ -0,0 +1,58 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/upboarding/query_tiles/internal/image_data_store.h" + +#include <utility> + +#include "base/logging.h" + +namespace upboarding { + +namespace { + +// An image data storage based on leveldb. +class ImageDataStoreImpl : public ImageDataStore { + public: + ImageDataStoreImpl() = default; + ~ImageDataStoreImpl() override = default; + + private: + // ImageDataStore implementation. + void Init(SuccessCallback callback) override { NOTIMPLEMENTED(); } + + void Update(std::unique_ptr<ImageData> data, + SuccessCallback callback) override { + NOTIMPLEMENTED(); + } + + void GetImageData(const std::string& image_id, + ImageDataCallback callback) override { + NOTIMPLEMENTED(); + } + + void Delete(std::vector<std::string> image_ids, + SuccessCallback callback) override { + NOTIMPLEMENTED(); + } +}; + +} // namespace + +ImageData::ImageData(const std::string& id, std::string data) + : id_(id), data_(std::move(data)) {} + +ImageData::~ImageData() = default; + +void ImageData::TakeData(std::string* output) { + DCHECK(output); + output->swap(data_); +} + +// static +std::unique_ptr<ImageDataStore> ImageDataStore::Create() { + return std::make_unique<ImageDataStoreImpl>(); +} + +} // namespace upboarding
diff --git a/chrome/browser/upboarding/query_tiles/internal/image_data_store.h b/chrome/browser/upboarding/query_tiles/internal/image_data_store.h new file mode 100644 index 0000000..5f6801a --- /dev/null +++ b/chrome/browser/upboarding/query_tiles/internal/image_data_store.h
@@ -0,0 +1,71 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UPBOARDING_QUERY_TILES_INTERNAL_IMAGE_DATA_STORE_H_ +#define CHROME_BROWSER_UPBOARDING_QUERY_TILES_INTERNAL_IMAGE_DATA_STORE_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/callback.h" + +namespace upboarding { + +// Contains decoded image data. +// Serialized to ImageData protobuf in image.proto. +class ImageData { + public: + ImageData(const std::string& id, std::string data); + ImageData(const ImageData&) = delete; + ImageData& operator=(const ImageData&) = delete; + ~ImageData(); + + const std::string& id() const { return id_; } + + // Transfers the ownership of |data_|. + void TakeData(std::string* output); + + private: + // Unique id of the image. + std::string id_; + + // Raw bytes of the image. + std::string data_; +}; + +// Storage to save deoded query tile images' raw data. +// Only supports loads one image at a time. +class ImageDataStore { + public: + using SuccessCallback = base::OnceCallback<void(bool /*success*/)>; + using ImageDataCallback = + base::OnceCallback<void(std::unique_ptr<ImageData>)>; + + static std::unique_ptr<ImageDataStore> Create(); + + ImageDataStore() = default; + ImageDataStore(const ImageDataStore&) = delete; + ImageDataStore& operator=(const ImageDataStore&) = delete; + virtual ~ImageDataStore() = default; + + // Initializes the store. + virtual void Init(SuccessCallback callback) = 0; + + // Updates one image. + virtual void Update(std::unique_ptr<ImageData> data, + SuccessCallback callback) = 0; + + // Loads one image data into memory. + virtual void GetImageData(const std::string& image_id, + ImageDataCallback callback) = 0; + + // Deletes images from the store. + virtual void Delete(std::vector<std::string> image_ids, + SuccessCallback callback) = 0; +}; + +} // namespace upboarding + +#endif // CHROME_BROWSER_UPBOARDING_QUERY_TILES_INTERNAL_IMAGE_DATA_STORE_H_
diff --git a/chrome/browser/upboarding/query_tiles/internal/image_info_store.cc b/chrome/browser/upboarding/query_tiles/internal/image_info_store.cc new file mode 100644 index 0000000..07226356 --- /dev/null +++ b/chrome/browser/upboarding/query_tiles/internal/image_info_store.cc
@@ -0,0 +1,40 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/upboarding/query_tiles/internal/image_info_store.h" + +#include <utility> + +#include "base/logging.h" + +namespace upboarding { +namespace { + +class ImageInfoStoreImpl : public ImageInfoStore { + public: + ImageInfoStoreImpl() = default; + ~ImageInfoStoreImpl() override = default; + + private: + void InitAndLoad(Store::LoadCallback callback) override { NOTIMPLEMENTED(); } + + void Update(const std::string& key, + const ImageInfo& entry, + Store::UpdateCallback callback) override { + NOTIMPLEMENTED(); + } + + void Delete(const std::string& key, Store::DeleteCallback callback) override { + NOTIMPLEMENTED(); + } +}; + +} // namespace + +// static +std::unique_ptr<ImageInfoStore> ImageInfoStore::Create() { + return std::make_unique<ImageInfoStoreImpl>(); +} + +} // namespace upboarding
diff --git a/chrome/browser/upboarding/query_tiles/internal/image_info_store.h b/chrome/browser/upboarding/query_tiles/internal/image_info_store.h new file mode 100644 index 0000000..75b3e9d --- /dev/null +++ b/chrome/browser/upboarding/query_tiles/internal/image_info_store.h
@@ -0,0 +1,45 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UPBOARDING_QUERY_TILES_INTERNAL_IMAGE_INFO_STORE_H_ +#define CHROME_BROWSER_UPBOARDING_QUERY_TILES_INTERNAL_IMAGE_INFO_STORE_H_ + +#include <map> +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/time/time.h" +#include "chrome/browser/upboarding/query_tiles/internal/store.h" +#include "url/gurl.h" + +namespace upboarding { + +// Contains information for a query tile image. This doesn't include the raw +// bytes of the image. +// Serialized to ImageInfo protobuf in image.proto. +struct ImageInfo { + // Unique image id. + std::string id; + + // URL of the image. + GURL url; + + // The most recent update time, image will be expired after a certain period + // of time, + base::Time last_update; +}; + +// Store to save query tiles image info. +class ImageInfoStore : public Store<ImageInfo> { + public: + ImageInfoStore() = default; + ~ImageInfoStore() override = default; + + static std::unique_ptr<ImageInfoStore> Create(); +}; + +} // namespace upboarding + +#endif // CHROME_BROWSER_UPBOARDING_QUERY_TILES_INTERNAL_IMAGE_INFO_STORE_H_
diff --git a/chrome/browser/upboarding/query_tiles/internal/image_loader.h b/chrome/browser/upboarding/query_tiles/internal/image_loader.h index d9b6968..de141fc 100644 --- a/chrome/browser/upboarding/query_tiles/internal/image_loader.h +++ b/chrome/browser/upboarding/query_tiles/internal/image_loader.h
@@ -20,8 +20,7 @@ // on disk. class ImageLoader { public: - using UpdateCallback = base::OnceCallback<bool>; - using DeleteCallback = base::OnceCallback<bool>; + using SuccessCallback = base::OnceCallback<bool>; using BitmapCallback = base::OnceCallback<std::unique_ptr<SkBitmap>>; using Id = std::string; @@ -32,9 +31,9 @@ // immediately fetch the image, then invoke the callback. virtual void Update(const Id& id, const GURL& url, - UpdateCallback callback) = 0; + SuccessCallback callback) = 0; // Deletes an image cache for a specific tile. - virtual void Delete(const Id& id, DeleteCallback callback) = 0; + virtual void Delete(const Id& id, SuccessCallback callback) = 0; // Gets the bitmap for a specific tile. Callback will be invoked after // reading the data from disk or the fetch is done.
diff --git a/chrome/browser/upboarding/query_tiles/internal/store.h b/chrome/browser/upboarding/query_tiles/internal/store.h index 5eb44b8..d5c40ba 100644 --- a/chrome/browser/upboarding/query_tiles/internal/store.h +++ b/chrome/browser/upboarding/query_tiles/internal/store.h
@@ -5,10 +5,12 @@ #ifndef CHROME_BROWSER_UPBOARDING_QUERY_TILES_INTERNAL_STORE_H_ #define CHROME_BROWSER_UPBOARDING_QUERY_TILES_INTERNAL_STORE_H_ +#include <map> #include <memory> #include <string> #include <vector> +#include "base/callback.h" #include "base/macros.h" namespace upboarding {
diff --git a/chrome/browser/upboarding/query_tiles/proto/BUILD.gn b/chrome/browser/upboarding/query_tiles/proto/BUILD.gn index fa5632a..822c8fb8 100644 --- a/chrome/browser/upboarding/query_tiles/proto/BUILD.gn +++ b/chrome/browser/upboarding/query_tiles/proto/BUILD.gn
@@ -5,5 +5,8 @@ import("//third_party/protobuf/proto_library.gni") proto_library("proto") { - sources = [ "query_tile_entry.proto" ] + sources = [ + "image.proto", + "query_tile_entry.proto", + ] }
diff --git a/chrome/browser/upboarding/query_tiles/proto/image.proto b/chrome/browser/upboarding/query_tiles/proto/image.proto new file mode 100644 index 0000000..516c79c --- /dev/null +++ b/chrome/browser/upboarding/query_tiles/proto/image.proto
@@ -0,0 +1,33 @@ +// Copyright 2020 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. + +syntax = "proto3"; + +option optimize_for = LITE_RUNTIME; + +package upboarding.query_tiles.proto; + +// Information of a query tile image, doesn't contain image raw bytes. +// Next tag: 4 +message ImageInfo { + // Unique id of the image. + string id = 1; + + // URL of the image. + string url = 2; + + // The last update time in milliseconds since epoch, image will be expired + // after a certain amount of time. + int64 last_update_time_ms = 3; +} + +// Contains the decoded image bytes. +// Next tag: 3 +message ImageData { + // Unique id of the image. + string id = 1; + + // Decoded image data. + bytes data = 2; +} \ No newline at end of file
diff --git a/chrome/browser/upboarding/query_tiles/proto/query_tile_entry.proto b/chrome/browser/upboarding/query_tiles/proto/query_tile_entry.proto index 4a2bed33..b9b5865 100644 --- a/chrome/browser/upboarding/query_tiles/proto/query_tile_entry.proto +++ b/chrome/browser/upboarding/query_tiles/proto/query_tile_entry.proto
@@ -9,15 +9,15 @@ package upboarding.query_tiles.proto; // The QuertTileEntry is the schema to represent data in query tile entry. -// Next tag:7 +// Next tag: 7 message QueryTileEntry { // Metadata about the image. - // Next tag:3 + // Next tag: 3 message ImageMetadata { // Unique id of the query tile image. string id = 1; - // Origin URL of the image. + // URL of the image. string url = 2; }
diff --git a/chrome/common/extensions/api/passwords_private.idl b/chrome/common/extensions/api/passwords_private.idl index fa922fd..e0def107 100644 --- a/chrome/common/extensions/api/passwords_private.idl +++ b/chrome/common/extensions/api/passwords_private.idl
@@ -257,6 +257,9 @@ // Requests the account-storage opt-in state of the current user. static void isOptedInForAccountStorage(OptInCallback callback); + // Triggers the opt-in or opt-out flow for the account storage. + static void optInForAccountStorage(boolean optIn); + // Requests the latest compromised credentials. static void getCompromisedCredentials( CompromisedCredentialsCallback callback);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index f4a9a3e6..3a01e00 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3077,7 +3077,6 @@ "../browser/browsing_data/browsing_data_file_system_helper_unittest.cc", "../browser/browsing_data/browsing_data_helper_unittest.cc", "../browser/browsing_data/browsing_data_indexed_db_helper_unittest.cc", - "../browser/browsing_data/browsing_data_local_storage_helper_unittest.cc", "../browser/browsing_data/browsing_data_media_license_helper_unittest.cc", "../browser/browsing_data/browsing_data_quota_helper_unittest.cc", "../browser/browsing_data/browsing_data_service_worker_helper_unittest.cc",
diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc index bfedb561..f359888 100644 --- a/chrome/test/base/chrome_test_launcher.cc +++ b/chrome/test/base/chrome_test_launcher.cc
@@ -21,6 +21,7 @@ #include "base/strings/string_util.h" #include "base/test/test_file_util.h" #include "base/test/test_switches.h" +#include "base/time/time.h" #include "chrome/app/chrome_main_delegate.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" @@ -135,7 +136,7 @@ #if !defined(OS_ANDROID) content::ContentMainDelegate* ChromeTestLauncherDelegate::CreateContentMainDelegate() { - return new ChromeMainDelegate(); + return new ChromeMainDelegate(base::TimeTicks::Now()); } #endif
diff --git a/chrome/test/data/android/render_tests/TabSelectionEditorTest.list_view.Nexus_5X-23.png.sha1 b/chrome/test/data/android/render_tests/TabSelectionEditorTest.list_view.Nexus_5X-23.png.sha1 deleted file mode 100644 index 3a2dedc..0000000 --- a/chrome/test/data/android/render_tests/TabSelectionEditorTest.list_view.Nexus_5X-23.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -3ca70f365224a2acf417e16eb8f70957c82a0dc1 \ No newline at end of file
diff --git a/chrome/test/data/android/render_tests/TabSelectionEditorTest.list_view_one_selected_tab.Nexus_5X-23.png.sha1 b/chrome/test/data/android/render_tests/TabSelectionEditorTest.list_view_one_selected_tab.Nexus_5X-23.png.sha1 deleted file mode 100644 index c3e55b8..0000000 --- a/chrome/test/data/android/render_tests/TabSelectionEditorTest.list_view_one_selected_tab.Nexus_5X-23.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -828512f08172f235986d1a27f671c70528d51907 \ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/passwords_private/test.js b/chrome/test/data/extensions/api_test/passwords_private/test.js index 2e49a266..ceaf22f 100644 --- a/chrome/test/data/extensions/api_test/passwords_private/test.js +++ b/chrome/test/data/extensions/api_test/passwords_private/test.js
@@ -190,8 +190,8 @@ }, function isNotOptedInForAccountStorage() { - var callback = function(opted_in) { - chrome.test.assertEq(opted_in, false); + var callback = function(optedIn) { + chrome.test.assertEq(optedIn, false); // Ensure that the callback is invoked. chrome.test.succeed(); }; @@ -200,8 +200,8 @@ }, function isOptedInForAccountStorage() { - var callback = function(opted_in) { - chrome.test.assertEq(opted_in, true); + var callback = function(optedIn) { + chrome.test.assertEq(optedIn, true); // Ensure that the callback is invoked. chrome.test.succeed(); }; @@ -209,6 +209,22 @@ chrome.passwordsPrivate.isOptedInForAccountStorage(callback); }, + function optInForAccountStorage() { + chrome.passwordsPrivate.optInForAccountStorage(true); + chrome.passwordsPrivate.isOptedInForAccountStorage(function(optedIn) { + chrome.test.assertEq(optedIn, true); + chrome.test.succeed(); + }); + }, + + function optOutForAccountStorage() { + chrome.passwordsPrivate.optInForAccountStorage(false); + chrome.passwordsPrivate.isOptedInForAccountStorage(function(optedIn) { + chrome.test.assertEq(optedIn, false); + chrome.test.succeed(); + }); + }, + function getCompromisedCredentials() { chrome.passwordsPrivate.getCompromisedCredentials( compromisedCredentials => {
diff --git a/chrome/test/data/webui/chromeos/edu_login/edu_login_browsertest.js b/chrome/test/data/webui/chromeos/edu_login/edu_login_browsertest.js index 75ba0150..f31a071e 100644 --- a/chrome/test/data/webui/chromeos/edu_login/edu_login_browsertest.js +++ b/chrome/test/data/webui/chromeos/edu_login/edu_login_browsertest.js
@@ -66,3 +66,32 @@ TEST_F('EduLoginButtonTest', 'BackButtonRtlIcon', function() { this.runMochaTest(edu_login_button_tests.TestNames.BackButtonRtlIcon); }); + +// eslint-disable-next-line no-var +var EduLoginParentsTest = class extends EduLoginTest { + /** @override */ + get browsePreload() { + return 'chrome://chrome-signin/test_loader.html?module=chromeos/edu_login/edu_login_parents_test.js'; + } + + /** @override */ + get suiteName() { + return edu_login_parents_tests.suiteName; + } +}; + +TEST_F('EduLoginParentsTest', 'Initialize', function() { + this.runMochaTest(edu_login_parents_tests.TestNames.Initialize); +}); + +TEST_F('EduLoginParentsTest', 'NextButton', function() { + this.runMochaTest(edu_login_parents_tests.TestNames.NextButton); +}); + +TEST_F('EduLoginParentsTest', 'GoNext', function() { + this.runMochaTest(edu_login_parents_tests.TestNames.GoNext); +}); + +TEST_F('EduLoginParentsTest', 'SelectedParent', function() { + this.runMochaTest(edu_login_parents_tests.TestNames.SelectedParent); +});
diff --git a/chrome/test/data/webui/chromeos/edu_login/edu_login_parents_test.js b/chrome/test/data/webui/chromeos/edu_login/edu_login_parents_test.js new file mode 100644 index 0000000..66faac77 --- /dev/null +++ b/chrome/test/data/webui/chromeos/edu_login/edu_login_parents_test.js
@@ -0,0 +1,138 @@ +// Copyright 2020 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 'chrome://chrome-signin/edu_login_parents.js'; + +import {EduAccountLoginBrowserProxyImpl} from 'chrome://chrome-signin/browser_proxy.js'; +import {ParentAccount} from 'chrome://chrome-signin/edu_login_util.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {TestBrowserProxy} from '../../test_browser_proxy.m.js'; + +window.edu_login_parents_tests = {}; +edu_login_parents_tests.suiteName = 'EduLoginParentsTest'; + +/** @enum {string} */ +edu_login_parents_tests.TestNames = { + Initialize: 'Expect getParents call on initialize', + NextButton: 'Next button is enabled only when parent is selected', + GoNext: 'go-next event should be fired when parent is selected', + SelectedParent: 'Selected parent', +}; + +/** + * @param {string} email + * @param {string} displayName + * @param {string} profileImage + * @param {string} obfuscatedGaiaId + * @return {ParentAccount} + */ +function getFakeParent(email, displayName, profileImage, obfuscatedGaiaId) { + return { + email: email, + displayName: displayName, + profileImage: profileImage, + obfuscatedGaiaId: obfuscatedGaiaId, + }; +} + +/** @return {Array<ParentAccount>} */ +function getFakeParentsList() { + return [ + getFakeParent('parent1@gmail.com', 'Parent 1', '', 'parent1gaia'), + getFakeParent('parent2@gmail.com', 'Parent 2', '', 'parent2gaia'), + ]; +} + +suite(edu_login_parents_tests.suiteName, function() { + let parentsComponent; + let testBrowserProxy; + + /** @implements {EduAccountLoginBrowserProxy} */ + class TestEduAccountLoginBrowserProxy extends TestBrowserProxy { + constructor() { + super(['getParents']); + } + + /** @override */ + getParents() { + this.methodCalled('getParents'); + return Promise.resolve(getFakeParentsList()); + } + } + + /** @return {NodeList} */ + function getAccountListItems() { + return parentsComponent.shadowRoot.querySelectorAll('.account-list-item'); + } + + setup(function() { + PolymerTest.clearBody(); + testBrowserProxy = new TestEduAccountLoginBrowserProxy(); + EduAccountLoginBrowserProxyImpl.instance_ = testBrowserProxy; + parentsComponent = document.createElement('edu-login-parents'); + document.body.appendChild(parentsComponent); + flush(); + }); + + test(assert(edu_login_parents_tests.TestNames.Initialize), function() { + assertEquals(1, testBrowserProxy.getCallCount('getParents')); + }); + + test(assert(edu_login_parents_tests.TestNames.NextButton), function() { + testBrowserProxy.whenCalled('getParents').then(function() { + flush(); + assertTrue( + parentsComponent.$$('edu-login-button[button-type="next"]').disabled); + // Select the first parent from the list. + getAccountListItems()[0].click(); + assertFalse( + parentsComponent.$$('edu-login-button[button-type="next"]').disabled); + }); + }); + + test(assert(edu_login_parents_tests.TestNames.GoNext), function() { + let goNextCalls = 0; + parentsComponent.addEventListener('go-next', function() { + goNextCalls++; + }); + testBrowserProxy.whenCalled('getParents').then(function() { + flush(); + assertEquals(0, goNextCalls); + const accountListItems = getAccountListItems(); + // Select the first parent from the list. + accountListItems[0].click(); + assertEquals(1, goNextCalls); + // If user goes back and selects the same item -'go-next' should be fired. + accountListItems[0].click(); + assertEquals(2, goNextCalls); + // If user goes back and selects another item - 'go-next' should be fired. + accountListItems[1].click(); + assertEquals(3, goNextCalls); + }); + }); + + test(assert(edu_login_parents_tests.TestNames.SelectedParent), function() { + testBrowserProxy.whenCalled('getParents').then(function() { + flush(); + assertDeepEquals(getFakeParentsList(), parentsComponent.parents_); + assertEquals(null, parentsComponent.selectedParent); + const accountListItems = getAccountListItems(); + accountListItems.forEach(element => { + // No option should be selected. + assertEquals('false', element.getAttribute('aria-selected')); + }); + // Select the first parent from the list. + accountListItems[0].click(); + assertDeepEquals( + getFakeParentsList()[0], parentsComponent.selectedParent); + accountListItems.forEach((element, index) => { + assertEquals( + index === 0 ? 'true' : 'false', + element.getAttribute('aria-selected')); + }); + }); + }); +});
diff --git a/chrome/test/data/webui/media/media_feeds_webui_browsertest.js b/chrome/test/data/webui/media/media_feeds_webui_browsertest.js index 78f841d..6927c3b 100644 --- a/chrome/test/data/webui/media/media_feeds_webui_browsertest.js +++ b/chrome/test/data/webui/media/media_feeds_webui_browsertest.js
@@ -35,7 +35,9 @@ let feedHeaders = Array.from(document.querySelector('#feed-table-header').children); - assertDeepEquals(['ID', 'Url'], feedHeaders.map(x => x.textContent.trim())); + assertDeepEquals( + ['ID', 'Url', 'Last Discovery Time'], + feedHeaders.map(x => x.textContent.trim())); }); mocha.run();
diff --git a/chrome/test/data/webui/settings/collapse_radio_button_tests.js b/chrome/test/data/webui/settings/collapse_radio_button_tests.js index e829e4a..8ffe9a2f 100644 --- a/chrome/test/data/webui/settings/collapse_radio_button_tests.js +++ b/chrome/test/data/webui/settings/collapse_radio_button_tests.js
@@ -57,4 +57,42 @@ Polymer.dom.flush(); assertFalse(collapse.opened); }); + + test('expansionHiddenWhenNoCollapseSet', function() { + assertTrue( + test_util.isChildVisible(collapseRadioButton, 'cr-expand-button')); + assertTrue(test_util.isChildVisible(collapseRadioButton, '.separator')); + + collapseRadioButton.noCollapse = true; + Polymer.dom.flush(); + assertFalse( + test_util.isChildVisible(collapseRadioButton, 'cr-expand-button')); + assertFalse(test_util.isChildVisible(collapseRadioButton, '.separator')); + }); + + test('openOnExpandHitWhenDisabled', function() { + collapseRadioButton.checked = false; + collapseRadioButton.disabled = true; + const collapse = collapseRadioButton.$$('iron-collapse'); + + Polymer.dom.flush(); + assertFalse(collapse.opened); + collapseRadioButton.$$('cr-expand-button').click(); + + Polymer.dom.flush(); + assertTrue(collapse.opened); + }); + + test('displayPolicyIndicator', function() { + assertFalse( + test_util.isChildVisible(collapseRadioButton, '#policyIndicator')); + assertEquals( + collapseRadioButton.policyIndicatorType, CrPolicyIndicatorType.NONE); + + collapseRadioButton.policyIndicatorType = + CrPolicyIndicatorType.DEVICE_POLICY; + Polymer.dom.flush(); + assertTrue( + test_util.isChildVisible(collapseRadioButton, '#policyIndicator')); + }); });
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index 71d3347..0976326e 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -2069,6 +2069,7 @@ browsePreload: 'chrome://settings/privacy_page/collapse_radio_button.html', extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ + '../test_util.js', 'collapse_radio_button_tests.js', ]), };
diff --git a/chrome/test/data/webui/settings/password_check_test.js b/chrome/test/data/webui/settings/password_check_test.js index 1bee10c..bb66b20f 100644 --- a/chrome/test/data/webui/settings/password_check_test.js +++ b/chrome/test/data/webui/settings/password_check_test.js
@@ -310,13 +310,33 @@ }); // Test verifies that if no compromised credentials found than list is not - // shown TODO(https://crbug.com/1047726): add additional checks after - // UI is implemented + // shown test('testNoCompromisedCredentials', function() { - const checkPasswordSection = createCheckPasswordSection(); - assertTrue(checkPasswordSection.$.passwordCheckBody.hidden); - assertFalse(checkPasswordSection.$.noCompromisedCredentials.hidden); - validateLeakedPasswordsList(checkPasswordSection, []); + const data = passwordManager.data; + data.checkStatus = autofill_test_util.makePasswordCheckStatus( + /*state=*/ PasswordCheckState.IDLE, + /*checked=*/ 4, + /*remaining=*/ 0, + /*lastCheck=*/ 'Just now'); + data.leakedCredentials = []; + + const section = createCheckPasswordSection(); + assertFalse(isElementVisible(section.$.noCompromisedCredentials)); + cr.webUIListenerCallback( + 'sync-prefs-changed', sync_test_util.getSyncAllPrefs()); + sync_test_util.simulateSyncStatus({signedIn: true}); + + // Initialize with dummy data breach detection settings + section.prefs = { + profile: {password_manager_leak_detection: {value: true}} + }; + + return passwordManager.whenCalled('getCompromisedCredentials') + .then(() => { + Polymer.dom.flush(); + assertFalse(isElementVisible(section.$.passwordCheckBody)); + assertTrue(isElementVisible(section.$.noCompromisedCredentials)); + }); }); // Test verifies that compromised credentials are displayed in a proper way @@ -392,8 +412,8 @@ passwordManager.data.checkStatus = autofill_test_util.makePasswordCheckStatus( /*state=*/ PasswordCheckState.RUNNING, - /*checked=*/ 1, - /*remaining=*/ 1); + /*checked=*/ 0, + /*remaining=*/ 2); const section = createCheckPasswordSection(); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { @@ -409,8 +429,8 @@ passwordManager.lastCallback.addPasswordCheckStatusListener( autofill_test_util.makePasswordCheckStatus( /*state=*/ PasswordCheckState.RUNNING, - /*checked=*/ 2, - /*remaining=*/ 0)); + /*checked=*/ 1, + /*remaining=*/ 1)); Polymer.dom.flush(); assertTrue(isElementVisible(section.$.title)); @@ -537,8 +557,8 @@ passwordManager.data.checkStatus = autofill_test_util.makePasswordCheckStatus( /*state=*/ PasswordCheckState.RUNNING, - /*checked=*/ 1, - /*remaining=*/ 3); + /*checked=*/ 0, + /*remaining=*/ 4); const section = createCheckPasswordSection(); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { @@ -551,13 +571,33 @@ }); }); + // Verifies that in case the backend could not obtain the number of checked + // and remaining credentials the UI does not surface 0s to the user. + test('runningProgressHandlesZeroCaseFromBackend', function() { + passwordManager.data.checkStatus = + autofill_test_util.makePasswordCheckStatus( + /*state=*/ PasswordCheckState.RUNNING, + /*checked=*/ 0, + /*remaining=*/ 0); + + const section = createCheckPasswordSection(); + return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { + Polymer.dom.flush(); + const title = section.$.title; + assertTrue(isElementVisible(title)); + expectEquals( + section.i18n('checkPasswordsProgress', 1, 1), title.innerText); + expectFalse(isElementVisible(section.$.subtitle)); + }); + }); + // While running, show progress and already found leak count. test('testShowProgressAndLeaksWhileRunning', function() { const data = passwordManager.data; data.checkStatus = autofill_test_util.makePasswordCheckStatus( /*state=*/ PasswordCheckState.RUNNING, - /*checked=*/ 2, - /*remaining=*/ 3); + /*checked=*/ 1, + /*remaining=*/ 4); data.leakedCredentials = [ autofill_test_util.makeCompromisedCredential( 'one.com', 'test4', 'LEAKED'),
diff --git a/chrome/test/data/webui/settings/passwords_section_test.js b/chrome/test/data/webui/settings/passwords_section_test.js index 6208974..fcbc520f 100644 --- a/chrome/test/data/webui/settings/passwords_section_test.js +++ b/chrome/test/data/webui/settings/passwords_section_test.js
@@ -812,31 +812,88 @@ assertFalse(passwordsSection.$.manageLink.hidden); }); - test('showPasswordCheckBannerWhenNotCheckedBefore', function() { - // Suppose no check done initially. - assertEquals( - passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, - undefined); - const passwordsSection = - elementFactory.createPasswordsSection(passwordManager, [], []); - return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { - Polymer.dom.flush(); - assertFalse( - passwordsSection.$$('#checkPasswordsBannerContainer').hidden); - assertFalse(passwordsSection.$$('#checkPasswordsButton').hidden); - assertTrue(passwordsSection.$$('#checkPasswordsLinkRow').hidden); - }); - }); + test( + 'showPasswordCheckBannerWhenNotCheckedBeforeAndSignedInAndHavePasswords', + function() { + // Suppose no check done initially, non-empty list of passwords, + // signed in. + assertEquals( + passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, + undefined); + const passwordList = [ + autofill_test_util.createPasswordEntry('site1.com', 'luigi', 1), + ]; + const passwordsSection = elementFactory.createPasswordsSection( + passwordManager, passwordList, []); + return passwordManager.whenCalled('getPasswordCheckStatus') + .then(() => { + Polymer.dom.flush(); + assertFalse( + passwordsSection.$$('#checkPasswordsBannerContainer') + .hidden); + assertFalse( + passwordsSection.$$('#checkPasswordsButton').hidden); + assertTrue( + passwordsSection.$$('#checkPasswordsLinkRow').hidden); + }); + }); + + test( + 'showPasswordCheckLinkButtonWithoutWarningWhenNotSignedIn', function() { + // Suppose no check done initially, non-empty list of passwords, + // signed out. + assertEquals( + passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, + undefined); + const passwordList = [ + autofill_test_util.createPasswordEntry('site1.com', 'luigi', 1), + ]; + const passwordsSection = elementFactory.createPasswordsSection( + passwordManager, passwordList, []); + sync_test_util.simulateSyncStatus({signedIn: false}); + return passwordManager.whenCalled('getPasswordCheckStatus') + .then(() => { + Polymer.dom.flush(); + assertTrue(passwordsSection.$$('#checkPasswordsBannerContainer') + .hidden); + assertTrue(passwordsSection.$$('#checkPasswordsButton').hidden); + assertFalse( + passwordsSection.$$('#checkPasswordsLinkRow').hidden); + }); + }); + + test( + 'showPasswordCheckLinkButtonWithoutWarningWhenNoPasswords', function() { + // Suppose no check done initially, empty list of passwords, signed + // in. + assertEquals( + passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, + undefined); + const passwordsSection = + elementFactory.createPasswordsSection(passwordManager, [], []); + return passwordManager.whenCalled('getPasswordCheckStatus') + .then(() => { + Polymer.dom.flush(); + assertTrue(passwordsSection.$$('#checkPasswordsBannerContainer') + .hidden); + assertTrue(passwordsSection.$$('#checkPasswordsButton').hidden); + assertFalse( + passwordsSection.$$('#checkPasswordsLinkRow').hidden); + }); + }); test( 'showPasswordCheckLinkButtonWithoutWarningWhenNoCredentialsLeaked', function() { - // Suppose no leaks detected initially. + // Suppose no leaks initially, non-empty list of passwords, signed in. passwordManager.data.leakedCredentials = []; passwordManager.data.checkStatus.elapsedTimeSinceLastCheck = '5 min ago'; - const passwordsSection = - elementFactory.createPasswordsSection(passwordManager, [], []); + const passwordList = [ + autofill_test_util.createPasswordEntry('site1.com', 'luigi', 1), + ]; + const passwordsSection = elementFactory.createPasswordsSection( + passwordManager, passwordList, []); return passwordManager.whenCalled('getPasswordCheckStatus') .then(() => { Polymer.dom.flush(); @@ -857,7 +914,7 @@ test( 'showPasswordCheckLinkButtonWithWarningWhenSomeCredentialsLeaked', function() { - // Suppose two leaks detected initially. + // Suppose no leaks initially, non-empty list of passwords, signed in. passwordManager.data.leakedCredentials = [ autofill_test_util.makeCompromisedCredential( 'one.com', 'test4', 'LEAKED'), @@ -866,8 +923,11 @@ ]; passwordManager.data.checkStatus.elapsedTimeSinceLastCheck = '5 min ago'; - const passwordsSection = - elementFactory.createPasswordsSection(passwordManager, [], []); + const passwordList = [ + autofill_test_util.createPasswordEntry('site1.com', 'luigi', 1), + ]; + const passwordsSection = elementFactory.createPasswordsSection( + passwordManager, passwordList, []); return passwordManager.whenCalled('getPasswordCheckStatus') .then(() => { Polymer.dom.flush(); @@ -886,11 +946,19 @@ }); test('makeWarningAppearWhenLeaksDetected', function() { - // Suppose no leaks detected initially. + // Suppose no leaks detected initially, non-empty list of passwords, + // signed in. + assertEquals( + passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, + undefined); passwordManager.data.leakedCredentials = []; passwordManager.data.checkStatus.elapsedTimeSinceLastCheck = '5 min ago'; - const passwordsSection = - elementFactory.createPasswordsSection(passwordManager, [], []); + const passwordList = [ + autofill_test_util.createPasswordEntry('one.com', 'test4', 1), + autofill_test_util.createPasswordEntry('two.com', 'test3', 1), + ]; + const passwordsSection = elementFactory.createPasswordsSection( + passwordManager, passwordList, []); return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { Polymer.dom.flush(); assertTrue( @@ -930,6 +998,30 @@ assertFalse(passwordsSection.$$('#checkPasswordLeakCount').hidden); }); }); + + test('makeBannerDisappearWhenSignedOut', function() { + // Suppose no leaks detected initially, non-empty list of passwords, + // signed in. + const passwordList = [ + autofill_test_util.createPasswordEntry('one.com', 'test4', 1), + autofill_test_util.createPasswordEntry('two.com', 'test3', 1), + ]; + const passwordsSection = elementFactory.createPasswordsSection( + passwordManager, passwordList, []); + return passwordManager.whenCalled('getPasswordCheckStatus').then(() => { + Polymer.dom.flush(); + assertFalse( + passwordsSection.$$('#checkPasswordsBannerContainer').hidden); + assertFalse(passwordsSection.$$('#checkPasswordsButton').hidden); + assertTrue(passwordsSection.$$('#checkPasswordsLinkRow').hidden); + sync_test_util.simulateSyncStatus({signedIn: false}); + Polymer.dom.flush(); + assertTrue( + passwordsSection.$$('#checkPasswordsBannerContainer').hidden); + assertTrue(passwordsSection.$$('#checkPasswordsButton').hidden); + assertFalse(passwordsSection.$$('#checkPasswordsLinkRow').hidden); + }); + }); }); // #cr_define_end });
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js index 9e54dde..ab62d62 100644 --- a/chrome/test/data/webui/settings/people_page_sync_page_test.js +++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -46,11 +46,6 @@ suiteSetup(function() { loadTimeData.overrideValues({ syncSetupFriendlySettings: true, - SwaaOn: 'On', - SwaaOff: 'Off', - SwaaOffHint: 'SwaaOffHint', - historySyncOffHint: 'historySyncOffHint', - dataEncryptedHint: 'dataEncryptedHint', signinAllowed: true }); }); @@ -565,87 +560,6 @@ assertTrue(dashboardLink.hidden); }); - test('Swaa', async function() { - function verifyResults( - hidden, Swaa, SwaaOffHint, hideActivityControlsUrl) { - const SwaaText = syncPage.$$('#history-usage-state .secondary'); - const historyUsageOffHint = syncPage.$$('#history-usage-off-hint'); - assertEquals(SwaaText.hidden, hidden); - assertEquals(historyUsageOffHint.hidden, Swaa !== 'Off'); - assertEquals( - syncPage.$$('#history-usage-row') - .querySelector('.icon-external') - .hidden, - hideActivityControlsUrl); - - if (!hidden) { - assertEquals(SwaaText.textContent.trim(), Swaa); - if (Swaa === 'Off') { - assertEquals(historyUsageOffHint.textContent.trim(), SwaaOffHint); - } - } - } - - /** @param {Object=} syncPrefOverrides */ - function setSyncPrefs(syncPrefOverrides = {}) { - const defaults = sync_test_util.getSyncAllPrefs(); - const syncPrefs = Object.assign({}, defaults, syncPrefOverrides); - cr.webUIListenerCallback('sync-prefs-changed', syncPrefs); - Polymer.dom.flush(); - } - - const syncSection = syncPage.$$('#sync-section'); - assertTrue(syncSection.hidden); - syncPage.syncStatus = { - signedIn: true, - disabled: false, - hasError: false, - statusAction: settings.StatusAction.NO_ACTION, - }; - Polymer.dom.flush(); - assertFalse(syncSection.hidden); - await browserProxy.whenCalled('queryIsHistoryRecordingEnabled'); - verifyResults( - /*hidden=*/ false, 'On', '', /*hideActivityControlsUrl=*/ false); - - // Data encrypted with custom passphrase. - setSyncPrefs({encryptAllData: true}); - verifyResults( - /*hidden=*/ false, 'Off', 'dataEncryptedHint', - /*hideActivityControlsUrl=*/ true); - - // sWAA off. - browserProxy.setHistoryRecordingEnabled({ - requestSucceeded: true, - historyRecordingEnabled: /*hideActivityControlsUrl=*/ false - }); - setSyncPrefs(); - await browserProxy.whenCalled('queryIsHistoryRecordingEnabled'); - verifyResults( - /*hidden=*/ false, 'Off', 'SwaaOffHint', - /*hideActivityControlsUrl=*/ false); - - // Turn history sync off. - setSyncPrefs({syncAllDataTypes: false, typedUrlsSynced: false}); - verifyResults( - /*hidden=*/ false, 'Off', 'historySyncOffHint', - /*hideActivityControlsUrl=*/ true); - - // Verify hint is updated. - setSyncPrefs({encryptAllData: true}); - verifyResults( - /*hidden=*/ false, 'Off', 'dataEncryptedHint', - /*hideActivityControlsUrl=*/ true); - - // Failed to fetch |historyRecordingEnabled|. - browserProxy.setHistoryRecordingEnabled( - {requestSucceeded: false, historyRecordingEnabled: false}); - setSyncPrefs(); - await browserProxy.whenCalled('queryIsHistoryRecordingEnabled'); - verifyResults( - /*hidden=*/ true, '', '', /*hideActivityControlsUrl=*/ false); - }); - // ################################## // TESTS THAT ARE SKIPPED ON CHROMEOS // ##################################
diff --git a/chrome/test/data/webui/settings/test_sync_browser_proxy.js b/chrome/test/data/webui/settings/test_sync_browser_proxy.js index 05e4e898..fb7a4a0 100644 --- a/chrome/test/data/webui/settings/test_sync_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_sync_browser_proxy.js
@@ -23,7 +23,6 @@ 'sendSyncPrefsChanged', 'startSignIn', 'startSyncingWithEmail', - 'queryIsHistoryRecordingEnabled', ]; if (cr.isChromeOS) { @@ -35,12 +34,6 @@ /** @private {number} */ this.impressionCount_ = 0; - /** @type {!HistoryRecordingEnabled} */ - this.historyRecordingEnabled_ = { - requestSucceeded: true, - historyRecordingEnabled: true - }; - /** @type {!settings.PageStatus} */ this.encryptionResponse = settings.PageStatus.CONFIGURE; } @@ -118,19 +111,6 @@ sendSyncPrefsChanged() { this.methodCalled('sendSyncPrefsChanged'); } - - /** - * @param {!HistoryRecordingEnabled} historyRecordingEnabled - */ - setHistoryRecordingEnabled(historyRecordingEnabled) { - this.historyRecordingEnabled_ = historyRecordingEnabled; - } - - /** @override */ - queryIsHistoryRecordingEnabled() { - this.methodCalled('queryIsHistoryRecordingEnabled'); - return Promise.resolve(this.historyRecordingEnabled_); - } } if (cr.isChromeOS) {
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index 43c278c..b1255c750 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -181,6 +181,8 @@ "persisted_data_unittest.cc", "prefs_unittest.cc", "run_all_unittests.cc", + "test/integration_tests.cc", + "test/integration_tests.h", "updater_unittest.cc", ] @@ -197,17 +199,26 @@ ] if (is_win) { + sources += [ "test/integration_tests_win.cc" ] + deps += [ "//chrome/updater/win:updater_tests" ] data_deps = [ "//chrome/updater/win:updater" ] } if (is_mac) { + sources += [ "test/integration_tests_mac.cc" ] + deps += [ "//chrome/updater/mac:updater_bundle", "//chrome/updater/mac:updater_setup_tests", "//chrome/updater/mac:updater_tests", ] + + data_deps = [ + "//chrome/updater/mac:updater_bundle", + "//chrome/updater/mac:updater_setup", + ] } if (is_win || is_mac) {
diff --git a/chrome/updater/run_all_unittests.cc b/chrome/updater/run_all_unittests.cc index b03b357..6929486 100644 --- a/chrome/updater/run_all_unittests.cc +++ b/chrome/updater/run_all_unittests.cc
@@ -10,7 +10,7 @@ int main(int argc, char** argv) { base::TestSuite test_suite(argc, argv); chrome::RegisterPathProvider(); - return base::LaunchUnitTests( + return base::LaunchUnitTestsSerially( argc, argv, base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite))); }
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc new file mode 100644 index 0000000..a763b94d --- /dev/null +++ b/chrome/updater/test/integration_tests.cc
@@ -0,0 +1,41 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/updater/test/integration_tests.h" + +#include "build/build_config.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace updater { + +namespace test { + +class IntegrationTest : public ::testing::Test { + protected: + void SetUp() override { + Clean(); + ExpectClean(); + } + + void TearDown() override { + ExpectClean(); + Clean(); + } +}; + +// TODO(crbug.com/1063064): Fix the test on Windows. +#if defined(OS_WIN) +#define MAYBE_InstallUninstall DISABLED_InstallUninstall +#else +#define MAYBE_InstallUninstall InstallUninstall +#endif +TEST_F(IntegrationTest, MAYBE_InstallUninstall) { + Install(); + ExpectInstalled(); + Uninstall(); +} + +} // namespace test + +} // namespace updater
diff --git a/chrome/updater/test/integration_tests.h b/chrome/updater/test/integration_tests.h new file mode 100644 index 0000000..44786b6 --- /dev/null +++ b/chrome/updater/test/integration_tests.h
@@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_UPDATER_TEST_INTEGRATION_TESTS_H_ +#define CHROME_UPDATER_TEST_INTEGRATION_TESTS_H_ + +namespace updater { + +namespace test { + +// Removes traces of the updater from the system. It is best to run this at the +// start of each test in case a previous crash or timeout on the machine running +// the test left the updater in an installed or partially installed state. +void Clean(); + +// Expect that the system is in a clean state, i.e. no updater is installed and +// no traces of an updater exist. Should be run at the start and end of each +// test. +void ExpectClean(); + +// Expect that the updater is installed on the system. +void ExpectInstalled(); + +// Install the updater. +void Install(); + +// Uninstall the updater. If the updater was installed during the test, it +// should be uninstalled before the end of the test to avoid having an actual +// live updater on the machine that ran the test. +void Uninstall(); + +} // namespace test + +} // namespace updater + +#endif // CHROME_UPDATER_TEST_INTEGRATION_TESTS_H_
diff --git a/chrome/updater/test/integration_tests_mac.cc b/chrome/updater/test/integration_tests_mac.cc new file mode 100644 index 0000000..f757f41 --- /dev/null +++ b/chrome/updater/test/integration_tests_mac.cc
@@ -0,0 +1,99 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/mac/foundation_util.h" +#include "base/path_service.h" +#include "base/process/launch.h" +#include "base/process/process.h" +#include "chrome/updater/updater_version.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace updater { + +namespace test { + +namespace { + +base::FilePath GetExecutablePath() { + base::FilePath test_executable; + if (!base::PathService::Get(base::FILE_EXE, &test_executable)) + return base::FilePath(); + return test_executable.DirName() + .Append(FILE_PATH_LITERAL(PRODUCT_FULLNAME_STRING ".App")) + .Append(FILE_PATH_LITERAL("Contents")) + .Append(FILE_PATH_LITERAL("MacOS")) + .Append(FILE_PATH_LITERAL(PRODUCT_FULLNAME_STRING)); +} + +base::FilePath GetInstallerPath() { + base::FilePath test_executable; + if (!base::PathService::Get(base::FILE_EXE, &test_executable)) + return base::FilePath(); + return test_executable.DirName().Append("updater_setup"); +} + +bool Run(base::CommandLine command_line, int* exit_code) { + auto process = base::LaunchProcess(command_line, {}); + if (!process.IsValid()) + return false; + if (!process.WaitForExitWithTimeout(base::TimeDelta::FromSeconds(60), + exit_code)) + return false; + return true; +} + +} // namespace + +void Clean() { + EXPECT_TRUE(base::DeleteFile(base::mac::GetUserLibraryPath() + .AppendASCII(COMPANY_SHORTNAME_STRING) + .AppendASCII(PRODUCT_FULLNAME_STRING), + true)); + // TODO(crbug.com/1062288): Delete the service launchd entry. + // TODO(crbug.com/1062288): Delete the update task launchd entry. +} + +void ExpectClean() { + // Files must not exist on the file system. + EXPECT_FALSE(base::PathExists(base::mac::GetUserLibraryPath() + .AppendASCII(COMPANY_SHORTNAME_STRING) + .AppendASCII(PRODUCT_FULLNAME_STRING))); + // TODO(crbug.com/1062288): Check that service Launchd entry does not exist. + // TODO(crbug.com/1062288): Check that update task Launchd entry does not + // exist. +} + +void ExpectInstalled() { + // Files must exist on the file system. + EXPECT_TRUE(base::PathExists(base::mac::GetUserLibraryPath() + .AppendASCII(COMPANY_SHORTNAME_STRING) + .AppendASCII(PRODUCT_FULLNAME_STRING))); + // TODO(crbug.com/1062288): Check that service Launchd entry exists. + // TODO(crbug.com/1062288): Check that update task Launchd entry exists. +} + +void Install() { + base::FilePath path = GetInstallerPath(); + ASSERT_FALSE(path.empty()); + int exit_code = -1; + ASSERT_TRUE(Run(base::CommandLine(path), &exit_code)); + EXPECT_EQ(0, exit_code); +} + +void Uninstall() { + base::FilePath path = GetExecutablePath(); + ASSERT_FALSE(path.empty()); + base::CommandLine command_line(path); + command_line.AppendSwitch("uninstall"); + int exit_code = -1; + ASSERT_TRUE(Run(command_line, &exit_code)); + EXPECT_EQ(0, exit_code); +} + +} // namespace test + +} // namespace updater
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc new file mode 100644 index 0000000..efe49a3 --- /dev/null +++ b/chrome/updater/test/integration_tests_win.cc
@@ -0,0 +1,104 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "base/process/launch.h" +#include "base/process/process.h" +#include "chrome/updater/updater_version.h" +#include "chrome/updater/util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace updater { + +namespace test { + +namespace { + +base::FilePath GetInstallerPath() { + base::FilePath test_executable; + if (!base::PathService::Get(base::FILE_EXE, &test_executable)) + return base::FilePath(); + return test_executable.DirName().AppendASCII("UpdaterSetup.exe"); +} + +bool Run(base::CommandLine command_line, int* exit_code) { + auto process = base::LaunchProcess(command_line, {}); + if (!process.IsValid()) + return false; + if (!process.WaitForExitWithTimeout(base::TimeDelta::FromSeconds(60), + exit_code)) + return false; + return true; +} + +base::FilePath GetProductPath() { + base::FilePath app_data_dir; + if (!base::PathService::Get(base::DIR_LOCAL_APP_DATA, &app_data_dir)) + return base::FilePath(); + return app_data_dir.AppendASCII(COMPANY_SHORTNAME_STRING) + .AppendASCII(PRODUCT_FULLNAME_STRING); +} + +base::FilePath GetExecutablePath() { + return GetProductPath().AppendASCII("updater.exe"); +} + +} // namespace + +void Clean() { + // TODO(crbug.com/1062288): Delete the Client / ClientState registry keys. + // TODO(crbug.com/1062288): Delete the COM server items. + // TODO(crbug.com/1062288): Delete the COM service items. + // TODO(crbug.com/1062288): Delete the COM interfaces. + // TODO(crbug.com/1062288): Delete the UpdateApps task. + EXPECT_TRUE(base::DeleteFile(GetProductPath(), true)); +} + +void ExpectClean() { + // TODO(crbug.com/1062288): Assert there are no Client / ClientState registry + // keys. + // TODO(crbug.com/1062288): Assert there are no COM server items. + // TODO(crbug.com/1062288): Assert there are no COM service items. + // TODO(crbug.com/1062288): Assert there are no COM interfaces. + // TODO(crbug.com/1062288): Assert there are no UpdateApps tasks. + + // Files must not exist on the file system. + + // EXPECT_FALSE(base::PathExists(GetProductPath())); +} + +void ExpectInstalled() { + // TODO(crbug.com/1062288): Assert there are Client / ClientState registry + // keys. + // TODO(crbug.com/1062288): Assert there are COM server items. + // TODO(crbug.com/1062288): Assert there are COM service items. (Maybe.) + // TODO(crbug.com/1062288): Assert there are COM interfaces. + // TODO(crbug.com/1062288): Assert there are UpdateApps tasks. + + // Files must exist on the file system. + EXPECT_TRUE(base::PathExists(GetProductPath())); +} + +void Install() { + int exit_code = -1; + ASSERT_TRUE(Run(base::CommandLine(GetInstallerPath()), &exit_code)); + EXPECT_EQ(0, exit_code); +} + +void Uninstall() { + base::FilePath path = GetExecutablePath(); + ASSERT_FALSE(path.empty()); + base::CommandLine command_line(path); + command_line.AppendSwitch("uninstall"); + int exit_code = -1; + ASSERT_TRUE(Run(command_line, &exit_code)); + EXPECT_EQ(0, exit_code); +} + +} // namespace test + +} // namespace updater
diff --git a/chromecast/browser/accessibility/touch_exploration_controller.cc b/chromecast/browser/accessibility/touch_exploration_controller.cc index faaae8d2..b2898fa4 100644 --- a/chromecast/browser/accessibility/touch_exploration_controller.cc +++ b/chromecast/browser/accessibility/touch_exploration_controller.cc
@@ -195,6 +195,12 @@ if (side_gesture_pass_through_ && type == ui::ET_TOUCH_PRESSED && FindEdgesWithinInset(location, gesture_start_width_, gesture_start_height_) != NO_EDGE) { + // If we are already in pass-through, ignore additional presses + // or the other fingers will clobber our initial press. + if (state_ == ONE_FINGER_PASSTHROUGH) { + return DiscardEvent(continuation); + } + SET_STATE(ONE_FINGER_PASSTHROUGH); initial_press_ = std::make_unique<ui::TouchEvent>(touch_event); passthrough_offset_ = gfx::Vector2dF(0, 0);
diff --git a/chromeos/constants/chromeos_switches.cc b/chromeos/constants/chromeos_switches.cc index 3cdb92f9..add7294 100644 --- a/chromeos/constants/chromeos_switches.cc +++ b/chromeos/constants/chromeos_switches.cc
@@ -561,12 +561,6 @@ return base::CommandLine::ForCurrentProcess()->HasSwitch(kShelfHoverPreviews); } -bool ShouldShowScrollableShelf() { - // TODO(manucornet): Remove this method and simplify conditions depending - // on it since it's now always true. - return true; -} - bool ShouldTetherHostScansIgnoreWiredConnections() { return base::CommandLine::ForCurrentProcess()->HasSwitch( kTetherHostScansIgnoreWiredConnections);
diff --git a/chromeos/constants/chromeos_switches.h b/chromeos/constants/chromeos_switches.h index bca1f4f..3327821 100644 --- a/chromeos/constants/chromeos_switches.h +++ b/chromeos/constants/chromeos_switches.h
@@ -230,9 +230,6 @@ // on the shelf. COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool ShouldShowShelfHoverPreviews(); -// Returns true if we should show a scrollable list of apps in the main shelf. -COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool ShouldShowScrollableShelf(); - // Returns true if the Chromebook should ignore its wired connections when // deciding whether to run scans for tethering hosts. Should be used only for // testing.
diff --git a/chromeos/profiles/airmont.afdo.newest.txt b/chromeos/profiles/airmont.afdo.newest.txt index a4159b4..642a171 100644 --- a/chromeos/profiles/airmont.afdo.newest.txt +++ b/chromeos/profiles/airmont.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-airmont-82-4079.0-1584355719-benchmark-82.0.4085.10-r1-redacted.afdo.xz \ No newline at end of file +chromeos-chrome-amd64-airmont-82-4079.0-1584355719-benchmark-82.0.4085.12-r1-redacted.afdo.xz \ No newline at end of file
diff --git a/chromeos/profiles/broadwell.afdo.newest.txt b/chromeos/profiles/broadwell.afdo.newest.txt index 198fb031..e7d57ab 100644 --- a/chromeos/profiles/broadwell.afdo.newest.txt +++ b/chromeos/profiles/broadwell.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-broadwell-82-4044.42-1584352428-benchmark-82.0.4085.10-r1-redacted.afdo.xz \ No newline at end of file +chromeos-chrome-amd64-broadwell-82-4044.42-1584352428-benchmark-82.0.4085.12-r1-redacted.afdo.xz \ No newline at end of file
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index c5f8690e..53bab7e 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -709,11 +709,6 @@ it->OnOpenUrlResponse(gurl, is_background); } -void AssistantManagerServiceImpl::OnPlaybackStateChange( - const MediaStatus& status) { - media_session_->NotifyMediaSessionMetadataChanged(status); -} - void AssistantManagerServiceImpl::OnShowNotification( const action::Notification& notification) { ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnShowNotification, @@ -1338,10 +1333,9 @@ }); } -void AssistantManagerServiceImpl::MediaSessionChanged( - const base::Optional<base::UnguessableToken>& request_id) { - if (request_id.has_value()) - media_session_audio_focus_id_ = std::move(request_id.value()); +void AssistantManagerServiceImpl::OnPlaybackStateChange( + const MediaStatus& status) { + media_session_->NotifyMediaSessionMetadataChanged(status); } void AssistantManagerServiceImpl::MediaSessionInfoChanged( @@ -1356,6 +1350,12 @@ UpdateMediaState(); } +void AssistantManagerServiceImpl::MediaSessionChanged( + const base::Optional<base::UnguessableToken>& request_id) { + if (request_id.has_value()) + media_session_audio_focus_id_ = std::move(request_id.value()); +} + // TODO(dmblack): Handle non-firing (e.g. paused or scheduled) timers. void AssistantManagerServiceImpl::OnAlarmTimerStateChanged() { ENSURE_MAIN_THREAD(&AssistantManagerServiceImpl::OnAlarmTimerStateChanged);
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.h b/chromeos/services/assistant/assistant_manager_service_impl.h index b1c2b43..c67fb2d6 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.h +++ b/chromeos/services/assistant/assistant_manager_service_impl.h
@@ -165,8 +165,6 @@ const std::vector<action::Suggestion>& suggestions) override; void OnShowText(const std::string& text) override; void OnOpenUrl(const std::string& url, bool in_background) override; - void OnPlaybackStateChange( - const assistant_client::MediaStatus& status) override; void OnShowNotification(const action::Notification& notification) override; void OnOpenAndroidApp(const action::AndroidAppInfo& app_info, const action::InteractionInfo& interaction) override; @@ -216,6 +214,10 @@ } CrosPlatformApi* platform_api() { return platform_api_.get(); } + // assistant_client::MediaManager::Listener overrides: + void OnPlaybackStateChange( + const assistant_client::MediaStatus& status) override; + // media_session::mojom::MediaControllerObserver overrides: void MediaSessionInfoChanged( media_session::mojom::MediaSessionInfoPtr info) override;
diff --git a/components/BUILD.gn b/components/BUILD.gn index 51f5d2e..81e7c48 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -222,6 +222,7 @@ "//components/autofill/content/browser:unit_tests", "//components/autofill/content/renderer:unit_tests", "//components/autofill/core/common/mojom:unit_tests", + "//components/browsing_data/content:unit_tests", "//components/captive_portal/content:unit_tests", "//components/cast_certificate:unit_tests", "//components/cast_channel:unit_tests",
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc index 7adcb7a5..b70b30a 100644 --- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc +++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -766,7 +766,8 @@ TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIcon) { IssueOnQuery(kQueryId); - auto element_icons = testing::ElementsAre(std::string(), "googlePay"); + auto element_icons = + testing::ElementsAre(std::string(), testing::StartsWith("googlePay")); EXPECT_CALL(autofill_client_, ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons), false, PopupType::kPersonalInformation, _));
diff --git a/components/autofill/core/browser/ui/popup_item_ids.h b/components/autofill/core/browser/ui/popup_item_ids.h index 2e2372e..085863e1 100644 --- a/components/autofill/core/browser/ui/popup_item_ids.h +++ b/components/autofill/core/browser/ui/popup_item_ids.h
@@ -27,10 +27,11 @@ POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY = -13, POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY = -14, POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS = -15, - POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN = -16, + POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN = -16, POPUP_ITEM_ID_HIDE_AUTOFILL_SUGGESTIONS = -17, POPUP_ITEM_ID_USE_VIRTUAL_CARD = -18, POPUP_ITEM_ID_LOADING_SPINNER = -20, + POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE = -21, }; } // namespace autofill
diff --git a/components/autofill/core/common/save_password_progress_logger.cc b/components/autofill/core/common/save_password_progress_logger.cc index cb4d60e2..8d98ef9 100644 --- a/components/autofill/core/common/save_password_progress_logger.cc +++ b/components/autofill/core/common/save_password_progress_logger.cc
@@ -504,6 +504,12 @@ return "Server predictions"; case STRING_USERNAME_FIRST_FLOW_VOTE: return "Username first flow vote"; + case STRING_POSSIBLE_USERNAME_USED: + return "Possible username is used"; + case STRING_POSSIBLE_USERNAME_NOT_USED: + return "Possible username is not used"; + case STRING_LOCALLY_SAVED_PREDICTION: + return "Locally saved prediction"; case SavePasswordProgressLogger::STRING_INVALID: return "INVALID"; // Intentionally no default: clause here -- all IDs need to get covered.
diff --git a/components/autofill/core/common/save_password_progress_logger.h b/components/autofill/core/common/save_password_progress_logger.h index e4656f0..59825fd 100644 --- a/components/autofill/core/common/save_password_progress_logger.h +++ b/components/autofill/core/common/save_password_progress_logger.h
@@ -160,6 +160,9 @@ STRING_NAVIGATION_NTP, STRING_SERVER_PREDICTIONS, STRING_USERNAME_FIRST_FLOW_VOTE, + STRING_POSSIBLE_USERNAME_USED, + STRING_POSSIBLE_USERNAME_NOT_USED, + STRING_LOCALLY_SAVED_PREDICTION, STRING_INVALID, // Represents a string returned in a case of an error. STRING_MAX = STRING_INVALID };
diff --git a/components/autofill_assistant/browser/basic_interactions.cc b/components/autofill_assistant/browser/basic_interactions.cc index 4f737d55f..687420a 100644 --- a/components/autofill_assistant/browser/basic_interactions.cc +++ b/components/autofill_assistant/browser/basic_interactions.cc
@@ -416,7 +416,10 @@ } bool BasicInteractions::EndAction(const EndActionProto& proto) { - CHECK(end_action_callback_) << "Failed to EndAction: no callback set"; + if (!end_action_callback_) { + DVLOG(2) << "Failed to EndAction: no callback set"; + return false; + } std::move(end_action_callback_) .Run(proto.status(), delegate_->GetUserModel()); return true;
diff --git a/components/autofill_assistant/browser/basic_interactions_unittest.cc b/components/autofill_assistant/browser/basic_interactions_unittest.cc index 18e74fbe..0c99874 100644 --- a/components/autofill_assistant/browser/basic_interactions_unittest.cc +++ b/components/autofill_assistant/browser/basic_interactions_unittest.cc
@@ -237,8 +237,7 @@ TEST_F(BasicInteractionsTest, EndActionWithoutCallbackFails) { EndActionProto proto; - ASSERT_DEATH(basic_interactions_.EndAction(proto), - "Failed to EndAction: no callback set"); + EXPECT_FALSE(basic_interactions_.EndAction(proto)); } TEST_F(BasicInteractionsTest, EndActionWithCallbackSucceeds) {
diff --git a/components/browsing_data/content/BUILD.gn b/components/browsing_data/content/BUILD.gn index 179a40a..e32ecc0 100644 --- a/components/browsing_data/content/BUILD.gn +++ b/components/browsing_data/content/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "conditional_cache_counting_helper.cc", "conditional_cache_counting_helper.h", + "local_storage_helper.cc", + "local_storage_helper.h", ] configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] @@ -19,3 +21,16 @@ "//net", ] } + +source_set("unit_tests") { + testonly = true + sources = [ "local_storage_helper_unittest.cc" ] + + deps = [ + ":content", + "//base", + "//content/test:test_support", + "//testing/gtest", + "//url", + ] +}
diff --git a/components/browsing_data/content/DEPS b/components/browsing_data/content/DEPS index 9093044..27dbf2d 100644 --- a/components/browsing_data/content/DEPS +++ b/components/browsing_data/content/DEPS
@@ -2,6 +2,7 @@ "+components/content_settings/core/browser", "+components/content_settings/core/common", "+content/public/browser", + "+content/public/test", "+mojo/public/cpp/bindings", "+net", "+services/network/public/cpp",
diff --git a/components/browsing_data/content/local_storage_helper.cc b/components/browsing_data/content/local_storage_helper.cc new file mode 100644 index 0000000..5dabe4263 --- /dev/null +++ b/components/browsing_data/content/local_storage_helper.cc
@@ -0,0 +1,121 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/browsing_data/content/local_storage_helper.h" + +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/location.h" +#include "base/stl_util.h" +#include "base/task/post_task.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/storage_usage_info.h" +#include "url/gurl.h" +#include "url/origin.h" +#include "url/url_constants.h" +#include "url/url_util.h" + +using content::BrowserContext; +using content::BrowserThread; + +namespace browsing_data { + +namespace { + +// Only websafe state is considered browsing data. +bool HasStorageScheme(const GURL& origin_url) { + return base::Contains(url::GetWebStorageSchemes(), origin_url.scheme()); +} + +void GetUsageInfoCallback(LocalStorageHelper::FetchCallback callback, + const std::vector<content::StorageUsageInfo>& infos) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(!callback.is_null()); + + std::list<content::StorageUsageInfo> result; + for (const content::StorageUsageInfo& info : infos) { + if (HasStorageScheme(info.origin.GetURL())) + result.push_back(info); + } + + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(callback), result)); +} + +} // namespace + +LocalStorageHelper::LocalStorageHelper(BrowserContext* context) + : dom_storage_context_(BrowserContext::GetDefaultStoragePartition(context) + ->GetDOMStorageContext()) { + DCHECK(dom_storage_context_); +} + +LocalStorageHelper::~LocalStorageHelper() = default; + +void LocalStorageHelper::StartFetching(FetchCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(!callback.is_null()); + dom_storage_context_->GetLocalStorageUsage( + base::BindOnce(&GetUsageInfoCallback, std::move(callback))); +} + +void LocalStorageHelper::DeleteOrigin(const url::Origin& origin, + base::OnceClosure callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + dom_storage_context_->DeleteLocalStorage(origin, std::move(callback)); +} + +//--------------------------------------------------------- + +CannedLocalStorageHelper::CannedLocalStorageHelper(BrowserContext* context) + : LocalStorageHelper(context) {} + +void CannedLocalStorageHelper::Add(const url::Origin& origin) { + if (!HasStorageScheme(origin.GetURL())) + return; + pending_origins_.insert(origin); +} + +void CannedLocalStorageHelper::Reset() { + pending_origins_.clear(); +} + +bool CannedLocalStorageHelper::empty() const { + return pending_origins_.empty(); +} + +size_t CannedLocalStorageHelper::GetCount() const { + return pending_origins_.size(); +} + +const std::set<url::Origin>& CannedLocalStorageHelper::GetOrigins() const { + return pending_origins_; +} + +void CannedLocalStorageHelper::StartFetching(FetchCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(!callback.is_null()); + + std::list<content::StorageUsageInfo> result; + for (const auto& origin : pending_origins_) + result.emplace_back(origin, 0, base::Time()); + + base::PostTask(FROM_HERE, {BrowserThread::UI}, + base::BindOnce(std::move(callback), result)); +} + +void CannedLocalStorageHelper::DeleteOrigin(const url::Origin& origin, + base::OnceClosure callback) { + pending_origins_.erase(origin); + LocalStorageHelper::DeleteOrigin(origin, std::move(callback)); +} + +CannedLocalStorageHelper::~CannedLocalStorageHelper() = default; + +} // namespace browsing_data
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper.h b/components/browsing_data/content/local_storage_helper.h similarity index 68% rename from chrome/browser/browsing_data/browsing_data_local_storage_helper.h rename to components/browsing_data/content/local_storage_helper.h index 09368b8..2d33dc22 100644 --- a/chrome/browser/browsing_data/browsing_data_local_storage_helper.h +++ b/components/browsing_data/content/local_storage_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_LOCAL_STORAGE_HELPER_H_ -#define CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_LOCAL_STORAGE_HELPER_H_ +#ifndef COMPONENTS_BROWSING_DATA_CONTENT_LOCAL_STORAGE_HELPER_H_ +#define COMPONENTS_BROWSING_DATA_CONTENT_LOCAL_STORAGE_HELPER_H_ #include <stddef.h> #include <stdint.h> @@ -21,17 +21,20 @@ #include "content/public/browser/storage_usage_info.h" #include "url/origin.h" -class Profile; +namespace content { +class BrowserContext; +} + +namespace browsing_data { // This class fetches local storage information and provides a // means to delete the data associated with an origin. -class BrowsingDataLocalStorageHelper - : public base::RefCounted<BrowsingDataLocalStorageHelper> { +class LocalStorageHelper : public base::RefCounted<LocalStorageHelper> { public: using FetchCallback = base::OnceCallback<void(const std::list<content::StorageUsageInfo>&)>; - explicit BrowsingDataLocalStorageHelper(Profile* profile); + explicit LocalStorageHelper(content::BrowserContext* context); // Starts the fetching process, which will notify its completion via // callback. This must be called only in the UI thread. @@ -44,22 +47,21 @@ base::OnceClosure callback); protected: - friend class base::RefCounted<BrowsingDataLocalStorageHelper>; - virtual ~BrowsingDataLocalStorageHelper(); + friend class base::RefCounted<LocalStorageHelper>; + virtual ~LocalStorageHelper(); - content::DOMStorageContext* dom_storage_context_; // Owned by the profile + content::DOMStorageContext* dom_storage_context_; // Owned by the context private: - DISALLOW_COPY_AND_ASSIGN(BrowsingDataLocalStorageHelper); + DISALLOW_COPY_AND_ASSIGN(LocalStorageHelper); }; -// This class is a thin wrapper around BrowsingDataLocalStorageHelper that does +// This class is a thin wrapper around LocalStorageHelper that does // not fetch its information from the local storage context, but gets them // passed by a call when accessed. -class CannedBrowsingDataLocalStorageHelper - : public BrowsingDataLocalStorageHelper { +class CannedLocalStorageHelper : public LocalStorageHelper { public: - explicit CannedBrowsingDataLocalStorageHelper(Profile* profile); + explicit CannedLocalStorageHelper(content::BrowserContext* context); // Add a local storage to the set of canned local storages that is returned // by this helper. @@ -77,17 +79,19 @@ // Returns the set of origins that use local storage. const std::set<url::Origin>& GetOrigins() const; - // BrowsingDataLocalStorageHelper implementation. + // LocalStorageHelper implementation. void StartFetching(FetchCallback callback) override; void DeleteOrigin(const url::Origin& origin, base::OnceClosure callback) override; private: - ~CannedBrowsingDataLocalStorageHelper() override; + ~CannedLocalStorageHelper() override; std::set<url::Origin> pending_origins_; - DISALLOW_COPY_AND_ASSIGN(CannedBrowsingDataLocalStorageHelper); + DISALLOW_COPY_AND_ASSIGN(CannedLocalStorageHelper); }; -#endif // CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_LOCAL_STORAGE_HELPER_H_ +} // namespace browsing_data + +#endif // COMPONENTS_BROWSING_DATA_CONTENT_LOCAL_STORAGE_HELPER_H_
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper_unittest.cc b/components/browsing_data/content/local_storage_helper_unittest.cc similarity index 73% rename from chrome/browser/browsing_data/browsing_data_local_storage_helper_unittest.cc rename to components/browsing_data/content/local_storage_helper_unittest.cc index fa1ad468..1a1c841 100644 --- a/chrome/browser/browsing_data/browsing_data_local_storage_helper_unittest.cc +++ b/components/browsing_data/content/local_storage_helper_unittest.cc
@@ -2,12 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" +#include "components/browsing_data/content/local_storage_helper.h" #include "base/bind_helpers.h" -#include "chrome/test/base/testing_profile.h" #include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_browser_context.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace browsing_data { namespace { @@ -16,12 +19,12 @@ }; TEST_F(CannedBrowsingDataLocalStorageTest, Empty) { - TestingProfile profile; + content::TestBrowserContext context; const GURL origin("http://host1:1/"); - scoped_refptr<CannedBrowsingDataLocalStorageHelper> helper( - new CannedBrowsingDataLocalStorageHelper(&profile)); + scoped_refptr<CannedLocalStorageHelper> helper( + new CannedLocalStorageHelper(&context)); ASSERT_TRUE(helper->empty()); helper->Add(url::Origin::Create(origin)); @@ -31,14 +34,14 @@ } TEST_F(CannedBrowsingDataLocalStorageTest, Delete) { - TestingProfile profile; + content::TestBrowserContext context; const GURL origin1("http://host1:9000"); const GURL origin2("http://example.com"); const GURL origin3("http://foo.example.com"); - scoped_refptr<CannedBrowsingDataLocalStorageHelper> helper( - new CannedBrowsingDataLocalStorageHelper(&profile)); + scoped_refptr<CannedLocalStorageHelper> helper( + new CannedLocalStorageHelper(&context)); EXPECT_TRUE(helper->empty()); helper->Add(url::Origin::Create(origin1)); @@ -52,13 +55,13 @@ } TEST_F(CannedBrowsingDataLocalStorageTest, IgnoreExtensionsAndDevTools) { - TestingProfile profile; + content::TestBrowserContext context; const GURL origin1("chrome-extension://abcdefghijklmnopqrstuvwxyz/"); const GURL origin2("devtools://abcdefghijklmnopqrstuvwxyz/"); - scoped_refptr<CannedBrowsingDataLocalStorageHelper> helper( - new CannedBrowsingDataLocalStorageHelper(&profile)); + scoped_refptr<CannedLocalStorageHelper> helper( + new CannedLocalStorageHelper(&context)); ASSERT_TRUE(helper->empty()); helper->Add(url::Origin::Create(origin1)); @@ -68,3 +71,5 @@ } } // namespace + +} // namespace browsing_data
diff --git a/components/browsing_data/core/BUILD.gn b/components/browsing_data/core/BUILD.gn index a1b573f1..28f8cd2a 100644 --- a/components/browsing_data/core/BUILD.gn +++ b/components/browsing_data/core/BUILD.gn
@@ -39,12 +39,10 @@ "//components/password_manager/core/browser", "//components/pref_registry", "//components/prefs", - "//components/signin/public/identity_manager", "//components/strings", "//components/sync", "//components/version_info", "//components/webdata/common", - "//services/network/public/cpp", "//ui/base", ] }
diff --git a/components/browsing_data/core/DEPS b/components/browsing_data/core/DEPS index cf7d954..3b68fd56 100644 --- a/components/browsing_data/core/DEPS +++ b/components/browsing_data/core/DEPS
@@ -7,7 +7,6 @@ "+components/password_manager/core/browser", "+components/pref_registry", "+components/prefs", - "+components/signin/public/identity_manager", "+components/strings/grit/components_strings.h", "+components/sync/base", "+components/sync/driver", @@ -15,6 +14,5 @@ "+components/version_info", "+components/webdata/common", "+net", - "+services/network/public", "+ui/base", ]
diff --git a/components/browsing_data/core/history_notice_utils.cc b/components/browsing_data/core/history_notice_utils.cc index e454a5d3..ef252ed 100644 --- a/components/browsing_data/core/history_notice_utils.cc +++ b/components/browsing_data/core/history_notice_utils.cc
@@ -10,40 +10,13 @@ #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" +#include "components/history/core/browser/web_history_service.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_user_settings.h" #include "components/version_info/version_info.h" +#include "net/traffic_annotation/network_traffic_annotation.h" namespace { -constexpr net::PartialNetworkTrafficAnnotationTag - kHistoryRecordingEnabledAnnotation = - net::DefinePartialNetworkTrafficAnnotation("history_recording_enabled", - "web_history_service", - R"( - semantics { - description: - "Queries history.google.com to find out if user has the 'Include " - "Chrome browsing history and activity from websites and apps that " - "use Google services' option enabled in the Activity controls of " - "their Google account. This is done for users who sync their " - "browsing history without a custom passphrase in order to show " - "information about history.google.com on the history page, " - "the settings sync setup page and in the Clear Browsing Data " - "dialog." - trigger: - "This request is sent when user opens the history page or the " - "settings sync setup page or the Clear Browsing Data dialog and " - "history sync without a custom passphrase is (re)enabled." - data: - "An OAuth2 token authenticating the user." - } - policy { - chrome_policy { - SyncDisabled { - SyncDisabled: true - } - } - })"); // Merges several asynchronous boolean callbacks into one that returns a boolean // product of their responses. Deletes itself when done. @@ -85,51 +58,42 @@ const syncer::SyncService* sync_service, history::WebHistoryService* history_service, base::OnceCallback<void(bool)> callback) { - IsHistoryRecordingEnabledAndCanBeUsed( - sync_service, history_service, - base::BindOnce( - [](base::OnceCallback<void(bool)> callback, - const base::Optional<bool>& history_recording_enabled) { - std::move(callback).Run(history_recording_enabled.value_or(false)); - }, - std::move(callback))); -} - -std::unique_ptr<history::WebHistoryService::Request> -CreateQueryWebAndAppActivityRequest( - signin::IdentityManager* identity_manager, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - base::OnceCallback<void(history::WebHistoryService::Request*, - const base::Optional<bool>&)> callback) { - DCHECK(identity_manager); - DCHECK(url_loader_factory); - - return history::WebHistoryService::CreateQueryWebAndAppActivityRequest( - identity_manager, url_loader_factory, std::move(callback), - kHistoryRecordingEnabledAnnotation); -} - -void IsHistoryRecordingEnabledAndCanBeUsed( - const syncer::SyncService* sync_service, - history::WebHistoryService* history_service, - base::OnceCallback<void(const base::Optional<bool>&)> callback) { if (!sync_service || !sync_service->IsSyncFeatureActive() || !sync_service->GetActiveDataTypes().Has( syncer::HISTORY_DELETE_DIRECTIVES) || + sync_service->GetUserSettings()->IsUsingSecondaryPassphrase() || !history_service) { - std::move(callback).Run(base::nullopt); - return; - } - - if (sync_service->GetUserSettings()->IsUsingSecondaryPassphrase()) { - // The user has a custom passphrase. The data is encrypted and can not be - // used. std::move(callback).Run(false); return; } - + net::PartialNetworkTrafficAnnotationTag partial_traffic_annotation = + net::DefinePartialNetworkTrafficAnnotation("history_notice_utils_notice", + "web_history_service", R"( + semantics { + description: + "Queries history.google.com to find out if user has the 'Include " + "Chrome browsing history and activity from websites and apps that " + "use Google services' option enabled in the Activity controls of " + "their Google account. This is done for users who sync their " + "browsing history without a custom passphrase in order to show " + "information about history.google.com on the history page and in " + "the Clear Browsing Data dialog." + trigger: + "This request is sent when user opens the history page or the " + "Clear Browsing Data dialog and history sync without a custom " + "passphrase is (re)enabled." + data: + "An OAuth2 token authenticating the user." + } + policy { + chrome_policy { + SyncDisabled { + SyncDisabled: true + } + } + })"); history_service->QueryWebAndAppActivity(std::move(callback), - kHistoryRecordingEnabledAnnotation); + partial_traffic_annotation); } void ShouldPopupDialogAboutOtherFormsOfBrowsingHistory( @@ -176,13 +140,8 @@ } })"); history_service->QueryWebAndAppActivity( - base::BindOnce( - [](base::OnceCallback<void(bool)> callback, - const base::Optional<bool>& history_recording_enabled) { - std::move(callback).Run(history_recording_enabled.value_or(false)); - }, - base::BindOnce(&MergeBooleanCallbacks::RunCallback, - base::Unretained(merger))), + base::BindOnce(&MergeBooleanCallbacks::RunCallback, + base::Unretained(merger)), partial_traffic_annotation); history_service->QueryOtherFormsOfBrowsingHistory( channel,
diff --git a/components/browsing_data/core/history_notice_utils.h b/components/browsing_data/core/history_notice_utils.h index f5c575b9..ff51743 100644 --- a/components/browsing_data/core/history_notice_utils.h +++ b/components/browsing_data/core/history_notice_utils.h
@@ -8,10 +8,10 @@ #include <string> #include "base/callback_forward.h" -#include "base/optional.h" -#include "components/history/core/browser/web_history_service.h" -#include "components/signin/public/identity_manager/identity_manager.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" + +namespace history { +class WebHistoryService; +} namespace syncer { class SyncService; @@ -23,38 +23,6 @@ namespace browsing_data { -// Returns a request that can be used to query |Web and App Activity|. It can be -// made independently from the history sync state and its lifetime needs to be -// managed by the caller. -// -// Once the request is completed, |callback| is called with the following -// arguments: -// * a pointer to the request associated with the response. -// * a base::Optional<bool> that indicated whether the user has enabled -// 'Include Chrome browsing history and activity from websites and apps that -// use Google services' in the |Web and App Activity| for their Google -// Account. This argument is base::nullopt if the request to fetch the -// |Web and App Activity| information failed. -std::unique_ptr<history::WebHistoryService::Request> -CreateQueryWebAndAppActivityRequest( - signin::IdentityManager* identity_manager, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - base::OnceCallback<void(history::WebHistoryService::Request*, - const base::Optional<bool>&)> callback); - -// The response is returned in the |callback|. It can be: -// * nullopt: If we fail to query the |Web And App Activity| or history sync is -// not fully active yet. -// * True: If the user has enabled 'Include Chrome browsing history and activity -// from websites and apps that use Google services' in the -// |Web and App Activity| of their Google Account, data is not encrypted with -// custom passphrase and history sync is active. -// * False: Otherwise. -void IsHistoryRecordingEnabledAndCanBeUsed( - const syncer::SyncService* sync_service, - history::WebHistoryService* history_service, - base::OnceCallback<void(const base::Optional<bool>&)> callback); - // Whether the Clear Browsing Data UI should show a notice about the existence // of other forms of browsing history stored in user's account. The response // is returned in a |callback|.
diff --git a/components/cast_channel/cast_message_util_unittest.cc b/components/cast_channel/cast_message_util_unittest.cc index 9515808..65ee3dcb 100644 --- a/components/cast_channel/cast_message_util_unittest.cc +++ b/components/cast_channel/cast_message_util_unittest.cc
@@ -10,7 +10,7 @@ #include "third_party/openscreen/src/cast/common/channel/proto/cast_channel.pb.h" using base::test::IsJson; -using base::test::ParseJsonDeprecated; +using base::test::ParseJson; namespace cast_channel { @@ -38,8 +38,7 @@ } )"; - LaunchSessionResponse response = - GetLaunchSessionResponse(*ParseJsonDeprecated(payload)); + LaunchSessionResponse response = GetLaunchSessionResponse(ParseJson(payload)); EXPECT_EQ(LaunchSessionResponse::Result::kOk, response.result); EXPECT_TRUE(response.receiver_status); } @@ -52,8 +51,7 @@ } )"; - LaunchSessionResponse response = - GetLaunchSessionResponse(*ParseJsonDeprecated(payload)); + LaunchSessionResponse response = GetLaunchSessionResponse(ParseJson(payload)); EXPECT_EQ(LaunchSessionResponse::Result::kError, response.result); EXPECT_FALSE(response.receiver_status); } @@ -68,8 +66,7 @@ } )"; - LaunchSessionResponse response = - GetLaunchSessionResponse(*ParseJsonDeprecated(payload)); + LaunchSessionResponse response = GetLaunchSessionResponse(ParseJson(payload)); EXPECT_EQ(LaunchSessionResponse::Result::kUnknown, response.result); EXPECT_FALSE(response.receiver_status); } @@ -127,8 +124,8 @@ "requestId": 123, })"; - CastMessage message = CreateMediaRequest(*ParseJsonDeprecated(body), 123, - "theSourceId", "theDestinationId"); + CastMessage message = CreateMediaRequest(ParseJson(body), 123, "theSourceId", + "theDestinationId"); ASSERT_TRUE(IsCastMessageValid(message)); EXPECT_EQ(kMediaNamespace, message.namespace_()); EXPECT_EQ("theSourceId", message.source_id()); @@ -147,7 +144,7 @@ })"; CastMessage message = - CreateSetVolumeRequest(*ParseJsonDeprecated(body), 123, "theSourceId"); + CreateSetVolumeRequest(ParseJson(body), 123, "theSourceId"); ASSERT_TRUE(IsCastMessageValid(message)); EXPECT_EQ(kReceiverNamespace, message.namespace_()); EXPECT_EQ("theSourceId", message.source_id());
diff --git a/components/dom_distiller/content/browser/BUILD.gn b/components/dom_distiller/content/browser/BUILD.gn index 584e8849..77f0757 100644 --- a/components/dom_distiller/content/browser/BUILD.gn +++ b/components/dom_distiller/content/browser/BUILD.gn
@@ -18,6 +18,8 @@ "distiller_page_web_contents.h", "dom_distiller_viewer_source.cc", "dom_distiller_viewer_source.h", + "uma_helper.cc", + "uma_helper.h", ] public_deps = [ @@ -50,9 +52,13 @@ source_set("unit_tests") { testonly = true - sources = [ "dom_distiller_viewer_source_unittest.cc" ] + sources = [ + "dom_distiller_viewer_source_unittest.cc", + "uma_helper_unittest.cc", + ] deps = [ ":browser", + "//base/test:test_support", "//content/test:test_support", "//testing/gtest", ]
diff --git a/components/dom_distiller/content/browser/distillability_driver.h b/components/dom_distiller/content/browser/distillability_driver.h index 21fa749..f14eb90 100644 --- a/components/dom_distiller/content/browser/distillability_driver.h +++ b/components/dom_distiller/content/browser/distillability_driver.h
@@ -12,6 +12,7 @@ #include "base/observer_list.h" #include "base/optional.h" #include "components/dom_distiller/content/browser/distillable_page_utils.h" +#include "components/dom_distiller/content/browser/uma_helper.h" #include "components/dom_distiller/content/common/mojom/distillability_service.mojom.h" #include "content/public/browser/web_contents_user_data.h" #include "mojo/public/cpp/bindings/pending_receiver.h" @@ -33,6 +34,8 @@ return latest_result_; } + UMAHelper::DistillabilityDriverTimer& GetTimer() { return timer_; } + private: explicit DistillabilityDriver(content::WebContents* web_contents); friend class content::WebContentsUserData<DistillabilityDriver>; @@ -48,6 +51,13 @@ // new page, accounting for same-document navigation. base::Optional<DistillabilityResult> latest_result_; + // For UMA metrics on durations spent in distilled or distillable pages. + // Because each DistillabilityDriver is associated with just one WebContents, + // it can be used to track the amount of time spent actively viewing that + // WebContents when the page is distillable or distilled, creating useful + // metrics for the ReaderMode experiment. + UMAHelper::DistillabilityDriverTimer timer_; + base::WeakPtrFactory<DistillabilityDriver> weak_factory_{this}; WEB_CONTENTS_USER_DATA_KEY_DECL();
diff --git a/components/dom_distiller/content/browser/uma_helper.cc b/components/dom_distiller/content/browser/uma_helper.cc new file mode 100644 index 0000000..fb3da6ab --- /dev/null +++ b/components/dom_distiller/content/browser/uma_helper.cc
@@ -0,0 +1,175 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/dom_distiller/content/browser/uma_helper.h" + +#include "base/metrics/histogram_functions.h" +#include "base/time/time.h" +#include "components/dom_distiller/content/browser/distillability_driver.h" +#include "content/public/browser/visibility.h" +#include "content/public/browser/web_contents.h" + +namespace dom_distiller { + +void UMAHelper::DistillabilityDriverTimer::Start(bool is_distilled_page) { + if (HasStarted()) + DCHECK_EQ(is_distilled_page_, is_distilled_page); + is_distilled_page_ = is_distilled_page; + if (active_time_start_ != base::Time()) + return; + active_time_start_ = base::Time::Now(); +} + +void UMAHelper::DistillabilityDriverTimer::Resume() { + DCHECK(HasStarted()); + if (active_time_start_ != base::Time()) + return; + active_time_start_ = base::Time::Now(); +} + +void UMAHelper::DistillabilityDriverTimer::Pause() { + // Return early if already paused. + if (active_time_start_ == base::Time()) + return; + total_active_time_ += base::Time::Now() - active_time_start_; + active_time_start_ = base::Time(); +} + +void UMAHelper::DistillabilityDriverTimer::Reset() { + active_time_start_ = base::Time(); + total_active_time_ = base::TimeDelta(); + is_distilled_page_ = false; +} + +bool UMAHelper::DistillabilityDriverTimer::HasStarted() { + return active_time_start_ != base::Time() || + total_active_time_ != base::TimeDelta(); +} + +bool UMAHelper::DistillabilityDriverTimer::IsTimingDistilledPage() { + return HasStarted() && is_distilled_page_; +} + +base::TimeDelta UMAHelper::DistillabilityDriverTimer::GetElapsedTime() { + // If the timer is unpaused, add in the current time too. + if (active_time_start_ != base::Time()) + return total_active_time_ + (base::Time::Now() - active_time_start_); + return total_active_time_; +} + +// static +void UMAHelper::RecordReaderModeEntry(ReaderModeEntryPoint entry_point) { + // Use histograms instead of user actions because order doesn't matter. + base::UmaHistogramEnumeration("DomDistiller.ReaderMode.EntryPoint", + entry_point); +} + +// static +void UMAHelper::RecordReaderModeExit(ReaderModeEntryPoint exit_point) { + // Use histograms instead of user actions because order doesn't matter. + base::UmaHistogramEnumeration("DomDistiller.ReaderMode.ExitPoint", + exit_point); +} + +// static +void UMAHelper::UpdateTimersOnContentsChange( + content::WebContents* web_contents, + content::WebContents* old_contents) { + if (old_contents && old_contents != web_contents) { + // Pause the timer on the the driver at the old contents. + DistillabilityDriver::CreateForWebContents(old_contents); + DistillabilityDriver* old_driver = + DistillabilityDriver::FromWebContents(old_contents); + CHECK(old_driver); + if (old_driver->GetTimer().HasStarted()) { + old_driver->GetTimer().Pause(); + } + } + + CHECK(web_contents); + DistillabilityDriver::CreateForWebContents(web_contents); + DistillabilityDriver* driver = + DistillabilityDriver::FromWebContents(web_contents); + CHECK(driver); + + // If we were already timing the new page, pause or resume as necessary. + if (!driver->GetTimer().HasStarted()) + return; + + if (web_contents->GetVisibility() != content::Visibility::VISIBLE) { + // Pause any running timer if the web contents are no longer visible. + driver->GetTimer().Pause(); + return; + } + // Resume the driver's timer when contents have come back into focus. + driver->GetTimer().Resume(); +} + +// static +void UMAHelper::StartTimerIfNeeded(content::WebContents* web_contents, + ReaderModePageType page_type) { + CHECK(web_contents); + DistillabilityDriver::CreateForWebContents(web_contents); + DistillabilityDriver* driver = + DistillabilityDriver::FromWebContents(web_contents); + CHECK(driver); + + if (page_type == ReaderModePageType::kDistilled) { + // If this is a distilled page, ensure the timer is running. + driver->GetTimer().Start(/* is_distilled_page */ true); + } else if (page_type == ReaderModePageType::kDistillable) { + // If we are on a distillable page, ensure the timer is running. + driver->GetTimer().Start(false); + } +} + +// static +void UMAHelper::UpdateTimersOnNavigation(content::WebContents* web_contents, + ReaderModePageType page_type) { + CHECK(web_contents); + DistillabilityDriver::CreateForWebContents(web_contents); + DistillabilityDriver* driver = + DistillabilityDriver::FromWebContents(web_contents); + CHECK(driver); + + if (!driver->GetTimer().HasStarted()) + return; + + // Stop timing distilled pages when a user navigates away. (Note that + // distillable pages are logged only when reader mode is triggered, so there + // is no need to log time on a distillable page at navigation. + if (driver->GetTimer().IsTimingDistilledPage()) + LogTimeOnDistilledPage(driver->GetTimer().GetElapsedTime()); + driver->GetTimer().Reset(); +} + +// static +void UMAHelper::LogTimeOnDistillablePage(content::WebContents* web_contents) { + CHECK(web_contents); + DistillabilityDriver::CreateForWebContents(web_contents); + DistillabilityDriver* driver = + DistillabilityDriver::FromWebContents(web_contents); + CHECK(driver); + + // TODO(crbug.com/1061928): Check that the timer has started before logging. + // This is currently causing tests to fail, but they can begin passing if they + // add DistillabilityObservers and wait for DistillabilityResults before + // trying to toggle from a distillable to a distilled page. + // DCHECK(driver->GetTimer().HasStarted()); + + // We shouldn't log time on a distillable page if this is a distilled page. + DCHECK(!driver->GetTimer().IsTimingDistilledPage()); + + base::UmaHistogramLongTimes( + "DomDistiller.Time.ActivelyViewingArticleBeforeDistilling", + driver->GetTimer().GetElapsedTime()); + driver->GetTimer().Reset(); +} + +void UMAHelper::LogTimeOnDistilledPage(base::TimeDelta time) { + base::UmaHistogramLongTimes("DomDistiller.Time.ActivelyViewingReaderModePage", + time); +} + +} // namespace dom_distiller
diff --git a/components/dom_distiller/content/browser/uma_helper.h b/components/dom_distiller/content/browser/uma_helper.h new file mode 100644 index 0000000..c144ff41 --- /dev/null +++ b/components/dom_distiller/content/browser/uma_helper.h
@@ -0,0 +1,103 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_UMA_HELPER_H_ +#define COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_UMA_HELPER_H_ + +#include "base/macros.h" +#include "base/time/time.h" + +namespace content { +class WebContents; +} // namespace content + +namespace dom_distiller { + +// A utility class for logging UMA metrics. +class UMAHelper { + public: + // Must agree with ReaderModeEntryPoint in enums.xml. + enum class ReaderModeEntryPoint { + kOmniboxIcon = 0, + kMenuOption = 1, + kMaxValue = kMenuOption, + }; + + // A page can be distillable (an article), distilled (a reader mode + // page), or neither (some other webpage). + enum class ReaderModePageType { + kDistillable, + kDistilled, + kNone, + }; + + // A class to time the active time of a page, so that metrics for time spent + // on distillable pages and distilled pages can be logged. There should be + // exactly one of these associated with each DistillabilityDriver. + class DistillabilityDriverTimer { + public: + DistillabilityDriverTimer() = default; + + ~DistillabilityDriverTimer() { + // The timer has the same life as a DistillabilityDriver, which is + // destroyed when a WebContents is destroyed. Thus if we are being + // destroyed and on a distilled page, go ahead and log the total time to + // UMA. This may happen if the user closes the tab or window, for example. + if (IsTimingDistilledPage()) + UMAHelper::LogTimeOnDistilledPage(GetElapsedTime()); + } + + // Starts if not already started. + void Start(bool is_distilled_page); + // Starts up again. + void Resume(); + // Pauses if not already paused. + void Pause(); + // Resets the timer and whether it is tracking a distilled page. + void Reset(); + // Returns true if the timer is not zeroed, whether it is paused or + // currently running. + bool HasStarted(); + // If the timer is not zeroed and the timer is associated with a distilled + // page. + bool IsTimingDistilledPage(); + // The amount of active time so far. + base::TimeDelta GetElapsedTime(); + + private: + base::TimeDelta total_active_time_; + base::Time active_time_start_; + bool is_distilled_page_ = false; + }; + + static void RecordReaderModeEntry(ReaderModeEntryPoint entry_point); + static void RecordReaderModeExit(ReaderModeEntryPoint exit_point); + + // Timers at the old contents may need to be stopped / paused. + static void UpdateTimersOnContentsChange(content::WebContents* web_contents, + content::WebContents* old_contents); + // Starts the timer if the page time is one which should be timed. + static void StartTimerIfNeeded(content::WebContents* web_contents, + ReaderModePageType page_type); + // Timers may need to be paused on navigation. + static void UpdateTimersOnNavigation(content::WebContents* web_contents, + ReaderModePageType page_type); + + // Logs the time spent on a distillable page. Should be called just before + // when switching to a distilled page. We are only interested in time on + // distillable pages when the user then decides to distill the article. + static void LogTimeOnDistillablePage(content::WebContents* web_contents); + + // Logs the time spent on a distilled (reader mode) page. Should be called + // when leaving a distilled page, i.e. if the tab is closed or if the user + // navigates to another page. + static void LogTimeOnDistilledPage(base::TimeDelta time); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(UMAHelper); +}; + +} // namespace dom_distiller + +#endif // COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_UMA_HELPER_H_
diff --git a/components/dom_distiller/content/browser/uma_helper_unittest.cc b/components/dom_distiller/content/browser/uma_helper_unittest.cc new file mode 100644 index 0000000..417154f --- /dev/null +++ b/components/dom_distiller/content/browser/uma_helper_unittest.cc
@@ -0,0 +1,116 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/dom_distiller/content/browser/uma_helper.h" +#include <string> + +#include "base/macros.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace dom_distiller { + +namespace { +const std::string kDistilledPageHistogram = + "DomDistiller.Time.ActivelyViewingReaderModePage"; +} // namespace + +class UMAHelperTest : public testing::Test { + public: + void FastForwardBy(int milliseconds) { + task_environment_.FastForwardBy( + base::TimeDelta::FromMilliseconds(milliseconds)); + } + + protected: + base::test::TaskEnvironment task_environment_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; +}; + +TEST_F(UMAHelperTest, TestTimerBasics) { + UMAHelper::DistillabilityDriverTimer timer; + ASSERT_FALSE(timer.HasStarted()); + timer.Start(false); + ASSERT_FALSE(timer.IsTimingDistilledPage()); + ASSERT_TRUE(timer.HasStarted()); + + FastForwardBy(100); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 100); + FastForwardBy(100); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 200); + + // After pausing, the timer should still be running (active), and the + // value should be unchanged. + timer.Pause(); + ASSERT_TRUE(timer.HasStarted()); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 200); + // Paused timer shouldn't increase value when time changes. + FastForwardBy(100); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 200); + + // Starting the timer again will cause it to move forward again as time + // changes. + timer.Start(false); + ASSERT_TRUE(timer.HasStarted()); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 200); + FastForwardBy(100); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 300); + + // Pause again, but this time continue with Resume instead of Start. This + // should have the same effect. + timer.Pause(); + FastForwardBy(100); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 300); + timer.Resume(); + FastForwardBy(100); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 400); + + // Calling start or pause multiple times in a row does not break anything. + timer.Start(false); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 400); + FastForwardBy(100); + timer.Start(false); + timer.Start(false); + timer.Resume(); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 500); + timer.Pause(); + timer.Pause(); + ASSERT_EQ(timer.GetElapsedTime().InMilliseconds(), 500); + + // Reset the timer. + timer.Reset(); + ASSERT_FALSE(timer.HasStarted()); +} + +TEST_F(UMAHelperTest, TestTimerForDistilledPage) { + UMAHelper::DistillabilityDriverTimer* timer = + new UMAHelper::DistillabilityDriverTimer(); + base::HistogramTester histogram_tester; + + timer->Start(true); + ASSERT_TRUE(timer->HasStarted()); + ASSERT_TRUE(timer->IsTimingDistilledPage()); + FastForwardBy(100); + ASSERT_EQ(timer->GetElapsedTime().InMilliseconds(), 100); + timer->Start(true); + ASSERT_EQ(timer->GetElapsedTime().InMilliseconds(), 100); + + // Destroy the timer. Since it was running and on a distilled page, expect + // logging to have happened. + delete timer; + histogram_tester.ExpectTimeBucketCount( + kDistilledPageHistogram, base::TimeDelta::FromMilliseconds(100), 1); + + // Nothing is logged if it wasn't destroyed while on a distilled page. + timer = new UMAHelper::DistillabilityDriverTimer(); + timer->Start(false); + FastForwardBy(200); + delete timer; + histogram_tester.ExpectTimeBucketCount( + kDistilledPageHistogram, base::TimeDelta::FromMilliseconds(200), 0); +} + +} // namespace dom_distiller
diff --git a/components/dom_distiller/core/BUILD.gn b/components/dom_distiller/core/BUILD.gn index a956479..d70bbd2 100644 --- a/components/dom_distiller/core/BUILD.gn +++ b/components/dom_distiller/core/BUILD.gn
@@ -43,8 +43,6 @@ "pref_names.h", "task_tracker.cc", "task_tracker.h", - "uma_helper.cc", - "uma_helper.h", "url_constants.cc", "url_constants.h", "url_utils.cc",
diff --git a/components/dom_distiller/core/uma_helper.cc b/components/dom_distiller/core/uma_helper.cc deleted file mode 100644 index 66fefc3c..0000000 --- a/components/dom_distiller/core/uma_helper.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/dom_distiller/core/uma_helper.h" - -#include "base/metrics/histogram_functions.h" - -namespace dom_distiller { - -// static -void UMAHelper::RecordReaderModeEntry(ReaderModeEntryPoint entry_point) { - // Use histograms instead of user actions because order doesn't matter. - base::UmaHistogramEnumeration("DomDistiller.ReaderMode.EntryPoint", - entry_point); -} - -// static -void UMAHelper::RecordReaderModeExit(ReaderModeEntryPoint exit_point) { - // Use histograms instead of user actions because order doesn't matter. - base::UmaHistogramEnumeration("DomDistiller.ReaderMode.ExitPoint", - exit_point); -} - -} // namespace dom_distiller
diff --git a/components/dom_distiller/core/uma_helper.h b/components/dom_distiller/core/uma_helper.h deleted file mode 100644 index cd85416..0000000 --- a/components/dom_distiller/core/uma_helper.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DOM_DISTILLER_CORE_UMA_HELPER_H_ -#define COMPONENTS_DOM_DISTILLER_CORE_UMA_HELPER_H_ - -#include "base/macros.h" - -namespace dom_distiller { - -// A utility class for logging UMA metrics. -class UMAHelper { - public: - // Must agree with ReaderModeEntryPoint in enums.xml. - enum class ReaderModeEntryPoint { - kOmniboxIcon = 0, - kMenuOption = 1, - kMaxValue = kMenuOption, - }; - - static void RecordReaderModeEntry(ReaderModeEntryPoint entry_point); - static void RecordReaderModeExit(ReaderModeEntryPoint exit_point); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(UMAHelper); -}; - -} // namespace dom_distiller - -#endif // COMPONENTS_DOM_DISTILLER_CORE_UMA_HELPER_H_
diff --git a/components/exo/wayland/clients/client_base.cc b/components/exo/wayland/clients/client_base.cc index aa6c0ccc..843bc27 100644 --- a/components/exo/wayland/clients/client_base.cc +++ b/components/exo/wayland/clients/client_base.cc
@@ -374,6 +374,7 @@ LOG(ERROR) << "Invalid value for " << switches::kTransform; return false; } + has_transform = true; } use_drm = command_line.HasSwitch(switches::kUseDrm); @@ -429,6 +430,7 @@ fullscreen_ = params.fullscreen; transparent_background_ = params.transparent_background; y_invert_ = params.y_invert; + has_transform_ = params.has_transform; display_.reset(wl_display_connect(nullptr)); if (!display_) { @@ -751,7 +753,29 @@ int32_t subpixel, const char* make, const char* model, - int32_t transform) {} + int32_t transform) { + if (has_transform_) + return; + // |transform| describes the display transform. In order to take advantage of + // hardware overlays, content needs to be rotated in the opposite direction to + // show right-side up on the display. + switch (transform) { + case WL_OUTPUT_TRANSFORM_90: + transform_ = WL_OUTPUT_TRANSFORM_270; + break; + case WL_OUTPUT_TRANSFORM_270: + transform_ = WL_OUTPUT_TRANSFORM_90; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + transform_ = WL_OUTPUT_TRANSFORM_FLIPPED_270; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + transform_ = WL_OUTPUT_TRANSFORM_FLIPPED_90; + break; + default: + transform_ = transform; + } +} void ClientBase::HandleMode(void* data, struct wl_output* wl_output,
diff --git a/components/exo/wayland/clients/client_base.h b/components/exo/wayland/clients/client_base.h index 4e4b192..0b4c2c26 100644 --- a/components/exo/wayland/clients/client_base.h +++ b/components/exo/wayland/clients/client_base.h
@@ -48,6 +48,7 @@ size_t height = 256; int scale = 1; int transform = WL_OUTPUT_TRANSFORM_NORMAL; + bool has_transform = false; bool fullscreen = false; bool transparent_background = false; bool use_drm = false; @@ -179,6 +180,7 @@ gfx::Size size_ = gfx::Size(256, 256); int scale_ = 1; int transform_ = WL_OUTPUT_TRANSFORM_NORMAL; + bool has_transform_ = false; gfx::Size surface_size_ = gfx::Size(256, 256); bool fullscreen_ = false; bool use_memfd_ = false;
diff --git a/components/history/core/browser/web_history_service.cc b/components/history/core/browser/web_history_service.cc index 341280f..bfd7569 100644 --- a/components/history/core/browser/web_history_service.cc +++ b/components/history/core/browser/web_history_service.cc
@@ -64,19 +64,6 @@ const char kSyncProtoMimeType[] = "application/octet-stream"; -const char kQueryWebAndAppActivityStateHistogramName[] = - "WebHistory.QueryWebAndAppActivity.State"; - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class QueryWebAndAppActivityState { - kOn = 0, - kOff = 1, - kRequestFailed = 2, - kUnexpectedResponse = 3, - kMaxValue = kUnexpectedResponse, -}; - // The maximum number of retries for the SimpleURLLoader requests. const size_t kMaxRetries = 1; @@ -540,30 +527,6 @@ request->Start(); } -// static -std::unique_ptr<history::WebHistoryService::Request> -WebHistoryService::CreateQueryWebAndAppActivityRequest( - signin::IdentityManager* identity_manager, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - QueryWebAndAppActivityWithRequestCallback callback, - const net::PartialNetworkTrafficAnnotationTag& partial_traffic_annotation) { - CompletionCallback completion_callback = base::BindOnce( - [](QueryWebAndAppActivityWithRequestCallback callback, - WebHistoryService::Request* request, bool success) { - std::move(callback).Run( - request, - WebHistoryService::ReportQueryWebAndAppActivity(request, success)); - }, - std::move(callback)); - - GURL url(kQueryWebAndAppActivityUrl); - std::unique_ptr<history::WebHistoryService::Request> request = - base::WrapUnique(new RequestImpl(identity_manager, url_loader_factory, - url, std::move(completion_callback), - partial_traffic_annotation)); - return request; -} - void WebHistoryService::QueryOtherFormsOfBrowsingHistory( version_info::Channel channel, QueryOtherFormsOfBrowsingHistoryCallback callback, @@ -666,7 +629,18 @@ std::move(pending_web_and_app_activity_requests_[request]); pending_web_and_app_activity_requests_.erase(request); - std::move(callback).Run(ReportQueryWebAndAppActivity(request, success)); + std::unique_ptr<base::DictionaryValue> response_value; + bool web_and_app_activity_enabled = false; + + if (success) { + response_value = ReadResponse(request); + if (response_value) { + response_value->GetBoolean("history_recording_enabled", + &web_and_app_activity_enabled); + } + } + + std::move(callback).Run(web_and_app_activity_enabled); } void WebHistoryService::QueryOtherFormsOfBrowsingHistoryCompletionCallback( @@ -687,29 +661,4 @@ std::move(callback).Run(has_other_forms_of_browsing_history); } -// static -base::Optional<bool> WebHistoryService::ReportQueryWebAndAppActivity( - WebHistoryService::Request* request, - bool success) { - if (success) { - std::unique_ptr<base::DictionaryValue> response_value; - response_value = ReadResponse(request); - bool web_and_app_activity_enabled = false; - if (response_value && - response_value->GetBoolean("history_recording_enabled", - &web_and_app_activity_enabled)) { - UMA_HISTOGRAM_ENUMERATION(kQueryWebAndAppActivityStateHistogramName, - web_and_app_activity_enabled - ? QueryWebAndAppActivityState::kOn - : QueryWebAndAppActivityState::kOff); - return web_and_app_activity_enabled; - } - } - UMA_HISTOGRAM_ENUMERATION( - kQueryWebAndAppActivityStateHistogramName, - success ? QueryWebAndAppActivityState::kUnexpectedResponse - : QueryWebAndAppActivityState::kRequestFailed); - return base::nullopt; -} - } // namespace history
diff --git a/components/history/core/browser/web_history_service.h b/components/history/core/browser/web_history_service.h index 18b0036..a7acd29 100644 --- a/components/history/core/browser/web_history_service.h +++ b/components/history/core/browser/web_history_service.h
@@ -89,12 +89,7 @@ using AudioWebHistoryCallback = base::OnceCallback<void(bool success, bool new_enabled_value)>; - using QueryWebAndAppActivityCallback = base::OnceCallback<void( - const base::Optional<bool>& history_recording_enabled)>; - - using QueryWebAndAppActivityWithRequestCallback = base::OnceCallback<void( - WebHistoryService::Request* request, - const base::Optional<bool>& history_recording_enabled)>; + using QueryWebAndAppActivityCallback = base::OnceCallback<void(bool success)>; using QueryOtherFormsOfBrowsingHistoryCallback = base::OnceCallback<void(bool success)>; @@ -157,18 +152,6 @@ const net::PartialNetworkTrafficAnnotationTag& partial_traffic_annotation); - // Returns a request to query whether web and app activity is enabled on the - // server. The request can be made independently from sync state. The caller - // must make sure that the |identity_manager| outlives the returned request - // object. - static std::unique_ptr<history::WebHistoryService::Request> - CreateQueryWebAndAppActivityRequest( - signin::IdentityManager* identity_manager, - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - QueryWebAndAppActivityWithRequestCallback callback, - const net::PartialNetworkTrafficAnnotationTag& - partial_traffic_annotation); - // Used for tests. size_t GetNumberOfPendingAudioHistoryRequests(); @@ -228,18 +211,13 @@ // completed. Unpacks the response and calls |callback|, which is the original // callback that was passed to QueryOtherFormsOfBrowsingHistory(). void QueryOtherFormsOfBrowsingHistoryCompletionCallback( - WebHistoryService::QueryOtherFormsOfBrowsingHistoryCallback callback, + WebHistoryService::QueryWebAndAppActivityCallback callback, WebHistoryService::Request* request, bool success); private: friend class WebHistoryServiceTest; - // Extracts from the request's response if history recording is enabled. - static base::Optional<bool> ReportQueryWebAndAppActivity( - WebHistoryService::Request* request, - bool success); - // Stores pointer to IdentityManager instance. It must outlive the // WebHistoryService and can be null during tests. signin::IdentityManager* identity_manager_;
diff --git a/components/media_message_center/media_notification_controller.h b/components/media_message_center/media_notification_controller.h index 7fdbcdb..344bf9e 100644 --- a/components/media_message_center/media_notification_controller.h +++ b/components/media_message_center/media_notification_controller.h
@@ -8,6 +8,7 @@ #include <string> #include "base/component_export.h" +#include "services/media_session/public/mojom/media_session.mojom.h" template <typename T> class scoped_refptr; @@ -37,7 +38,9 @@ // Notifies the MediaNotificationController that a media button was pressed on // the MediaNotificationView. - virtual void LogMediaSessionActionButtonPressed(const std::string& id) = 0; + virtual void LogMediaSessionActionButtonPressed( + const std::string& id, + media_session::mojom::MediaSessionAction action) = 0; protected: virtual ~MediaNotificationController() = default;
diff --git a/components/media_message_center/media_notification_view_impl_unittest.cc b/components/media_message_center/media_notification_view_impl_unittest.cc index 9f331c3..4815360f 100644 --- a/components/media_message_center/media_notification_view_impl_unittest.cc +++ b/components/media_message_center/media_notification_view_impl_unittest.cc
@@ -80,7 +80,9 @@ scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override { return nullptr; } - MOCK_METHOD1(LogMediaSessionActionButtonPressed, void(const std::string& id)); + MOCK_METHOD2(LogMediaSessionActionButtonPressed, + void(const std::string& id, + media_session::mojom::MediaSessionAction action)); private: DISALLOW_COPY_AND_ASSIGN(MockMediaNotificationController); @@ -449,7 +451,8 @@ } TEST_F(MAYBE_MediaNotificationViewImplTest, NextTrackButtonClick) { - EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(_)); + EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed( + _, MediaSessionAction::kNextTrack)); EnableAction(MediaSessionAction::kNextTrack); EXPECT_EQ(0, media_controller()->next_track_count()); @@ -462,7 +465,8 @@ } TEST_F(MAYBE_MediaNotificationViewImplTest, PlayButtonClick) { - EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(_)); + EXPECT_CALL(controller(), + LogMediaSessionActionButtonPressed(_, MediaSessionAction::kPlay)); EnableAction(MediaSessionAction::kPlay); EXPECT_EQ(0, media_controller()->resume_count()); @@ -475,7 +479,8 @@ } TEST_F(MAYBE_MediaNotificationViewImplTest, PauseButtonClick) { - EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(_)); + EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed( + _, MediaSessionAction::kPause)); EnableAction(MediaSessionAction::kPause); EXPECT_CALL(container(), OnMediaSessionInfoChanged(_)); @@ -496,7 +501,8 @@ } TEST_F(MAYBE_MediaNotificationViewImplTest, PreviousTrackButtonClick) { - EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(_)); + EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed( + _, MediaSessionAction::kPreviousTrack)); EnableAction(MediaSessionAction::kPreviousTrack); EXPECT_EQ(0, media_controller()->previous_track_count()); @@ -509,7 +515,8 @@ } TEST_F(MAYBE_MediaNotificationViewImplTest, SeekBackwardButtonClick) { - EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(_)); + EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed( + _, MediaSessionAction::kSeekBackward)); EnableAction(MediaSessionAction::kSeekBackward); EXPECT_EQ(0, media_controller()->seek_backward_count()); @@ -522,7 +529,8 @@ } TEST_F(MAYBE_MediaNotificationViewImplTest, SeekForwardButtonClick) { - EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed(_)); + EXPECT_CALL(controller(), LogMediaSessionActionButtonPressed( + _, MediaSessionAction::kSeekForward)); EnableAction(MediaSessionAction::kSeekForward); EXPECT_EQ(0, media_controller()->seek_forward_count());
diff --git a/components/media_message_center/media_session_notification_item.cc b/components/media_message_center/media_session_notification_item.cc index 3cfe476..88d5f4c 100644 --- a/components/media_message_center/media_session_notification_item.cc +++ b/components/media_message_center/media_session_notification_item.cc
@@ -155,7 +155,7 @@ if (frozen_) return; - controller_->LogMediaSessionActionButtonPressed(request_id_); + controller_->LogMediaSessionActionButtonPressed(request_id_, action); media_session::PerformMediaSessionAction(action, media_controller_remote_); }
diff --git a/components/new_or_sad_tab_strings.grdp b/components/new_or_sad_tab_strings.grdp index 270a8ed..d33b2dc 100644 --- a/components/new_or_sad_tab_strings.grdp +++ b/components/new_or_sad_tab_strings.grdp
@@ -174,7 +174,7 @@ Block third-party cookies </message> <message name="IDS_NEW_TAB_OTR_THIRD_PARTY_COOKIE_SUBLABEL" desc="A sub-label below the Block 3rd-party cookie checkbox." formatter_data="android_java"> - When on, sites can’t use your browsing activity across different sites to personalize ads. Features on some sites may break. + When on, sites can't use cookies that track you across the web. Features on some sites may break. </message> </grit-part>
diff --git a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_OTR_THIRD_PARTY_COOKIE_SUBLABEL.png.sha1 b/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_OTR_THIRD_PARTY_COOKIE_SUBLABEL.png.sha1 index a2ca154..47d8a4f 100644 --- a/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_OTR_THIRD_PARTY_COOKIE_SUBLABEL.png.sha1 +++ b/components/new_or_sad_tab_strings_grdp/IDS_NEW_TAB_OTR_THIRD_PARTY_COOKIE_SUBLABEL.png.sha1
@@ -1 +1 @@ -5e55b66b9d0bbf98a85ff7ecfc246ed18d79f986 \ No newline at end of file +9bb944c2ad3e4319e18666958944710b6bbb801a \ No newline at end of file
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc index ae1666c..0fccdcc3 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc +++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -50,8 +50,7 @@ } UserInitiatedInfo CreateUserInitiatedInfo( - content::NavigationHandle* navigation_handle, - PageLoadTracker* committed_load) { + content::NavigationHandle* navigation_handle) { if (!navigation_handle->IsRendererInitiated()) return UserInitiatedInfo::BrowserInitiated(); @@ -181,7 +180,7 @@ void MetricsWebContentsObserver::WillStartNavigationRequestImpl( content::NavigationHandle* navigation_handle) { UserInitiatedInfo user_initiated_info( - CreateUserInitiatedInfo(navigation_handle, committed_load_.get())); + CreateUserInitiatedInfo(navigation_handle)); std::unique_ptr<PageLoadTracker> last_aborted = NotifyAbortedProvisionalLoadsNewNavigation(navigation_handle, user_initiated_info); @@ -198,7 +197,7 @@ chain_size = last_aborted->aborted_chain_size() + 1; } - if (!ShouldTrackNavigation(navigation_handle)) + if (!ShouldTrackMainFrameNavigation(navigation_handle)) return; // Pass in the last committed url to the PageLoadTracker. If the MWCO has @@ -412,15 +411,15 @@ // ensure it is set consistently for all navigations. has_navigated_ = true; - std::unique_ptr<PageLoadTracker> finished_nav( + std::unique_ptr<PageLoadTracker> navigation_handle_tracker( std::move(provisional_loads_[navigation_handle])); provisional_loads_.erase(navigation_handle); // Ignore same-document navigations. if (navigation_handle->HasCommitted() && navigation_handle->IsSameDocument()) { - if (finished_nav) - finished_nav->StopTracking(); + if (navigation_handle_tracker) + navigation_handle_tracker->StopTracking(); if (committed_load_) committed_load_->DidCommitSameDocumentNavigation(navigation_handle); return; @@ -431,41 +430,35 @@ if (!navigation_handle->HasCommitted() && navigation_handle->GetNetErrorCode() == net::ERR_ABORTED && navigation_handle->GetResponseHeaders()) { - if (finished_nav) { - finished_nav->DidInternalNavigationAbort(navigation_handle); - finished_nav->StopTracking(); + if (navigation_handle_tracker) { + navigation_handle_tracker->DidInternalNavigationAbort(navigation_handle); + navigation_handle_tracker->StopTracking(); } return; } - const bool should_track = - finished_nav && ShouldTrackNavigation(navigation_handle); + if (navigation_handle->HasCommitted()) { + // A new navigation is committing, so finalize and destroy the tracker for + // the currently committed navigation. + FinalizeCurrentlyCommittedLoad(navigation_handle, + navigation_handle_tracker.get()); + committed_load_.reset(); + } - if (finished_nav && !should_track) - finished_nav->StopTracking(); + if (!navigation_handle_tracker) + return; + + if (!ShouldTrackMainFrameNavigation(navigation_handle)) { + navigation_handle_tracker->StopTracking(); + return; + } if (navigation_handle->HasCommitted()) { - UserInitiatedInfo user_initiated_info = - finished_nav - ? finished_nav->user_initiated_info() - : CreateUserInitiatedInfo(navigation_handle, committed_load_.get()); - - // Notify other loads that they may have been aborted by this committed - // load. is_certainly_browser_timestamp is set to false because - // NavigationStart() could be set in either the renderer or browser process. - NotifyPageEndAllLoadsWithTimestamp( - EndReasonForPageTransition(navigation_handle->GetPageTransition()), - user_initiated_info, navigation_handle->NavigationStart(), false); - - if (should_track) { - HandleCommittedNavigationForTrackedLoad(navigation_handle, - std::move(finished_nav)); - } else { - committed_load_.reset(); - } - } else if (should_track) { + HandleCommittedNavigationForTrackedLoad( + navigation_handle, std::move(navigation_handle_tracker)); + } else { HandleFailedNavigationForTrackedLoad(navigation_handle, - std::move(finished_nav)); + std::move(navigation_handle_tracker)); } } @@ -500,15 +493,6 @@ void MetricsWebContentsObserver::HandleCommittedNavigationForTrackedLoad( content::NavigationHandle* navigation_handle, std::unique_ptr<PageLoadTracker> tracker) { - if (!IsNavigationUserInitiated(navigation_handle) && - (navigation_handle->GetPageTransition() & - ui::PAGE_TRANSITION_CLIENT_REDIRECT) != 0 && - committed_load_) { - // TODO(bmcquade): consider carrying the user_gesture bit forward to the - // redirected navigation. - committed_load_->NotifyClientRedirectTo(*tracker); - } - committed_load_ = std::move(tracker); committed_load_->Commit(navigation_handle); DCHECK(committed_load_->did_commit()); @@ -517,6 +501,34 @@ observer.OnCommit(committed_load_.get()); } +void MetricsWebContentsObserver::FinalizeCurrentlyCommittedLoad( + content::NavigationHandle* newly_committed_navigation, + PageLoadTracker* newly_committed_navigation_tracker) { + UserInitiatedInfo user_initiated_info = + newly_committed_navigation_tracker + ? newly_committed_navigation_tracker->user_initiated_info() + : CreateUserInitiatedInfo(newly_committed_navigation); + + // Notify other loads that they may have been aborted by this committed + // load. is_certainly_browser_timestamp is set to false because + // NavigationStart() could be set in either the renderer or browser process. + NotifyPageEndAllLoadsWithTimestamp( + EndReasonForPageTransition( + newly_committed_navigation->GetPageTransition()), + user_initiated_info, newly_committed_navigation->NavigationStart(), + /*is_certainly_browser_timestamp=*/false); + + if (committed_load_) { + bool is_non_user_initiated_client_redirect = + !IsNavigationUserInitiated(newly_committed_navigation) && + (newly_committed_navigation->GetPageTransition() & + ui::PAGE_TRANSITION_CLIENT_REDIRECT) != 0; + if (is_non_user_initiated_client_redirect) { + committed_load_->NotifyClientRedirectTo(newly_committed_navigation); + } + } +} + void MetricsWebContentsObserver::NavigationStopped() { // TODO(csharrison): Use a more user-initiated signal for STOP. NotifyPageEndAllLoads(END_STOP, UserInitiatedInfo::NotUserInitiated()); @@ -617,7 +629,8 @@ PageEndReason page_end_reason, UserInitiatedInfo user_initiated_info) { NotifyPageEndAllLoadsWithTimestamp(page_end_reason, user_initiated_info, - base::TimeTicks::Now(), true); + base::TimeTicks::Now(), + /*is_certainly_browser_timestamp=*/true); } void MetricsWebContentsObserver::NotifyPageEndAllLoadsWithTimestamp( @@ -743,7 +756,7 @@ std::move(cpu_timing), std::move(new_deferred_resource_data)); } -bool MetricsWebContentsObserver::ShouldTrackNavigation( +bool MetricsWebContentsObserver::ShouldTrackMainFrameNavigation( content::NavigationHandle* navigation_handle) const { DCHECK(navigation_handle->IsInMainFrame()); DCHECK(!navigation_handle->HasCommitted() ||
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.h b/components/page_load_metrics/browser/metrics_web_contents_observer.h index 6b36c86..fe68929 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer.h +++ b/components/page_load_metrics/browser/metrics_web_contents_observer.h
@@ -195,6 +195,10 @@ content::NavigationHandle* navigation_handle, std::unique_ptr<PageLoadTracker> tracker); + void FinalizeCurrentlyCommittedLoad( + content::NavigationHandle* newly_committed_navigation, + PageLoadTracker* newly_committed_navigation_tracker); + // Return a PageLoadTracker (either provisional or committed) that matches the // given request attributes, or nullptr if there are no matching // PageLoadTrackers. @@ -225,8 +229,9 @@ content::NavigationHandle* new_navigation, UserInitiatedInfo user_initiated_info); - // Whether metrics should be tracked for the navigation. - bool ShouldTrackNavigation( + // Whether metrics should be tracked, and a PageLoadTracker should be created, + // for the given main frame navigation. + bool ShouldTrackMainFrameNavigation( content::NavigationHandle* navigation_handle) const; void OnBrowserFeatureUsage(content::RenderFrameHost* render_frame_host,
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc index 6d4a16b..2cc2d86 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc +++ b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
@@ -22,12 +22,13 @@ #include "content/public/test/navigation_simulator.h" #include "content/public/test/render_frame_host_test_support.h" #include "content/public/test/test_renderer_host.h" -#include "content/public/test/web_contents_tester.h" #include "net/base/net_errors.h" +#include "net/cert/cert_status_flags.h" #include "services/network/public/mojom/fetch_api.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h" +#include "url/url_constants.h" using content::NavigationSimulator; @@ -87,9 +88,10 @@ content::SetBrowserClientForTesting(original_browser_client_); RenderViewHostTestHarness::TearDown(); } + void NavigateToUntrackedUrl() { - content::WebContentsTester::For(web_contents()) - ->NavigateAndCommit(GURL(url::kAboutBlankURL)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(url::kAboutBlankURL)); } // Returns the mock timer used for buffering updates in the @@ -240,12 +242,10 @@ page_load_metrics::InitPageLoadTimingForTest(&timing); timing.navigation_start = base::Time::FromDoubleT(1); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - ASSERT_TRUE(observed_committed_urls_from_on_start().empty()); ASSERT_FALSE(is_first_navigation_in_web_contents().has_value()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_EQ(1u, observed_committed_urls_from_on_start().size()); ASSERT_TRUE(observed_committed_urls_from_on_start().at(0).is_empty()); ASSERT_TRUE(is_first_navigation_in_web_contents().has_value()); @@ -256,7 +256,8 @@ ASSERT_EQ(1, CountUpdatedTimingReported()); ASSERT_EQ(0, CountCompleteTimingReported()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); ASSERT_FALSE(is_first_navigation_in_web_contents().value()); ASSERT_EQ(1, CountCompleteTimingReported()); ASSERT_EQ(0, CountEmptyCompleteTimingReported()); @@ -271,10 +272,10 @@ TEST_F(MetricsWebContentsObserverTest, DISABLED_MainFrameNavigationInternalAbort) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndFail( - GURL(kDefaultTestUrl), net::ERR_ABORTED, + auto navigation = content::NavigationSimulator::CreateBrowserInitiated( + GURL(kDefaultTestUrl), web_contents()); + navigation->FailWithResponseHeaders( + net::ERR_ABORTED, base::MakeRefCounted<net::HttpResponseHeaders>("some_headers")); ASSERT_EQ(1u, observed_aborted_urls().size()); ASSERT_EQ(kDefaultTestUrl, observed_aborted_urls().front().spec()); @@ -287,9 +288,8 @@ timing.response_start = base::TimeDelta::FromMilliseconds(10); timing.parse_timing->parse_start = base::TimeDelta::FromMilliseconds(20); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); ASSERT_EQ(1, CountUpdatedTimingReported()); @@ -322,7 +322,8 @@ EXPECT_TRUE(updated_timings().back()->paint_timing->first_paint); // Navigate again to see if the timing updated for a subframe message. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); ASSERT_EQ(1, CountCompleteTimingReported()); ASSERT_EQ(2, CountUpdatedTimingReported()); @@ -339,13 +340,13 @@ page_load_metrics::InitPageLoadTimingForTest(&timing); timing.navigation_start = base::Time::FromDoubleT(1); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_EQ(0, CountUpdatedTimingReported()); SimulateTimingUpdate(timing); ASSERT_EQ(1, CountUpdatedTimingReported()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrlAnchor)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrlAnchor)); // Send the same timing update. The original tracker for kDefaultTestUrl // should dedup the update, and the tracker for kDefaultTestUrlAnchor should // have been destroyed as a result of its being a same page navigation, so @@ -356,7 +357,8 @@ ASSERT_EQ(0, CountCompleteTimingReported()); // Navigate again to force histogram logging. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); // A same page navigation shouldn't trigger logging UMA for the original. ASSERT_EQ(1, CountUpdatedTimingReported()); @@ -370,20 +372,21 @@ page_load_metrics::InitPageLoadTimingForTest(&timing); timing.navigation_start = base::Time::FromDoubleT(1); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); embedder_interface_->set_is_ntp(true); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); ASSERT_EQ(0, CountUpdatedTimingReported()); ASSERT_EQ(0, CountCompleteTimingReported()); // Ensure that NTP and other untracked loads are still accounted for as part // of keeping track of the first navigation in the WebContents. embedder_interface_->set_is_ntp(false); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_TRUE(is_first_navigation_in_web_contents().has_value()); ASSERT_FALSE(is_first_navigation_in_web_contents().value()); @@ -396,14 +399,13 @@ page_load_metrics::InitPageLoadTimingForTest(&timing); timing.navigation_start = base::Time::FromDoubleT(10); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - GURL about_blank_url = GURL("about:blank"); - web_contents_tester->NavigateAndCommit(about_blank_url); + content::NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(), + about_blank_url); SimulateTimingUpdate(timing); ASSERT_EQ(0, CountUpdatedTimingReported()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_EQ(0, CountUpdatedTimingReported()); ASSERT_EQ(0, CountCompleteTimingReported()); @@ -421,10 +423,8 @@ mojom::PageLoadTiming timing; page_load_metrics::InitPageLoadTimingForTest(&timing); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); ASSERT_EQ(0, CountUpdatedTimingReported()); NavigateToUntrackedUrl(); @@ -447,10 +447,8 @@ page_load_metrics::InitPageLoadTimingForTest(&timing); timing.parse_timing->parse_start = base::TimeDelta::FromMilliseconds(1); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); ASSERT_EQ(0, CountUpdatedTimingReported()); NavigateToUntrackedUrl(); @@ -474,10 +472,8 @@ timing.navigation_start = base::Time::FromDoubleT(1); timing.parse_timing->parse_stop = base::TimeDelta::FromMilliseconds(1); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); ASSERT_EQ(0, CountUpdatedTimingReported()); NavigateToUntrackedUrl(); @@ -503,9 +499,8 @@ page_load_metrics::InitPageLoadTimingForTest(&timing2); timing2.navigation_start = base::Time::FromDoubleT(100); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); ASSERT_EQ(1, CountUpdatedTimingReported()); @@ -539,9 +534,8 @@ SimulateTimingUpdate(timing); // Navigate again to force histogram logging. - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); ASSERT_EQ(0, CountCompleteTimingReported()); ASSERT_EQ(0, CountUpdatedTimingReported()); CheckErrorEvent(ERR_IPC_WITH_NO_RELEVANT_LOAD, 1); @@ -615,9 +609,8 @@ } TEST_F(MetricsWebContentsObserverTest, FlushMetricsOnAppEnterBackground) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); histogram_tester_.ExpectTotalCount( internal::kPageLoadCompletedAfterAppBackground, 0); @@ -633,7 +626,8 @@ // Navigate again, which forces completion callbacks on the previous // navigation to be invoked. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); // Verify that, even though the page load completed, no complete timings were // reported, because the TestPageLoadMetricsObserver's @@ -652,47 +646,51 @@ } TEST_F(MetricsWebContentsObserverTest, StopObservingOnCommit) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); ASSERT_TRUE(completed_filtered_urls().empty()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_TRUE(completed_filtered_urls().empty()); // kFilteredCommitUrl should stop observing in OnCommit, and thus should not // reach OnComplete(). - web_contents_tester->NavigateAndCommit(GURL(kFilteredCommitUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kFilteredCommitUrl)); ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl)}), completed_filtered_urls()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl)}), completed_filtered_urls()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl), GURL(kDefaultTestUrl2)}), completed_filtered_urls()); } TEST_F(MetricsWebContentsObserverTest, StopObservingOnStart) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); ASSERT_TRUE(completed_filtered_urls().empty()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_TRUE(completed_filtered_urls().empty()); // kFilteredCommitUrl should stop observing in OnStart, and thus should not // reach OnComplete(). - web_contents_tester->NavigateAndCommit(GURL(kFilteredStartUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kFilteredStartUrl)); ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl)}), completed_filtered_urls()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl)}), completed_filtered_urls()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_EQ(std::vector<GURL>({GURL(kDefaultTestUrl), GURL(kDefaultTestUrl2)}), completed_filtered_urls()); } @@ -705,9 +703,8 @@ timing.navigation_start = base::Time::FromDoubleT(1); timing.response_start = base::TimeDelta::FromMilliseconds(10); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); ASSERT_EQ(1, CountUpdatedTimingReported()); @@ -750,7 +747,8 @@ EXPECT_TRUE(updated_timings().back()->paint_timing->first_paint); // Navigate again to see if the timing updated for a subframe message. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); ASSERT_EQ(1, CountCompleteTimingReported()); ASSERT_EQ(2, CountUpdatedTimingReported()); @@ -773,9 +771,8 @@ // currently can't inject the navigation start offset, so we must ensure that // subframe first paint + navigation start offset < main frame first paint. timing.paint_timing->first_paint = base::TimeDelta::FromMilliseconds(100000); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdateWithoutFiringDispatchTimer(timing, main_rfh()); EXPECT_TRUE(GetMostRecentTimer()->IsRunning()); @@ -862,12 +859,11 @@ timing.interactive_timing->first_input_delay = base::TimeDelta::FromMilliseconds(10); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -893,12 +889,11 @@ timing.interactive_timing->first_input_timestamp = base::TimeDelta::FromMilliseconds(10); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -924,12 +919,11 @@ timing.interactive_timing->longest_input_delay = base::TimeDelta::FromMilliseconds(10); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -955,12 +949,11 @@ timing.interactive_timing->longest_input_timestamp = base::TimeDelta::FromMilliseconds(10); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -993,12 +986,11 @@ timing.interactive_timing->longest_input_timestamp = base::TimeDelta::FromMilliseconds(2000); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -1033,12 +1025,11 @@ timing.interactive_timing->longest_input_timestamp = base::TimeDelta::FromMilliseconds(500); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -1074,9 +1065,8 @@ timing.interactive_timing->first_input_timestamp = base::TimeDelta::FromMinutes(100); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); content::RenderFrameHostTester* rfh_tester = @@ -1097,7 +1087,8 @@ SimulateTimingUpdate(subframe_timing, subframe); // Navigate again to confirm the timing updated for a subframe message. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -1117,11 +1108,9 @@ // FirstInputDelay and FirstInputTimestamp come from the main frame. TEST_F(MetricsWebContentsObserverTest, FirstInputDelayAndTimingMainframeFirstDeliveredSecond) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - // We need to navigate before we can navigate the subframe. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); content::RenderFrameHostTester* rfh_tester = content::RenderFrameHostTester::For(main_rfh()); @@ -1151,11 +1140,13 @@ timing.interactive_timing->first_input_timestamp = base::TimeDelta::FromMilliseconds(90); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(timing); // Navigate again to confirm the timing updated for the mainframe message. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -1171,11 +1162,9 @@ } TEST_F(MetricsWebContentsObserverTest, DISABLED_LongestInputInMainFrame) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - // We need to navigate before we can navigate the subframe. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); content::RenderFrameHostTester* rfh_tester = content::RenderFrameHostTester::For(main_rfh()); @@ -1201,7 +1190,8 @@ base::TimeDelta::FromMilliseconds(100); main_frame_timing.interactive_timing->longest_input_timestamp = base::TimeDelta::FromMilliseconds(2000); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(main_frame_timing); // Second subframe. @@ -1217,7 +1207,8 @@ SimulateTimingUpdate(subframe2_timing, subframe2); // Navigate again to confirm all timings are updated. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -1238,16 +1229,14 @@ // // Delivery order: Main Frame -> Subframe1 -> Subframe2. TEST_F(MetricsWebContentsObserverTest, LongestInputInSubframe) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - mojom::PageLoadTiming main_frame_timing; PopulatePageLoadTiming(&main_frame_timing); main_frame_timing.interactive_timing->longest_input_delay = base::TimeDelta::FromMilliseconds(100); main_frame_timing.interactive_timing->longest_input_timestamp = base::TimeDelta::FromMilliseconds(2000); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdate(main_frame_timing); content::RenderFrameHostTester* rfh_tester = @@ -1279,7 +1268,8 @@ SimulateTimingUpdate(subframe2_timing, subframe2); // Navigate again to confirm all timings are updated. - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); const mojom::InteractiveTiming& interactive_timing = *complete_timings().back()->interactive_timing; @@ -1301,9 +1291,8 @@ mojom::PageLoadTiming timing; PopulatePageLoadTiming(&timing); timing.paint_timing->first_paint = base::TimeDelta::FromMilliseconds(1000); - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); SimulateTimingUpdateWithoutFiringDispatchTimer(timing, main_rfh()); // Throw in a cpu timing update, shouldn't affect the page timing results. @@ -1331,9 +1320,8 @@ // Make sure the dispatch of CPU occurs immediately. TEST_F(MetricsWebContentsObserverTest, DispatchCpuMetricsImmediately) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); mojom::CpuTiming timing; timing.task_time = base::TimeDelta::FromMilliseconds(1000); @@ -1353,8 +1341,8 @@ TEST_F(MetricsWebContentsObserverTest, OnLoadedResource_MainFrame) { GURL main_resource_url(kDefaultTestUrl); - content::WebContentsTester::For(web_contents()) - ->NavigateAndCommit(main_resource_url); + content::NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(), + main_resource_url); auto navigation_simulator = content::NavigationSimulator::CreateRendererInitiated( @@ -1386,9 +1374,8 @@ } TEST_F(MetricsWebContentsObserverTest, OnLoadedResource_Subresource) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); GURL loaded_resource_url("http://www.other.com/"); observer()->ResourceLoadComplete( web_contents()->GetMainFrame(), content::GlobalRequestID(), @@ -1422,9 +1409,8 @@ TEST_F(MetricsWebContentsObserverTest, OnLoadedResource_IgnoreNonHttpOrHttpsScheme) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); GURL loaded_resource_url("data:text/html,Hello world"); observer()->ResourceLoadComplete( web_contents()->GetMainFrame(), content::GlobalRequestID(), @@ -1435,9 +1421,8 @@ } TEST_F(MetricsWebContentsObserverTest, RecordFeatureUsage) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_EQ(main_rfh()->GetLastCommittedURL().spec(), GURL(kDefaultTestUrl)); std::vector<blink::mojom::WebFeature> web_features; @@ -1486,9 +1471,8 @@ TEST_F(MetricsWebContentsObserverBackForwardCacheTest, RecordFeatureUsageWithBackForwardCache) { - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl)); ASSERT_EQ(main_rfh()->GetLastCommittedURL().spec(), GURL(kDefaultTestUrl)); std::vector<blink::mojom::WebFeature> web_features1{ @@ -1496,7 +1480,8 @@ mojom::PageLoadFeatures features1(web_features1, {}, {}); MetricsWebContentsObserver::RecordFeatureUsage(main_rfh(), features1); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl2)); + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL(kDefaultTestUrl2)); content::NavigationSimulator::GoBack(web_contents()); std::vector<blink::mojom::WebFeature> web_features2{
diff --git a/components/page_load_metrics/browser/page_load_tracker.cc b/components/page_load_metrics/browser/page_load_tracker.cc index a6bc3758..f136027 100644 --- a/components/page_load_metrics/browser/page_load_tracker.cc +++ b/components/page_load_metrics/browser/page_load_tracker.cc
@@ -415,15 +415,15 @@ } void PageLoadTracker::NotifyClientRedirectTo( - const PageLoadTracker& destination) { + content::NavigationHandle* destination) { if (metrics_update_dispatcher_.timing().paint_timing->first_paint) { base::TimeTicks first_paint_time = navigation_start() + metrics_update_dispatcher_.timing().paint_timing->first_paint.value(); base::TimeDelta first_paint_to_navigation; - if (destination.navigation_start() > first_paint_time) + if (destination->NavigationStart() > first_paint_time) first_paint_to_navigation = - destination.navigation_start() - first_paint_time; + destination->NavigationStart() - first_paint_time; PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation, first_paint_to_navigation); } else {
diff --git a/components/page_load_metrics/browser/page_load_tracker.h b/components/page_load_metrics/browser/page_load_tracker.h index 555bf9c..4913899 100644 --- a/components/page_load_metrics/browser/page_load_tracker.h +++ b/components/page_load_metrics/browser/page_load_tracker.h
@@ -258,7 +258,7 @@ visibility_tracker_ = tracker; } - void NotifyClientRedirectTo(const PageLoadTracker& destination); + void NotifyClientRedirectTo(content::NavigationHandle* destination); void OnLoadedResource( const ExtraRequestCompleteInfo& extra_request_complete_info);
diff --git a/components/password_manager/core/browser/credential_manager_impl_unittest.cc b/components/password_manager/core/browser/credential_manager_impl_unittest.cc index f38893c..8d639276 100644 --- a/components/password_manager/core/browser/credential_manager_impl_unittest.cc +++ b/components/password_manager/core/browser/credential_manager_impl_unittest.cc
@@ -470,13 +470,14 @@ RunAllPendingTasks(); TestPasswordStore::PasswordMap passwords = store_->stored_passwords(); - EXPECT_THAT(passwords["https://example.com/"], ElementsAre(form_)); + EXPECT_THAT(passwords["https://example.com/"], + ElementsAre(MatchesFormExceptStore(form_))); federated.date_created = passwords["federation://example.com/google.com"][0].date_created; federated.date_last_used = passwords["federation://example.com/google.com"][0].date_last_used; EXPECT_THAT(passwords["federation://example.com/google.com"], - ElementsAre(federated)); + ElementsAre(MatchesFormExceptStore(federated))); } TEST_F(CredentialManagerImplTest, CredentialManagerStoreOverwrite) { @@ -508,7 +509,8 @@ TestPasswordStore::PasswordMap passwords = store_->stored_passwords(); EXPECT_EQ(1U, passwords.size()); EXPECT_EQ(2U, passwords[form_.signon_realm].size()); - EXPECT_EQ(origin_path_form_, passwords[form_.signon_realm][0]); + EXPECT_THAT(origin_path_form_, + MatchesFormExceptStore(passwords[form_.signon_realm][0])); EXPECT_EQ(base::ASCIIToUTF16("Totally new password."), passwords[form_.signon_realm][1].password_value); EXPECT_EQ(base::ASCIIToUTF16("New Name"), @@ -827,9 +829,10 @@ CredentialManagerOnRequestCredentialWithPSLCredential) { store_->AddLogin(subdomain_form_); subdomain_form_.is_public_suffix_match = true; - EXPECT_CALL(*client_, - PromptUserToChooseCredentialsPtr( - UnorderedElementsAre(Pointee(subdomain_form_)), _, _)); + EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr( + UnorderedElementsAre(Pointee( + MatchesFormExceptStore(subdomain_form_))), + _, _)); EXPECT_CALL(*client_, NotifyUserAutoSigninPtr()).Times(0); ExpectCredentialType(CredentialMediationRequirement::kOptional, true, @@ -843,10 +846,12 @@ store_->AddLogin(origin_path_form_); store_->AddLogin(subdomain_form_); - EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr( - UnorderedElementsAre(Pointee(origin_path_form_), - Pointee(form_)), - _, _)); + EXPECT_CALL(*client_, + PromptUserToChooseCredentialsPtr( + UnorderedElementsAre( + Pointee(MatchesFormExceptStore(origin_path_form_)), + Pointee(MatchesFormExceptStore(form_))), + _, _)); ExpectCredentialType(CredentialMediationRequirement::kOptional, true, std::vector<GURL>(), @@ -894,11 +899,13 @@ "federation://" + federated.origin.host() + "/google.com"; store_->AddLogin(federated); - EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr( - UnorderedElementsAre(Pointee(form_), - Pointee(origin_path_form_), - Pointee(federated)), - _, _)); + EXPECT_CALL(*client_, + PromptUserToChooseCredentialsPtr( + UnorderedElementsAre( + Pointee(MatchesFormExceptStore(form_)), + Pointee(MatchesFormExceptStore(origin_path_form_)), + Pointee(MatchesFormExceptStore(federated))), + _, _)); bool called = false; CredentialManagerError error; @@ -1113,8 +1120,8 @@ store_->AddLogin(form_); std::vector<GURL> federations; - EXPECT_CALL(*client_, - NotifyUserCouldBeAutoSignedInPtr(testing::Pointee(form_))) + EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr( + Pointee(MatchesFormExceptStore(form_)))) .Times(1); ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true, @@ -1128,8 +1135,8 @@ store_->AddLogin(form_); std::vector<GURL> federations; - EXPECT_CALL(*client_, - NotifyUserCouldBeAutoSignedInPtr(testing::Pointee(form_))) + EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr( + Pointee(MatchesFormExceptStore(form_)))) .Times(1); ExpectZeroClickSignInFailure(CredentialMediationRequirement::kSilent, true, @@ -1560,7 +1567,8 @@ blacklisted.origin = form_.origin; blacklisted.signon_realm = form_.signon_realm; blacklisted.date_created = passwords[form_.signon_realm][0].date_created; - EXPECT_THAT(passwords[form_.signon_realm], testing::ElementsAre(blacklisted)); + EXPECT_THAT(passwords[form_.signon_realm], + ElementsAre(MatchesFormExceptStore(blacklisted))); } TEST_F(CredentialManagerImplTest, BlacklistFederatedCredential) { @@ -1590,7 +1598,7 @@ blacklisted.date_created = passwords[blacklisted.signon_realm][0].date_created; EXPECT_THAT(passwords[blacklisted.signon_realm], - testing::ElementsAre(blacklisted)); + ElementsAre(MatchesFormExceptStore(blacklisted))); } TEST_F(CredentialManagerImplTest, RespectBlacklistingPasswordCredential) { @@ -1644,9 +1652,11 @@ form_.username_value = base::ASCIIToUTF16("username_value"); store_->AddLogin(form_); - EXPECT_CALL(*client_, - PasswordWasAutofilled(ElementsAre(Pointee(form_)), _, - Pointee(ElementsAre(Pointee(federated))))); + EXPECT_CALL( + *client_, + PasswordWasAutofilled( + ElementsAre(Pointee(MatchesFormExceptStore(form_))), _, + Pointee(ElementsAre(Pointee(MatchesFormExceptStore(federated)))))); bool called = false; CredentialManagerError error;
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc index 326e575..eb057a2 100644 --- a/components/password_manager/core/browser/password_autofill_manager.cc +++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -199,12 +199,23 @@ return suggestion; } -autofill::Suggestion CreateAccountStorageOptInEntry() { - // TODO(crbug.com/1024332): Add proper (translated) string. +// Entry for opting in to password account storage and then filling. +autofill::Suggestion CreateEntryToOptInToAccountStorageThenFill() { + // TODO(crbug.com/1062344): Add proper (translated) string. autofill::Suggestion suggestion( base::ASCIIToUTF16("Use passwords stored in your Google account")); suggestion.frontend_id = - autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN; + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN; + return suggestion; +} + +// Entry for opting in to password account storage and then generating password. +autofill::Suggestion CreateEntryToOptInToAccountStorageThenGenerate() { + // TODO(crbug.com/1062344): Add proper (translated) string. + autofill::Suggestion suggestion(base::ASCIIToUTF16( + "Use your Google account to generate a strong password")); + suggestion.frontend_id = + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE; return suggestion; } @@ -233,27 +244,42 @@ } std::vector<autofill::Suggestion> ReplaceUnlockButtonWithLoadingIndicator( - base::span<const autofill::Suggestion> suggestions) { + base::span<const autofill::Suggestion> suggestions, + autofill::PopupItemId unlock_item) { + DCHECK( + unlock_item == autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN || + unlock_item == + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE); std::vector<autofill::Suggestion> new_suggestions; new_suggestions.push_back(CreateLoadingSpinner()); std::copy_if(suggestions.begin(), suggestions.end(), std::back_inserter(new_suggestions), - [](const autofill::Suggestion& suggestion) { - return suggestion.frontend_id != - autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN; + [unlock_item](const autofill::Suggestion& suggestion) { + return suggestion.frontend_id != unlock_item; }); return new_suggestions; } std::vector<autofill::Suggestion> ReplaceLoaderWithUnlock( - base::span<const autofill::Suggestion> suggestions) { + base::span<const autofill::Suggestion> suggestions, + autofill::PopupItemId unlock_item) { std::vector<autofill::Suggestion> new_suggestions; new_suggestions.reserve(suggestions.size()); for (const auto& suggestion : suggestions) { if (suggestion.frontend_id != autofill::POPUP_ITEM_ID_LOADING_SPINNER) new_suggestions.push_back(suggestion); } - new_suggestions.push_back(CreateAccountStorageOptInEntry()); + switch (unlock_item) { + case autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE: + new_suggestions.push_back( + CreateEntryToOptInToAccountStorageThenGenerate()); + break; + case autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN: + new_suggestions.push_back(CreateEntryToOptInToAccountStorageThenFill()); + break; + default: + NOTREACHED(); + } return new_suggestions; } @@ -286,12 +312,38 @@ ClearPreviewedForm(); if (identifier == autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY || identifier == autofill::POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY || - identifier == autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN) + identifier == autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN || + identifier == + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE) return; bool success = PreviewSuggestion(GetUsernameFromSuggestion(value)); DCHECK(success); } +void PasswordAutofillManager::OnUnlockItemAccepted( + autofill::PopupItemId unlock_item) { + DCHECK( + unlock_item == autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN || + unlock_item == + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE); + + signin::IdentityManager* identity_manager = + password_client_->GetIdentityManager(); + if (!identity_manager) + return; + CoreAccountId account_id = + identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kNotRequired); + if (account_id.empty()) + return; + UpdatePopup(ReplaceUnlockButtonWithLoadingIndicator( + autofill_client_->GetPopupSuggestions(), unlock_item)); + autofill_client_->PinPopupViewUntilUpdate(); + password_client_->TriggerReauthForAccount( + account_id, + base::BindOnce(&PasswordAutofillManager::OnUnlockReauthCompleted, + weak_ptr_factory_.GetWeakPtr(), unlock_item)); +} + void PasswordAutofillManager::DidAcceptSuggestion(const base::string16& value, int identifier, int position) { @@ -317,22 +369,12 @@ password_client_->GetMetricsRecorder()->RecordPageLevelUserAction( UserAction::kShowAllPasswordsWhileSomeAreSuggested); } - } else if (identifier == - autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN) { - signin::IdentityManager* identity_manager = - password_client_->GetIdentityManager(); - if (!identity_manager) - return; - CoreAccountId account_id = identity_manager->GetPrimaryAccountId( - signin::ConsentLevel::kNotRequired); - if (account_id.empty()) - return; - UpdatePopup(ReplaceUnlockButtonWithLoadingIndicator( - autofill_client_->GetPopupSuggestions())); - autofill_client_->PinPopupViewUntilUpdate(); - password_client_->TriggerReauthForAccount( - account_id, base::BindOnce(&PasswordAutofillManager::OnReauthCompleted, - weak_ptr_factory_.GetWeakPtr())); + } else if ( + identifier == autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN || + identifier == + autofill:: + POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE) { + OnUnlockItemAccepted(static_cast<autofill::PopupItemId>(identifier)); return; // Do not hide the popup while loading data. } else { metrics_util::LogPasswordDropdownItemSelected( @@ -472,9 +514,8 @@ ShowPasswordSuggestions show_password_suggestions) { std::vector<autofill::Suggestion> suggestions; bool show_account_storage_optin = - !offers_generation && password_client_ && - password_client_->GetPasswordFeatureManager() - ->ShouldShowAccountStorageOptIn(); + password_client_ && password_client_->GetPasswordFeatureManager() + ->ShouldShowAccountStorageOptIn(); if (!fill_data_ && !show_account_storage_optin) { // Probably the credential was deleted in the mean time. @@ -489,15 +530,19 @@ } // Add password generation entry, if available. - if (offers_generation) - suggestions.push_back(CreateGenerationEntry()); + if (offers_generation) { + suggestions.push_back(show_account_storage_optin + ? CreateEntryToOptInToAccountStorageThenGenerate() + : CreateGenerationEntry()); + } // Add "Manage all passwords" link to settings. MaybeAppendManualFallback(autofill_client_->GetSyncService(), &suggestions); - // Add button to opt into using the account storage for passwords. + // Add button to opt into using the account storage for passwords and then + // suggest. if (show_account_storage_optin) - suggestions.push_back(CreateAccountStorageOptInEntry()); + suggestions.push_back(CreateEntryToOptInToAccountStorageThenFill()); return suggestions; } @@ -513,6 +558,9 @@ metrics_util::ShowAllSavedPasswordsContext::kPassword); continue; case autofill::POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY: + // TODO(crbug.com/1062709): Revisit metrics for the "opt in and + // generate" button. + case autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE: dropdown_state = metrics_util::PasswordDropdownState::kStandardGenerate; continue; } @@ -622,13 +670,19 @@ page_favicon_ = result.image; } -void PasswordAutofillManager::OnReauthCompleted( +void PasswordAutofillManager::OnUnlockReauthCompleted( + autofill::PopupItemId unlock_item, PasswordManagerClient::ReauthSucceeded reauth_succeeded) { if (reauth_succeeded) { password_client_->GetPasswordFeatureManager()->SetAccountStorageOptIn(true); + if (unlock_item == + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE) { + password_client_->GeneratePassword(); + } return; } - UpdatePopup(ReplaceLoaderWithUnlock(autofill_client_->GetPopupSuggestions())); + UpdatePopup(ReplaceLoaderWithUnlock(autofill_client_->GetPopupSuggestions(), + unlock_item)); } } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_autofill_manager.h b/components/password_manager/core/browser/password_autofill_manager.h index 40d0e780d..4fc1cca 100644 --- a/components/password_manager/core/browser/password_autofill_manager.h +++ b/components/password_manager/core/browser/password_autofill_manager.h
@@ -160,10 +160,16 @@ // store is canceled on navigation. void OnFaviconReady(const favicon_base::FaviconImageResult& result); - // Checks the result of the reauth triggered by UnlockAccountStoreAfterReauth - // and either unlocks the account store if the reauth succeeded or resets the - // suggestions to show the unlock button again. - void OnReauthCompleted( + // Replaces |unlock_item| with a loading symbol and triggers a reauth flow to + // opt in for passwords account storage, with OnUnlockReauthCompleted as + // callback. + void OnUnlockItemAccepted(autofill::PopupItemId unlock_item); + + // If reauth failed, resets the suggestions to show the |unlock_item| again. + // Otherwise, unlocks the account store and either triggers generation or + // filling based on the |unlock_item| that was clicked. + void OnUnlockReauthCompleted( + autofill::PopupItemId unlock_item, PasswordManagerClient::ReauthSucceeded reauth_succeeded); std::unique_ptr<autofill::PasswordFormFillData> fill_data_;
diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc index 8d217028..adba7c0 100644 --- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc +++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -64,7 +64,10 @@ using autofill::SuggestionVectorValuesAre; using favicon_base::FaviconImageCallback; using testing::_; +using testing::AllOf; using testing::ElementsAreArray; +using testing::Eq; +using testing::Field; using testing::Invoke; using testing::NiceMock; using testing::Return; @@ -195,7 +198,9 @@ return 1; } -std::vector<autofill::Suggestion> CreateTestSuggestions(bool has_opt_in) { +std::vector<autofill::Suggestion> CreateTestSuggestions( + bool has_opt_in_and_fill, + bool has_opt_in_and_generate) { std::vector<Suggestion> suggestions; suggestions.push_back( Suggestion(/*label=*/"User1", /*value=*/"PW1", /*icon=*/"", @@ -205,10 +210,17 @@ /*label=*/"Show all pwds", /*value=*/"", /*icon=*/"", /*fronend_id=*/autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY)); } - if (has_opt_in) { + if (has_opt_in_and_fill) { suggestions.push_back(Suggestion( - /*label=*/"Unlock passwords", /*value=*/"", /*icon=*/"", - /*fronend_id=*/autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN)); + /*label=*/"Unlock passwords and fill", /*value=*/"", /*icon=*/"", + /*fronend_id=*/ + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN)); + } + if (has_opt_in_and_generate) { + suggestions.push_back(Suggestion( + /*label=*/"Unlock passwords and generate", /*value=*/"", /*icon=*/"", + /*fronend_id=*/ + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE)); } return suggestions; } @@ -383,7 +395,7 @@ } // Test that the popup is updated once remote suggestions are unlocked. -TEST_F(PasswordAutofillManagerTest, ShowUnlockButton) { +TEST_F(PasswordAutofillManagerTest, ShowOptInAndFillButton) { TestPasswordManagerClient client; NiceMock<MockAutofillClient> autofill_client; InitializePasswordAutofillManager(&client, &autofill_client); @@ -397,15 +409,16 @@ SuggestionVectorIdsAre(ElementsAreArray(RemoveShowAllBeforeLollipop( {autofill::POPUP_ITEM_ID_PASSWORD_ENTRY, autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY, - autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN}))), + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN}))), /*autoselect_first_suggestion=*/false, PopupType::kPasswords, _)); password_autofill_manager_->OnShowPasswordSuggestions( base::i18n::RIGHT_TO_LEFT, base::string16(), autofill::SHOW_ALL | autofill::IS_PASSWORD_FIELD, gfx::RectF()); } -// Test that the popup is updated once remote suggestions are unlocked. -TEST_F(PasswordAutofillManagerTest, ClickOnUnlockPutsPopupInWaitingState) { +// Test that the popup is updated once "opt in and fill" is clicked. +TEST_F(PasswordAutofillManagerTest, + ClickOnOptInAndFillPutsPopupInWaitingState) { TestPasswordManagerClient client; NiceMock<MockAutofillClient> autofill_client; InitializePasswordAutofillManager(&client, &autofill_client); @@ -428,14 +441,47 @@ EXPECT_CALL(autofill_client, PinPopupViewUntilUpdate); EXPECT_CALL(client, TriggerReauthForAccount(kAliceId, _)); EXPECT_CALL(autofill_client, GetPopupSuggestions()) - .WillOnce(Return(CreateTestSuggestions(/*has_opt_in=*/true))); + .WillOnce(Return(CreateTestSuggestions( + /*has_opt_in_and_fill=*/true, /*has_opt_in_and_generate*/ false))); password_autofill_manager_->DidAcceptSuggestion( - test_username_, autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN, + test_username_, autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN, 1); } -// Test that the popup is updated once remote suggestions are unlocked. -TEST_F(PasswordAutofillManagerTest, FailedUnlockUpdatesPopup) { +// Test that the popup is updated once "opt in and generate" is clicked. +TEST_F(PasswordAutofillManagerTest, + ClickOnOptInAndGeneratePutsPopupInWaitingState) { + TestPasswordManagerClient client; + NiceMock<MockAutofillClient> autofill_client; + InitializePasswordAutofillManager(&client, &autofill_client); + client.SetAccountStorageOptIn(false); + const CoreAccountId kAliceId = client.identity_test_env() + .SetUnconsentedPrimaryAccount(kAliceEmail) + .account_id; + testing::Mock::VerifyAndClearExpectations(&autofill_client); + + // Accepting a suggestion should trigger a call to update the popup. The first + // update removes the unlock button + EXPECT_CALL( + autofill_client, + UpdatePopup( + SuggestionVectorIdsAre(ElementsAreArray(RemoveShowAllBeforeLollipop( + {autofill::POPUP_ITEM_ID_LOADING_SPINNER, + autofill::POPUP_ITEM_ID_PASSWORD_ENTRY, + autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY}))), + PopupType::kPasswords)); + EXPECT_CALL(autofill_client, PinPopupViewUntilUpdate); + EXPECT_CALL(client, TriggerReauthForAccount(kAliceId, _)); + EXPECT_CALL(autofill_client, GetPopupSuggestions()) + .WillOnce(Return(CreateTestSuggestions( + /*has_opt_in_and_fill=*/false, /*has_opt_in_and_generate*/ true))); + password_autofill_manager_->DidAcceptSuggestion( + test_username_, + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE, 1); +} + +// Test that the popup is updated once "opt in and fill" is clicked. +TEST_F(PasswordAutofillManagerTest, FailedOptInAndFillUpdatesPopup) { TestPasswordManagerClient client; NiceMock<MockAutofillClient> autofill_client; InitializePasswordAutofillManager(&client, &autofill_client); @@ -450,14 +496,16 @@ // Accepting a suggestion should trigger a call to update the popup. // First the popup enters the waiting state. EXPECT_CALL(autofill_client, GetPopupSuggestions) - .WillOnce(Return(CreateTestSuggestions(/*has_opt_in=*/true))); + .WillOnce(Return(CreateTestSuggestions( + /*has_opt_in_and_fill=*/true, /*has_opt_in_and_generate*/ false))); EXPECT_CALL(autofill_client, UpdatePopup); // As soon as the waiting state is pending, the next update resets the popup. EXPECT_CALL(autofill_client, PinPopupViewUntilUpdate).WillOnce([&] { testing::Mock::VerifyAndClear(&autofill_client); EXPECT_CALL(autofill_client, GetPopupSuggestions) - .WillOnce(Return(CreateTestSuggestions(/*has_opt_in=*/false))); + .WillOnce(Return(CreateTestSuggestions( + /*has_opt_in_and_fill=*/false, /*has_opt_in_and_generate*/ false))); EXPECT_CALL(client, TriggerReauthForAccount(kAliceId, _)) .WillOnce([](const auto& unused, auto reauth_callback) { std::move(reauth_callback).Run(ReauthSucceeded(false)); @@ -468,17 +516,63 @@ SuggestionVectorIdsAre(ElementsAreArray(RemoveShowAllBeforeLollipop( {autofill::POPUP_ITEM_ID_PASSWORD_ENTRY, autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY, - autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN}))), + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN}))), PopupType::kPasswords)); }); password_autofill_manager_->DidAcceptSuggestion( - test_username_, autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN, + test_username_, autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN, 1); } -// Test that the popup is updated once remote suggestions are unlocked. -TEST_F(PasswordAutofillManagerTest, SuccessfullUnlockTriggersOptIn) { +// Test that the popup is updated once "opt in and generate" is clicked. +TEST_F(PasswordAutofillManagerTest, FailedOptInAndGenerateUpdatesPopup) { + TestPasswordManagerClient client; + NiceMock<MockAutofillClient> autofill_client; + InitializePasswordAutofillManager(&client, &autofill_client); + client.SetAccountStorageOptIn(false); + const CoreAccountId kAliceId = client.identity_test_env() + .SetUnconsentedPrimaryAccount(kAliceEmail) + .account_id; + testing::Mock::VerifyAndClearExpectations(&autofill_client); + EXPECT_CALL(*client.GetPasswordFeatureManager(), SetAccountStorageOptIn) + .Times(0); + + // Accepting a suggestion should trigger a call to update the popup. + // First the popup enters the waiting state. + EXPECT_CALL(autofill_client, GetPopupSuggestions) + .WillOnce(Return(CreateTestSuggestions( + /*has_opt_in_and_fill=*/false, /*has_opt_in_and_generate*/ true))); + EXPECT_CALL(autofill_client, UpdatePopup); + + // As soon as the waiting state is pending, the next update resets the popup. + EXPECT_CALL(autofill_client, PinPopupViewUntilUpdate).WillOnce([&] { + testing::Mock::VerifyAndClear(&autofill_client); + EXPECT_CALL(autofill_client, GetPopupSuggestions) + .WillOnce(Return(CreateTestSuggestions( + /*has_opt_in_and_fill=*/false, /*has_opt_in_and_generate*/ false))); + EXPECT_CALL(client, TriggerReauthForAccount(kAliceId, _)) + .WillOnce([](const auto& unused, auto reauth_callback) { + std::move(reauth_callback).Run(ReauthSucceeded(false)); + }); + EXPECT_CALL( + autofill_client, + UpdatePopup( + SuggestionVectorIdsAre(ElementsAreArray(RemoveShowAllBeforeLollipop( + {autofill::POPUP_ITEM_ID_PASSWORD_ENTRY, + autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY, + autofill:: + POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE}))), + PopupType::kPasswords)); + }); + + password_autofill_manager_->DidAcceptSuggestion( + test_username_, + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE, 1); +} + +// Test that the popup is updated once "opt in and fill" is clicked. +TEST_F(PasswordAutofillManagerTest, SuccessfullOptInAndFillTriggersOptIn) { TestPasswordManagerClient client; NiceMock<MockAutofillClient> autofill_client; InitializePasswordAutofillManager(&client, &autofill_client); @@ -490,7 +584,8 @@ // Accepting a suggestion should trigger a call to update the popup. EXPECT_CALL(autofill_client, GetPopupSuggestions) - .WillOnce(Return(CreateTestSuggestions(/*has_opt_in=*/true))); + .WillOnce(Return(CreateTestSuggestions( + /*has_opt_in_and_fill=*/true, /*has_opt_in_and_generate*/ false))); EXPECT_CALL(autofill_client, UpdatePopup); EXPECT_CALL(autofill_client, PinPopupViewUntilUpdate); @@ -502,12 +597,45 @@ SetAccountStorageOptIn(true)); password_autofill_manager_->DidAcceptSuggestion( - test_username_, autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPTIN, + test_username_, autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN, 1); } -// Test that the popup is updated once remote suggestions are unlocked. -TEST_F(PasswordAutofillManagerTest, AddOnFillDataAfterUnlockPopuplatesPopup) { +// Test that the popup is updated once "opt in and generate" is clicked. +TEST_F(PasswordAutofillManagerTest, + SuccessfullOptInAndGenerateTriggersOptInAndGeneration) { + TestPasswordManagerClient client; + NiceMock<MockAutofillClient> autofill_client; + InitializePasswordAutofillManager(&client, &autofill_client); + client.SetAccountStorageOptIn(false); + const CoreAccountId kAliceId = client.identity_test_env() + .SetUnconsentedPrimaryAccount(kAliceEmail) + .account_id; + testing::Mock::VerifyAndClearExpectations(&autofill_client); + + // Accepting a suggestion should trigger a call to update the popup. + EXPECT_CALL(autofill_client, GetPopupSuggestions) + .WillOnce(Return(CreateTestSuggestions( + /*has_opt_in_and_fill=*/false, /*has_opt_in_and_generate*/ true))); + EXPECT_CALL(autofill_client, UpdatePopup); + EXPECT_CALL(autofill_client, PinPopupViewUntilUpdate); + + EXPECT_CALL(client, TriggerReauthForAccount(kAliceId, _)) + .WillOnce([](const auto& id, auto reauth_callback) { + std::move(reauth_callback).Run(ReauthSucceeded(true)); + }); + EXPECT_CALL(*client.GetPasswordFeatureManager(), + SetAccountStorageOptIn(true)); + EXPECT_CALL(client, GeneratePassword()); + + password_autofill_manager_->DidAcceptSuggestion( + test_username_, + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE, 1); +} + +// Test that the popup is updated once "opt in and fill" is clicked". +TEST_F(PasswordAutofillManagerTest, + AddOnFillDataAfterOptInAndFillPopulatesPopup) { TestPasswordManagerClient client; NiceMock<MockAutofillClient> autofill_client; InitializePasswordAutofillManager(&client, &autofill_client); @@ -523,7 +651,8 @@ new_data.additional_logins[additional_username] = additional; EXPECT_CALL(autofill_client, GetPopupSuggestions()) .Times(2) - .WillRepeatedly(Return(CreateTestSuggestions(/*has_opt_in=*/false))); + .WillRepeatedly(Return(CreateTestSuggestions( + /*has_opt_in_and_fill=*/false, /*has_opt_in_and_generate*/ false))); EXPECT_CALL( autofill_client, UpdatePopup( @@ -1030,6 +1159,44 @@ /*show_password_suggestions=*/false)); } +// Test that if the "opt in and generate" button gets displayed, the regular +// generation button does not. +TEST_F(PasswordAutofillManagerTest, + MaybeShowPasswordSuggestionsWithAccountPasswordsEnabled) { + base::test::ScopedFeatureList features; + features.InitAndEnableFeature(features::kEnablePasswordsAccountStorage); + + TestPasswordManagerClient client; + client.SetAccountStorageOptIn(false); + + NiceMock<MockAutofillClient> autofill_client; + InitializePasswordAutofillManager(&client, &autofill_client); + + autofill::PasswordFormFillData data = CreateTestFormFillData(); + + favicon::MockFaviconService favicon_service; + EXPECT_CALL(client, GetFaviconService()).WillOnce(Return(&favicon_service)); + EXPECT_CALL(favicon_service, GetFaviconImageForPageURL(data.origin, _, _)); + password_autofill_manager_->OnAddPasswordFillData(data); + + auto opt_in_and_generate_id = static_cast<int>( + autofill::POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_OPT_IN_AND_GENERATE); + auto regular_generate_id = + static_cast<int>(autofill::POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY); + EXPECT_CALL(autofill_client, + ShowAutofillPopup( + _, _, + AllOf(Contains(Field(&autofill::Suggestion::frontend_id, + Eq(opt_in_and_generate_id))), + Not(Contains(Field(&autofill::Suggestion::frontend_id, + Eq(regular_generate_id))))), + _, _, _)); + + password_autofill_manager_->MaybeShowPasswordSuggestionsWithGeneration( + gfx::RectF(), base::i18n::RIGHT_TO_LEFT, + /*show_password_suggestions=*/true); +} + TEST_F(PasswordAutofillManagerTest, DisplayAccountSuggestionsIndicatorIcon) { base::test::ScopedFeatureList features; features.InitAndEnableFeature(features::kEnablePasswordsAccountStorage);
diff --git a/components/password_manager/core/browser/password_feature_manager_impl.cc b/components/password_manager/core/browser/password_feature_manager_impl.cc index bfdcc5d..216eeee 100644 --- a/components/password_manager/core/browser/password_feature_manager_impl.cc +++ b/components/password_manager/core/browser/password_feature_manager_impl.cc
@@ -21,7 +21,8 @@ bool PasswordFeatureManagerImpl::IsGenerationEnabled() const { switch (password_manager_util::GetPasswordSyncState(sync_service_)) { case NOT_SYNCING: - return false; + return password_manager_util::ShouldShowAccountStorageOptIn( + pref_service_, sync_service_); case SYNCING_WITH_CUSTOM_PASSPHRASE: case SYNCING_NORMAL_ENCRYPTION: case ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION:
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index fb965bc..0636796f 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -104,6 +104,17 @@ return nullptr; } +void LogUsingPossibleUsername(PasswordManagerClient* client, + bool is_used, + const char* message) { + if (!password_manager_util::IsLoggingActive(client)) + return; + BrowserSavePasswordProgressLogger logger(client->GetLogManager()); + logger.LogString(is_used ? Logger::STRING_POSSIBLE_USERNAME_USED + : Logger::STRING_POSSIBLE_USERNAME_NOT_USED, + message); +} + } // namespace PasswordFormManager::PasswordFormManager( @@ -901,19 +912,25 @@ bool PasswordFormManager::UsePossibleUsername( const PossibleUsernameData* possible_username) { - if (!possible_username) + if (!possible_username) { + LogUsingPossibleUsername(client_, /*is_used*/ false, "Null"); return false; + } // The username form and password forms signon realms must be the same. - if (GetSignonRealm(observed_form_.url) != possible_username->signon_realm) + if (GetSignonRealm(observed_form_.url) != possible_username->signon_realm) { + LogUsingPossibleUsername(client_, /*is_used*/ false, "Different domains"); return false; + } // The username candidate field should not be in |observed_form_|, otherwise // that is a task of FormParser to choose it from |observed_form_|. if (possible_username->driver_id == driver_id_) { for (const auto& field : observed_form_.fields) { - if (field.unique_renderer_id == possible_username->renderer_id) + if (field.unique_renderer_id == possible_username->renderer_id) { + LogUsingPossibleUsername(client_, /*is_used*/ false, "Same form"); return false; + } } } @@ -921,10 +938,15 @@ const PasswordFieldPrediction* field_prediction = FindFieldPrediction( possible_username->form_predictions, possible_username->renderer_id); if (field_prediction) { - if (field_prediction->type == SINGLE_USERNAME) + if (field_prediction->type == SINGLE_USERNAME) { + LogUsingPossibleUsername(client_, /*is_used*/ true, "Server predictions"); return true; - if (field_prediction->type == NOT_USERNAME) + } + if (field_prediction->type == NOT_USERNAME) { + LogUsingPossibleUsername(client_, /*is_used*/ false, + "Server predictions"); return false; + } } #if defined(OS_ANDROID) @@ -941,15 +963,22 @@ auto field_signature = field_prediction->signature; autofill::ServerFieldType type = field_info_manager->GetFieldType(form_signature, field_signature); - if (type == SINGLE_USERNAME) + if (type == SINGLE_USERNAME) { + LogUsingPossibleUsername(client_, /*is_used*/ true, "Local prediction"); return true; - if (type == NOT_USERNAME) + } + if (type == NOT_USERNAME) { + LogUsingPossibleUsername(client_, /*is_used*/ false, "Local prediction"); return false; + } } - return IsPossibleUsernameValid(*possible_username, - parsed_submitted_form_->signon_realm, - base::Time::Now()); + bool is_possible_username_valid = IsPossibleUsernameValid( + *possible_username, parsed_submitted_form_->signon_realm, + base::Time::Now()); + LogUsingPossibleUsername(client_, /*is_used*/ is_possible_username_valid, + "Local heuristics"); + return is_possible_username_valid; } } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index f69c503..e87978f 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -18,6 +18,7 @@ #include "base/threading/platform_thread.h" #include "build/build_config.h" #include "components/autofill/core/browser/autofill_field.h" +#include "components/autofill/core/browser/autofill_type.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/logging/log_manager.h" #include "components/autofill/core/common/form_data_predictions.h" @@ -51,8 +52,10 @@ using autofill::NOT_USERNAME; using autofill::PasswordForm; using autofill::SINGLE_USERNAME; +using autofill::UNKNOWN_TYPE; using autofill::USERNAME; using autofill::mojom::PasswordFormFieldPredictionType; +using base::NumberToString; #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) using password_manager::metrics_util::GaiaPasswordHashChange; #endif // SYNC_PASSWORD_REUSE_DETECTION_ENABLED @@ -159,7 +162,8 @@ // predictions for corresponding fields. Predictions from |field_info_manager| // have priority over server predictions. void AddLocallySavedPredictions(FieldInfoManager* field_info_manager, - FormPredictions* predictions) { + FormPredictions* predictions, + BrowserSavePasswordProgressLogger* logger) { DCHECK(predictions); if (!field_info_manager) return; @@ -176,6 +180,13 @@ if (field.type != SINGLE_USERNAME && field.type != USERNAME) field.type = NOT_USERNAME; } + if (logger && local_prediction != UNKNOWN_TYPE) { + std::string message = + "form signature=" + NumberToString(predictions->form_signature) + + " , field signature=" + NumberToString(field.signature) + ", type=" + + autofill::AutofillType::ServerFieldTypeToString(local_prediction); + logger->LogString(Logger::STRING_LOCALLY_SAVED_PREDICTION, message); + } } } @@ -979,7 +990,8 @@ predictions_[form->form_signature()] = ConvertToFormPredictions(driver_id, *form); AddLocallySavedPredictions(client_->GetFieldInfoManager(), - &predictions_[form->form_signature()]); + &predictions_[form->form_signature()], + logger.get()); } // Create form managers for non-password forms if |predictions_| has evidence
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index 9c37ccd..bcb20d5c5 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -383,31 +383,52 @@ if (!submitted_form.federation_origin.opaque()) return nullptr; - // Try to return form with matching |username_value|. - const PasswordForm* username_match = - FindFormByUsername(credentials, submitted_form.username_value); - if (username_match) { - if (!username_match->is_public_suffix_match) - return username_match; - - const auto& password_to_save = submitted_form.new_password_value.empty() - ? submitted_form.password_value - : submitted_form.new_password_value; - // Normally, the copy of the PSL matched credentials, adapted for the - // current domain, is saved automatically without asking the user, because - // the copy likely represents the same account, i.e., the one for which - // the user already agreed to store a password. - // - // However, if the user changes the suggested password, it might indicate - // that the autofilled credentials and |submitted_password_form| - // actually correspond to two different accounts (see - // http://crbug.com/385619). - return password_to_save == username_match->password_value ? username_match - : nullptr; + // Find any form(s) that match by username or by username+password. + const PasswordForm* username_password_match = nullptr; + const PasswordForm* username_match = nullptr; + const base::string16& password_to_save = + submitted_form.new_password_value.empty() + ? submitted_form.password_value + : submitted_form.new_password_value; + for (const PasswordForm* form : credentials) { + if (!username_password_match && + form->username_value == submitted_form.username_value && + form->password_value == password_to_save) { + username_password_match = form; + } + if (!username_match && + form->username_value == submitted_form.username_value) { + username_match = form; + } } + // First, try to return a non-PSL match. Prefer if the password also matches. + if (username_password_match && + !username_password_match->is_public_suffix_match) { + return username_password_match; + } + if (username_match && !username_match->is_public_suffix_match) + return username_match; + + // All matches (if there are any) are PSL matches. We only want to return + // PSL matches if the password also matches: + // + // Normally, the copy of the PSL matched credentials, adapted for the + // current domain, is saved automatically without asking the user, because + // the copy likely represents the same account, i.e., the one for which + // the user already agreed to store a password. + // + // However, if the user changes the suggested password, it might indicate + // that the autofilled credentials and |submitted_password_form| + // actually correspond to two different accounts (see + // http://crbug.com/385619). + if (username_password_match) + return username_password_match; + // Next attempt is to find a match by password value. It should not be tried // when the username was actually detected. + if (username_match) + return nullptr; if (submitted_form.type == PasswordForm::Type::kApi || !submitted_form.username_value.empty()) { return nullptr;
diff --git a/components/password_manager/core/browser/password_manager_util_unittest.cc b/components/password_manager/core/browser/password_manager_util_unittest.cc index 3928c582..f5dc0af 100644 --- a/components/password_manager/core/browser/password_manager_util_unittest.cc +++ b/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -392,6 +392,24 @@ GetMatchForUpdating(parsed, {&stored3, &stored2, &stored1})); } +TEST(PasswordManagerUtil, + GetMatchForUpdating_DuplicateUsernamePickMatchingPassword) { + // Two credentials with a matching username are stored. One has the same + // password as well, the other has a different password. This can happen when + // one credential comes from the profile store, the other from the password + // store. + autofill::PasswordForm parsed = GetTestCredential(); + autofill::PasswordForm stored_samepw = parsed; + autofill::PasswordForm stored_diffpw = parsed; + stored_diffpw.password_value = base::ASCIIToUTF16("different"); + + // The order of the two stored credentials shouldn't matter. + EXPECT_EQ(&stored_samepw, + GetMatchForUpdating(parsed, {&stored_diffpw, &stored_samepw})); + EXPECT_EQ(&stored_samepw, + GetMatchForUpdating(parsed, {&stored_samepw, &stored_diffpw})); +} + TEST(PasswordManagerUtil, MakeNormalizedBlacklistedForm_Android) { autofill::PasswordForm blacklisted_credential = MakeNormalizedBlacklistedForm( password_manager::PasswordStore::FormDigest(GetTestAndroidCredential()));
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc index 6151ac28..e0f6b80 100644 --- a/components/password_manager/core/browser/test_password_store.cc +++ b/components/password_manager/core/browser/test_password_store.cc
@@ -131,6 +131,9 @@ PasswordStoreChangeList TestPasswordStore::AddLoginImpl( const autofill::PasswordForm& form, AddLoginError* error) { + if (error) + *error = AddLoginError::kNone; + PasswordStoreChangeList changes; auto& passwords_for_signon_realm = stored_passwords_[form.signon_realm]; auto iter = std::find_if( @@ -143,23 +146,35 @@ changes.emplace_back(PasswordStoreChange::REMOVE, *iter); changes.emplace_back(PasswordStoreChange::ADD, form); *iter = form; + iter->in_store = is_account_store_ + ? autofill::PasswordForm::Store::kAccountStore + : autofill::PasswordForm::Store::kProfileStore; return changes; } changes.emplace_back(PasswordStoreChange::ADD, form); passwords_for_signon_realm.push_back(form); + passwords_for_signon_realm.back().in_store = + is_account_store_ ? autofill::PasswordForm::Store::kAccountStore + : autofill::PasswordForm::Store::kProfileStore; return changes; } PasswordStoreChangeList TestPasswordStore::UpdateLoginImpl( const autofill::PasswordForm& form, UpdateLoginError* error) { + if (error) + *error = UpdateLoginError::kNone; + PasswordStoreChangeList changes; std::vector<autofill::PasswordForm>& forms = stored_passwords_[form.signon_realm]; for (auto it = forms.begin(); it != forms.end(); ++it) { if (ArePasswordFormUniqueKeysEqual(form, *it)) { *it = form; + it->in_store = is_account_store_ + ? autofill::PasswordForm::Store::kAccountStore + : autofill::PasswordForm::Store::kProfileStore; changes.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, form)); } }
diff --git a/components/password_manager/core/browser/test_password_store.h b/components/password_manager/core/browser/test_password_store.h index d89ee97d..dd89e8c5 100644 --- a/components/password_manager/core/browser/test_password_store.h +++ b/components/password_manager/core/browser/test_password_store.h
@@ -17,9 +17,18 @@ #include "base/sequenced_task_runner.h" #include "components/password_manager/core/browser/compromised_credentials_table.h" #include "components/password_manager/core/browser/password_store.h" +#include "testing/gmock/include/gmock/gmock.h" namespace password_manager { +// A matcher that compares two PasswordForm instances but ignores the |in_store| +// member. +MATCHER_P(MatchesFormExceptStore, expected, "") { + autofill::PasswordForm arg_copy = arg; + arg_copy.in_store = expected.in_store; + return arg_copy == expected; +} + // A very simple PasswordStore implementation that keeps all of the passwords // in memory and does all its manipulations on the main thread. Since this // is only used for testing, only the parts of the interface that are needed
diff --git a/components/password_manager/core/browser/ui/bulk_leak_check_service_adapter_unittest.cc b/components/password_manager/core/browser/ui/bulk_leak_check_service_adapter_unittest.cc index 7cc2d12..59a63267 100644 --- a/components/password_manager/core/browser/ui/bulk_leak_check_service_adapter_unittest.cc +++ b/components/password_manager/core/browser/ui/bulk_leak_check_service_adapter_unittest.cc
@@ -257,6 +257,10 @@ PasswordForm password = MakeSavedPassword(kExampleCom, kUsername1, kPassword1); store().AddLogin(password); + // When |password| is read back from the store, its |in_store| member will be + // set, and SavedPasswordsPresenter::EditPassword() actually depends on that. + // So set it here too. + password.in_store = PasswordForm::Store::kProfileStore; RunUntilIdle(); EXPECT_CALL(factory(), TryCreateBulkLeakCheck).Times(0); @@ -270,6 +274,10 @@ PasswordForm password = MakeSavedPassword(kExampleCom, kUsername1, kPassword1); store().AddLogin(password); + // When |password| is read back from the store, its |in_store| member will be + // set, and SavedPasswordsPresenter::EditPassword() actually depends on that. + // So set it here too. + password.in_store = PasswordForm::Store::kProfileStore; RunUntilIdle(); std::vector<LeakCheckCredential> expected;
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc b/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc index 7dd6b75..63a1ad04 100644 --- a/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc +++ b/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc
@@ -66,7 +66,8 @@ // Adding a credential should notify observers. Furthermore, the credential // should be present of the list that is passed along. - EXPECT_CALL(observer, OnSavedPasswordsChanged(ElementsAre(form))); + EXPECT_CALL(observer, OnSavedPasswordsChanged( + ElementsAre(MatchesFormExceptStore(form)))); store().AddLogin(form); RunUntilIdle(); EXPECT_FALSE(store().IsEmpty()); @@ -122,6 +123,11 @@ RunUntilIdle(); EXPECT_FALSE(store().IsEmpty()); + // When |form| is read back from the store, its |in_store| member will be set, + // and SavedPasswordsPresenter::EditPassword() actually depends on that. So + // set it here too. + form.in_store = PasswordForm::Store::kProfileStore; + const base::string16 new_password = base::ASCIIToUTF16("new_password"); PasswordForm updated = form; updated.password_value = new_password;
diff --git a/components/payments/content/installable_payment_app_crawler.cc b/components/payments/content/installable_payment_app_crawler.cc index 25925fc..c548b99 100644 --- a/components/payments/content/installable_payment_app_crawler.cc +++ b/components/payments/content/installable_payment_app_crawler.cc
@@ -33,6 +33,7 @@ namespace payments { // TODO(crbug.com/782270): Use cache to accelerate crawling procedure. +// TODO(crbug.com/782270): Add integration tests for this class. InstallablePaymentAppCrawler::InstallablePaymentAppCrawler( const url::Origin& merchant_origin, content::RenderFrameHost* initiator_render_frame_host, @@ -43,13 +44,7 @@ : WebContentsObserver(web_contents), log_(web_contents), merchant_origin_(merchant_origin), - initiator_frame_routing_id_( - initiator_render_frame_host && - initiator_render_frame_host->GetProcess() - ? content::GlobalFrameRoutingId( - initiator_render_frame_host->GetProcess()->GetID(), - initiator_render_frame_host->GetRoutingID()) - : content::GlobalFrameRoutingId()), + initiator_render_frame_host_(initiator_render_frame_host), downloader_(downloader), parser_(parser), number_of_payment_method_manifest_to_download_(0), @@ -412,21 +407,13 @@ number_of_web_app_icons_to_download_and_decode_++; - // If the initiator frame doesn't exists any more, e.g. the frame has - // navigated away, don't download the icon. - // TODO(crbug.com/1058840): Move this sanity check to ManifestIconDownloader - // after DownloadImage refactor is done. - content::RenderFrameHost* render_frame_host = - content::RenderFrameHost::FromID(initiator_frame_routing_id_); - if (!render_frame_host || !render_frame_host->IsCurrent() || - content::WebContents::FromRenderFrameHost(render_frame_host) != - web_contents()) { - // Shortcircuit to the done callback with an empty bitmap. - OnPaymentWebAppIconDownloadAndDecoded(method_manifest_url, - web_app_manifest_url, SkBitmap()); - return; + content::GlobalFrameRoutingId frame_routing_id; + if (initiator_render_frame_host_ && + initiator_render_frame_host_->GetProcess()) { + frame_routing_id = content::GlobalFrameRoutingId( + initiator_render_frame_host_->GetProcess()->GetID(), + initiator_render_frame_host_->GetRoutingID()); } - bool can_download_icon = content::ManifestIconDownloader::Download( web_contents(), downloader_->FindTestServerURL(best_icon_url), IconSizeCalculator::IdealIconHeight(native_view), @@ -436,7 +423,7 @@ weak_ptr_factory_.GetWeakPtr(), method_manifest_url, web_app_manifest_url), false, /* square_only */ - initiator_frame_routing_id_); + frame_routing_id); DCHECK(can_download_icon); }
diff --git a/components/payments/content/installable_payment_app_crawler.h b/components/payments/content/installable_payment_app_crawler.h index 7b49e2d..fdad1391 100644 --- a/components/payments/content/installable_payment_app_crawler.h +++ b/components/payments/content/installable_payment_app_crawler.h
@@ -19,7 +19,6 @@ #include "components/payments/content/utility/payment_manifest_parser.h" #include "components/payments/content/web_app_manifest.h" #include "components/payments/core/payment_manifest_downloader.h" -#include "content/public/browser/global_routing_id.h" #include "content/public/browser/web_contents_observer.h" #include "third_party/blink/public/mojom/payments/payment_request.mojom.h" #include "url/origin.h" @@ -112,7 +111,7 @@ DeveloperConsoleLogger log_; const url::Origin merchant_origin_; - const content::GlobalFrameRoutingId initiator_frame_routing_id_; + content::RenderFrameHost* initiator_render_frame_host_; PaymentManifestDownloader* downloader_; PaymentManifestParser* parser_; FinishedCrawlingCallback callback_;
diff --git a/components/safe_browsing/core/db/v4_get_hash_protocol_manager.cc b/components/safe_browsing/core/db/v4_get_hash_protocol_manager.cc index 268285f..cbcb0a6 100644 --- a/components/safe_browsing/core/db/v4_get_hash_protocol_manager.cc +++ b/components/safe_browsing/core/db/v4_get_hash_protocol_manager.cc
@@ -16,7 +16,6 @@ #include "base/timer/timer.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" -#include "build/build_config.h" #include "components/safe_browsing/core/common/thread_utils.h" #include "net/base/load_flags.h" #include "net/http/http_response_headers.h" @@ -301,12 +300,6 @@ return; } - // TODO(crbug.com/1028755): Enable full hash checks on iOS. -#if defined(OS_IOS) - std::move(callback).Run(cached_full_hash_infos); - return; -#endif - net::NetworkTrafficAnnotationTag traffic_annotation = net::DefineNetworkTrafficAnnotation("safe_browsing_v4_get_hash", R"( semantics { @@ -779,12 +772,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(CurrentlyOnThread(ThreadID::IO)); - // Ensure that full hash requests are not being sent on iOS. - // TODO(crbug.com/1028755): Enable full hash checks on iOS. -#if defined(OS_IOS) - CHECK(false); -#endif - int response_code = 0; if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers) response_code = url_loader->ResponseInfo()->headers->response_code();
diff --git a/components/safe_browsing/ios/BUILD.gn b/components/safe_browsing/ios/BUILD.gn index 4622ac5..c273050 100644 --- a/components/safe_browsing/ios/BUILD.gn +++ b/components/safe_browsing/ios/BUILD.gn
@@ -12,7 +12,7 @@ "//components/safe_browsing/core/browser", "//components/safe_browsing/core/common", "//components/safe_browsing/core/common:unit_tests", - "//components/safe_browsing/core/db", + "//components/safe_browsing/core/db:unit_tests_local_db", "//components/safe_browsing/core/realtime:unit_tests", ] }
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc index 429bedf..89485e8 100644 --- a/components/startup_metric_utils/browser/startup_metric_utils.cc +++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -42,9 +42,9 @@ base::TimeTicks g_process_creation_ticks; -base::TimeTicks g_browser_main_entry_point_ticks; +base::TimeTicks g_application_start_ticks; -base::TimeTicks g_browser_exe_main_entry_point_ticks; +base::TimeTicks g_chrome_main_entry_ticks; base::TimeTicks g_message_loop_start_ticks; @@ -346,13 +346,14 @@ return trace_ticks_base - delta_since_base; } -void AddStartupEventsForTelemetry() -{ - DCHECK(!g_browser_main_entry_point_ticks.is_null()); +void AddStartupEventsForTelemetry() { + // Record the event only if RecordChromeMainEntryTime() was called, which is + // not the case for some tests. + if (g_chrome_main_entry_ticks.is_null()) + return; - TRACE_EVENT_INSTANT_WITH_TIMESTAMP0("startup", - "Startup.BrowserMainEntryPoint", 0, - g_browser_main_entry_point_ticks); + TRACE_EVENT_INSTANT_WITH_TIMESTAMP0( + "startup", "Startup.BrowserMainEntryPoint", 0, g_chrome_main_entry_ticks); } bool ShouldLogStartupHistogram() { @@ -380,16 +381,16 @@ DCHECK(!g_process_creation_ticks.is_null()); } -void RecordMainEntryPointTime(base::TimeTicks ticks) { - DCHECK(g_browser_main_entry_point_ticks.is_null()); - g_browser_main_entry_point_ticks = ticks; - DCHECK(!g_browser_main_entry_point_ticks.is_null()); +void RecordApplicationStartTime(base::TimeTicks ticks) { + DCHECK(g_application_start_ticks.is_null()); + g_application_start_ticks = ticks; + DCHECK(!g_application_start_ticks.is_null()); } -void RecordExeMainEntryPointTicks(base::TimeTicks ticks) { - DCHECK(g_browser_exe_main_entry_point_ticks.is_null()); - g_browser_exe_main_entry_point_ticks = ticks; - DCHECK(!g_browser_exe_main_entry_point_ticks.is_null()); +void RecordChromeMainEntryTime(base::TimeTicks ticks) { + DCHECK(g_chrome_main_entry_ticks.is_null()); + g_chrome_main_entry_ticks = ticks; + DCHECK(!g_chrome_main_entry_ticks.is_null()); } void RecordMessageLoopStartTicks(base::TimeTicks ticks) { @@ -434,24 +435,19 @@ // Record timings between process creation, the main() in the executable being // reached and the main() in the shared library being reached. if (!g_process_creation_ticks.is_null() && - !g_browser_exe_main_entry_point_ticks.is_null()) { - // Process create to chrome.exe:main(). + !g_application_start_ticks.is_null()) { + // Process create to application start. UmaHistogramWithTraceAndTemperature( &base::UmaHistogramLongTimes, - "Startup.LoadTime.ProcessCreateToExeMain2", g_process_creation_ticks, - g_browser_exe_main_entry_point_ticks); + "Startup.LoadTime.ProcessCreateToApplicationStart", + g_process_creation_ticks, g_application_start_ticks); - // chrome.exe:main() to chrome.dll:main(). + // Application start to ChromeMain(). + DCHECK(!g_chrome_main_entry_ticks.is_null()); UmaHistogramWithTraceAndTemperature( - &base::UmaHistogramLongTimes, "Startup.LoadTime.ExeMainToDllMain2", - g_browser_exe_main_entry_point_ticks, g_browser_main_entry_point_ticks); - - // Process create to chrome.dll:main(). Reported as a histogram only as - // the other two events above are sufficient for tracing purposes. - UmaHistogramWithTemperature( &base::UmaHistogramLongTimes, - "Startup.LoadTime.ProcessCreateToDllMain2", - g_browser_main_entry_point_ticks - g_process_creation_ticks); + "Startup.LoadTime.ApplicationStartToChromeMain", + g_application_start_ticks, g_chrome_main_entry_ticks); } } @@ -485,6 +481,10 @@ UmaHistogramAndTraceWithTemperatureAndMaxPressure( &base::UmaHistogramLongTimes100, "Startup.FirstWebContents.NonEmptyPaint2", g_process_creation_ticks, now); + UmaHistogramAndTraceWithTemperatureAndMaxPressure( + &base::UmaHistogramLongTimes100, + "Startup.FirstWebContents.NonEmptyPaint3", g_application_start_ticks, + now); UmaHistogramWithTemperature( &base::UmaHistogramLongTimes100, "Startup.BrowserMessageLoopStart.To.NonEmptyPaint2", @@ -553,7 +553,7 @@ } base::TimeTicks MainEntryPointTicks() { - return g_browser_main_entry_point_ticks; + return g_chrome_main_entry_ticks; } void RecordWebFooterDidFirstVisuallyNonEmptyPaint(base::TimeTicks ticks) {
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.h b/components/startup_metric_utils/browser/startup_metric_utils.h index e6d4a08..3168bb4 100644 --- a/components/startup_metric_utils/browser/startup_metric_utils.h +++ b/components/startup_metric_utils/browser/startup_metric_utils.h
@@ -36,14 +36,14 @@ void RecordStartupProcessCreationTime(base::Time time); // Call this with a time recorded as early as possible in the startup process. -// On Android, the entry point time is the time at which the Java code starts. -// In Mojo, the entry point time is the time at which the shell starts. -void RecordMainEntryPointTime(base::TimeTicks ticks); +// On Android, the application start is the time at which the Java code starts. +// On Windows, the application start is sampled from chrome.exe:main, before +// chrome.dll is loaded. +void RecordApplicationStartTime(base::TimeTicks ticks); -// Call this with the time when the executable is loaded and main() is entered. -// Can be different from |RecordMainEntryPointTime| when the startup process is -// contained in a separate dll, such as with chrome.exe / chrome.dll on Windows. -void RecordExeMainEntryPointTicks(base::TimeTicks ticks); +// Call this with the time when the executable is loaded and the ChromeMain() +// function is invoked. +void RecordChromeMainEntryTime(base::TimeTicks ticks); // Call this with the time recorded just before the message loop is started. // |is_first_run| - is the current launch part of a first run.
diff --git a/components/viz/service/display/process_renderer_perftest_results.py b/components/viz/service/display/process_renderer_perftest_results.py new file mode 100755 index 0000000..588dece3 --- /dev/null +++ b/components/viz/service/display/process_renderer_perftest_results.py
@@ -0,0 +1,98 @@ +#!/usr/bin/env python +# Copyright 2020 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. +"""Script which process RendererPerfTest output. + +Run viz_perftests.exe --gtest_filter=RendererPerfTest* > stdout.txt. +Then run this script as + python process_renderer_perftest_results.py --test-stdout="stdout.txt" + +The perf data will be collected and stored in "output.csv". +""" + +import argparse +import csv +import logging +import sys + + +def SaveResultsAsCSV(csv_data, csv_filename): + assert len(csv_data) > 0 + with open(csv_filename, 'wb') as csv_file: + labels = sorted(csv_data[0].keys(), reverse=True) + writer = csv.DictWriter(csv_file, fieldnames=labels) + writer.writeheader() + writer.writerows(csv_data) + + +def FindTestEntry(csv_data, test_name): + for entry in csv_data: + if entry['TestName'] == test_name: + return entry + return None + + +def ProcessOutput(lines): + csv_data = [] + for line in lines: + line = line.strip() + if line.startswith('[ RUN ]'): + test_name = line.split('.')[1] + entry = FindTestEntry(csv_data, test_name) + if entry is None: + entry = {'TestName': test_name} + csv_data.append(entry) + elif line.startswith('Using '): + renderer = line.split()[1][:-8] + elif line.startswith('*RESULT '): + fps = line.split('=')[1].strip().split()[0] + assert renderer == 'GL' or renderer == 'Skia' + assert entry is not None + entry['FPS_' + renderer] = fps + elif line.startswith('Histogram: '): + draw_to_swap_us_mean = line.split('=')[1].strip() + assert renderer == 'GL' or renderer == 'Skia' + assert entry is not None + entry['DrawToSwap_' + renderer] = draw_to_swap_us_mean + elif line.startswith('[ OK ]'): + end_test_name = line.split('.')[1].split()[0] + assert test_name == end_test_name + test_name = None + entry = None + renderer = None + return csv_data + + +def main(): + rest_args = sys.argv[1:] + parser = argparse.ArgumentParser( + description='Gather RendererPerfTest results.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument( + '--test-stdout', + metavar='FILE', + help='Test stdout filename. Input of this script.') + parser.add_argument( + '--csv-file', + metavar='FILE', + default='output.csv', + help='CSV filename. Output of this script. ' + 'Default is output.csv.') + + options = parser.parse_args(rest_args) + input_filename = options.test_stdout + if input_filename is None: + logging.error('Specify test stdout filename with --test-stdout.') + return 0 + + with open(input_filename, 'r') as input_file: + lines = input_file.readlines() + + csv_data = ProcessOutput(lines) + SaveResultsAsCSV(csv_data, options.csv_file) + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 93348ce..442d7d34 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -3601,7 +3601,7 @@ // Trilinear filtering is only supported in the gl renderer. // TODO(https://crbug.com/1044841): Flaky, especially on Linux/TSAN and Fuchsia. -TYPED_TEST(GPURendererPixelTest, DISABLED_TrilinearFiltering) { +TYPED_TEST(GPURendererPixelTest, TrilinearFiltering) { gfx::Rect viewport_rect(this->device_viewport_size_); int root_pass_id = 1;
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index 4b92312..12baf4e 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -50,6 +50,7 @@ #include "third_party/isimpledom/ISimpleDOMNode.h" #include "ui/accessibility/accessibility_switches.h" #include "ui/accessibility/ax_event_generator.h" +#include "ui/accessibility/platform/ax_fragment_root_win.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" @@ -4267,6 +4268,44 @@ } IN_PROC_BROWSER_TEST_F(AccessibilityWinUIABrowserTest, + GetFocusFromRootReachesWebContent) { + LoadInitialAccessibilityTreeFromHtml( + R"HTML(<!DOCTYPE html> + <html> + <button>Focus target</button> + <script> + document.querySelector('button').focus(); + </script> + </html>)HTML"); + + // Obtain the fragment root from the top-level HWND. + HWND hwnd = shell()->window()->GetHost()->GetAcceleratedWidget(); + ASSERT_NE(gfx::kNullAcceleratedWidget, hwnd); + ui::AXFragmentRootWin* fragment_root = + ui::AXFragmentRootWin::GetForAcceleratedWidget(hwnd); + ASSERT_NE(nullptr, fragment_root); + Microsoft::WRL::ComPtr<IRawElementProviderFragmentRoot> uia_fragment_root; + ASSERT_HRESULT_SUCCEEDED( + fragment_root->GetNativeViewAccessible()->QueryInterface( + IID_PPV_ARGS(&uia_fragment_root))); + + // Verify that calling GetFocus on the fragment root reaches web content. + Microsoft::WRL::ComPtr<IRawElementProviderFragment> focused_fragment; + ASSERT_HRESULT_SUCCEEDED(uia_fragment_root->GetFocus(&focused_fragment)); + + Microsoft::WRL::ComPtr<IRawElementProviderSimple> focused_element; + ASSERT_HRESULT_SUCCEEDED(focused_fragment.As(&focused_element)); + + base::win::ScopedVariant name_property; + ASSERT_HRESULT_SUCCEEDED(focused_element->GetPropertyValue( + UIA_NamePropertyId, name_property.Receive())); + ASSERT_EQ(name_property.type(), VT_BSTR); + BSTR name_bstr = name_property.ptr()->bstrVal; + base::string16 actual_name(name_bstr, ::SysStringLen(name_bstr)); + EXPECT_EQ(L"Focus target", actual_name); +} + +IN_PROC_BROWSER_TEST_F(AccessibilityWinUIABrowserTest, LegacyWindowIsNotControlElement) { LoadInitialAccessibilityTreeFromHtml( R"HTML(<!DOCTYPE html>
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index 688bbeb..f346780 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -765,14 +765,13 @@ EXPECT_TRUE(NavigateToURL(popup, url_b)); EXPECT_EQ(1u, rfh_a_new->GetSiteInstance()->GetRelatedActiveContentsCount()); - // 5) Navigate to B again. In theory, the current document should be able to - // enter the BackForwardCache. It can't, because the RenderFrameHost still - // "remembers" it had access to the popup. See - // RenderFrameHostImpl::scheduler_tracked_features(). + // 5) Navigate to B again. As the scripting relationship with the popup is + // now severed, the current page (|rfh_a_new|) can enter back-forward cache. RenderFrameDeletedObserver delete_observer_rfh_a_new(rfh_a_new); EXPECT_TRUE(ExecJs(rfh_a_new, JsReplace("location = $1;", url_b.spec()))); EXPECT_TRUE(WaitForLoadStop(web_contents())); - delete_observer_rfh_a_new.WaitUntilDeleted(); + EXPECT_FALSE(delete_observer_rfh_a_new.deleted()); + EXPECT_TRUE(rfh_a_new->is_in_back_forward_cache()); // 6) Go back to A. The current document can finally enter the // BackForwardCache, because it is alone in its BrowsingInstance and has never
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc index 828078d..22e7abc 100644 --- a/content/browser/devtools/devtools_instrumentation.cc +++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -358,7 +358,7 @@ // No other overrides, so just returns ours as is. *factory_override = network::mojom::URLLoaderFactoryOverride::New( std::move(devtools_override.overriding_factory), - std::move(devtools_override.overridden_factory_receiver)); + std::move(devtools_override.overridden_factory_receiver), false); } // ... else things are already taken care of, as handler_override was pointing // to factory override and we've done all magic in-place. @@ -410,7 +410,7 @@ if (!*factory_override) { *factory_override = network::mojom::URLLoaderFactoryOverride::New( std::move(devtools_override.overriding_factory), - std::move(devtools_override.overridden_factory_receiver)); + std::move(devtools_override.overridden_factory_receiver), false); } return true; }
diff --git a/content/browser/devtools/protocol/emulation_handler.cc b/content/browser/devtools/protocol/emulation_handler.cc index 8a0f582..f7b9bdf 100644 --- a/content/browser/devtools/protocol/emulation_handler.cc +++ b/content/browser/devtools/protocol/emulation_handler.cc
@@ -19,7 +19,6 @@ #include "services/device/public/cpp/geolocation/geoposition.h" #include "services/device/public/mojom/geolocation_context.mojom.h" #include "services/device/public/mojom/geoposition.mojom.h" -#include "third_party/blink/public/mojom/devtools/device_emulation_params.mojom.h" #include "ui/events/gesture_detection/gesture_provider_config_helper.h" namespace content { @@ -27,17 +26,17 @@ namespace { -blink::mojom::ScreenOrientationType ScreenOrientationFromString( +blink::WebScreenOrientationType WebScreenOrientationTypeFromString( const std::string& type) { if (type == Emulation::ScreenOrientation::TypeEnum::PortraitPrimary) - return blink::mojom::ScreenOrientationType::kPortraitPrimary; + return blink::kWebScreenOrientationPortraitPrimary; if (type == Emulation::ScreenOrientation::TypeEnum::PortraitSecondary) - return blink::mojom::ScreenOrientationType::kPortraitSecondary; + return blink::kWebScreenOrientationPortraitSecondary; if (type == Emulation::ScreenOrientation::TypeEnum::LandscapePrimary) - return blink::mojom::ScreenOrientationType::kLandscapePrimary; + return blink::kWebScreenOrientationLandscapePrimary; if (type == Emulation::ScreenOrientation::TypeEnum::LandscapeSecondary) - return blink::mojom::ScreenOrientationType::kLandscapeSecondary; - return blink::mojom::ScreenOrientationType::kUndefined; + return blink::kWebScreenOrientationLandscapeSecondary; + return blink::kWebScreenOrientationUndefined; } ui::GestureProviderConfigType TouchEmulationConfigurationToType( @@ -60,6 +59,7 @@ EmulationHandler::EmulationHandler() : DevToolsDomainHandler(Emulation::Metainfo::domainName), touch_emulation_enabled_(false), + device_emulation_enabled_(false), host_(nullptr) { } @@ -80,7 +80,7 @@ host_ = frame_host; if (touch_emulation_enabled_) UpdateTouchEventEmulationState(); - if (device_emulation_params_) + if (device_emulation_enabled_) UpdateDeviceEmulationState(); } @@ -94,8 +94,8 @@ UpdateTouchEventEmulationState(); } user_agent_ = std::string(); - if (device_emulation_params_) { - device_emulation_params_.reset(); + if (device_emulation_enabled_) { + device_emulation_enabled_ = false; UpdateDeviceEmulationState(); } return Response::OK(); @@ -205,13 +205,14 @@ base::NumberToString(max_scale)); } - blink::mojom::ScreenOrientationType orientation_type = - blink::mojom::ScreenOrientationType::kUndefined; + blink::WebScreenOrientationType orientationType = + blink::kWebScreenOrientationUndefined; int orientationAngle = 0; if (screen_orientation.isJust()) { Emulation::ScreenOrientation* orientation = screen_orientation.fromJust(); - orientation_type = ScreenOrientationFromString(orientation->GetType()); - if (orientation_type == blink::mojom::ScreenOrientationType::kUndefined) + orientationType = WebScreenOrientationTypeFromString( + orientation->GetType()); + if (orientationType == blink::kWebScreenOrientationUndefined) return Response::InvalidParams("Invalid screen orientation type value"); orientationAngle = orientation->GetAngle(); if (orientationAngle < 0 || orientationAngle >= max_orientation_angle) { @@ -222,23 +223,23 @@ } blink::WebDeviceEmulationParams params; - params.screen_position = mobile ? blink::mojom::ScreenPosition::kMobile - : blink::mojom::ScreenPosition::kDesktop; + params.screen_position = mobile ? blink::WebDeviceEmulationParams::kMobile + : blink::WebDeviceEmulationParams::kDesktop; params.screen_size = - gfx::Size(screen_width.fromMaybe(0), screen_height.fromMaybe(0)); + blink::WebSize(screen_width.fromMaybe(0), screen_height.fromMaybe(0)); if (position_x.isJust() && position_y.isJust()) { params.view_position = gfx::Point(position_x.fromMaybe(0), position_y.fromMaybe(0)); } params.device_scale_factor = device_scale_factor; - params.view_size = gfx::Size(width, height); + params.view_size = blink::WebSize(width, height); params.scale = scale.fromMaybe(1); - params.screen_orientation_type = orientation_type; + params.screen_orientation_type = orientationType; params.screen_orientation_angle = orientationAngle; if (viewport.isJust()) { - params.viewport_offset = - gfx::PointF(viewport.fromJust()->GetX(), viewport.fromJust()->GetY()); + params.viewport_offset.SetPoint(viewport.fromJust()->GetX(), + viewport.fromJust()->GetY()); ScreenInfo screen_info; host_->GetRenderWidgetHost()->GetScreenInfo(&screen_info); @@ -264,7 +265,7 @@ } } - if (device_emulation_params_ && *device_emulation_params_ == params) { + if (device_emulation_enabled_ && params == device_emulation_params_) { // Renderer should answer after size was changed, so that the response is // only sent to the client once updates were applied. if (size_changed) @@ -272,7 +273,8 @@ return Response::OK(); } - device_emulation_params_ = std::move(params); + device_emulation_enabled_ = true; + device_emulation_params_ = params; UpdateDeviceEmulationState(); // Renderer should answer after emulation params were updated, so that the @@ -284,12 +286,13 @@ } Response EmulationHandler::ClearDeviceMetricsOverride() { - if (!device_emulation_params_) + if (!device_emulation_enabled_) return Response::OK(); if (!host_) return Response::Error("Can't find the associated web contents"); GetWebContents()->ClearDeviceEmulationSize(); - device_emulation_params_.reset(); + device_emulation_enabled_ = false; + device_emulation_params_ = blink::WebDeviceEmulationParams(); UpdateDeviceEmulationState(); // Renderer should answer after emulation was disabled, so that the response // is only sent to the client once updates were applied. @@ -326,15 +329,20 @@ return Response::FallThrough(); } -const base::Optional<blink::WebDeviceEmulationParams>& -EmulationHandler::GetDeviceEmulationParams() const { +blink::WebDeviceEmulationParams EmulationHandler::GetDeviceEmulationParams() { return device_emulation_params_; } void EmulationHandler::SetDeviceEmulationParams( - const base::Optional<blink::WebDeviceEmulationParams>& params) { - if (params == device_emulation_params_) - return; + const blink::WebDeviceEmulationParams& params) { + bool enabled = params != blink::WebDeviceEmulationParams(); + bool enable_changed = enabled != device_emulation_enabled_; + bool params_changed = params != device_emulation_params_; + if (!device_emulation_enabled_ && !enable_changed) + return; // Still disabled. + if (!enable_changed && !params_changed) + return; // Nothing changed. + device_emulation_enabled_ = enabled; device_emulation_params_ = params; UpdateDeviceEmulationState(); } @@ -373,11 +381,21 @@ if (!host_->frame_tree_node()->IsMainFrame()) return; - // TODO(caseq,eseckler): We should wait for an ack to these messages from the - // renderer. The renderer should send the ack once the emulation params were - // applied. That way, we can avoid having to handle - // Set/ClearDeviceMetricsOverride in the renderer. - host_->SetDeviceEmulation(device_emulation_params_); + // TODO(eseckler): Once we change this to mojo, we should wait for an ack to + // these messages from the renderer. The renderer should send the ack once the + // emulation params were applied. That way, we can avoid having to handle + // Set/ClearDeviceMetricsOverride in the renderer. With the old IPC system, + // this is tricky since we'd have to track the DevTools message id with the + // WidgetMsg and acknowledgment, as well as plump the acknowledgment back to + // the EmulationHandler somehow. Mojo callbacks should make this much simpler. + if (device_emulation_enabled_) { + host_->GetRenderWidgetHost()->Send(new WidgetMsg_EnableDeviceEmulation( + host_->GetRenderWidgetHost()->GetRoutingID(), + device_emulation_params_)); + } else { + host_->GetRenderWidgetHost()->Send(new WidgetMsg_DisableDeviceEmulation( + host_->GetRenderWidgetHost()->GetRoutingID())); + } } void EmulationHandler::ApplyOverrides(net::HttpRequestHeaders* headers) {
diff --git a/content/browser/devtools/protocol/emulation_handler.h b/content/browser/devtools/protocol/emulation_handler.h index 828bc9b..5890b67 100644 --- a/content/browser/devtools/protocol/emulation_handler.h +++ b/content/browser/devtools/protocol/emulation_handler.h
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "content/browser/devtools/protocol/devtools_domain_handler.h" #include "content/browser/devtools/protocol/emulation.h" -#include "third_party/blink/public/mojom/devtools/device_emulation_params.mojom.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" namespace net { class HttpRequestHeaders; @@ -68,12 +68,10 @@ Response SetVisibleSize(int width, int height) override; - const base::Optional<blink::WebDeviceEmulationParams>& - GetDeviceEmulationParams() const; - void SetDeviceEmulationParams( - const base::Optional<blink::WebDeviceEmulationParams>& params); + blink::WebDeviceEmulationParams GetDeviceEmulationParams(); + void SetDeviceEmulationParams(const blink::WebDeviceEmulationParams& params); - bool device_emulation_enabled() const { return !!device_emulation_params_; } + bool device_emulation_enabled() { return device_emulation_enabled_; } void ApplyOverrides(net::HttpRequestHeaders* headers); @@ -85,7 +83,8 @@ bool touch_emulation_enabled_; std::string touch_emulation_configuration_; - base::Optional<blink::WebDeviceEmulationParams> device_emulation_params_; + bool device_emulation_enabled_; + blink::WebDeviceEmulationParams device_emulation_params_; std::string user_agent_; std::string accept_language_;
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc index 2a76ec9..1516029 100644 --- a/content/browser/devtools/protocol/page_handler.cc +++ b/content/browser/devtools/protocol/page_handler.cc
@@ -678,7 +678,8 @@ base::BindOnce(&PageHandler::ScreenshotCaptured, weak_factory_.GetWeakPtr(), base::Passed(std::move(callback)), screenshot_format, - screenshot_quality, gfx::Size(), gfx::Size(), nullptr), + screenshot_quality, gfx::Size(), gfx::Size(), + blink::WebDeviceEmulationParams()), false); return; } @@ -686,13 +687,9 @@ // Welcome to the neural net of capturing screenshot while emulating device // metrics! bool emulation_enabled = emulation_handler_->device_emulation_enabled(); - std::unique_ptr<blink::WebDeviceEmulationParams> original_params; - blink::WebDeviceEmulationParams modified_params; - if (emulation_enabled) { - original_params = std::make_unique<blink::WebDeviceEmulationParams>( - *emulation_handler_->GetDeviceEmulationParams()); - modified_params = *original_params; - } + blink::WebDeviceEmulationParams original_params = + emulation_handler_->GetDeviceEmulationParams(); + blink::WebDeviceEmulationParams modified_params = original_params; // Capture original view size if we know we are going to destroy it. We use // it in ScreenshotCaptured to restore. @@ -706,17 +703,16 @@ ScreenInfo screen_info; widget_host->GetScreenInfo(&screen_info); if (emulation_enabled) { - DCHECK(original_params); // When emulating, emulate again and scale to make resulting image match - // physical DP resolution. If view_size is not overridden, use actual view + // physical DP resolution. If view_size is not overriden, use actual view // size. float original_scale = - original_params->scale > 0 ? original_params->scale : 1; - if (!modified_params.view_size.width()) { + original_params.scale > 0 ? original_params.scale : 1; + if (!modified_params.view_size.width) { emulated_view_size.set_width( ceil(original_view_size.width() / original_scale)); } - if (!modified_params.view_size.height()) { + if (!modified_params.view_size.height) { emulated_view_size.set_height( ceil(original_view_size.height() / original_scale)); } @@ -728,19 +724,22 @@ // When clip is specified, we scale viewport via clip, otherwise we use // scale. modified_params.scale = clip.isJust() ? 1 : dpfactor; - modified_params.view_size = emulated_view_size; + modified_params.view_size.width = emulated_view_size.width(); + modified_params.view_size.height = emulated_view_size.height(); } else if (clip.isJust()) { // When not emulating, still need to emulate the page size. - modified_params.view_size = original_view_size; - modified_params.screen_size = gfx::Size(); + modified_params.view_size.width = original_view_size.width(); + modified_params.view_size.height = original_view_size.height(); + modified_params.screen_size.width = 0; + modified_params.screen_size.height = 0; modified_params.device_scale_factor = 0; modified_params.scale = 1; } // Set up viewport in renderer. if (clip.isJust()) { - modified_params.viewport_offset = - gfx::PointF(clip.fromJust()->GetX(), clip.fromJust()->GetY()); + modified_params.viewport_offset.SetPoint(clip.fromJust()->GetX(), + clip.fromJust()->GetY()); modified_params.viewport_scale = clip.fromJust()->GetScale() * dpfactor; if (IsUseZoomForDSFEnabled()) { modified_params.viewport_offset.Scale(screen_info.device_scale_factor); @@ -768,7 +767,7 @@ } else { requested_image_size = emulated_view_size; } - double scale = emulation_enabled ? original_params->device_scale_factor + double scale = emulation_enabled ? original_params.device_scale_factor : screen_info.device_scale_factor; if (clip.isJust()) scale *= clip.fromJust()->GetScale(); @@ -780,7 +779,7 @@ weak_factory_.GetWeakPtr(), base::Passed(std::move(callback)), screenshot_format, screenshot_quality, original_view_size, - requested_image_size, std::move(original_params)), + requested_image_size, original_params), true); } @@ -1107,16 +1106,12 @@ int quality, const gfx::Size& original_view_size, const gfx::Size& requested_image_size, - std::unique_ptr<blink::WebDeviceEmulationParams> original_emulation_params, + const blink::WebDeviceEmulationParams& original_emulation_params, const gfx::Image& image) { if (original_view_size.width()) { RenderWidgetHostImpl* widget_host = host_->GetRenderWidgetHost(); widget_host->GetView()->SetSize(original_view_size); - if (original_emulation_params) { - emulation_handler_->SetDeviceEmulationParams(*original_emulation_params); - } else { - emulation_handler_->SetDeviceEmulationParams(base::nullopt); - } + emulation_handler_->SetDeviceEmulationParams(original_emulation_params); } if (image.IsEmpty()) {
diff --git a/content/browser/devtools/protocol/page_handler.h b/content/browser/devtools/protocol/page_handler.h index 107117f..b84d23a5 100644 --- a/content/browser/devtools/protocol/page_handler.h +++ b/content/browser/devtools/protocol/page_handler.h
@@ -183,14 +183,14 @@ std::unique_ptr<Page::ScreencastFrameMetadata> metadata, const protocol::Binary& data); - void ScreenshotCaptured(std::unique_ptr<CaptureScreenshotCallback> callback, - const std::string& format, - int quality, - const gfx::Size& original_view_size, - const gfx::Size& requested_image_size, - std::unique_ptr<blink::WebDeviceEmulationParams> - original_emulation_params, - const gfx::Image& image); + void ScreenshotCaptured( + std::unique_ptr<CaptureScreenshotCallback> callback, + const std::string& format, + int quality, + const gfx::Size& original_view_size, + const gfx::Size& requested_image_size, + const blink::WebDeviceEmulationParams& original_params, + const gfx::Image& image); void GotManifest(std::unique_ptr<GetAppManifestCallback> callback, const GURL& manifest_url,
diff --git a/content/browser/frame_host/back_forward_cache_impl.cc b/content/browser/frame_host/back_forward_cache_impl.cc index 2de9a62..b7c636b1 100644 --- a/content/browser/frame_host/back_forward_cache_impl.cc +++ b/content/browser/frame_host/back_forward_cache_impl.cc
@@ -118,8 +118,6 @@ FeatureToBit( WebSchedulerTrackedFeature::kOutstandingIndexedDBTransaction) | FeatureToBit( - WebSchedulerTrackedFeature::kHasScriptableFramesInMultipleTabs) | - FeatureToBit( WebSchedulerTrackedFeature::kRequestedNotificationsPermission) | FeatureToBit(WebSchedulerTrackedFeature::kRequestedMIDIPermission) | FeatureToBit(
diff --git a/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc b/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc index ffcefd9..bc9061e96 100644 --- a/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc +++ b/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc
@@ -37,10 +37,6 @@ constexpr uint64_t kPageShowFeature = static_cast<uint64_t>( blink::scheduler::WebSchedulerTrackedFeature::kPageShowEventListener); -constexpr uint64_t kHasScriptableFramesInMultipleTabsFeature = - static_cast<uint64_t>(blink::scheduler::WebSchedulerTrackedFeature:: - kHasScriptableFramesInMultipleTabs); - constexpr uint64_t kRequestedGeolocationPermissionFeature = static_cast<uint64_t>(blink::scheduler::WebSchedulerTrackedFeature:: kRequestedGeolocationPermission); @@ -648,118 +644,6 @@ blink::scheduler::WebSchedulerTrackedFeature::kSharedWorker)); } -IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsBrowserTest, - WindowOpen_SameOrigin) { - ukm::TestAutoSetUkmRecorder recorder; - - const GURL url1(embedded_test_server()->GetURL("/title1.html")); - const GURL url2(embedded_test_server()->GetURL("/title2.html")); - - EXPECT_TRUE(NavigateToURL(shell(), url1)); - - ShellAddedObserver observer; - EXPECT_TRUE(ExecJs(shell(), JsReplace("window.open($1, '_blank');", url2))); - Shell* shell2 = observer.GetShell(); - EXPECT_TRUE(WaitForLoadStop(shell2->web_contents())); - - EXPECT_TRUE(NavigateToURL(shell(), url2)); - - { - // We emit metrics when we navigate back to the previously visited page, - // so navigate back to trigger the metrics. - TestNavigationObserver navigation_observer(shell()->web_contents()); - shell()->GoBackOrForward(-1); - navigation_observer.WaitForNavigationFinished(); - } - - ASSERT_EQ(navigation_ids_.size(), static_cast<size_t>(3)); - // ukm::SourceId id1 = ToSourceId(navigation_ids_[0]); - // ukm::SourceId id2 = ToSourceId(navigation_ids_[1]); - ukm::SourceId id3 = ToSourceId(navigation_ids_[2]); - - EXPECT_THAT(GetFeatureUsageMetrics(&recorder), - testing::ElementsAre(FeatureUsage{ - id3, 1 << kHasScriptableFramesInMultipleTabsFeature, 0, 0})); -} - -IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsBrowserTest, - WindowOpen_CrossOrigin) { - ukm::TestAutoSetUkmRecorder recorder; - - const GURL url1(embedded_test_server()->GetURL("/title1.html")); - const GURL url2(embedded_test_server()->GetURL("/title2.html")); - const GURL url3( - embedded_test_server()->GetURL("/cross-site/bar.com/title3.html")); - - EXPECT_TRUE(NavigateToURL(shell(), url1)); - - ShellAddedObserver observer; - EXPECT_TRUE(ExecJs(shell(), JsReplace("window.open($1, '_blank');", url3))); - - Shell* shell2 = observer.GetShell(); - EXPECT_TRUE(WaitForLoadStop(shell2->web_contents())); - - EXPECT_TRUE(NavigateToURL(shell(), url2)); - - { - // We emit metrics when we navigate back to the previously visited page, - // so navigate back to trigger the metrics. - TestNavigationObserver navigation_observer(shell()->web_contents()); - shell()->GoBackOrForward(-1); - navigation_observer.WaitForNavigationFinished(); - } - - ASSERT_EQ(navigation_ids_.size(), static_cast<size_t>(3)); - // ukm::SourceId id1 = ToSourceId(navigation_ids_[0]); - // ukm::SourceId id2 = ToSourceId(navigation_ids_[1]); - ukm::SourceId id3 = ToSourceId(navigation_ids_[2]); - - // TODO(altimin): For now we don't distinguish between same-origin and - // cross-origin window.opens. We might want to revisit this in the future. - EXPECT_THAT(GetFeatureUsageMetrics(&recorder), - testing::ElementsAre(FeatureUsage{ - id3, 1 << kHasScriptableFramesInMultipleTabsFeature, 0, 0})); -} - -IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsBrowserTest, - WindowOpen_SameOrigin_Openee) { - ukm::TestAutoSetUkmRecorder recorder; - - const GURL url1(embedded_test_server()->GetURL("/title1.html")); - const GURL url2(embedded_test_server()->GetURL("/title2.html")); - const GURL url3(embedded_test_server()->GetURL("/title3.html")); - - EXPECT_TRUE(NavigateToURL(shell(), url1)); - - ShellAddedObserver observer; - EXPECT_TRUE(ExecJs(shell(), JsReplace("window.open($1, '_blank');", url2))); - Shell* shell2 = observer.GetShell(); - EXPECT_TRUE(WaitForLoadStop(shell2->web_contents())); - - Observe(shell2->web_contents()); - - // Navigate the second shell and ensure that the openee doesn't get cached - // too. - EXPECT_TRUE(NavigateToURL(shell2, url3)); - - { - // We emit metrics when we navigate back to the previously visited page, - // so navigate back to trigger the metrics. - TestNavigationObserver navigation_observer(shell2->web_contents()); - shell2->GoBackOrForward(-1); - navigation_observer.WaitForNavigationFinished(); - } - - ASSERT_EQ(navigation_ids_.size(), static_cast<size_t>(3)); - // ukm::SourceId id1 = ToSourceId(navigation_ids_[0]); - // ukm::SourceId id2 = ToSourceId(navigation_ids_[1]); - ukm::SourceId id3 = ToSourceId(navigation_ids_[2]); - - EXPECT_THAT(GetFeatureUsageMetrics(&recorder), - testing::ElementsAre(FeatureUsage{ - id3, 1 << kHasScriptableFramesInMultipleTabsFeature, 0, 0})); -} - IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsBrowserTest, Geolocation) { const GURL url1(embedded_test_server()->GetURL("/title1.html")); EXPECT_TRUE(NavigateToURL(shell(), url1));
diff --git a/content/browser/frame_host/render_document_host_browsertest.cc b/content/browser/frame_host/render_document_host_browsertest.cc index 26c73d8a..06c1885 100644 --- a/content/browser/frame_host/render_document_host_browsertest.cc +++ b/content/browser/frame_host/render_document_host_browsertest.cc
@@ -6,12 +6,14 @@ #include "base/test/scoped_feature_list.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/content_navigation_policy.h" #include "content/public/common/content_features.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/public/test/test_utils.h" #include "content/shell/browser/shell.h" +#include "content/test/render_document_feature.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -23,7 +25,11 @@ class RenderDocumentHostBrowserTest : public ContentBrowserTest { protected: void SetUpCommandLine(base::CommandLine* command_line) override { - feature_list_.InitWithFeatures({features::kRenderDocument}, {}); + // RenderDocumentHost only works when RenderDocument is enabled at at least + // the sub-frame level. + InitAndEnableRenderDocumentFeature( + &feature_list_, + GetRenderDocumentLevelName(RenderDocumentLevel::kSubframe)); } void SetUpOnMainThread() override {
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 33e4d999..b17e8fa 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -206,7 +206,6 @@ #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h" #include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h" -#include "third_party/blink/public/mojom/devtools/device_emulation_params.mojom.h" #include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom.h" #include "third_party/blink/public/mojom/frame/fullscreen.mojom.h" #include "third_party/blink/public/mojom/frame/media_player_action.mojom.h" @@ -557,8 +556,8 @@ } // namespace -bool IsRenderDocumentEnabledForCrashedFrame() { - return base::FeatureList::IsEnabled(features::kRenderDocumentForCrashedFrame); +bool CreateNewHostForCrashedFrame() { + return GetRenderDocumentLevel() >= RenderDocumentLevel::kCrashedFrame; } class RenderFrameHostImpl::DroppedInterfaceRequestLogger @@ -1697,7 +1696,7 @@ SetLastCommittedUrl(GURL()); web_bundle_handle_.reset(); - must_be_replaced_ = IsRenderDocumentEnabledForCrashedFrame(); + must_be_replaced_ = CreateNewHostForCrashedFrame(); has_committed_any_navigation_ = false; #if defined(OS_ANDROID) @@ -2680,7 +2679,7 @@ } else { // RenderDocument: After a local<->local swap, this function is called with // a null |proxy|. - CHECK(IsRenderDocumentEnabled()); + CHECK(CreateNewHostForSameSiteSubframe()); // The unload handlers already ran for this document during the // local<->local swap. Hence, there is no need to send @@ -3122,12 +3121,6 @@ render_view_host_->OnDidContentsPreferredSizeChange(pref_size); } -void RenderFrameHostImpl::SetDeviceEmulation( - const base::Optional<blink::WebDeviceEmulationParams>& params) { - DCHECK(frame_tree_node()->IsMainFrame()); - device_emulator_remote_->SetDeviceEmulation(params); -} - void RenderFrameHostImpl::UpdateFaviconURL( std::vector<blink::mojom::FaviconURLPtr> favicon_urls) { delegate_->UpdateFaviconURL(this, std::move(favicon_urls)); @@ -6108,16 +6101,8 @@ void RenderFrameHostImpl::BindDevToolsAgent( mojo::PendingAssociatedRemote<blink::mojom::DevToolsAgentHost> host, mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgent> receiver) { - mojo::PendingAssociatedReceiver<mojom::DeviceEmulator> - pending_emulator_receiver; - if (frame_tree_node()->IsMainFrame()) { - device_emulator_remote_.reset(); - pending_emulator_receiver = - device_emulator_remote_.BindNewEndpointAndPassReceiver(); - } - GetNavigationControl()->BindDevToolsAgent( - std::move(host), std::move(receiver), - std::move(pending_emulator_receiver)); + GetNavigationControl()->BindDevToolsAgent(std::move(host), + std::move(receiver)); } bool RenderFrameHostImpl::IsSameSiteInstance(
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 781a00f..c542d61 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -213,7 +213,7 @@ // True if feature-flags indicate that we should replace crashed RFHs with new // instances rather than reusing them. See http://crbug.com/981339. -CONTENT_EXPORT bool IsRenderDocumentEnabledForCrashedFrame(); +CONTENT_EXPORT bool CreateNewHostForCrashedFrame(); // To be called when a RenderFrameHostImpl receives an event. // Provides the host, the event fired, and which node id the event was for. @@ -1440,9 +1440,6 @@ // - Ignore any OnUnloadACK sent by the renderer process. void DoNotDeleteForTesting(); - void SetDeviceEmulation( - const base::Optional<blink::WebDeviceEmulationParams>& params); - protected: friend class RenderFrameHostFactory; @@ -2765,8 +2762,6 @@ // stuck in pending deletion. bool do_not_delete_for_testing_ = false; - mojo::AssociatedRemote<mojom::DeviceEmulator> device_emulator_remote_; - // NOTE: This must be the last member. base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_{this};
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 98be35f..50533c33 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -829,7 +829,7 @@ // Force using a different RenderFrameHost when RenderDocument is enabled. // TODO(arthursonzogni, fergal): Add support for the main frame. - if (IsRenderDocumentEnabled() && !frame_tree_node_->IsMainFrame() && + if (CreateNewHostForSameSiteSubframe() && !frame_tree_node_->IsMainFrame() && !request->IsSameDocument() && render_frame_host_->has_committed_any_navigation()) { use_current_rfh = false; @@ -2121,16 +2121,18 @@ CHECK(new_instance); // This DCHECK is going to be fully removed as part of RenderDocument [1]. // - // With RenderDocument: every cross-document navigation creates a new - // RenderFrameHost. The navigation is potentially same-SiteInstance. + // With RenderDocument for sub frames or main frames: cross-document + // navigation creates a new RenderFrameHost. The navigation is potentially + // same-SiteInstance. // - // With RenderDocumentForCrashedFrame: navigations from a crashed + // With RenderDocument for crashed frames: navigations from a crashed // RenderFrameHost creates a new RenderFrameHost. The navigation is // potentially same-SiteInstance. // // [1] http://crbug.com/936696 DCHECK(old_instance != new_instance || - render_frame_host_->must_be_replaced() || IsRenderDocumentEnabled()); + render_frame_host_->must_be_replaced() || + CreateNewHostForSameSiteSubframe()); // The process for the new SiteInstance may (if we're sharing a process with // another host that already initialized it) or may not (we have our own @@ -2161,16 +2163,18 @@ CHECK(instance); // This DCHECK is going to be fully removed as part of RenderDocument [1]. // - // With RenderDocument: every cross-document navigation creates a new - // RenderFrameHost. The navigation is potentially same-SiteInstance. + // With RenderDocument for sub frames or main frames: cross-document + // navigation creates a new RenderFrameHost. The navigation is potentially + // same-SiteInstance. // - // With RenderDocumentForCrashedFrame: navigations from a crashed + // With RenderDocument for crashed frames: navigations from a crashed // RenderFrameHost creates a new RenderFrameHost. The navigation is // potentially same-SiteInstance. // // [1] http://crbug.com/936696 DCHECK(render_frame_host_->GetSiteInstance() != instance || - render_frame_host_->must_be_replaced() || IsRenderDocumentEnabled()); + render_frame_host_->must_be_replaced() || + CreateNewHostForSameSiteSubframe()); std::unique_ptr<RenderFrameHostImpl> new_render_frame_host = CreateRenderFrameHost(CreateFrameCase::kCreateSpeculative, instance, @@ -2505,7 +2509,7 @@ CHECK_NE(previous_routing_id, MSG_ROUTING_NONE); if (!existing_proxy->is_render_frame_proxy_live()) existing_proxy->InitRenderFrameProxy(); - } else if (IsRenderDocumentEnabled()) { + } else if (CreateNewHostForSameSiteSubframe()) { previous_routing_id = current_frame_host()->GetRoutingID(); }
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc index 9297b0c..73e70f2 100644 --- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -69,6 +69,7 @@ #include "content/shell/browser/shell.h" #include "content/test/content_browser_test_utils_internal.h" #include "content/test/did_commit_navigation_interceptor.h" +#include "content/test/render_document_feature.h" #include "content/test/test_content_browser_client.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/controllable_http_response.h" @@ -211,15 +212,13 @@ } // anonymous namespace -class RenderFrameHostManagerTest : public ContentBrowserTest, - public ::testing::WithParamInterface<bool> { +class RenderFrameHostManagerTest + : public ContentBrowserTest, + public ::testing::WithParamInterface<std::string> { public: RenderFrameHostManagerTest() : foo_com_("foo.com") { replace_host_.SetHostStr(foo_com_); - if (GetParam()) { - feature_list_.InitAndEnableFeature( - features::kRenderDocumentForCrashedFrame); - } + InitAndEnableRenderDocumentFeature(&feature_list_, GetParam()); } void SetUpOnMainThread() override { @@ -6906,8 +6905,8 @@ ASSERT_EQ(0u, b3->child_count()); EXPECT_FALSE(a1->must_be_replaced()); - EXPECT_EQ(b2->must_be_replaced(), IsRenderDocumentEnabledForCrashedFrame()); - EXPECT_EQ(b3->must_be_replaced(), IsRenderDocumentEnabledForCrashedFrame()); + EXPECT_EQ(b2->must_be_replaced(), CreateNewHostForCrashedFrame()); + EXPECT_EQ(b3->must_be_replaced(), CreateNewHostForCrashedFrame()); EXPECT_FALSE(c5->must_be_replaced()); EXPECT_EQ(2u, proxy_count(a1)); @@ -6928,7 +6927,7 @@ // 3. Reload B2, B6 is created. NavigateFrameToURL(b2->frame_tree_node(), b2_url); - if (IsRenderDocumentEnabledForCrashedFrame()) { + if (CreateNewHostForCrashedFrame()) { // B2 has been replaced EXPECT_NE(b2_routing_id, a1->child_at(0)->current_frame_host()->routing_id()); @@ -6940,7 +6939,7 @@ // B3 hasn't been replaced. EXPECT_EQ(b3, a1->child_at(1)->current_frame_host()); RenderFrameHostImpl* b6 = a1->child_at(0)->current_frame_host(); - EXPECT_EQ(b3->must_be_replaced(), IsRenderDocumentEnabledForCrashedFrame()); + EXPECT_EQ(b3->must_be_replaced(), CreateNewHostForCrashedFrame()); EXPECT_FALSE(b6->must_be_replaced()); EXPECT_EQ(a_site_instance, a1->GetSiteInstance()); @@ -6963,24 +6962,27 @@ EXPECT_TRUE(is_proxy_live(c5, b_site_instance)); } -// These tests are parametrized to toggle kRenderDocumentForCrashedFrame on/off. -INSTANTIATE_TEST_SUITE_P(All, RenderFrameHostManagerTest, ::testing::Bool()); +INSTANTIATE_TEST_SUITE_P(All, + RenderFrameHostManagerTest, + testing::ValuesIn(RenderDocumentFeatureLevelValues())); INSTANTIATE_TEST_SUITE_P( All, ProactivelySwapBrowsingInstancesCrossSiteSwapProcessTest, - ::testing::Bool()); + testing::ValuesIn(RenderDocumentFeatureLevelValues())); INSTANTIATE_TEST_SUITE_P( All, ProactivelySwapBrowsingInstancesCrossSiteReuseProcessTest, - ::testing::Bool()); + testing::ValuesIn(RenderDocumentFeatureLevelValues())); INSTANTIATE_TEST_SUITE_P(All, RenderFrameHostManagerUnloadBrowserTest, - ::testing::Bool()); + testing::ValuesIn(RenderDocumentFeatureLevelValues())); INSTANTIATE_TEST_SUITE_P(All, RenderFrameHostManagerSpoofingTest, - ::testing::Bool()); -INSTANTIATE_TEST_SUITE_P(All, RFHMProcessPerTabTest, ::testing::Bool()); + testing::ValuesIn(RenderDocumentFeatureLevelValues())); +INSTANTIATE_TEST_SUITE_P(All, + RFHMProcessPerTabTest, + testing::ValuesIn(RenderDocumentFeatureLevelValues())); INSTANTIATE_TEST_SUITE_P(All, RenderFrameHostManagerDefaultProcessTest, - ::testing::Bool()); + testing::ValuesIn(RenderDocumentFeatureLevelValues())); } // namespace content
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc index b57e96b..85113ef 100644 --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -22,7 +22,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" -#include "base/test/with_feature_override.h" #include "base/time/time.h" #include "build/build_config.h" #include "content/browser/child_process_security_policy_impl.h" @@ -33,6 +32,7 @@ #include "content/browser/frame_host/render_frame_proxy_host.h" #include "content/browser/site_instance_impl.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" +#include "content/common/content_navigation_policy.h" #include "content/common/frame_messages.h" #include "content/common/input_messages.h" #include "content/common/view_messages.h" @@ -56,6 +56,7 @@ #include "content/public/test/test_utils.h" #include "content/test/mock_widget_input_handler.h" #include "content/test/navigation_simulator_impl.h" +#include "content/test/render_document_feature.h" #include "content/test/test_content_browser_client.h" #include "content/test/test_content_client.h" #include "content/test/test_render_frame_host.h" @@ -266,11 +267,48 @@ } // namespace -class RenderFrameHostManagerTest : public base::test::WithFeatureOverride, - public RenderViewHostImplTestHarness { +// Test that the "level" feature param has the expected effect. +class RenderDocumentFeatureTest : public testing::Test { + protected: + void SetLevel(const RenderDocumentLevel level) { + InitAndEnableRenderDocumentFeature(&feature_list_, + GetRenderDocumentLevelName(level)); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +TEST_F(RenderDocumentFeatureTest, FeatureDisabled) { + EXPECT_FALSE(CreateNewHostForCrashedFrame()); + EXPECT_FALSE(CreateNewHostForSameSiteSubframe()); +} + +TEST_F(RenderDocumentFeatureTest, LevelDisabled) { + SetLevel(RenderDocumentLevel::kDisabled); + EXPECT_FALSE(CreateNewHostForCrashedFrame()); + EXPECT_FALSE(CreateNewHostForSameSiteSubframe()); +} + +TEST_F(RenderDocumentFeatureTest, LevelCrashed) { + SetLevel(RenderDocumentLevel::kCrashedFrame); + EXPECT_TRUE(CreateNewHostForCrashedFrame()); + EXPECT_FALSE(CreateNewHostForSameSiteSubframe()); +} + +TEST_F(RenderDocumentFeatureTest, LevelSub) { + SetLevel(RenderDocumentLevel::kSubframe); + EXPECT_TRUE(CreateNewHostForCrashedFrame()); + EXPECT_TRUE(CreateNewHostForSameSiteSubframe()); +} + +class RenderFrameHostManagerTest + : public RenderViewHostImplTestHarness, + public ::testing::WithParamInterface<std::string> { public: - RenderFrameHostManagerTest() - : WithFeatureOverride(features::kRenderDocumentForCrashedFrame) {} + RenderFrameHostManagerTest() { + InitAndEnableRenderDocumentFeature(&feature_list_, GetParam()); + } void SetUp() override { RenderViewHostImplTestHarness::SetUp(); @@ -1945,7 +1983,7 @@ EXPECT_FALSE(contents2->GetMainFrame()->IsRenderFrameLive()); EXPECT_EQ(contents1->GetSiteInstance(), contents2->GetSiteInstance()); EXPECT_EQ((bool)contents1->GetMainFrame()->GetView(), - IsRenderDocumentEnabledForCrashedFrame()); + CreateNewHostForCrashedFrame()); EXPECT_FALSE(contents2->GetMainFrame()->GetView()); // |contents1| creates an out of process iframe. @@ -3575,12 +3613,14 @@ ExpectAdSubframeSignalForFrameProxy(proxy_to_main_frame, true); } -INSTANTIATE_FEATURE_OVERRIDE_TEST_SUITE(RenderFrameHostManagerTest); +INSTANTIATE_TEST_SUITE_P(All, + RenderFrameHostManagerTest, + testing::ValuesIn(RenderDocumentFeatureLevelValues())); INSTANTIATE_TEST_SUITE_P(All, RenderFrameHostManagerTestWithSiteIsolation, - ::testing::Bool()); + testing::ValuesIn(RenderDocumentFeatureLevelValues())); INSTANTIATE_TEST_SUITE_P(All, RenderFrameHostManagerAdTaggingSignalTest, - ::testing::Bool()); + testing::ValuesIn(RenderDocumentFeatureLevelValues())); } // namespace content
diff --git a/content/browser/renderer_host/input/scroll_latency_browsertest.cc b/content/browser/renderer_host/input/scroll_latency_browsertest.cc index 525c63fc..e7cb819f 100644 --- a/content/browser/renderer_host/input/scroll_latency_browsertest.cc +++ b/content/browser/renderer_host/input/scroll_latency_browsertest.cc
@@ -44,7 +44,7 @@ "<title>Scroll latency histograms browsertests.</title>" "<style>" "body {" - " height:3000px;" + " height:9000px;" "}" "</style>" "</head>" @@ -265,6 +265,51 @@ 0, "Event.Latency.ScrollBegin.Touch.TimeToScrollUpdateSwapBegin4")); } +using ScrollThroughputBrowserTest = ScrollLatencyBrowserTest; + +// The test does a fling during the test, and it times out in slower builds +// (e.g. when sanitizers are turned on). +#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) +#define MAYBE_ScrollThroughputMetrics DISABLED_ScrollThroughputMetrics +#else +#define MAYBE_ScrollThroughputMetrics ScrollThroughputMetrics +#endif +IN_PROC_BROWSER_TEST_F(ScrollThroughputBrowserTest, + MAYBE_ScrollThroughputMetrics) { + LoadURL(); + auto scroll_update_watcher = std::make_unique<InputMsgWatcher>( + GetWidgetHost(), blink::WebInputEvent::kGestureScrollEnd); + + SyntheticSmoothScrollGestureParams params; + params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; + params.anchor = gfx::PointF(10, 10); + params.distances.push_back(gfx::Vector2d(0, -6000)); + params.fling_velocity_x = 0; + params.fling_velocity_y = -2000; + params.prevent_fling = false; + + run_loop_ = std::make_unique<base::RunLoop>(); + + auto gesture = std::make_unique<SyntheticSmoothScrollGesture>(params); + GetWidgetHost()->QueueSyntheticGesture( + std::move(gesture), + base::BindOnce(&ScrollLatencyBrowserTest::OnSyntheticGestureCompleted, + base::Unretained(this))); + run_loop_->Run(); + + while (!GetSampleCountForHistogram( + "Graphics.Smoothness.PercentDroppedFrames.CompositorThread." + "TouchScroll")) { + GiveItSomeTime(); + FetchHistogramsFromChildProcesses(); + } + EXPECT_TRUE(VerifyRecordedSamplesForHistogram( + 1, + "Graphics.Smoothness.PercentDroppedFrames.ScrollingThread.TouchScroll")); + EXPECT_TRUE(VerifyRecordedSamplesForHistogram( + 1, "Event.Latency.ScrollBegin.Touch.BrowserNotifiedToBeforeGpuSwap2")); +} + class ScrollLatencyScrollbarBrowserTest : public ScrollLatencyBrowserTest { public: ScrollLatencyScrollbarBrowserTest() = default;
diff --git a/content/browser/site_per_process_unload_browsertest.cc b/content/browser/site_per_process_unload_browsertest.cc index c0c35df..409b23e 100644 --- a/content/browser/site_per_process_unload_browsertest.cc +++ b/content/browser/site_per_process_unload_browsertest.cc
@@ -1330,7 +1330,7 @@ WebContents::FromRenderFrameHost(web_contents()->GetMainFrame())); // All the documents must be properly deleted: - if (IsRenderDocumentEnabled()) + if (CreateNewHostForSameSiteSubframe()) delete_B2.WaitUntilDeleted(); delete_B3.WaitUntilDeleted(); delete_C4.WaitUntilDeleted();
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index a440a8f..f22f6c8 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -443,7 +443,6 @@ "ax_content_tree_data.mojom", "ax_content_tree_update.mojom", "child_process.mojom", - "device_emulator.mojom", "document_scoped_interface_bundle.mojom", "download/mhtml_file_writer.mojom", "field_trial_recorder.mojom",
diff --git a/content/common/common_param_traits_macros.h b/content/common/common_param_traits_macros.h index f647c66..0701e83 100644 --- a/content/common/common_param_traits_macros.h +++ b/content/common/common_param_traits_macros.h
@@ -12,13 +12,22 @@ #include "content/common/frame_messages.h" #include "content/common/visual_properties.h" #include "ipc/ipc_message_macros.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #undef IPC_MESSAGE_EXPORT #define IPC_MESSAGE_EXPORT CONTENT_EXPORT +// Traits for VisualProperties. +IPC_ENUM_TRAITS_MAX_VALUE(blink::WebDeviceEmulationParams::ScreenPosition, + blink::WebDeviceEmulationParams::kScreenPositionLast) + IPC_ENUM_TRAITS_MAX_VALUE(content::ScreenOrientationValues, content::SCREEN_ORIENTATION_VALUES_LAST) +IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebScreenOrientationType, + blink::kWebScreenOrientationUndefined, + blink::WebScreenOrientationTypeLast) + IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::DisplayMode, blink::mojom::DisplayMode::kMaxValue)
diff --git a/content/common/content_navigation_policy.cc b/content/common/content_navigation_policy.cc index f89c0d2..da00bec 100644 --- a/content/common/content_navigation_policy.cc +++ b/content/common/content_navigation_policy.cc
@@ -70,9 +70,34 @@ return GetProactivelySwapBrowsingInstanceLevel() >= ProactivelySwapBrowsingInstanceLevel::kCrossSiteReuseProcess; } +const char kRenderDocumentLevelParameterName[] = "level"; -bool IsRenderDocumentEnabled() { - return base::FeatureList::IsEnabled(features::kRenderDocument); +constexpr base::FeatureParam<RenderDocumentLevel>::Option + render_document_levels[] = { + {RenderDocumentLevel::kDisabled, "disabled"}, + {RenderDocumentLevel::kCrashedFrame, "crashed-frame"}, + {RenderDocumentLevel::kSubframe, "subframe"}}; +const base::FeatureParam<RenderDocumentLevel> render_document_level{ + &features::kRenderDocument, kRenderDocumentLevelParameterName, + RenderDocumentLevel::kDisabled, &render_document_levels}; + +RenderDocumentLevel GetRenderDocumentLevel() { + if (base::FeatureList::IsEnabled(features::kRenderDocument)) + return render_document_level.Get(); + return RenderDocumentLevel::kDisabled; +} + +std::string GetRenderDocumentLevelName(RenderDocumentLevel level) { + for (size_t i = 0; i < render_document_level.option_count; ++i) { + if (level == render_document_level.options[i].value) + return render_document_level.options[i].name; + } + NOTREACHED(); + return ""; +} + +bool CreateNewHostForSameSiteSubframe() { + return GetRenderDocumentLevel() >= RenderDocumentLevel::kSubframe; } } // namespace content
diff --git a/content/common/content_navigation_policy.h b/content/common/content_navigation_policy.h index 7107208b..3d9abb7 100644 --- a/content/common/content_navigation_policy.h +++ b/content/common/content_navigation_policy.h
@@ -7,6 +7,8 @@ #include "content/common/content_export.h" +#include <string> + namespace content { CONTENT_EXPORT bool IsBackForwardCacheEnabled(); @@ -26,11 +28,25 @@ // navigations with process reuse. }; CONTENT_EXPORT bool IsProactivelySwapBrowsingInstanceEnabled(); + CONTENT_EXPORT bool IsProactivelySwapBrowsingInstanceWithProcessReuseEnabled(); CONTENT_EXPORT extern const char kProactivelySwapBrowsingInstanceLevelParameterName[]; -CONTENT_EXPORT bool IsRenderDocumentEnabled(); +// Levels of RenderDocument support. These are additive in that features enabled +// at lower levels remain enabled at all higher levels. +enum class RenderDocumentLevel { + kDisabled = 0, + // Do not reused RenderFrameHosts when recovering from crashes. + kCrashedFrame = 1, + // Also do not reuse RenderFrameHosts when navigating subframes. + kSubframe = 2, +}; +CONTENT_EXPORT bool CreateNewHostForSameSiteSubframe(); +CONTENT_EXPORT RenderDocumentLevel GetRenderDocumentLevel(); +CONTENT_EXPORT std::string GetRenderDocumentLevelName( + RenderDocumentLevel level); +CONTENT_EXPORT extern const char kRenderDocumentLevelParameterName[]; } // namespace content
diff --git a/content/common/device_emulator.mojom b/content/common/device_emulator.mojom deleted file mode 100644 index cbbfb72..0000000 --- a/content/common/device_emulator.mojom +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2020 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. - -module content.mojom; - -import "third_party/blink/public/mojom/devtools/device_emulation_params.mojom"; - -// Interface exposed by the renderer to allow configuration of device emulator. -// Used internally by DevTools, but needs to be a separate interface now, as it -// needs to be implemented in content and be associated to -// FrameNavigationControl. -interface DeviceEmulator { - // Conigure device emulation parameter. When |params| is null, the emulation - // is disabled and all parameters are reverted to original values. - SetDeviceEmulation(blink.mojom.DeviceEmulationParams? params); -};
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index c4ff6c3..edf716bc 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -5,7 +5,6 @@ module content.mojom; import "content/common/ax_content_tree_update.mojom"; -import "content/common/device_emulator.mojom"; import "content/common/document_scoped_interface_bundle.mojom"; import "content/common/frame_messages.mojom"; import "content/common/native_types.mojom"; @@ -173,13 +172,9 @@ // Returned DevToolsAgent must be associated with navigation control, // due to various ordering dependencies between DevTools protocol and // navigation. - // The same applies to DeviceEmulator interface, which is currently - // a separate interface for convenience of implementation and is only - // passed for the root frame. BindDevToolsAgent( pending_associated_remote<blink.mojom.DevToolsAgentHost> agent_host, - pending_associated_receiver<blink.mojom.DevToolsAgent> agent, - pending_associated_receiver<DeviceEmulator>? emulator); + pending_associated_receiver<blink.mojom.DevToolsAgent> agent); // Request for the renderer to execute JavaScript in the frame's context. //
diff --git a/content/common/widget_messages.h b/content/common/widget_messages.h index 3a3137d6d..dfc2894 100644 --- a/content/common/widget_messages.h +++ b/content/common/widget_messages.h
@@ -46,6 +46,19 @@ IPC_STRUCT_TRAITS_MEMBER(height) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(blink::WebDeviceEmulationParams) + IPC_STRUCT_TRAITS_MEMBER(screen_position) + IPC_STRUCT_TRAITS_MEMBER(screen_size) + IPC_STRUCT_TRAITS_MEMBER(view_position) + IPC_STRUCT_TRAITS_MEMBER(device_scale_factor) + IPC_STRUCT_TRAITS_MEMBER(view_size) + IPC_STRUCT_TRAITS_MEMBER(scale) + IPC_STRUCT_TRAITS_MEMBER(viewport_offset) + IPC_STRUCT_TRAITS_MEMBER(viewport_scale) + IPC_STRUCT_TRAITS_MEMBER(screen_orientation_angle) + IPC_STRUCT_TRAITS_MEMBER(screen_orientation_type) +IPC_STRUCT_TRAITS_END() + IPC_ENUM_TRAITS_MAX_VALUE(base::i18n::TextDirection, base::i18n::TEXT_DIRECTION_MAX) @@ -93,6 +106,13 @@ // Expects a Close_ACK message when finished. IPC_MESSAGE_ROUTED0(WidgetMsg_Close) +// Enables device emulation. See WebDeviceEmulationParams for description. +IPC_MESSAGE_ROUTED1(WidgetMsg_EnableDeviceEmulation, + blink::WebDeviceEmulationParams /* params */) + +// Disables device emulation, enabled previously by EnableDeviceEmulation. +IPC_MESSAGE_ROUTED0(WidgetMsg_DisableDeviceEmulation) + // Sent to inform the widget that it was hidden. This allows it to reduce its // resource utilization. IPC_MESSAGE_ROUTED0(WidgetMsg_WasHidden)
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 5022acc..e16445a 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -478,10 +478,6 @@ // Design doc: https://bit.ly/renderdocument // Main bug tracker: https://crbug.com/936696 -// Enable using the RenderDocument when recovering from crashes. -const base::Feature kRenderDocumentForCrashedFrame{ - "RenderDocumentForCrashedFrame", base::FEATURE_DISABLED_BY_DEFAULT}; - // Enable using the RenderDocument. const base::Feature kRenderDocument{"RenderDocument", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index fb8cf5d..1f03f8b 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -104,7 +104,6 @@ CONTENT_EXPORT extern const base::Feature kRelaxIsolatedWorldCorsInFileUrlLoaderFactory; CONTENT_EXPORT extern const base::Feature kReloadHiddenTabsWithCrashedSubframes; -CONTENT_EXPORT extern const base::Feature kRenderDocumentForCrashedFrame; CONTENT_EXPORT extern const base::Feature kRenderDocument; CONTENT_EXPORT extern const base::Feature kRequestUnbufferedDispatch; CONTENT_EXPORT extern const base::Feature kResamplingInputEvents;
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index e512760..88c9b0d 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -736,7 +736,18 @@ LOG(ERROR) << "WebContents was destroyed during waiting for load stop."; return false; } - return IsLastCommittedEntryOfPageType(web_contents, PAGE_TYPE_NORMAL); + bool is_page_normal = + IsLastCommittedEntryOfPageType(web_contents, PAGE_TYPE_NORMAL); + if (!is_page_normal) { + NavigationEntry* last_entry = + web_contents->GetController().GetLastCommittedEntry(); + if (last_entry) + LOG(ERROR) << "Http status code = " << last_entry->GetHttpStatusCode() + << ", page type = " << last_entry->GetPageType(); + else + LOG(ERROR) << "No committed entry."; + } + return is_page_normal; } void PrepContentsForBeforeUnloadTest(WebContents* web_contents,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 4928dc7..e964089 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3677,12 +3677,8 @@ void RenderFrameImpl::BindDevToolsAgent( mojo::PendingAssociatedRemote<blink::mojom::DevToolsAgentHost> host, - mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgent> agent, - mojo::PendingAssociatedReceiver<mojom::DeviceEmulator> device_emulator) { - frame_->BindDevToolsAgent(host.PassHandle(), agent.PassHandle()); - DCHECK_EQ(!!device_emulator, IsMainFrame()); - if (device_emulator) - render_widget_->BindDeviceEmulator(std::move(device_emulator)); + mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgent> receiver) { + frame_->BindDevToolsAgent(host.PassHandle(), receiver.PassHandle()); } // blink::WebLocalFrameClient implementation @@ -4116,7 +4112,7 @@ CHECK_EQ(routing_id_, proxy->provisional_frame_routing_id()); proxy->set_provisional_frame_routing_id(MSG_ROUTING_NONE); } else - CHECK(IsRenderDocumentEnabled()); + CHECK(CreateNewHostForSameSiteSubframe()); } delete this;
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 7080a4d..ac3e90f 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -32,7 +32,6 @@ #include "base/values.h" #include "build/build_config.h" #include "content/common/buildflags.h" -#include "content/common/device_emulator.mojom.h" #include "content/common/download/mhtml_file_writer.mojom.h" #include "content/common/frame.mojom.h" #include "content/common/frame_delete_intention.h" @@ -597,8 +596,7 @@ subresource_loader_factories) override; void BindDevToolsAgent( mojo::PendingAssociatedRemote<blink::mojom::DevToolsAgentHost> host, - mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgent> agent, - mojo::PendingAssociatedReceiver<mojom::DeviceEmulator> device_emulator) + mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgent> receiver) override; void JavaScriptExecuteRequest(
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 2e827ba..85f08187ff 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc
@@ -69,7 +69,6 @@ #include "services/network/public/cpp/resource_request_body.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/devtools/web_device_emulation_params.h" #include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h" #include "third_party/blink/public/common/origin_trials/origin_trial_policy.h" #include "third_party/blink/public/common/origin_trials/trial_token_validator.h" @@ -84,6 +83,7 @@ #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url_response.h" #include "third_party/blink/public/web/web_autofill_client.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/public/web/web_document_loader.h" #include "third_party/blink/public/web/web_frame_content_dumper.h" #include "third_party/blink/public/web/web_frame_widget.h" @@ -278,12 +278,20 @@ return GetRenderAccessibilityManager()->GetAccessibilityMode(); } - void SetDeviceEmulation( - RenderViewImpl* view, - const base::Optional<blink::WebDeviceEmulationParams>& params) { - mojom::DeviceEmulator* emulator = + void ReceiveDisableDeviceEmulation(RenderViewImpl* view) { + // Emulates receiving an IPC message. + RenderWidget* widget = view->GetMainRenderFrame()->GetLocalRootRenderWidget(); - emulator->SetDeviceEmulation(params); + widget->OnDisableDeviceEmulation(); + } + + void ReceiveEnableDeviceEmulation( + RenderViewImpl* view, + const blink::WebDeviceEmulationParams& params) { + // Emulates receiving an IPC message. + RenderWidget* widget = + view->GetMainRenderFrame()->GetLocalRootRenderWidget(); + widget->OnEnableDeviceEmulation(params); } void ReceiveSetTextDirection(RenderWidget* widget, @@ -522,12 +530,13 @@ static base::string16 get_dpr = base::ASCIIToUTF16("Number(window.devicePixelRatio * 10)"); - blink::WebDeviceEmulationParams params; - params.view_size = gfx::Size(width, height); - params.device_scale_factor = dpr; - SetDeviceEmulation(view(), params); int emulated_width, emulated_height; int emulated_dpr; + blink::WebDeviceEmulationParams params; + params.view_size.width = width; + params.view_size.height = height; + params.device_scale_factor = dpr; + ReceiveEnableDeviceEmulation(view(), params); EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_width, &emulated_width)); EXPECT_EQ(width, emulated_width); EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_height, @@ -694,11 +703,14 @@ gfx::Rect emulated_widget_rect(150, 160, 980, 1200); // In mobile emulation the WindowScreenRect and ScreenRect are both set to // match the WidgetScreenRect, which we set here. - emulation_params.screen_position = blink::mojom::ScreenPosition::kMobile; + emulation_params.screen_position = blink::WebDeviceEmulationParams::kMobile; emulation_params.view_size = emulated_widget_rect.size(); emulation_params.view_position = emulated_widget_rect.origin(); - mojom::DeviceEmulator* emulator = main_widget(); - emulator->SetDeviceEmulation(emulation_params); + { + WidgetMsg_EnableDeviceEmulation msg(main_widget()->routing_id(), + emulation_params); + main_widget()->OnMessageReceived(msg); + } { // Make a popup again. It should inherit device emulation params. @@ -1102,9 +1114,10 @@ main_widget()->GetOriginalScreenInfo().device_scale_factor); EXPECT_EQ(device_scale, child_proxy->screen_info().device_scale_factor); - SetDeviceEmulation(view(), base::nullopt); + ReceiveDisableDeviceEmulation(view()); - SetDeviceEmulation(view(), blink::WebDeviceEmulationParams()); + blink::WebDeviceEmulationParams params; + ReceiveEnableDeviceEmulation(view(), params); // Don't disable here to test that emulation is being shutdown properly. } @@ -2763,9 +2776,10 @@ TestEmulatedSizeDprDsf(1005, 1102, 3.f, 1.f); } - SetDeviceEmulation(view(), base::nullopt); + ReceiveDisableDeviceEmulation(view()); - SetDeviceEmulation(view(), blink::WebDeviceEmulationParams()); + blink::WebDeviceEmulationParams params; + ReceiveEnableDeviceEmulation(view(), params); // Don't disable here to test that emulation is being shutdown properly. } @@ -2791,9 +2805,10 @@ TestEmulatedSizeDprDsf(1005, 1102, 3.f, compositor_dsf); } - SetDeviceEmulation(view(), base::nullopt); + ReceiveDisableDeviceEmulation(view()); - SetDeviceEmulation(view(), blink::WebDeviceEmulationParams()); + blink::WebDeviceEmulationParams params; + ReceiveEnableDeviceEmulation(view(), params); // Don't disable here to test that emulation is being shutdown properly. }
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 0678ea4b..f0cb483 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1102,8 +1102,12 @@ } void RenderViewImpl::SetScreenMetricsEmulationParametersForWidget( - const base::Optional<blink::WebDeviceEmulationParams>& params) { - GetWebView()->SetDeviceEmulation(params); + bool enabled, + const blink::WebDeviceEmulationParams& params) { + if (enabled) + GetWebView()->EnableDeviceEmulation(params); + else + GetWebView()->DisableDeviceEmulation(); } // IPC message handlers -----------------------------------------
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 40816db..701aac4 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -382,7 +382,8 @@ const gfx::Size& visible_viewport_size, cc::BrowserControlsParams browser_controls_params) override; void SetScreenMetricsEmulationParametersForWidget( - const base::Optional<blink::WebDeviceEmulationParams>& params) override; + bool enabled, + const blink::WebDeviceEmulationParams& params) override; // Old WebLocalFrameClient implementations // ----------------------------------------
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index a24fc4a..640945d 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -92,6 +92,7 @@ #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/web/web_autofill_client.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_input_method_controller.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -548,6 +549,19 @@ } bool RenderWidget::OnMessageReceived(const IPC::Message& message) { + // The EnableDeviceEmulation message is sent to a provisional RenderWidget + // before the navigation completes. Some investigation into why is done in + // https://chromium-review.googlesource.com/c/chromium/src/+/1853675/5#message-e6edc3fd708d7d267ee981ffe43cae090b37a906 + // but it's unclear what would need to be done to delay this until after + // navigation. + bool handled = false; + IPC_BEGIN_MESSAGE_MAP(RenderWidget, message) + IPC_MESSAGE_HANDLER(WidgetMsg_EnableDeviceEmulation, + OnEnableDeviceEmulation) + IPC_END_MESSAGE_MAP() + if (handled) + return true; + // We shouldn't receive IPC messages on provisional frames. It's possible the // message was destined for a RenderWidget that was destroyed and then // recreated since it keeps the same routing id. Just drop it here if that @@ -560,8 +574,9 @@ return text_input_client_observer_->OnMessageReceived(message); #endif - bool handled = false; IPC_BEGIN_MESSAGE_MAP(RenderWidget, message) + IPC_MESSAGE_HANDLER(WidgetMsg_DisableDeviceEmulation, + OnDisableDeviceEmulation) IPC_MESSAGE_HANDLER(WidgetMsg_ShowContextMenu, OnShowContextMenu) IPC_MESSAGE_HANDLER(WidgetMsg_Close, OnClose) IPC_MESSAGE_HANDLER(WidgetMsg_UpdateVisualProperties, @@ -906,6 +921,34 @@ AfterUpdateVisualProperties(); } +void RenderWidget::OnEnableDeviceEmulation( + const blink::WebDeviceEmulationParams& params) { + // Device emulation can only be applied to the local main frame render widget. + // TODO(https://crbug.com/1006052): We should move emulation into the browser + // and send consistent ScreenInfo and ScreenRects to all RenderWidgets based + // on emulation. + if (!delegate_) + return; + + if (!device_emulator_) { + device_emulator_ = std::make_unique<RenderWidgetScreenMetricsEmulator>( + this, screen_info_, size_, visible_viewport_size_, widget_screen_rect_, + window_screen_rect_); + } + device_emulator_->ChangeEmulationParams(params); +} + +void RenderWidget::OnDisableDeviceEmulation() { + // Device emulation can only be applied to the local main frame render widget. + // TODO(https://crbug.com/1006052): We should move emulation into the browser + // and send consistent ScreenInfo and ScreenRects to all RenderWidgets based + // on emulation. + if (!delegate_ || !device_emulator_) + return; + device_emulator_->DisableAndApply(); + device_emulator_.reset(); +} + float RenderWidget::GetEmulatorScale() const { if (device_emulator_) return device_emulator_->scale(); @@ -1017,11 +1060,6 @@ layer_tree_host_->SetNeedsCommitWithForcedRedraw(); } -void RenderWidget::BindDeviceEmulator( - mojo::PendingAssociatedReceiver<mojom::DeviceEmulator> pending_receiver) { - device_emulator_receiver_.Bind(std::move(pending_receiver)); -} - void RenderWidget::DidPresentForceDrawFrame( int snapshot_id, const gfx::PresentationFeedback& feedback) { @@ -1524,29 +1562,6 @@ return layer_tree_host_->device_viewport_rect(); } -void RenderWidget::SetDeviceEmulation( - const base::Optional<::blink::WebDeviceEmulationParams>& params) { - // Device emulation can only be applied to the local main frame render widget. - // TODO(https://crbug.com/1006052): We should move emulation into the browser - // and send consistent ScreenInfo and ScreenRects to all RenderWidgets based - // on emulation. - DCHECK(delegate_); - - if (params) { - if (!device_emulator_) { - device_emulator_ = std::make_unique<RenderWidgetScreenMetricsEmulator>( - this, screen_info_, size_, visible_viewport_size_, - widget_screen_rect_, window_screen_rect_); - } - device_emulator_->ChangeEmulationParams(*params); - } else { - if (!device_emulator_) - return; - device_emulator_->DisableAndApply(); - device_emulator_.reset(); - } -} - void RenderWidget::SetScreenInfoAndSize( const ScreenInfo& screen_info, const gfx::Size& widget_size, @@ -1583,10 +1598,11 @@ } void RenderWidget::SetScreenMetricsEmulationParameters( - const base::Optional<blink::WebDeviceEmulationParams>& params) { - // Device emulation can only be applied to the local main frame render widget. + bool enabled, + const blink::WebDeviceEmulationParams& params) { + // This is only supported in RenderView, which has an delegate(). DCHECK(delegate()); - delegate()->SetScreenMetricsEmulationParametersForWidget(params); + delegate()->SetScreenMetricsEmulationParametersForWidget(enabled, params); } void RenderWidget::SetScreenRects(const gfx::Rect& widget_screen_rect,
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 0568b41..fd76b067 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -33,7 +33,6 @@ #include "content/common/buildflags.h" #include "content/common/content_export.h" #include "content/common/content_to_visible_time_reporter.h" -#include "content/common/device_emulator.mojom.h" #include "content/common/drag_event_source_info.h" #include "content/common/edit_command.h" #include "content/common/widget.mojom.h" @@ -49,7 +48,6 @@ #include "ipc/ipc_listener.h" #include "ipc/ipc_message.h" #include "ipc/ipc_sender.h" -#include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "ppapi/buildflags/buildflags.h" @@ -148,7 +146,6 @@ public IPC::Sender, public blink::WebPagePopupClient, // Is-a WebWidgetClient also. public mojom::Widget, - public mojom::DeviceEmulator, public LayerTreeViewDelegate, public RenderWidgetInputHandlerDelegate, public RenderWidgetScreenMetricsEmulatorDelegate, @@ -357,7 +354,8 @@ // RenderWidgetScreenMetricsEmulatorDelegate void SetScreenMetricsEmulationParameters( - const base::Optional<blink::WebDeviceEmulationParams>& params) override; + bool enabled, + const blink::WebDeviceEmulationParams& params) override; void SetScreenInfoAndSize(const ScreenInfo& screen_info, const gfx::Size& widget_size, const gfx::Size& visible_viewport_size) override; @@ -612,9 +610,6 @@ base::OnceCallback<void(const gfx::PresentationFeedback&)>; virtual void RequestPresentation(PresentationTimeCallback callback); - void BindDeviceEmulator( - mojo::PendingAssociatedReceiver<mojom::DeviceEmulator> pending_receiver); - base::WeakPtr<RenderWidget> AsWeakPtr(); protected: @@ -673,10 +668,6 @@ // is always in physical pixels. gfx::Rect CompositorViewportRect() const; - // DeviceEmulator mojom overrides. - void SetDeviceEmulation( - const base::Optional<::blink::WebDeviceEmulationParams>& params) override; - // RenderWidget IPC message handlers. void OnHandleInputEvent( const blink::WebInputEvent* event, @@ -686,6 +677,8 @@ void OnClose(); void OnUpdateVisualProperties(const VisualProperties& properties); void OnCreatingNewAck(); + void OnEnableDeviceEmulation(const blink::WebDeviceEmulationParams& params); + void OnDisableDeviceEmulation(); void OnWasHidden(); void OnWasShown( base::TimeTicks show_request_timestamp, @@ -1064,8 +1057,6 @@ scoped_refptr<MainThreadEventQueue> input_event_queue_; mojo::Receiver<mojom::Widget> widget_receiver_; - mojo::AssociatedReceiver<mojom::DeviceEmulator> device_emulator_receiver_{ - this}; gfx::Rect compositor_visible_rect_;
diff --git a/content/renderer/render_widget_delegate.h b/content/renderer/render_widget_delegate.h index 2a7db42d..bd7d362 100644 --- a/content/renderer/render_widget_delegate.h +++ b/content/renderer/render_widget_delegate.h
@@ -76,7 +76,8 @@ // Called when RenderWidget services RenderWidgetScreenMetricsEmulatorDelegate // SetScreenMetricsEmulationParameters(). virtual void SetScreenMetricsEmulationParametersForWidget( - const base::Optional<blink::WebDeviceEmulationParams>& params) = 0; + bool enabled, + const blink::WebDeviceEmulationParams& params) = 0; }; } // namespace content
diff --git a/content/renderer/render_widget_screen_metrics_emulator.cc b/content/renderer/render_widget_screen_metrics_emulator.cc index f72894f..c1dbc65 100644 --- a/content/renderer/render_widget_screen_metrics_emulator.cc +++ b/content/renderer/render_widget_screen_metrics_emulator.cc
@@ -27,7 +27,7 @@ default; void RenderWidgetScreenMetricsEmulator::DisableAndApply() { - delegate_->SetScreenMetricsEmulationParameters(base::nullopt); + delegate_->SetScreenMetricsEmulationParameters(false, emulation_params_); delegate_->SetScreenRects(original_view_screen_rect_, original_window_screen_rect_); delegate_->SetScreenInfoAndSize(original_screen_info_, original_widget_size_, @@ -59,14 +59,14 @@ // If either the width or height are specified by the emulator, then we use // that size, and assume that they have the scale pre-applied to them. - if (emulation_params_.view_size.width()) { - widget_size.set_width(emulation_params_.view_size.width()); + if (emulation_params_.view_size.width) { + widget_size.set_width(emulation_params_.view_size.width); } else { widget_size.set_width( gfx::ToRoundedInt(widget_size.width() / emulation_params_.scale)); } - if (emulation_params_.view_size.height()) { - widget_size.set_height(emulation_params_.view_size.height()); + if (emulation_params_.view_size.height) { + widget_size.set_height(emulation_params_.view_size.height); } else { widget_size.set_height( gfx::ToRoundedInt(widget_size.height() / emulation_params_.scale)); @@ -113,21 +113,21 @@ uint16_t orientation_angle = original_screen_info().orientation_angle; switch (emulation_params_.screen_orientation_type) { - case blink::mojom::ScreenOrientationType::kUndefined: + case blink::kWebScreenOrientationUndefined: break; // Leave as the real value. - case blink::mojom::ScreenOrientationType::kPortraitPrimary: + case blink::kWebScreenOrientationPortraitPrimary: orientation_type = SCREEN_ORIENTATION_VALUES_PORTRAIT_PRIMARY; orientation_angle = emulation_params_.screen_orientation_angle; break; - case blink::mojom::ScreenOrientationType::kPortraitSecondary: + case blink::kWebScreenOrientationPortraitSecondary: orientation_type = SCREEN_ORIENTATION_VALUES_PORTRAIT_SECONDARY; orientation_angle = emulation_params_.screen_orientation_angle; break; - case blink::mojom::ScreenOrientationType::kLandscapePrimary: + case blink::kWebScreenOrientationLandscapePrimary: orientation_type = SCREEN_ORIENTATION_VALUES_LANDSCAPE_PRIMARY; orientation_angle = emulation_params_.screen_orientation_angle; break; - case blink::mojom::ScreenOrientationType::kLandscapeSecondary: + case blink::kWebScreenOrientationLandscapeSecondary: orientation_type = SCREEN_ORIENTATION_VALUES_LANDSCAPE_SECONDARY; orientation_angle = emulation_params_.screen_orientation_angle; break; @@ -136,10 +136,11 @@ // Pass three emulation parameters to the blink side: // - we keep the real device scale factor in compositor to produce sharp image // even when emulating different scale factor; - auto modified_emulation_params = emulation_params_; + blink::WebDeviceEmulationParams modified_emulation_params = emulation_params_; modified_emulation_params.device_scale_factor = original_screen_info().device_scale_factor; - delegate_->SetScreenMetricsEmulationParameters(modified_emulation_params); + delegate_->SetScreenMetricsEmulationParameters(true, + modified_emulation_params); delegate_->SetScreenRects(gfx::Rect(widget_pos, widget_size), gfx::Rect(window_pos, window_size));
diff --git a/content/renderer/render_widget_screen_metrics_emulator.h b/content/renderer/render_widget_screen_metrics_emulator.h index bae4f8e..469a46d 100644 --- a/content/renderer/render_widget_screen_metrics_emulator.h +++ b/content/renderer/render_widget_screen_metrics_emulator.h
@@ -9,7 +9,7 @@ #include "content/common/content_export.h" #include "content/public/common/screen_info.h" -#include "third_party/blink/public/mojom/devtools/device_emulation_params.mojom.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -68,7 +68,7 @@ private: bool emulating_desktop() const { return emulation_params_.screen_position == - blink::mojom::ScreenPosition::kDesktop; + blink::WebDeviceEmulationParams::kDesktop; } // Applies emulated values to the RenderWidget. @@ -76,7 +76,7 @@ RenderWidgetScreenMetricsEmulatorDelegate* const delegate_; - // Parameters as passed by RenderWidget::SetScreenMetricsEmulation. + // Parameters as passed by RenderWidget::EnableScreenMetricsEmulation. blink::WebDeviceEmulationParams emulation_params_; // Original values to restore back after emulation ends.
diff --git a/content/renderer/render_widget_screen_metrics_emulator_delegate.h b/content/renderer/render_widget_screen_metrics_emulator_delegate.h index 12c714d..2ad2536 100644 --- a/content/renderer/render_widget_screen_metrics_emulator_delegate.h +++ b/content/renderer/render_widget_screen_metrics_emulator_delegate.h
@@ -19,7 +19,8 @@ public: // Passes device emulation parameters to the delegate. virtual void SetScreenMetricsEmulationParameters( - const base::Optional<blink::WebDeviceEmulationParams>& params) = 0; + bool enabled, + const blink::WebDeviceEmulationParams& params) = 0; // Passes an updated ScreenInfo and sizes to the delegate. virtual void SetScreenInfoAndSize(const ScreenInfo& screen_info,
diff --git a/content/renderer/render_widget_unittest.cc b/content/renderer/render_widget_unittest.cc index 177e8f6..f03bffc 100644 --- a/content/renderer/render_widget_unittest.cc +++ b/content/renderer/render_widget_unittest.cc
@@ -40,6 +40,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_coalesced_input_event.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/public/web/web_external_widget.h" #include "third_party/blink/public/web/web_external_widget_client.h" #include "third_party/blink/public/web/web_frame_widget.h" @@ -550,7 +551,8 @@ const gfx::Size& visible_viewport_size, cc::BrowserControlsParams) override {} void SetScreenMetricsEmulationParametersForWidget( - const base::Optional<blink::WebDeviceEmulationParams>& params) override {} + bool enabled, + const blink::WebDeviceEmulationParams& params) override {} }; // Tests that the value of VisualProperties::is_pinch_gesture_active is
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index d895f2d2..548ce84 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -295,6 +295,8 @@ "portal/portal_created_observer.h", "portal/portal_interceptor_for_testing.cc", "portal/portal_interceptor_for_testing.h", + "render_document_feature.cc", + "render_document_feature.h", "storage_partition_test_utils.cc", "storage_partition_test_utils.h", "stub_layer_tree_view_delegate.cc",
diff --git a/content/test/data/accessibility/aria/annotation-roles-expected-uia-win.txt b/content/test/data/accessibility/aria/annotation-roles-expected-uia-win.txt index a1889b7..9ecfe799 100644 --- a/content/test/data/accessibility/aria/annotation-roles-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/annotation-roles-expected-uia-win.txt
@@ -6,4 +6,3 @@ ++++Text LocalizedControlType='highlight' ++++++Text Name='highlighted' ++++Text Name='.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-button-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-button-expected-uia-win.txt index bba71c2..0a9b5cb 100644 --- a/content/test/data/accessibility/aria/aria-button-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-button-expected-uia-win.txt
@@ -13,4 +13,3 @@ ++Button Name='Complex pop up button ' ExpandCollapse.ExpandCollapseState='Collapsed' ++++Text Name='Complex pop up button ' ++++Edit -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-code-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-code-expected-uia-win.txt index b676cf7..b246de5d 100644 --- a/content/test/data/accessibility/aria/aria-code-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-code-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++Text LocalizedControlType='text' Name=' ' ++Text LocalizedControlType='code' Name='include me' ++++Text LocalizedControlType='text' Name='element (with name)' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-contentinfo-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-contentinfo-expected-uia-win.txt index 0765bdf..b265954b 100644 --- a/content/test/data/accessibility/aria/aria-contentinfo-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-contentinfo-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group LocalizedControlType='content information' LocalizedLandmarkType='content information' ++++Text Name='This is ARIA role contentinfo.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-contentinfo-expected-uia-win7.txt b/content/test/data/accessibility/aria/aria-contentinfo-expected-uia-win7.txt index d9d968e6..00a31d3 100644 --- a/content/test/data/accessibility/aria/aria-contentinfo-expected-uia-win7.txt +++ b/content/test/data/accessibility/aria/aria-contentinfo-expected-uia-win7.txt
@@ -1,4 +1,3 @@ Document ++Group LocalizedControlType='content information' ++++Text Name='This is ARIA role contentinfo.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-emphasis-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-emphasis-expected-uia-win.txt index 13e36bdb..9d472d9e 100644 --- a/content/test/data/accessibility/aria/aria-emphasis-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-emphasis-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++Text LocalizedControlType='text' Name=' ' ++Text LocalizedControlType='emphasis' Name='include me' ++++Text LocalizedControlType='text' Name='element (with name)' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-generic-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-generic-expected-uia-win.txt index 7b2c656..faf2453 100644 --- a/content/test/data/accessibility/aria/aria-generic-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-generic-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group ++++Text Name='content' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-gridcell-focused-only-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-gridcell-focused-only-expected-uia-win.txt index 1b14abe..c069b1c 100644 --- a/content/test/data/accessibility/aria/aria-gridcell-focused-only-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-gridcell-focused-only-expected-uia-win.txt
@@ -11,4 +11,3 @@ ++++++DataItem Name='Blink' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1 ++++++++Text Name='Blink' IsControlElement=false ++Text Name='Done' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-hidden-described-by-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-hidden-described-by-expected-uia-win.txt index e3c48954..ad28b7ec 100644 --- a/content/test/data/accessibility/aria/aria-hidden-described-by-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-hidden-described-by-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++Group Name='span-B' DescribedBy='span-2' ++Group Name='span-C' DescribedBy='span-3' ++Group Name='span-D' DescribedBy='span-4' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-hidden-labelled-by-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-hidden-labelled-by-expected-uia-win.txt index 1423b9bb..e958bf8 100644 --- a/content/test/data/accessibility/aria/aria-hidden-labelled-by-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-hidden-labelled-by-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++Group Name='span-2' LabeledBy='span-2' ++Group Name='span-3' LabeledBy='span-4' ++Group Name='span-4' LabeledBy='span-4' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-strong-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-strong-expected-uia-win.txt index d429537..090fa66 100644 --- a/content/test/data/accessibility/aria/aria-strong-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-strong-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++Text LocalizedControlType='text' Name=' ' ++Text LocalizedControlType='strong' Name='include me' ++++Text LocalizedControlType='text' Name='element (with name)' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-tab-nested-in-lists-expected-blink.txt b/content/test/data/accessibility/aria/aria-tab-nested-in-lists-expected-blink.txt index a441ed9..fd69e57 100644 --- a/content/test/data/accessibility/aria/aria-tab-nested-in-lists-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-tab-nested-in-lists-expected-blink.txt
@@ -9,4 +9,3 @@ ++++++++tab name='tab3' setSize=5 posInSet=4 selected=false ++++++listItem hierarchicalLevel=1 ++++++++tab name='tab4' setSize=5 posInSet=5 selected=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-tablist-expected-win.txt b/content/test/data/accessibility/aria/aria-tablist-expected-win.txt index 2b3925f..69bb54e 100644 --- a/content/test/data/accessibility/aria/aria-tablist-expected-win.txt +++ b/content/test/data/accessibility/aria/aria-tablist-expected-win.txt
@@ -9,4 +9,3 @@ ++++++++ROLE_SYSTEM_PAGETABLIST IA2_STATE_HORIZONTAL xml-roles:tablist level:3 ++++++++++ROLE_SYSTEM_PAGETAB name='Tab 1, level 3' xml-roles:tab ++++ROLE_SYSTEM_PAGETAB name='Tab 3, level 1' xml-roles:tab -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-time-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-time-expected-uia-win.txt index 2e4ed51..def6784 100644 --- a/content/test/data/accessibility/aria/aria-time-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-time-expected-uia-win.txt
@@ -6,4 +6,3 @@ ++Text LocalizedControlType='text' Name=' ' ++Text LocalizedControlType='time' Name='include me' ++++Text LocalizedControlType='text' Name='element (with name)' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win.txt index 93c4b8d..4c13f7d 100644 --- a/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++++Group PositionInSet=0 SizeOfSet=0 ++++TreeItem Name='card content' PositionInSet=2 SizeOfSet=2 ExpandCollapse.ExpandCollapseState='LeafNode' ++++++Text Name='card content' IsControlElement=false PositionInSet=0 SizeOfSet=0 -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win7.txt b/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win7.txt index 02ecc25..b3137d3 100644 --- a/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win7.txt +++ b/content/test/data/accessibility/aria/aria-tree-discontinuous-expected-uia-win7.txt
@@ -5,4 +5,3 @@ ++++Group ++++TreeItem Name='card content' ExpandCollapse.ExpandCollapseState='LeafNode' ++++++Text Name='card content' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/hidden-described-by-expected-uia-win.txt b/content/test/data/accessibility/aria/hidden-described-by-expected-uia-win.txt index b5f9193..554aad7 100644 --- a/content/test/data/accessibility/aria/hidden-described-by-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/hidden-described-by-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group Name='span-A3' DescribedBy='span-A4' ++Group Name='span-B' DescribedBy='span-A2' ++Group Name='span-C' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/hidden-expected-uia-win.txt b/content/test/data/accessibility/aria/hidden-expected-uia-win.txt index 923230f8..7b3188f 100644 --- a/content/test/data/accessibility/aria/hidden-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/hidden-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group Name='b' ++Group Name='c' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/aria/hidden-labelled-by-expected-uia-win.txt b/content/test/data/accessibility/aria/hidden-labelled-by-expected-uia-win.txt index 52d2557c..2456b36 100644 --- a/content/test/data/accessibility/aria/hidden-labelled-by-expected-uia-win.txt +++ b/content/test/data/accessibility/aria/hidden-labelled-by-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group Name='span-A4' LabeledBy='span-A4' ++Group Name='span-A2' LabeledBy='span-A2' ++Group Name='span-C' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/css/transform-expected-uia-win.txt b/content/test/data/accessibility/css/transform-expected-uia-win.txt index 572f77a..1b1d409 100644 --- a/content/test/data/accessibility/css/transform-expected-uia-win.txt +++ b/content/test/data/accessibility/css/transform-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group BoundingRectangle=(0, 50, 48, 18) IsControlElement=false ++++Group BoundingRectangle=(0, 50, 48, 18) IsControlElement=false ++++++Text BoundingRectangle=(0, 50, 48, 17) Name='content' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/css/visibility-expected-uia-win.txt b/content/test/data/accessibility/css/visibility-expected-uia-win.txt index 68486b2..c70accf2 100644 --- a/content/test/data/accessibility/css/visibility-expected-uia-win.txt +++ b/content/test/data/accessibility/css/visibility-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Text Name='visible link' ++Text Name='visible link' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/aria-combo-box-collapse-expected-uia-win7.txt b/content/test/data/accessibility/event/aria-combo-box-collapse-expected-uia-win7.txt new file mode 100644 index 0000000..b665a9a --- /dev/null +++ b/content/test/data/accessibility/event/aria-combo-box-collapse-expected-uia-win7.txt
@@ -0,0 +1,6 @@ +AriaProperties changed on role=combobox +AutomationFocusChanged on role=combobox +AutomationFocusChanged on role=combobox +AutomationFocusChanged on role=option, name=Orange +ExpandCollapseExpandCollapseState changed on role=combobox +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/aria-combo-box-expand-expected-uia-win7.txt b/content/test/data/accessibility/event/aria-combo-box-expand-expected-uia-win7.txt new file mode 100644 index 0000000..5d77f3e --- /dev/null +++ b/content/test/data/accessibility/event/aria-combo-box-expand-expected-uia-win7.txt
@@ -0,0 +1,8 @@ +AriaProperties changed on role=combobox +AriaProperties changed on role=option, name=Apple +AutomationFocusChanged on role=combobox +AutomationFocusChanged on role=option, name=Apple +AutomationFocusChanged on role=option, name=Apple +ExpandCollapseExpandCollapseState changed on role=combobox +SelectionItem_ElementSelected on role=option, name=Apple +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/aria-combo-box-next-expected-uia-win7.txt b/content/test/data/accessibility/event/aria-combo-box-next-expected-uia-win7.txt new file mode 100644 index 0000000..649cf09 --- /dev/null +++ b/content/test/data/accessibility/event/aria-combo-box-next-expected-uia-win7.txt
@@ -0,0 +1,14 @@ +AriaProperties changed on role=option, name=Apple +AriaProperties changed on role=option, name=Orange +AutomationFocusChanged on role=option, name=Apple +AutomationFocusChanged on role=option, name=Orange +AutomationFocusChanged on role=option, name=Orange +SelectionItem_ElementSelected on role=option, name=Orange +=== Start Continuation === +AriaProperties changed on role=option, name=Banana +AriaProperties changed on role=option, name=Orange +AutomationFocusChanged on role=option, name=Banana +AutomationFocusChanged on role=option, name=Banana +AutomationFocusChanged on role=option, name=Orange +SelectionItem_ElementSelected on role=option, name=Banana +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/listbox-next-expected-uia-win7.txt b/content/test/data/accessibility/event/listbox-next-expected-uia-win7.txt new file mode 100644 index 0000000..ab7a250 --- /dev/null +++ b/content/test/data/accessibility/event/listbox-next-expected-uia-win7.txt
@@ -0,0 +1,7 @@ +AriaProperties changed on role=option, name=Apple +AriaProperties changed on role=option, name=Orange +AutomationFocusChanged on role=option, name=Apple +AutomationFocusChanged on role=option, name=Orange +AutomationFocusChanged on role=option, name=Orange +SelectionItem_ElementSelected on role=option, name=Orange +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/menulist-collapse-expected-mac.txt b/content/test/data/accessibility/event/menulist-collapse-expected-mac.txt index 4dc69e86..9fcb8ce 100644 --- a/content/test/data/accessibility/event/menulist-collapse-expected-mac.txt +++ b/content/test/data/accessibility/event/menulist-collapse-expected-mac.txt
@@ -1,2 +1,5 @@ +AXFocusedUIElementChanged on AXPopUpButton AXValue="Apple" +=== Start Continuation === AXSelectedChildrenChanged on AXMenu AXValueChanged on AXPopUpButton +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt b/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt index 4cd300f..90ceb35 100644 --- a/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt +++ b/content/test/data/accessibility/event/menulist-collapse-expected-uia-win.txt
@@ -1,3 +1,7 @@ +AutomationFocusChanged on role=combobox +AutomationFocusChanged on role=combobox +=== Start Continuation === AriaProperties changed on role=listitem, name=Apple SelectionItem_ElementRemovedFromSelection on role=listitem, name=Apple ValueValue changed on role=combobox +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/menulist-collapse-expected-uia-win7.txt b/content/test/data/accessibility/event/menulist-collapse-expected-uia-win7.txt new file mode 100644 index 0000000..22a595f --- /dev/null +++ b/content/test/data/accessibility/event/menulist-collapse-expected-uia-win7.txt
@@ -0,0 +1,8 @@ +AutomationFocusChanged on role=combobox +AutomationFocusChanged on role=combobox +=== Start Continuation === +AriaProperties changed on role=listitem, name=Apple +AutomationFocusChanged on role=combobox +SelectionItem_ElementRemovedFromSelection on role=listitem, name=Apple +ValueValue changed on role=combobox +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/menulist-collapse-expected-win.txt b/content/test/data/accessibility/event/menulist-collapse-expected-win.txt index 286e043..6903d28 100644 --- a/content/test/data/accessibility/event/menulist-collapse-expected-win.txt +++ b/content/test/data/accessibility/event/menulist-collapse-expected-win.txt
@@ -1,4 +1,7 @@ +EVENT_OBJECT_FOCUS on <select> role=ROLE_SYSTEM_COMBOBOX value="Apple" FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP SetSize=3 +=== Start Continuation === EVENT_OBJECT_SELECTIONREMOVE on <option> role=ROLE_SYSTEM_LISTITEM name="Apple" INVISIBLE,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=3 EVENT_OBJECT_SELECTIONWITHIN on role=ROLE_SYSTEM_LIST INVISIBLE SetSize=3 EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Apple" INVISIBLE,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=3 -EVENT_OBJECT_VALUECHANGE on <select> role=ROLE_SYSTEM_COMBOBOX FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP SetSize=3 \ No newline at end of file +EVENT_OBJECT_VALUECHANGE on <select> role=ROLE_SYSTEM_COMBOBOX FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP SetSize=3 +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/menulist-collapse-next-expected-auralinux.txt b/content/test/data/accessibility/event/menulist-collapse-next-expected-auralinux.txt index 09f8aed..a7ef68a 100644 --- a/content/test/data/accessibility/event/menulist-collapse-next-expected-auralinux.txt +++ b/content/test/data/accessibility/event/menulist-collapse-next-expected-auralinux.txt
@@ -1,2 +1,8 @@ +FOCUS-EVENT role=ROLE_COMBO_BOX name='(null)' ENABLED,EXPANDABLE,FOCUSABLE,FOCUSED,SENSITIVE,SHOWING,VISIBLE +FOCUS-EVENT role=ROLE_DOCUMENT_WEB name='(null)' ENABLED,FOCUSABLE,SENSITIVE,SHOWING,VISIBLE +STATE-CHANGE:FOCUSED:FALSE role=ROLE_DOCUMENT_WEB name='(null)' ENABLED,FOCUSABLE,SENSITIVE,SHOWING,VISIBLE +STATE-CHANGE:FOCUSED:TRUE role=ROLE_COMBO_BOX name='(null)' ENABLED,EXPANDABLE,FOCUSABLE,FOCUSED,SENSITIVE,SHOWING,VISIBLE +=== Start Continuation === SELECTION-CHANGED role=ROLE_MENU name='(null)' ENABLED,SENSITIVE STATE-CHANGE:SELECTED:TRUE role=ROLE_MENU_ITEM name='Orange' ENABLED,FOCUSABLE,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE +<-- End-of-file --> \ No newline at end of file
diff --git a/content/test/data/accessibility/event/menulist-collapse-next-expected-mac.txt b/content/test/data/accessibility/event/menulist-collapse-next-expected-mac.txt index ac839fd..9f95856 100644 --- a/content/test/data/accessibility/event/menulist-collapse-next-expected-mac.txt +++ b/content/test/data/accessibility/event/menulist-collapse-next-expected-mac.txt
@@ -1,2 +1,5 @@ +AXFocusedUIElementChanged on AXPopUpButton AXValue="Apple" +=== Start Continuation === AXSelectedChildrenChanged on AXMenu AXValueChanged on AXPopUpButton AXValue="Orange" +<-- End-of-file --> \ No newline at end of file
diff --git a/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win.txt b/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win.txt index 33216a32..b12bee8 100644 --- a/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win.txt +++ b/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win.txt
@@ -1,4 +1,8 @@ +AutomationFocusChanged on role=combobox +AutomationFocusChanged on role=combobox +=== Start Continuation === AriaProperties changed on role=listitem, name=Apple AriaProperties changed on role=listitem, name=Orange SelectionItem_ElementSelected on role=listitem, name=Orange ValueValue changed on role=combobox +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win7.txt b/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win7.txt new file mode 100644 index 0000000..b7aa066b --- /dev/null +++ b/content/test/data/accessibility/event/menulist-collapse-next-expected-uia-win7.txt
@@ -0,0 +1,9 @@ +AutomationFocusChanged on role=combobox +AutomationFocusChanged on role=combobox +=== Start Continuation === +AriaProperties changed on role=listitem, name=Apple +AriaProperties changed on role=listitem, name=Orange +AutomationFocusChanged on role=combobox +SelectionItem_ElementSelected on role=listitem, name=Orange +ValueValue changed on role=combobox +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/menulist-collapse-next-expected-win.txt b/content/test/data/accessibility/event/menulist-collapse-next-expected-win.txt index 64feb950..d7e2c78 100644 --- a/content/test/data/accessibility/event/menulist-collapse-next-expected-win.txt +++ b/content/test/data/accessibility/event/menulist-collapse-next-expected-win.txt
@@ -1,5 +1,8 @@ +EVENT_OBJECT_FOCUS on <select> role=ROLE_SYSTEM_COMBOBOX value="Apple" FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP SetSize=3 +=== Start Continuation === EVENT_OBJECT_SELECTION on <option> role=ROLE_SYSTEM_LISTITEM name="Orange" SELECTED,FOCUSABLE,SELECTABLE PosInSet=2 SetSize=3 EVENT_OBJECT_SELECTIONWITHIN on role=ROLE_SYSTEM_LIST INVISIBLE SetSize=3 EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Apple" INVISIBLE,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=3 EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Orange" SELECTED,FOCUSABLE,SELECTABLE PosInSet=2 SetSize=3 EVENT_OBJECT_VALUECHANGE on <select> role=ROLE_SYSTEM_COMBOBOX value="Orange" FOCUSED,COLLAPSED,FOCUSABLE,HASPOPUP SetSize=3 +<-- End-of-file -->
diff --git a/content/test/data/accessibility/event/menulist-collapse-next.html b/content/test/data/accessibility/event/menulist-collapse-next.html index d1b01f5..75d3377 100644 --- a/content/test/data/accessibility/event/menulist-collapse-next.html +++ b/content/test/data/accessibility/event/menulist-collapse-next.html
@@ -10,9 +10,19 @@ <option>Banana</option> </select> <script> - document.querySelector('select').focus(); + const go_passes = [ + () => { + document.querySelector('select').focus(); + }, + () => { + document.querySelector('select').selectedIndex = 1; + } + ]; + + let current_pass = 0; function go() { - document.querySelector('select').selectedIndex = 1; + go_passes[current_pass++].call(); + return current_pass < go_passes.length; } </script> </body>
diff --git a/content/test/data/accessibility/event/menulist-collapse.html b/content/test/data/accessibility/event/menulist-collapse.html index ac1dacb..48a41e45 100644 --- a/content/test/data/accessibility/event/menulist-collapse.html +++ b/content/test/data/accessibility/event/menulist-collapse.html
@@ -10,10 +10,20 @@ <option>Banana</option> </select> <script> - document.querySelector('select').focus(); + const go_passes = [ + () => { + document.querySelector('select').focus(); + }, + () => { + // Setting |selectedIndex| to -1 unselects any selected item. + document.querySelector('select').selectedIndex = -1; + } + ]; + + let current_pass = 0; function go() { - // Setting |selectedIndex| to -1 unselects any selected item. - document.querySelector('select').selectedIndex = -1; + go_passes[current_pass++].call(); + return current_pass < go_passes.length; } </script> </body>
diff --git a/content/test/data/accessibility/html/a-expected-uia-win.txt b/content/test/data/accessibility/html/a-expected-uia-win.txt index 8bc3713..fa7c7d51 100644 --- a/content/test/data/accessibility/html/a-expected-uia-win.txt +++ b/content/test/data/accessibility/html/a-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Hyperlink Name='normal link' ++++++Text Name='normal link' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/a-name-calc-expected-uia-win.txt b/content/test/data/accessibility/html/a-name-calc-expected-uia-win.txt index 9d86ffb..2151687 100644 --- a/content/test/data/accessibility/html/a-name-calc-expected-uia-win.txt +++ b/content/test/data/accessibility/html/a-name-calc-expected-uia-win.txt
@@ -13,4 +13,3 @@ ++Hyperlink Name='Title4' ++Hyperlink Name='Label5' ++Hyperlink Name='LabelledBy6' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/a-name-calc-expected-uia-win7.txt b/content/test/data/accessibility/html/a-name-calc-expected-uia-win7.txt index 3329f62..73728b2 100644 --- a/content/test/data/accessibility/html/a-name-calc-expected-uia-win7.txt +++ b/content/test/data/accessibility/html/a-name-calc-expected-uia-win7.txt
@@ -13,4 +13,3 @@ ++Hyperlink Name='Title4' ++Hyperlink Name='Label5' ++Hyperlink Name='LabelledBy6' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/a-name-expected-uia-win.txt b/content/test/data/accessibility/html/a-name-expected-uia-win.txt index d527391e..a0d54cc 100644 --- a/content/test/data/accessibility/html/a-name-expected-uia-win.txt +++ b/content/test/data/accessibility/html/a-name-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='named anchor' ++Hyperlink Name='both a named anchor and a link' ++++Text Name='both a named anchor and a link' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/a-onclick-expected-uia-win.txt b/content/test/data/accessibility/html/a-onclick-expected-uia-win.txt index 1699f6a..d0ff9c9 100644 --- a/content/test/data/accessibility/html/a-onclick-expected-uia-win.txt +++ b/content/test/data/accessibility/html/a-onclick-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='link with no href but onclick' IsControlElement=false ++Hyperlink Name='link with no href and click handler added via script' ++++Text Name='link with no href and click handler added via script' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt b/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt index 8036d5d..c36522bb 100644 --- a/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt +++ b/content/test/data/accessibility/html/a-with-img-expected-uia-win.txt
@@ -17,4 +17,3 @@ ++++Hyperlink Name='Link with image at the end' ++++++Text Name='Link with image at the ' IsControlElement=false ++++++Image Name='end' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/abbr-expected-uia-win.txt b/content/test/data/accessibility/html/abbr-expected-uia-win.txt index 6b673dac..489fed7 100644 --- a/content/test/data/accessibility/html/abbr-expected-uia-win.txt +++ b/content/test/data/accessibility/html/abbr-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++Text Name='World Health Organization' ++++++Text Name='WHO' ++++Text Name=' was founded in 1948.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/action-verbs-expected-uia-win.txt b/content/test/data/accessibility/html/action-verbs-expected-uia-win.txt index 84529d4c..a227e47 100644 --- a/content/test/data/accessibility/html/action-verbs-expected-uia-win.txt +++ b/content/test/data/accessibility/html/action-verbs-expected-uia-win.txt
@@ -34,4 +34,3 @@ ++Button Name='ARIA button with negative tab index' ++Group ++++Button Name='ARIA button that is an active descendant' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/actions-expected-uia-win.txt b/content/test/data/accessibility/html/actions-expected-uia-win.txt index 02dad7ee..8f988d0 100644 --- a/content/test/data/accessibility/html/actions-expected-uia-win.txt +++ b/content/test/data/accessibility/html/actions-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Slider RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=100.00 RangeValue.Minimum=1.00 RangeValue.Value=50.00 Value.Value='50' ++++Edit Name='Test textfield' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/address-expected-uia-win.txt b/content/test/data/accessibility/html/address-expected-uia-win.txt index 280eadc..a79add76 100644 --- a/content/test/data/accessibility/html/address-expected-uia-win.txt +++ b/content/test/data/accessibility/html/address-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Text Name='Please contact John Citizen for more information.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/area-expected-uia-win.txt b/content/test/data/accessibility/html/area-expected-uia-win.txt index f8dee90..435a60028 100644 --- a/content/test/data/accessibility/html/area-expected-uia-win.txt +++ b/content/test/data/accessibility/html/area-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Document Name='pipe' ++++++Hyperlink Name='pipe1' ++++++Text Name='pipe2' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/article-expected-uia-win.txt b/content/test/data/accessibility/html/article-expected-uia-win.txt index 9117567a..86b5882 100644 --- a/content/test/data/accessibility/html/article-expected-uia-win.txt +++ b/content/test/data/accessibility/html/article-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group LocalizedControlType='article' ++++Text Name='This is an article element.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/aside-expected-uia-win.txt b/content/test/data/accessibility/html/aside-expected-uia-win.txt index ab252b8f..45ccd12 100644 --- a/content/test/data/accessibility/html/aside-expected-uia-win.txt +++ b/content/test/data/accessibility/html/aside-expected-uia-win.txt
@@ -6,4 +6,3 @@ ++++++Text Name='Aside tag' IsControlElement=false ++++Group IsControlElement=false ++++++Text Name='The aside content should be related to the surrounding content.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/b-expected-uia-win.txt b/content/test/data/accessibility/html/b-expected-uia-win.txt index d9305a3..1bb666f 100644 --- a/content/test/data/accessibility/html/b-expected-uia-win.txt +++ b/content/test/data/accessibility/html/b-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='Some ' ++++Text Name='bold' ++++Text Name=' text' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/bdo-expected-uia-win.txt b/content/test/data/accessibility/html/bdo-expected-uia-win.txt index fb47567..50e795d7 100644 --- a/content/test/data/accessibility/html/bdo-expected-uia-win.txt +++ b/content/test/data/accessibility/html/bdo-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++Text Name=' ' ++++Text Name='Some RTL text ' ++++Text Name='with some LTR text embedded' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/blockquote-expected-uia-win.txt b/content/test/data/accessibility/html/blockquote-expected-uia-win.txt index ab30414..46cf324 100644 --- a/content/test/data/accessibility/html/blockquote-expected-uia-win.txt +++ b/content/test/data/accessibility/html/blockquote-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++++Text Name='First blockquote has a child element.' ++Group ++++Text Name='Second blockquote has no child.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/body-expected-uia-win.txt b/content/test/data/accessibility/html/body-expected-uia-win.txt index 38cda4f0..d51a884 100644 --- a/content/test/data/accessibility/html/body-expected-uia-win.txt +++ b/content/test/data/accessibility/html/body-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Text Name='This test is for body tag' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/br-expected-uia-win.txt b/content/test/data/accessibility/html/br-expected-uia-win.txt index 0c3aeffe..3bb54ec 100644 --- a/content/test/data/accessibility/html/br-expected-uia-win.txt +++ b/content/test/data/accessibility/html/br-expected-uia-win.txt
@@ -6,4 +6,3 @@ ++++Separator Name='<newline>' ++++Text Name='Text line 3' ++Separator Name='<newline>' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/br-expected-win.txt b/content/test/data/accessibility/html/br-expected-win.txt index 52ede30..31dc103 100644 --- a/content/test/data/accessibility/html/br-expected-win.txt +++ b/content/test/data/accessibility/html/br-expected-win.txt
@@ -6,4 +6,3 @@ ++++ROLE_SYSTEM_WHITESPACE name='<newline>' ++++ROLE_SYSTEM_STATICTEXT name='Text line 3' ++ROLE_SYSTEM_WHITESPACE name='<newline>' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/button-expected-uia-win.txt b/content/test/data/accessibility/html/button-expected-uia-win.txt index 81c50aa..302c3e0 100644 --- a/content/test/data/accessibility/html/button-expected-uia-win.txt +++ b/content/test/data/accessibility/html/button-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Button Name='Click me!' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/button-name-calc-expected-uia-win.txt b/content/test/data/accessibility/html/button-name-calc-expected-uia-win.txt index 3b260f2..1b1cbaf3 100644 --- a/content/test/data/accessibility/html/button-name-calc-expected-uia-win.txt +++ b/content/test/data/accessibility/html/button-name-calc-expected-uia-win.txt
@@ -18,4 +18,3 @@ ++++Group ++++++Group IsControlElement=false ++++++++Text Name='grandchild' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/button-name-calc-expected-uia-win7.txt b/content/test/data/accessibility/html/button-name-calc-expected-uia-win7.txt index 5b04033..479732d 100644 --- a/content/test/data/accessibility/html/button-name-calc-expected-uia-win7.txt +++ b/content/test/data/accessibility/html/button-name-calc-expected-uia-win7.txt
@@ -18,4 +18,3 @@ ++++Group ++++++Group IsControlElement=false ++++++++Text Name='grandchild' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/button-with-listbox-popup-expected-uia-win.txt b/content/test/data/accessibility/html/button-with-listbox-popup-expected-uia-win.txt index ff31457..84e300ea 100644 --- a/content/test/data/accessibility/html/button-with-listbox-popup-expected-uia-win.txt +++ b/content/test/data/accessibility/html/button-with-listbox-popup-expected-uia-win.txt
@@ -8,4 +8,3 @@ ++++++ListItem Name='Baz' SelectionItem.IsSelected=false SelectionItem.SelectionContainer='Choose one:' ++++++ListItem Name='Bar' SelectionItem.IsSelected=false SelectionItem.SelectionContainer='Choose one:' ++++++ListItem Name='Foo' SelectionItem.IsSelected=false SelectionItem.SelectionContainer='Choose one:' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/canvas-expected-uia-win.txt b/content/test/data/accessibility/html/canvas-expected-uia-win.txt index c1c594a..b98eb69 100644 --- a/content/test/data/accessibility/html/canvas-expected-uia-win.txt +++ b/content/test/data/accessibility/html/canvas-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++++Image ++++++Hyperlink Name='Interactive fallback' ++++++++Text Name='Interactive fallback' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt b/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt index 6857a09..9588e631 100644 --- a/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt +++ b/content/test/data/accessibility/html/canvas-fallback-expected-uia-win.txt
@@ -19,4 +19,3 @@ ++++++Text IsControlElement=false ++++++++Text Name='Visibility hidden paragraph in fallback content' IsControlElement=false ++++++Text Name='<newline> ' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/caption-expected-uia-win.txt b/content/test/data/accessibility/html/caption-expected-uia-win.txt index ba5fe04..55a6af78 100644 --- a/content/test/data/accessibility/html/caption-expected-uia-win.txt +++ b/content/test/data/accessibility/html/caption-expected-uia-win.txt
@@ -17,4 +17,3 @@ ++++++++Text Name='Safari' IsControlElement=false ++++++DataItem Name='WebKit' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1 GridItem.ContainingGrid='Browser and Engine' ++++++++Text Name='WebKit' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/checkbox-name-calc-expected-uia-win.txt b/content/test/data/accessibility/html/checkbox-name-calc-expected-uia-win.txt index 01cccc0..edda8fb 100644 --- a/content/test/data/accessibility/html/checkbox-name-calc-expected-uia-win.txt +++ b/content/test/data/accessibility/html/checkbox-name-calc-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++CheckBox Name='LabelledBy3' Toggle.ToggleState='Off' ++CheckBox Name='LabelledBy4' Toggle.ToggleState='Off' ++CheckBox Toggle.ToggleState='Off' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/cite-expected-uia-win.txt b/content/test/data/accessibility/html/cite-expected-uia-win.txt index 168a646..0a4ea99 100644 --- a/content/test/data/accessibility/html/cite-expected-uia-win.txt +++ b/content/test/data/accessibility/html/cite-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++Group IsControlElement=false ++++Text Name='The pipe' ++++Text Name=' clicked by SomeOne.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/combobox-optgroup-expected-uia-win.txt b/content/test/data/accessibility/html/combobox-optgroup-expected-uia-win.txt index 63a71be..48a9d6a 100644 --- a/content/test/data/accessibility/html/combobox-optgroup-expected-uia-win.txt +++ b/content/test/data/accessibility/html/combobox-optgroup-expected-uia-win.txt
@@ -6,4 +6,3 @@ ++++++++ListItem Name='Saab Label' SelectionItem.IsSelected=false ++++++++ListItem Name='Mercedes Label' SelectionItem.IsSelected=true ++++++++ListItem Name='Audi Label' SelectionItem.IsSelected=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt index 108f5bc..ed82d56 100644 --- a/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt +++ b/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt
@@ -21,4 +21,3 @@ ++++Text Name='Non-editable paragraph.' ++Group ++++Text Name='Should keep the role but change the state.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt index 25e26fc..e75c2d3 100644 --- a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt +++ b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt
@@ -17,4 +17,3 @@ ++++++ListItem ++++++++Text Name='1. ' ++++++++Text Name='Editable list item.' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/contenteditable-with-embedded-contenteditables-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-with-embedded-contenteditables-expected-uia-win.txt index b53b59de7..760c6bdd 100644 --- a/content/test/data/accessibility/html/contenteditable-with-embedded-contenteditables-expected-uia-win.txt +++ b/content/test/data/accessibility/html/contenteditable-with-embedded-contenteditables-expected-uia-win.txt
@@ -8,4 +8,3 @@ ++++++Text Name='But this one is.' ++++Group ++++++Text Name='So is this one.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/contenteditable-with-no-descendants-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-with-no-descendants-expected-uia-win.txt index 7180b0d5..03278132 100644 --- a/content/test/data/accessibility/html/contenteditable-with-no-descendants-expected-uia-win.txt +++ b/content/test/data/accessibility/html/contenteditable-with-no-descendants-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++Group Name='title' ++Group IsControlElement=false ++++Text Name='description' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/dd-expected-uia-win.txt b/content/test/data/accessibility/html/dd-expected-uia-win.txt index 959d844..2549407 100644 --- a/content/test/data/accessibility/html/dd-expected-uia-win.txt +++ b/content/test/data/accessibility/html/dd-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++++Text Name='Coffee' ++++Text IsControlElement=false ++++++Text Name='Black hot drink' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/del-expected-uia-win.txt b/content/test/data/accessibility/html/del-expected-uia-win.txt index 1e8c418..50bd303 100644 --- a/content/test/data/accessibility/html/del-expected-uia-win.txt +++ b/content/test/data/accessibility/html/del-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='I am ' ++++Group IsControlElement=false ++++++Text Name='vegetarian' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/details-expected-uia-win.txt b/content/test/data/accessibility/html/details-expected-uia-win.txt index 372b8f7..8fa186c 100644 --- a/content/test/data/accessibility/html/details-expected-uia-win.txt +++ b/content/test/data/accessibility/html/details-expected-uia-win.txt
@@ -7,4 +7,3 @@ ++++++Text Name='details tag open' ++++Group IsControlElement=false ++++++Text Name='The details tag with open specifies that the details should be visible (open) to the user.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/dfn-expected-uia-win.txt b/content/test/data/accessibility/html/dfn-expected-uia-win.txt index c75ba543..4099a4e2 100644 --- a/content/test/data/accessibility/html/dfn-expected-uia-win.txt +++ b/content/test/data/accessibility/html/dfn-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Text Name='Web Browser' ++++Text Name=' A computer program with a graphical user interface for displaying HTML files, used to navigate the World Wide Web.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/dialog-expected-uia-win.txt b/content/test/data/accessibility/html/dialog-expected-uia-win.txt index 37ad3409..68f7175 100644 --- a/content/test/data/accessibility/html/dialog-expected-uia-win.txt +++ b/content/test/data/accessibility/html/dialog-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Pane IsControlElement=false Window.IsModal=false ++++Text Name='Text in dialog' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/div-expected-uia-win.txt b/content/test/data/accessibility/html/div-expected-uia-win.txt index d963f2d5..ccf3cc90 100644 --- a/content/test/data/accessibility/html/div-expected-uia-win.txt +++ b/content/test/data/accessibility/html/div-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='Unfocusable div' ++Group Name='Focusable div' ++++Text Name='Focusable div' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/dl-expected-uia-win.txt b/content/test/data/accessibility/html/dl-expected-uia-win.txt index 0b9cc322..843aff6 100644 --- a/content/test/data/accessibility/html/dl-expected-uia-win.txt +++ b/content/test/data/accessibility/html/dl-expected-uia-win.txt
@@ -6,4 +6,3 @@ ++++++Text Name='Description' ++Group ++++Text Name='Definition' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/dt-expected-uia-win.txt b/content/test/data/accessibility/html/dt-expected-uia-win.txt index 959d844..2549407 100644 --- a/content/test/data/accessibility/html/dt-expected-uia-win.txt +++ b/content/test/data/accessibility/html/dt-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++++Text Name='Coffee' ++++Text IsControlElement=false ++++++Text Name='Black hot drink' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/element-class-id-src-attr-expected-uia-win.txt b/content/test/data/accessibility/html/element-class-id-src-attr-expected-uia-win.txt index c88ec897..bfea8dd 100644 --- a/content/test/data/accessibility/html/element-class-id-src-attr-expected-uia-win.txt +++ b/content/test/data/accessibility/html/element-class-id-src-attr-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Text Name='Image' ClassName='headerClass' ++++Text Name='Image' IsControlElement=false ++Image Name='ImageAlt' ClassName='imageClass' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/em-expected-uia-win.txt b/content/test/data/accessibility/html/em-expected-uia-win.txt index 5ea0eae1..bc76855 100644 --- a/content/test/data/accessibility/html/em-expected-uia-win.txt +++ b/content/test/data/accessibility/html/em-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='One word is ' ++++Text Name='emphasized' ++++Text Name='.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/embed-expected-uia-win.txt b/content/test/data/accessibility/html/embed-expected-uia-win.txt index 56da86f..136cb730 100644 --- a/content/test/data/accessibility/html/embed-expected-uia-win.txt +++ b/content/test/data/accessibility/html/embed-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Pane -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/fieldset-expected-uia-win.txt b/content/test/data/accessibility/html/fieldset-expected-uia-win.txt index 83b9965..5400322 100644 --- a/content/test/data/accessibility/html/fieldset-expected-uia-win.txt +++ b/content/test/data/accessibility/html/fieldset-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Group Name='Browser Engines:' ++++++Text IsControlElement=false ++++++++Text Name='Browser Engines:' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/figcaption-expected-uia-win.txt b/content/test/data/accessibility/html/figcaption-expected-uia-win.txt index 8409d1af..b404448 100644 --- a/content/test/data/accessibility/html/figcaption-expected-uia-win.txt +++ b/content/test/data/accessibility/html/figcaption-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Image Name='This is a green box.' ++++Text IsControlElement=false ++++++Text Name='Fig.1 - A green Box' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/figure-expected-uia-win.txt b/content/test/data/accessibility/html/figure-expected-uia-win.txt index 80d5f36..6b39590 100644 --- a/content/test/data/accessibility/html/figure-expected-uia-win.txt +++ b/content/test/data/accessibility/html/figure-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group LocalizedControlType='figure' ++++Image Name='Sunspots' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/footer-expected-uia-win.txt b/content/test/data/accessibility/html/footer-expected-uia-win.txt index 5d5fff4..d8cc1b4 100644 --- a/content/test/data/accessibility/html/footer-expected-uia-win.txt +++ b/content/test/data/accessibility/html/footer-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group LocalizedControlType='footer' LocalizedLandmarkType='content information' ++++Text Name='Footer element' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/footer-expected-uia-win7.txt b/content/test/data/accessibility/html/footer-expected-uia-win7.txt index a0433b5..0aedab9 100644 --- a/content/test/data/accessibility/html/footer-expected-uia-win7.txt +++ b/content/test/data/accessibility/html/footer-expected-uia-win7.txt
@@ -1,4 +1,3 @@ Document ++Group LocalizedControlType='footer' ++++Text Name='Footer element' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/footer-inside-other-section-expected-uia-win.txt b/content/test/data/accessibility/html/footer-inside-other-section-expected-uia-win.txt index 1ef9e077..d3d4913 100644 --- a/content/test/data/accessibility/html/footer-inside-other-section-expected-uia-win.txt +++ b/content/test/data/accessibility/html/footer-inside-other-section-expected-uia-win.txt
@@ -11,4 +11,3 @@ ++++Group LocalizedControlType='footer' ++++++Group IsControlElement=false ++++++++Text Name='footer inside main.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/form-expected-uia-win.txt b/content/test/data/accessibility/html/form-expected-uia-win.txt index 7801cb85..32f3f57 100644 --- a/content/test/data/accessibility/html/form-expected-uia-win.txt +++ b/content/test/data/accessibility/html/form-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Button Name='Submit' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/form-validation-message-expected-uia-win.txt b/content/test/data/accessibility/html/form-validation-message-expected-uia-win.txt index fb5d2d21..4e33eb6 100644 --- a/content/test/data/accessibility/html/form-validation-message-expected-uia-win.txt +++ b/content/test/data/accessibility/html/form-validation-message-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++++Text Name='Pet name:' ++++Edit Name='Pet name:' IsRequiredForForm=true ++Text Name='Please enter pet name' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/frameset-expected-uia-win.txt b/content/test/data/accessibility/html/frameset-expected-uia-win.txt index 32ef044..47ec438b 100644 --- a/content/test/data/accessibility/html/frameset-expected-uia-win.txt +++ b/content/test/data/accessibility/html/frameset-expected-uia-win.txt
@@ -16,4 +16,3 @@ ++++++++Text IsControlElement=false ++++++++++Text Name='mark tag' ++++++++Text Name='.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/header-expected-uia-win.txt b/content/test/data/accessibility/html/header-expected-uia-win.txt index 4ac24c2..83c9be43 100644 --- a/content/test/data/accessibility/html/header-expected-uia-win.txt +++ b/content/test/data/accessibility/html/header-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group LocalizedControlType='header' ++++Text Name='Chromium Browser' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/header-inside-other-section-expected-uia-win.txt b/content/test/data/accessibility/html/header-inside-other-section-expected-uia-win.txt index 9194254..658d233 100644 --- a/content/test/data/accessibility/html/header-inside-other-section-expected-uia-win.txt +++ b/content/test/data/accessibility/html/header-inside-other-section-expected-uia-win.txt
@@ -11,4 +11,3 @@ ++++Group LocalizedControlType='header' ++++++Group IsControlElement=false ++++++++Text Name='Header inside main.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/heading-expected-uia-win.txt b/content/test/data/accessibility/html/heading-expected-uia-win.txt index c1da12e0..5e37774 100644 --- a/content/test/data/accessibility/html/heading-expected-uia-win.txt +++ b/content/test/data/accessibility/html/heading-expected-uia-win.txt
@@ -11,4 +11,3 @@ ++++Text Name='Heading 5' IsControlElement=false ++Text Name='Heading 6' ++++Text Name='Heading 6' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/hr-expected-uia-win.txt b/content/test/data/accessibility/html/hr-expected-uia-win.txt index 6ecff90d..59a0b829 100644 --- a/content/test/data/accessibility/html/hr-expected-uia-win.txt +++ b/content/test/data/accessibility/html/hr-expected-uia-win.txt
@@ -7,4 +7,3 @@ ++Separator ++Group IsControlElement=false ++++Text Name='After.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/i-expected-uia-win.txt b/content/test/data/accessibility/html/i-expected-uia-win.txt index d67794e..d75d733 100644 --- a/content/test/data/accessibility/html/i-expected-uia-win.txt +++ b/content/test/data/accessibility/html/i-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='This is to check ' ++++Text Name='italic property' ++++Text Name=' using i tag.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/iframe-coordinates-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-coordinates-expected-uia-win.txt index fbdec8ed..2d19938 100644 --- a/content/test/data/accessibility/html/iframe-coordinates-expected-uia-win.txt +++ b/content/test/data/accessibility/html/iframe-coordinates-expected-uia-win.txt
@@ -13,4 +13,3 @@ ++++++Document ++++++++Group IsControlElement=false ++++++++++Button Name='Scrolled Button' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/iframe-cross-process-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-cross-process-expected-uia-win.txt index 66d83c5..f24f037 100644 --- a/content/test/data/accessibility/html/iframe-cross-process-expected-uia-win.txt +++ b/content/test/data/accessibility/html/iframe-cross-process-expected-uia-win.txt
@@ -8,4 +8,3 @@ ++++++++++Text Name='Text in iframe' ++Group IsControlElement=false ++++Text Name='After frame' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/iframe-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-expected-uia-win.txt index a2b9659..b322bcbf 100644 --- a/content/test/data/accessibility/html/iframe-expected-uia-win.txt +++ b/content/test/data/accessibility/html/iframe-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Document Name='Empty iframe' ++++++Document -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/iframe-presentational-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-presentational-expected-uia-win.txt index 6183ef9..4869b37 100644 --- a/content/test/data/accessibility/html/iframe-presentational-expected-uia-win.txt +++ b/content/test/data/accessibility/html/iframe-presentational-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Group ++++++Group -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/iframe-transform-expected-uia-win.txt b/content/test/data/accessibility/html/iframe-transform-expected-uia-win.txt index e3fd32c..4c69ae2 100644 --- a/content/test/data/accessibility/html/iframe-transform-expected-uia-win.txt +++ b/content/test/data/accessibility/html/iframe-transform-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++Document ++++Document ++++++Image -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/ignored-selection-between-text-expected-uia-win.txt b/content/test/data/accessibility/html/ignored-selection-between-text-expected-uia-win.txt index a07b593..bc02e8c 100644 --- a/content/test/data/accessibility/html/ignored-selection-between-text-expected-uia-win.txt +++ b/content/test/data/accessibility/html/ignored-selection-between-text-expected-uia-win.txt
@@ -6,4 +6,3 @@ ++Group IsControlElement=false ++++Text Name='after selection' ++Text Name='Done' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/ignored-selection-expected-uia-win.txt b/content/test/data/accessibility/html/ignored-selection-expected-uia-win.txt index 82c12758..c424caa8 100644 --- a/content/test/data/accessibility/html/ignored-selection-expected-uia-win.txt +++ b/content/test/data/accessibility/html/ignored-selection-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++Group IsControlElement=false ++++Text Name='after selection' ++Text Name='Done' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/ignored-selection-no-unignored-expected-mac.txt b/content/test/data/accessibility/html/ignored-selection-no-unignored-expected-mac.txt index a7977fa0..0f075244 100644 --- a/content/test/data/accessibility/html/ignored-selection-no-unignored-expected-mac.txt +++ b/content/test/data/accessibility/html/ignored-selection-no-unignored-expected-mac.txt
@@ -1,3 +1,2 @@ AXWebArea ++AXStaticText AXValue='Done' -<-- End-of-file --> \ No newline at end of file
diff --git a/content/test/data/accessibility/html/ignored-selection-no-unignored-expected-uia-win.txt b/content/test/data/accessibility/html/ignored-selection-no-unignored-expected-uia-win.txt index a44b16b4..98ca2d2 100644 --- a/content/test/data/accessibility/html/ignored-selection-no-unignored-expected-uia-win.txt +++ b/content/test/data/accessibility/html/ignored-selection-no-unignored-expected-uia-win.txt
@@ -1,3 +1,2 @@ Document ++Text Name='Done' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/img-empty-alt-expected-uia-win.txt b/content/test/data/accessibility/html/img-empty-alt-expected-uia-win.txt index e52f496..1cc2677 100644 --- a/content/test/data/accessibility/html/img-empty-alt-expected-uia-win.txt +++ b/content/test/data/accessibility/html/img-empty-alt-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Image IsControlElement=false ++++Image ++++Image Name='full' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/img-expected-uia-win.txt b/content/test/data/accessibility/html/img-expected-uia-win.txt index 09b1da33..e14113e 100644 --- a/content/test/data/accessibility/html/img-expected-uia-win.txt +++ b/content/test/data/accessibility/html/img-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++Text Name=' ' ++++Text Name=' ' ++++Image Name=' ' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/img-link-empty-alt-expected-uia-win.txt b/content/test/data/accessibility/html/img-link-empty-alt-expected-uia-win.txt index b3a85da..c23e5f0 100644 --- a/content/test/data/accessibility/html/img-link-empty-alt-expected-uia-win.txt +++ b/content/test/data/accessibility/html/img-link-empty-alt-expected-uia-win.txt
@@ -9,4 +9,3 @@ ++++Hyperlink Name='read' ++++++Image ++++++Text Name='read' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/in-page-links-expected-uia-win.txt b/content/test/data/accessibility/html/in-page-links-expected-uia-win.txt index 6a82693..23a18c4 100644 --- a/content/test/data/accessibility/html/in-page-links-expected-uia-win.txt +++ b/content/test/data/accessibility/html/in-page-links-expected-uia-win.txt
@@ -33,4 +33,3 @@ ++++++Text Name='Span with content' ++Group IsControlElement=false ++++Text Name='Paragraph with content' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-button-expected-uia-win.txt b/content/test/data/accessibility/html/input-button-expected-uia-win.txt index fe57d81..8309aa9a 100644 --- a/content/test/data/accessibility/html/input-button-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-button-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Button Name='Button' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-button-in-menu-expected-uia-win.txt b/content/test/data/accessibility/html/input-button-in-menu-expected-uia-win.txt index 6833aafd..398507a 100644 --- a/content/test/data/accessibility/html/input-button-in-menu-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-button-in-menu-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++MenuItem Name='Button in menu element' ++Menu Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false ++++MenuItem Name='Button in element with menu role' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-checkbox-expected-uia-win.txt b/content/test/data/accessibility/html/input-checkbox-expected-uia-win.txt index 6cdfded..b191ea0 100644 --- a/content/test/data/accessibility/html/input-checkbox-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-checkbox-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++++CheckBox Name='Checkbox2' Toggle.ToggleState='On' ++++CheckBox Name='Checkbox3' Toggle.ToggleState='On' ++++CheckBox Name='Checkbox4' Toggle.ToggleState='Indeterminate' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-checkbox-in-menu-expected-uia-win.txt b/content/test/data/accessibility/html/input-checkbox-in-menu-expected-uia-win.txt index 0ebde5e..9247649 100644 --- a/content/test/data/accessibility/html/input-checkbox-in-menu-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-checkbox-in-menu-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++Menu Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false ++++CheckBox Name='Checkbox3' Toggle.ToggleState='On' ++++CheckBox Name='Checkbox4' Toggle.ToggleState='Indeterminate' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-color-expected-uia-win.txt b/content/test/data/accessibility/html/input-color-expected-uia-win.txt index e300dff9..334a8db 100644 --- a/content/test/data/accessibility/html/input-color-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-color-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Button LocalizedControlType='color picker' Value.Value='100% red 60% green 0% blue' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-date-expected-uia-win.txt b/content/test/data/accessibility/html/input-date-expected-uia-win.txt index 024e44e3..3f6a56a 100644 --- a/content/test/data/accessibility/html/input-date-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-date-expected-uia-win.txt
@@ -24,4 +24,3 @@ ++++++++++Spinner Name='Year When' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=275760.00 RangeValue.Minimum=1.00 RangeValue.Value=2008.00 Value.Value='2008' ++++++++++++Text Name='2008' ++++++Button Name='Show date picker' ExpandCollapse.ExpandCollapseState='Collapsed' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-date-with-popup-open-multiple-for-win-expected-uia-win.txt b/content/test/data/accessibility/html/input-date-with-popup-open-multiple-for-win-expected-uia-win.txt index 56c74508e..6b65984 100644 --- a/content/test/data/accessibility/html/input-date-with-popup-open-multiple-for-win-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-date-with-popup-open-multiple-for-win-expected-uia-win.txt
@@ -68,4 +68,3 @@ ++++++++++++++++++Group IsControlElement=false ++++++++++++++++++++Group IsControlElement=false ++++++++++++++++++Button Name='Today' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-datetime-expected-uia-win.txt b/content/test/data/accessibility/html/input-datetime-expected-uia-win.txt index 9abfb60..3051169 100644 --- a/content/test/data/accessibility/html/input-datetime-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-datetime-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Edit Value.Value='1/1/2015 1:00AM' ++++Edit Name='Launch' Value.Value='1/1/2015 1:00AM' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-datetime-local-expected-uia-win.txt b/content/test/data/accessibility/html/input-datetime-local-expected-uia-win.txt index 73555b0c..b3510762 100644 --- a/content/test/data/accessibility/html/input-datetime-local-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-datetime-local-expected-uia-win.txt
@@ -21,4 +21,3 @@ ++++++++++Spinner Name='AM/PM' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=2.00 RangeValue.Minimum=1.00 RangeValue.Value=0.00 Value.Value='0' ++++++++++++Text Name='--' ++++++Button Name='Show local date and time picker' ExpandCollapse.ExpandCollapseState='Collapsed' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-email-expected-uia-win.txt b/content/test/data/accessibility/html/input-email-expected-uia-win.txt index a75ec01..0f305cee 100644 --- a/content/test/data/accessibility/html/input-email-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-email-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document LocalizedControlType='document' ++Group LocalizedControlType='group' IsControlElement=false ++++Edit LocalizedControlType='email' Value.Value='someone@example.com' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-file-expected-uia-win.txt b/content/test/data/accessibility/html/input-file-expected-uia-win.txt index 1e0b340..4791dbd1 100644 --- a/content/test/data/accessibility/html/input-file-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-file-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Button Name='Choose File' ++++++Button Name='Choose File' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-image-expected-uia-win.txt b/content/test/data/accessibility/html/input-image-expected-uia-win.txt index 7801cb85..32f3f57 100644 --- a/content/test/data/accessibility/html/input-image-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-image-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Button Name='Submit' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-list-expected-uia-win.txt b/content/test/data/accessibility/html/input-list-expected-uia-win.txt index f671924..45ddce3a 100644 --- a/content/test/data/accessibility/html/input-list-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-list-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text ++++++Text Name='Choose a pokemon ' ++++++ComboBox Name='Choose a pokemon' ExpandCollapse.ExpandCollapseState='LeafNode' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-number-expected-uia-win.txt b/content/test/data/accessibility/html/input-number-expected-uia-win.txt index 45cdd54c..697b418 100644 --- a/content/test/data/accessibility/html/input-number-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-number-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Spinner RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=0.00 RangeValue.Minimum=0.00 RangeValue.Value=1.00 Value.Value='1' ++++Spinner RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=10.00 RangeValue.Minimum=5.00 RangeValue.Value=6.00 Value.Value='6' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-password-expected-uia-win.txt b/content/test/data/accessibility/html/input-password-expected-uia-win.txt index ce0730e5..7123ac8 100644 --- a/content/test/data/accessibility/html/input-password-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-password-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Edit IsPassword=true Value.Value='••••••' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-radio-checkbox-label-expected-uia-win.txt b/content/test/data/accessibility/html/input-radio-checkbox-label-expected-uia-win.txt index cc92e69d..8eede08 100644 --- a/content/test/data/accessibility/html/input-radio-checkbox-label-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-radio-checkbox-label-expected-uia-win.txt
@@ -10,4 +10,3 @@ ++++++Text Name='label exposed for checkbox ' ++++++CheckBox Name='label exposed for checkbox' Toggle.ToggleState='Off' ++++++Text Name=' ' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-radio-expected-uia-win.txt b/content/test/data/accessibility/html/input-radio-expected-uia-win.txt index f14091e..7283713 100644 --- a/content/test/data/accessibility/html/input-radio-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-radio-expected-uia-win.txt
@@ -11,4 +11,3 @@ ++Group IsControlElement=false ++++RadioButton Name='Radio5' SelectionItem.IsSelected=false ++++RadioButton Name='Radio6' SelectionItem.IsSelected=true -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt b/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt index b08d816..f0301d6 100644 --- a/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-radio-in-menu-expected-uia-win.txt
@@ -9,4 +9,3 @@ ++++RadioButton Name='Radio3' SelectionItem.IsSelected=false ++++RadioButton SelectionItem.IsSelected=false ++++RadioButton SelectionItem.IsSelected=true -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-range-expected-uia-win.txt b/content/test/data/accessibility/html/input-range-expected-uia-win.txt index 2ee0808e..7db37e3 100644 --- a/content/test/data/accessibility/html/input-range-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-range-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Slider RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=10.00 RangeValue.Minimum=1.00 RangeValue.Value=5.00 Value.Value='5' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-reset-expected-uia-win.txt b/content/test/data/accessibility/html/input-reset-expected-uia-win.txt index 90883b4..02273a0 100644 --- a/content/test/data/accessibility/html/input-reset-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-reset-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Edit ++++Button Name='Reset' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-search-expected-uia-win.txt b/content/test/data/accessibility/html/input-search-expected-uia-win.txt index 4bd58fa3..d545640 100644 --- a/content/test/data/accessibility/html/input-search-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-search-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document LocalizedControlType='document' ++Group LocalizedControlType='group' IsControlElement=false ++++Edit LocalizedControlType='search box' Value.Value='Search terms' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-submit-expected-uia-win.txt b/content/test/data/accessibility/html/input-submit-expected-uia-win.txt index 55a1b26b..2196c3c 100644 --- a/content/test/data/accessibility/html/input-submit-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-submit-expected-uia-win.txt
@@ -12,4 +12,3 @@ ++++++Image ++++++Text Name='Second image button in a form not a valid default button' IsControlElement=false ++Button Name='Submit outside of form not a valid default button' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-suggestions-source-element-expected-uia-win.txt b/content/test/data/accessibility/html/input-suggestions-source-element-expected-uia-win.txt index 9ca5a80a..cd8c68f 100644 --- a/content/test/data/accessibility/html/input-suggestions-source-element-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-suggestions-source-element-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++ComboBox ExpandCollapse.ExpandCollapseState='LeafNode' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-tel-expected-uia-win.txt b/content/test/data/accessibility/html/input-tel-expected-uia-win.txt index f3b5007..57a06b1 100644 --- a/content/test/data/accessibility/html/input-tel-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-tel-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document LocalizedControlType='document' ++Group LocalizedControlType='group' IsControlElement=false ++++Edit LocalizedControlType='telephone' Value.Value='123-456-7890' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-text-expected-uia-win.txt b/content/test/data/accessibility/html/input-text-expected-uia-win.txt index 52e66a28..7fb8ed5d 100644 --- a/content/test/data/accessibility/html/input-text-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-text-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Edit Name='Name' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-text-name-calc-expected-uia-win.txt b/content/test/data/accessibility/html/input-text-name-calc-expected-uia-win.txt index 3be26c3..41d8fbd5 100644 --- a/content/test/data/accessibility/html/input-text-name-calc-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-text-name-calc-expected-uia-win.txt
@@ -9,4 +9,3 @@ ++Edit Name='Placeholder5' HelpText='Placeholder5' ++Edit Name='LabelledBy6' HelpText='Title6' ++Edit Name='AriaLabel7' HelpText='Placeholder7' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-text-read-only-expected-uia-win.txt b/content/test/data/accessibility/html/input-text-read-only-expected-uia-win.txt index 52e66a28..7fb8ed5d 100644 --- a/content/test/data/accessibility/html/input-text-read-only-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-text-read-only-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Edit Name='Name' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-text-value-expected-uia-win.txt b/content/test/data/accessibility/html/input-text-value-expected-uia-win.txt index 7dc1deb..f9de9a3 100644 --- a/content/test/data/accessibility/html/input-text-value-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-text-value-expected-uia-win.txt
@@ -16,4 +16,3 @@ ++++Edit Name='l5' ++++Edit Name='l6' Value.Value='Value' ++++Edit Name='Name' Value.Value='value' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-text-with-selection-expected-uia-win.txt b/content/test/data/accessibility/html/input-text-with-selection-expected-uia-win.txt index 418bb10..ba8a9bb 100644 --- a/content/test/data/accessibility/html/input-text-with-selection-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-text-with-selection-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Edit Value.Value='Selection' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-time-expected-uia-win.txt b/content/test/data/accessibility/html/input-time-expected-uia-win.txt index 3755c37..53b5cb1 100644 --- a/content/test/data/accessibility/html/input-time-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-time-expected-uia-win.txt
@@ -24,4 +24,3 @@ ++++++++++Spinner Name='AM/PM Breakfast' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=2.00 RangeValue.Minimum=1.00 RangeValue.Value=1.00 Value.Value='AM' ++++++++++++Text Name='AM' ++++++Button Name='Show time picker' ExpandCollapse.ExpandCollapseState='Collapsed' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-types-expected-uia-win.txt b/content/test/data/accessibility/html/input-types-expected-uia-win.txt index 2f83314..b602363 100644 --- a/content/test/data/accessibility/html/input-types-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-types-expected-uia-win.txt
@@ -50,4 +50,3 @@ ++++Text ++++++Text Name='Url: ' ++++++Edit Name='Url:' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-url-expected-uia-win.txt b/content/test/data/accessibility/html/input-url-expected-uia-win.txt index 00454b26..25228dd1 100644 --- a/content/test/data/accessibility/html/input-url-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-url-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document LocalizedControlType='document' ++Group LocalizedControlType='group' IsControlElement=false ++++Edit LocalizedControlType='url' Value.Value='example.com' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/input-week-expected-uia-win.txt b/content/test/data/accessibility/html/input-week-expected-uia-win.txt index 7a93e8d..3d8c20f 100644 --- a/content/test/data/accessibility/html/input-week-expected-uia-win.txt +++ b/content/test/data/accessibility/html/input-week-expected-uia-win.txt
@@ -10,4 +10,3 @@ ++++++++++Spinner Name='Year' RangeValue.IsReadOnly=false RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=275760.00 RangeValue.Minimum=1.00 RangeValue.Value=0.00 Value.Value='0' ++++++++++++Text Name='----' ++++++Button Name='Show week picker' ExpandCollapse.ExpandCollapseState='Collapsed' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/ins-expected-uia-win.txt b/content/test/data/accessibility/html/ins-expected-uia-win.txt index 930cfb4..8cb0cbe0 100644 --- a/content/test/data/accessibility/html/ins-expected-uia-win.txt +++ b/content/test/data/accessibility/html/ins-expected-uia-win.txt
@@ -7,4 +7,3 @@ ++++Group IsControlElement=false ++++++Text Name='Chrome' ++++Text Name='!' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/label-expected-uia-win.txt b/content/test/data/accessibility/html/label-expected-uia-win.txt index 1c39d278..ef51a7f 100644 --- a/content/test/data/accessibility/html/label-expected-uia-win.txt +++ b/content/test/data/accessibility/html/label-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Text ++++++Text Name='Label' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/landmark-expected-uia-win.txt b/content/test/data/accessibility/html/landmark-expected-uia-win.txt index 8d58982..f58663d 100644 --- a/content/test/data/accessibility/html/landmark-expected-uia-win.txt +++ b/content/test/data/accessibility/html/landmark-expected-uia-win.txt
@@ -147,4 +147,3 @@ ++Group ++++Group ++++++Text Name='This should NOT have footer role.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/legend-expected-uia-win.txt b/content/test/data/accessibility/html/legend-expected-uia-win.txt index cceb92b6..1e5da53 100644 --- a/content/test/data/accessibility/html/legend-expected-uia-win.txt +++ b/content/test/data/accessibility/html/legend-expected-uia-win.txt
@@ -7,4 +7,3 @@ ++++++Edit ++++++Text Name=' Rendering Engine: ' IsControlElement=false ++++++Edit -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/li-expected-uia-win.txt b/content/test/data/accessibility/html/li-expected-uia-win.txt index 4c07ffe2..9679367 100644 --- a/content/test/data/accessibility/html/li-expected-uia-win.txt +++ b/content/test/data/accessibility/html/li-expected-uia-win.txt
@@ -12,4 +12,3 @@ ++++++Group ++++++++Text Name='• ' IsControlElement=false ++++++Text Name='Item 3' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/link-inside-heading-expected-uia-win.txt b/content/test/data/accessibility/html/link-inside-heading-expected-uia-win.txt index 1ae6278..316b3a7 100644 --- a/content/test/data/accessibility/html/link-inside-heading-expected-uia-win.txt +++ b/content/test/data/accessibility/html/link-inside-heading-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Text Name='Link In Heading' ++++Hyperlink Name='Link In Heading' ++++++Text Name='Link In Heading' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/list-expected-uia-win.txt b/content/test/data/accessibility/html/list-expected-uia-win.txt index f4d9449..06d3906 100644 --- a/content/test/data/accessibility/html/list-expected-uia-win.txt +++ b/content/test/data/accessibility/html/list-expected-uia-win.txt
@@ -21,4 +21,3 @@ ++++Text Name=' ' ++++ListItem ++++++Text Name='toe' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/list-item-aria-setsize-unknown-expected-uia-win.txt b/content/test/data/accessibility/html/list-item-aria-setsize-unknown-expected-uia-win.txt index ce62b08..d203d83 100644 --- a/content/test/data/accessibility/html/list-item-aria-setsize-unknown-expected-uia-win.txt +++ b/content/test/data/accessibility/html/list-item-aria-setsize-unknown-expected-uia-win.txt
@@ -13,4 +13,3 @@ ++++++Text Name='Level 1, item 7 of set size 2' PositionInSet=0 SizeOfSet=0 Level=0 ++++ListItem PositionInSet=8 SizeOfSet=3 Level=1 ++++++Text Name='Level 1, item 8 of set size 3' PositionInSet=0 SizeOfSet=0 Level=0 -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/list-item-aria-setsize-unknown-expected-uia-win7.txt b/content/test/data/accessibility/html/list-item-aria-setsize-unknown-expected-uia-win7.txt index 5a91cb4..4f6ba84 100644 --- a/content/test/data/accessibility/html/list-item-aria-setsize-unknown-expected-uia-win7.txt +++ b/content/test/data/accessibility/html/list-item-aria-setsize-unknown-expected-uia-win7.txt
@@ -13,4 +13,3 @@ ++++++Text Name='Level 1, item 7 of set size 2' ++++ListItem ++++++Text Name='Level 1, item 8 of set size 3' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/list-item-aria-setsize-unknown-flattened-expected-uia-win.txt b/content/test/data/accessibility/html/list-item-aria-setsize-unknown-flattened-expected-uia-win.txt index 64ff21399..8ded380 100644 --- a/content/test/data/accessibility/html/list-item-aria-setsize-unknown-flattened-expected-uia-win.txt +++ b/content/test/data/accessibility/html/list-item-aria-setsize-unknown-flattened-expected-uia-win.txt
@@ -30,4 +30,3 @@ ++++List PositionInSet=0 SizeOfSet=5 Level=0 ++++++ListItem PositionInSet=5 SizeOfSet=5 Level=2 ++++++++Text Name='Level Unspecified, aria-setsize attribute does not exist, item 5 of set size 5' PositionInSet=0 SizeOfSet=0 Level=0 -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/list-item-aria-setsize-unknown-flattened-expected-uia-win7.txt b/content/test/data/accessibility/html/list-item-aria-setsize-unknown-flattened-expected-uia-win7.txt index 018941b..7422339 100644 --- a/content/test/data/accessibility/html/list-item-aria-setsize-unknown-flattened-expected-uia-win7.txt +++ b/content/test/data/accessibility/html/list-item-aria-setsize-unknown-flattened-expected-uia-win7.txt
@@ -30,4 +30,3 @@ ++++List ++++++ListItem ++++++++Text Name='Level Unspecified, aria-setsize attribute does not exist, item 5 of set size 5' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/list-markers-expected-uia-win.txt b/content/test/data/accessibility/html/list-markers-expected-uia-win.txt index 1f5bdd0..25ed2d1f 100644 --- a/content/test/data/accessibility/html/list-markers-expected-uia-win.txt +++ b/content/test/data/accessibility/html/list-markers-expected-uia-win.txt
@@ -18,4 +18,3 @@ ++++++Text Name='Some ' IsControlElement=false ++++++Text Name='more' IsControlElement=false ++++++Text Name=' text.' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/main-expected-uia-win.txt b/content/test/data/accessibility/html/main-expected-uia-win.txt index 4c58089..62a1457a 100644 --- a/content/test/data/accessibility/html/main-expected-uia-win.txt +++ b/content/test/data/accessibility/html/main-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='This is main element.' ++Group ++++Text Name='This is an ARIA role main.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/mark-expected-uia-win.txt b/content/test/data/accessibility/html/mark-expected-uia-win.txt index 93247766..c9a7bc5 100644 --- a/content/test/data/accessibility/html/mark-expected-uia-win.txt +++ b/content/test/data/accessibility/html/mark-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++Text LocalizedControlType='highlight' IsControlElement=false ++++++Text Name='mark tag' ++++Text Name='.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/math-expected-uia-win.txt b/content/test/data/accessibility/html/math-expected-uia-win.txt index ce60f2c..e58ec51 100644 --- a/content/test/data/accessibility/html/math-expected-uia-win.txt +++ b/content/test/data/accessibility/html/math-expected-uia-win.txt
@@ -8,4 +8,3 @@ ++++Group IsControlElement=false ++++++Text Name='b' ++++++Text Name='2' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/meter-expected-uia-win.txt b/content/test/data/accessibility/html/meter-expected-uia-win.txt index d3f72020..4608cfba 100644 --- a/content/test/data/accessibility/html/meter-expected-uia-win.txt +++ b/content/test/data/accessibility/html/meter-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document LocalizedControlType='document' ++Group LocalizedControlType='group' IsControlElement=false ++++ProgressBar LocalizedControlType='meter' RangeValue.IsReadOnly=true RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=10.00 RangeValue.Minimum=1.00 RangeValue.Value=2.00 Value.Value='2' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/modal-dialog-closed-expected-uia-win.txt b/content/test/data/accessibility/html/modal-dialog-closed-expected-uia-win.txt index 5945bae..1ae2e9fe 100644 --- a/content/test/data/accessibility/html/modal-dialog-closed-expected-uia-win.txt +++ b/content/test/data/accessibility/html/modal-dialog-closed-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++++++List Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false ++++++++ListItem Name='This should be in the tree.' SelectionItem.IsSelected=true ++Button Value.Value='0% red 0% green 0% blue' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/navigation-expected-uia-win.txt b/content/test/data/accessibility/html/navigation-expected-uia-win.txt index a73a099a..950a8df8 100644 --- a/content/test/data/accessibility/html/navigation-expected-uia-win.txt +++ b/content/test/data/accessibility/html/navigation-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group ++++Hyperlink Name='Don't click on me' ++++++Text Name='Don't click on me' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-uia-win.txt b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-uia-win.txt index 7ca663b..98ccfe4 100644 --- a/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-uia-win.txt +++ b/content/test/data/accessibility/html/node-changed-crash-in-editable-text-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group Name='Done' ++++Group ++++Group -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/object-expected-uia-win.txt b/content/test/data/accessibility/html/object-expected-uia-win.txt index 8a379cf..b4a1703 100644 --- a/content/test/data/accessibility/html/object-expected-uia-win.txt +++ b/content/test/data/accessibility/html/object-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Document -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/offscreen-iframe-expected-uia-win.txt b/content/test/data/accessibility/html/offscreen-iframe-expected-uia-win.txt index f989df8..6ec11cc 100644 --- a/content/test/data/accessibility/html/offscreen-iframe-expected-uia-win.txt +++ b/content/test/data/accessibility/html/offscreen-iframe-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++++Document ++++++++Group Name='iframe_onscreen' ++++++++Group Name='iframe_offscreen' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/offscreen-select-expected-uia-win.txt b/content/test/data/accessibility/html/offscreen-select-expected-uia-win.txt index 78ec07d..271dd48 100644 --- a/content/test/data/accessibility/html/offscreen-select-expected-uia-win.txt +++ b/content/test/data/accessibility/html/offscreen-select-expected-uia-win.txt
@@ -9,4 +9,3 @@ ++++++ListItem Name='Offscreen 1' SelectionItem.IsSelected=true ++++++ListItem Name='Offscreen 2' SelectionItem.IsSelected=false ++++++ListItem Name='Offscreen 3' SelectionItem.IsSelected=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/ol-expected-uia-win.txt b/content/test/data/accessibility/html/ol-expected-uia-win.txt index 2c3aa2dd..1dc05bc 100644 --- a/content/test/data/accessibility/html/ol-expected-uia-win.txt +++ b/content/test/data/accessibility/html/ol-expected-uia-win.txt
@@ -25,4 +25,3 @@ ++++++Group ++++++++Text Name='12. ' IsControlElement=false ++++++Text Name='Windows' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/optgroup-expected-uia-win.txt b/content/test/data/accessibility/html/optgroup-expected-uia-win.txt index 2cb7b26d..019326a 100644 --- a/content/test/data/accessibility/html/optgroup-expected-uia-win.txt +++ b/content/test/data/accessibility/html/optgroup-expected-uia-win.txt
@@ -13,4 +13,3 @@ ++++++ListItem Name='Two' IsEnabled=false ++++++ListItem Name='Three' IsEnabled=false ++++++ListItem Name='Four' IsEnabled=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/output-expected-uia-win.txt b/content/test/data/accessibility/html/output-expected-uia-win.txt index 8c4c31d8..1c87df1 100644 --- a/content/test/data/accessibility/html/output-expected-uia-win.txt +++ b/content/test/data/accessibility/html/output-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++++Spinner RangeValue.IsReadOnly=false RangeValue.LargeChange=10.00 RangeValue.SmallChange=1.00 RangeValue.Maximum=0.00 RangeValue.Minimum=0.00 RangeValue.Value=0.00 ++++Text Name=' =' ++++StatusBar LocalizedControlType='output' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/p-expected-uia-win.txt b/content/test/data/accessibility/html/p-expected-uia-win.txt index f0bda32..2e7ccfc 100644 --- a/content/test/data/accessibility/html/p-expected-uia-win.txt +++ b/content/test/data/accessibility/html/p-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++Group IsControlElement=false ++++Text Name='Paragraph' ++Text Name='After' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/portal-expected-uia-win.txt b/content/test/data/accessibility/html/portal-expected-uia-win.txt index a764ebe..c33b658f 100644 --- a/content/test/data/accessibility/html/portal-expected-uia-win.txt +++ b/content/test/data/accessibility/html/portal-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++++Document Name='Text in iframe' ++Group IsControlElement=false ++++Text Name='After portal' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/portal-name-from-text-expected-auralinux.txt b/content/test/data/accessibility/html/portal-name-from-text-expected-auralinux.txt index 2e9aeed5..f9115ef 100644 --- a/content/test/data/accessibility/html/portal-name-from-text-expected-auralinux.txt +++ b/content/test/data/accessibility/html/portal-name-from-text-expected-auralinux.txt
@@ -2,4 +2,3 @@ ++[section] ++++[push button] name='Text in iframe' ++++++[document web] name='Text in iframe' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/portal-name-from-text-expected-blink.txt b/content/test/data/accessibility/html/portal-name-from-text-expected-blink.txt index 020b059..405b4c4 100644 --- a/content/test/data/accessibility/html/portal-name-from-text-expected-blink.txt +++ b/content/test/data/accessibility/html/portal-name-from-text-expected-blink.txt
@@ -2,4 +2,3 @@ ++genericContainer ++++portal ++++++rootWebArea name='Text in iframe' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/pre-expected-uia-win.txt b/content/test/data/accessibility/html/pre-expected-uia-win.txt index b2a6f5f..4fabf81 100644 --- a/content/test/data/accessibility/html/pre-expected-uia-win.txt +++ b/content/test/data/accessibility/html/pre-expected-uia-win.txt
@@ -7,4 +7,3 @@ ++++Text Name='This test is to check pre<newline>formatting.' ++Group IsControlElement=false ++++Text Name='This test is to check pre formatting.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/progress-expected-uia-win.txt b/content/test/data/accessibility/html/progress-expected-uia-win.txt index 3c2af83..dd08f429 100644 --- a/content/test/data/accessibility/html/progress-expected-uia-win.txt +++ b/content/test/data/accessibility/html/progress-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++ProgressBar RangeValue.IsReadOnly=true RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=100.00 RangeValue.Minimum=0.00 RangeValue.Value=22.00 Value.Value='22' ++++ProgressBar RangeValue.IsReadOnly=true RangeValue.LargeChange=0.00 RangeValue.SmallChange=0.00 RangeValue.Maximum=1.00 RangeValue.Minimum=0.00 RangeValue.Value=0.00 -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/q-expected-uia-win.txt b/content/test/data/accessibility/html/q-expected-uia-win.txt index 7fb9316..f829a962 100644 --- a/content/test/data/accessibility/html/q-expected-uia-win.txt +++ b/content/test/data/accessibility/html/q-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++++Text Name='Chromium Blink' ++++Text Name='"' ++++Text Name=' based browser.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/ruby-expected-uia-win.txt b/content/test/data/accessibility/html/ruby-expected-uia-win.txt index 54296ed..18fc8a4 100644 --- a/content/test/data/accessibility/html/ruby-expected-uia-win.txt +++ b/content/test/data/accessibility/html/ruby-expected-uia-win.txt
@@ -4,4 +4,3 @@ ++++++Text IsControlElement=false ++++++++Text Name='ruby text' ++++++Text Name='ruby base' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/scrollable-expected-uia-win.txt b/content/test/data/accessibility/html/scrollable-expected-uia-win.txt index 0aa0f99b..ffebe6e 100644 --- a/content/test/data/accessibility/html/scrollable-expected-uia-win.txt +++ b/content/test/data/accessibility/html/scrollable-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='not scrollable' ++Group Name='x' Scroll.HorizontalScrollPercent=0.00 Scroll.HorizontalViewSize=50.00 Scroll.HorizontallyScrollable=true Scroll.VerticalScrollPercent=-1.00 Scroll.VerticalViewSize=100.00 Scroll.VerticallyScrollable=false ++Group Name='y' Scroll.HorizontalScrollPercent=-1.00 Scroll.HorizontalViewSize=100.00 Scroll.HorizontallyScrollable=false Scroll.VerticalScrollPercent=0.00 Scroll.VerticalViewSize=50.00 Scroll.VerticallyScrollable=true -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/scrollable-textarea-expected-uia-win.txt b/content/test/data/accessibility/html/scrollable-textarea-expected-uia-win.txt index b2dc4fd..0d030ad8 100644 --- a/content/test/data/accessibility/html/scrollable-textarea-expected-uia-win.txt +++ b/content/test/data/accessibility/html/scrollable-textarea-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group IsControlElement=false ++++Edit Value.Value='little' ++++Edit Value.Value='lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text+ lots+of+text' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/section-expected-uia-win.txt b/content/test/data/accessibility/html/section-expected-uia-win.txt index a15a2b7..91224b28 100644 --- a/content/test/data/accessibility/html/section-expected-uia-win.txt +++ b/content/test/data/accessibility/html/section-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='This is a section element.' ++Group LocalizedControlType='section' Name='section' ++++Text Name='This is a named section element.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/select-expected-uia-win.txt b/content/test/data/accessibility/html/select-expected-uia-win.txt index c605a56..50c8276 100644 --- a/content/test/data/accessibility/html/select-expected-uia-win.txt +++ b/content/test/data/accessibility/html/select-expected-uia-win.txt
@@ -23,4 +23,3 @@ ++++++ListItem Name='Option 1' SelectionItem.IsSelected=false ++++++ListItem Name='Option 2' SelectionItem.IsSelected=false ++++++ListItem Name='Option 3' SelectionItem.IsSelected=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/selection-container-expected-uia-win.txt b/content/test/data/accessibility/html/selection-container-expected-uia-win.txt index f8a2d6db..3416c2d 100644 --- a/content/test/data/accessibility/html/selection-container-expected-uia-win.txt +++ b/content/test/data/accessibility/html/selection-container-expected-uia-win.txt
@@ -7,4 +7,3 @@ ++++++ListItem Name='Two' SelectionItem.IsSelected=false SelectionItem.SelectionContainer='selection_list' ++++++ListItem Name='Three' SelectionItem.IsSelected=false SelectionItem.SelectionContainer='selection_list' ++++++ListItem Name='Four' SelectionItem.IsSelected=false SelectionItem.SelectionContainer='selection_list' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/span-expected-uia-win.txt b/content/test/data/accessibility/html/span-expected-uia-win.txt index 2815441..2e727e9 100644 --- a/content/test/data/accessibility/html/span-expected-uia-win.txt +++ b/content/test/data/accessibility/html/span-expected-uia-win.txt
@@ -68,4 +68,3 @@ ++++Text Name='K8. Keep' ++++Text Name=' ' ++++Text Name='space' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/sub-expected-uia-win.txt b/content/test/data/accessibility/html/sub-expected-uia-win.txt index 13d3317..ca9e205 100644 --- a/content/test/data/accessibility/html/sub-expected-uia-win.txt +++ b/content/test/data/accessibility/html/sub-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='This text contains ' ++++Text Name='subscript' ++++Text Name=' text.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/summary-expected-uia-win.txt b/content/test/data/accessibility/html/summary-expected-uia-win.txt index c8b1315c..5737814 100644 --- a/content/test/data/accessibility/html/summary-expected-uia-win.txt +++ b/content/test/data/accessibility/html/summary-expected-uia-win.txt
@@ -2,4 +2,3 @@ ++Group ++++Button Name='details tag' ExpandCollapse.ExpandCollapseState='Collapsed' ++++++Text Name='details tag' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/sup-expected-uia-win.txt b/content/test/data/accessibility/html/sup-expected-uia-win.txt index b11f90f..53eba64f 100644 --- a/content/test/data/accessibility/html/sup-expected-uia-win.txt +++ b/content/test/data/accessibility/html/sup-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='This text contains' ++++Text Name='superscript' ++++Text Name='text.' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/svg-expected-uia-win.txt b/content/test/data/accessibility/html/svg-expected-uia-win.txt index 08454be..ab8d00b 100644 --- a/content/test/data/accessibility/html/svg-expected-uia-win.txt +++ b/content/test/data/accessibility/html/svg-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Image Name='svg' HelpText='SVG Title Tag' ++++++Group IsControlElement=false ++++++++Text Name='Test' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt b/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt index ca8790ef..7710b401 100644 --- a/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt +++ b/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt
@@ -23,4 +23,3 @@ ++++++++++Text Name='12' IsControlElement=false ++++++++DataItem Name='3' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=3 GridItem.RowSpan=1 ++++++++++Text Name='3' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/table-layout-expected-uia-win.txt b/content/test/data/accessibility/html/table-layout-expected-uia-win.txt index 0a8c4b5..808887c 100644 --- a/content/test/data/accessibility/html/table-layout-expected-uia-win.txt +++ b/content/test/data/accessibility/html/table-layout-expected-uia-win.txt
@@ -21,4 +21,3 @@ ++++++++Text Name='8' IsControlElement=false ++++++DataItem Name='9' GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1 ++++++++Text Name='9' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/table-presentation-expected-uia-win.txt b/content/test/data/accessibility/html/table-presentation-expected-uia-win.txt index cbb3a621..f939a808 100644 --- a/content/test/data/accessibility/html/table-presentation-expected-uia-win.txt +++ b/content/test/data/accessibility/html/table-presentation-expected-uia-win.txt
@@ -7,4 +7,3 @@ ++++Text Name='4' ++Group IsControlElement=false ++++Text Name='5' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt b/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt index 53e879b..111b354 100644 --- a/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt +++ b/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt
@@ -10,4 +10,3 @@ ++++++++Text Name='Jill' IsControlElement=false ++++++DataItem Name='Smith' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1 ++++++++Text Name='Smith' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt b/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt index 63e08936..e6d6bee 100644 --- a/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt +++ b/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt
@@ -10,4 +10,3 @@ ++++++++Text Name='Lastname' IsControlElement=false ++++++DataItem Name='Smith' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1 ++++++++Text Name='Smith' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/textarea-expected-uia-win.txt b/content/test/data/accessibility/html/textarea-expected-uia-win.txt index 8375af8..412d53e 100644 --- a/content/test/data/accessibility/html/textarea-expected-uia-win.txt +++ b/content/test/data/accessibility/html/textarea-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Edit Value.Value='The <newline>textarea tag defines a multi-line text input control.<newline>' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/textarea-read-only-expected-uia-win.txt b/content/test/data/accessibility/html/textarea-read-only-expected-uia-win.txt index a8b62c0..a728828 100644 --- a/content/test/data/accessibility/html/textarea-read-only-expected-uia-win.txt +++ b/content/test/data/accessibility/html/textarea-read-only-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Edit Value.Value='The textarea tag defines a multi-line text input control.<newline>' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/textarea-with-selection-expected-uia-win.txt b/content/test/data/accessibility/html/textarea-with-selection-expected-uia-win.txt index a8b62c0..a728828 100644 --- a/content/test/data/accessibility/html/textarea-with-selection-expected-uia-win.txt +++ b/content/test/data/accessibility/html/textarea-with-selection-expected-uia-win.txt
@@ -1,4 +1,3 @@ Document ++Group IsControlElement=false ++++Edit Value.Value='The textarea tag defines a multi-line text input control.<newline>' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/time-expected-uia-win.txt b/content/test/data/accessibility/html/time-expected-uia-win.txt index f00991d6..905bae09 100644 --- a/content/test/data/accessibility/html/time-expected-uia-win.txt +++ b/content/test/data/accessibility/html/time-expected-uia-win.txt
@@ -5,4 +5,3 @@ ++++Text Name=' ' ++++Text LocalizedControlType='time' ++++++Text Name='Valentines day' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/title-expected-uia-win.txt b/content/test/data/accessibility/html/title-expected-uia-win.txt index 8b05cda4..f2760f9 100644 --- a/content/test/data/accessibility/html/title-expected-uia-win.txt +++ b/content/test/data/accessibility/html/title-expected-uia-win.txt
@@ -1,2 +1 @@ Document Name='Title of the document' -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/ul-expected-uia-win.txt b/content/test/data/accessibility/html/ul-expected-uia-win.txt index 4c07ffe2..9679367 100644 --- a/content/test/data/accessibility/html/ul-expected-uia-win.txt +++ b/content/test/data/accessibility/html/ul-expected-uia-win.txt
@@ -12,4 +12,3 @@ ++++++Group ++++++++Text Name='• ' IsControlElement=false ++++++Text Name='Item 3' IsControlElement=false -<-- End-of-file -->
diff --git a/content/test/data/accessibility/html/wbr-expected-uia-win.txt b/content/test/data/accessibility/html/wbr-expected-uia-win.txt index cec2de9..4ab988a 100644 --- a/content/test/data/accessibility/html/wbr-expected-uia-win.txt +++ b/content/test/data/accessibility/html/wbr-expected-uia-win.txt
@@ -3,4 +3,3 @@ ++++Text Name='Supercali' ++++Text Name='fragilistic' ++++Text Name='expialidocious' -<-- End-of-file -->
diff --git a/content/test/render_document_feature.cc b/content/test/render_document_feature.cc new file mode 100644 index 0000000..39183b45 --- /dev/null +++ b/content/test/render_document_feature.cc
@@ -0,0 +1,30 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/render_document_feature.h" + +#include "base/test/scoped_feature_list.h" +#include "content/common/content_navigation_policy.h" +#include "content/public/common/content_features.h" + +namespace content { + +void InitAndEnableRenderDocumentFeature( + base::test::ScopedFeatureList* feature_list, + std::string level) { + std::map<std::string, std::string> parameters; + parameters[kRenderDocumentLevelParameterName] = level; + feature_list->InitAndEnableFeatureWithParameters(features::kRenderDocument, + parameters); +} + +std::vector<std::string> RenderDocumentFeatureLevelValues() { + return { + GetRenderDocumentLevelName(RenderDocumentLevel::kDisabled), + GetRenderDocumentLevelName(RenderDocumentLevel::kCrashedFrame), + // TODO(https://crbug.com/936696): Add kSubframe when tests are passing. + }; +} + +} // namespace content
diff --git a/content/test/render_document_feature.h b/content/test/render_document_feature.h new file mode 100644 index 0000000..7606001 --- /dev/null +++ b/content/test/render_document_feature.h
@@ -0,0 +1,30 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_RENDER_DOCUMENT_FEATURE_H_ +#define CONTENT_TEST_RENDER_DOCUMENT_FEATURE_H_ + +#include <string> +#include <vector> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace test { +class ScopedFeatureList; +} // namespace test +} // namespace base + +namespace content { + +void InitAndEnableRenderDocumentFeature( + base::test::ScopedFeatureList* feature_list, + std::string level); + +// The list of values to test for the "level" parameter. +std::vector<std::string> RenderDocumentFeatureLevelValues(); + +} // namespace content + +#endif // CONTENT_TEST_RENDER_DOCUMENT_FEATURE_H_
diff --git a/docs/android_debugging_instructions.md b/docs/android_debugging_instructions.md index 3596bf2d..85476a6 100644 --- a/docs/android_debugging_instructions.md +++ b/docs/android_debugging_instructions.md
@@ -222,19 +222,13 @@ **Googlers Only**: For official build mapping files, see [go/chromejavadeobfuscation](https://goto.google.com/chromejavadeobfuscation). -Once you have a .mapping file, build the `java_deobfuscate` tool: - -```shell -ninja -C out/Default java_deobfuscate -``` - -Then run it via: +Once you have a .mapping file: ```shell # For a file: -out/Default/bin/java_deobfuscate PROGUARD_MAPPING_FILE.mapping < FILE +build/android/stacktrace/java_deobfuscate.py PROGUARD_MAPPING_FILE.mapping < FILE # For logcat: -adb logcat | out/Default/bin/java_deobfuscate PROGUARD_MAPPING_FILE.mapping +adb logcat | build/android/stacktrace/java_deobfuscate.py PROGUARD_MAPPING_FILE.mapping ``` ## Get WebKit code to output to the adb log
diff --git a/docs/testing/android_test_instructions.md b/docs/testing/android_test_instructions.md index b728075..ec2786c0 100644 --- a/docs/testing/android_test_instructions.md +++ b/docs/testing/android_test_instructions.md
@@ -265,7 +265,7 @@ If running with `is_debug=false`, Java stacks from logcat need to be fixed up: ```shell -out/Release/bin/java_deobfuscate out/Release/apks/ChromePublicTest.apk.mapping < stacktrace.txt +build/android/stacktrace/java_deobfuscate.py out/Release/apks/ChromePublicTest.apk.mapping < stacktrace.txt ``` Any stacks produced by test runner output will already be deobfuscated.
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index addc904..d2aefe5 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h
@@ -1522,6 +1522,7 @@ PASSWORDSPRIVATE_STOPPASSWORDCHECK = 1459, PASSWORDSPRIVATE_GETPASSWORDCHECKSTATUS = 1460, TERMINALPRIVATE_OPENVMSHELLPROCESS = 1461, + PASSWORDSPRIVATE_OPTINFORACCOUNTSTORAGE = 1462, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY
diff --git a/gpu/command_buffer/service/shared_image_backing_ozone.cc b/gpu/command_buffer/service/shared_image_backing_ozone.cc index 25474b4..5354bf4 100644 --- a/gpu/command_buffer/service/shared_image_backing_ozone.cc +++ b/gpu/command_buffer/service/shared_image_backing_ozone.cc
@@ -24,6 +24,7 @@ #include "gpu/command_buffer/service/shared_image_manager.h" #include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/shared_image_representation_gl_ozone.h" +#include "gpu/command_buffer/service/shared_image_representation_skia_gl.h" #include "gpu/vulkan/vulkan_device_queue.h" #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/buffer_types.h" @@ -144,6 +145,23 @@ SharedImageManager* manager, MemoryTypeTracker* tracker, scoped_refptr<SharedContextState> context_state) { + if (context_state->GrContextIsGL()) { + auto gl_representation = ProduceGLTexture(manager, tracker); + if (!gl_representation) { + LOG(ERROR) << "SharedImageBackingOzone::ProduceSkia failed to create GL " + "representation"; + return nullptr; + } + auto skia_representation = SharedImageRepresentationSkiaGL::Create( + std::move(gl_representation), std::move(context_state), manager, this, + tracker); + if (!skia_representation) { + LOG(ERROR) << "SharedImageBackingOzone::ProduceSkia failed to create " + "Skia representation"; + return nullptr; + } + return skia_representation; + } NOTIMPLEMENTED_LOG_ONCE(); return nullptr; }
diff --git a/gpu/vulkan/vulkan_fence_helper.cc b/gpu/vulkan/vulkan_fence_helper.cc index 224e474..502436a8 100644 --- a/gpu/vulkan/vulkan_fence_helper.cc +++ b/gpu/vulkan/vulkan_fence_helper.cc
@@ -241,8 +241,10 @@ // recover from this. CHECK(result == VK_SUCCESS || result == VK_ERROR_DEVICE_LOST); bool device_lost = result == VK_ERROR_DEVICE_LOST; - if (!device_lost) - current_generation_ = next_generation_ - 1; + + // We're going to destroy all fences below, so we should consider them as + // passed. + current_generation_ = next_generation_ - 1; // Run all cleanup tasks. Create a temporary vector of tasks to run to avoid // reentrancy issues.
diff --git a/gpu/vulkan/vulkan_instance.cc b/gpu/vulkan/vulkan_instance.cc index f647f27c1..b1eddae 100644 --- a/gpu/vulkan/vulkan_instance.cc +++ b/gpu/vulkan/vulkan_instance.cc
@@ -237,15 +237,22 @@ } #endif - CollectInfo(); + if (!CollectInfo()) + return false; return true; } -void VulkanInstance::CollectInfo() { +bool VulkanInstance::CollectInfo() { uint32_t count = 0; VkResult result = vkEnumeratePhysicalDevices(vk_instance_, &count, nullptr); if (result != VK_SUCCESS) { DLOG(ERROR) << "vkEnumeratePhysicalDevices failed: " << result; + return false; + } + + if (!count) { + DLOG(ERROR) << "vkEnumeratePhysicalDevices returns zero device."; + return false; } std::vector<VkPhysicalDevice> physical_devices(count); @@ -253,7 +260,7 @@ vkEnumeratePhysicalDevices(vk_instance_, &count, physical_devices.data()); if (VK_SUCCESS != result) { DLOG(ERROR) << "vkEnumeratePhysicalDevices() failed: " << result; - return; + return false; } vulkan_info_.physical_devices.reserve(count); @@ -307,6 +314,7 @@ info.queue_families.data()); } } + return true; } void VulkanInstance::Destroy() {
diff --git a/gpu/vulkan/vulkan_instance.h b/gpu/vulkan/vulkan_instance.h index bd0092e..ad4497d3b 100644 --- a/gpu/vulkan/vulkan_instance.h +++ b/gpu/vulkan/vulkan_instance.h
@@ -35,7 +35,7 @@ VkInstance vk_instance() { return vk_instance_; } private: - void CollectInfo(); + bool CollectInfo(); void Destroy(); VulkanInfo vulkan_info_;
diff --git a/infra/config/consoles/main-m80.star b/infra/config/consoles/main-m80.star index 8956955..f4c4395 100644 --- a/infra/config/consoles/main-m80.star +++ b/infra/config/consoles/main-m80.star
@@ -6,7 +6,7 @@ # TODO(gbeaty) Define the main consoles inside the respective versioned # directories once their contents are stablilized refs = ['refs/branch-heads/3987'], - title = 'Chromium Stable Console', + title = 'Chromium M80 Console', entries = [ luci.console_view_entry( builder = 'ci-m80/Linux Builder',
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index 1887a91..2b975170 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg
@@ -11147,7 +11147,7 @@ > consoles: < id: "main-m80" - name: "Chromium Stable Console" + name: "Chromium M80 Console" repo_url: "https://chromium.googlesource.com/chromium/src" refs: "regexp:refs/branch-heads/3987" manifest_name: "REVISION"
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index b356644..ce08bf87 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -26,6 +26,7 @@ "//components/omnibox/common", "//components/password_manager/core/common", "//components/payments/core", + "//components/safe_browsing/core:features", "//components/search_provider_logos", "//components/security_state/core", "//components/send_tab_to_self",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 1b3094a..0c33cc33 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -39,6 +39,7 @@ #include "components/omnibox/common/omnibox_features.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/payments/core/features.h" +#include "components/safe_browsing/core/features.h" #include "components/security_state/core/features.h" #include "components/send_tab_to_self/features.h" #include "components/signin/core/browser/account_reconcilor.h" @@ -577,6 +578,9 @@ flags_ui::kOsIos, FEATURE_VALUE_TYPE( web::features::kIOSLookalikeUrlNavigationSuggestionsUI)}, + {"safe-browsing-available", flag_descriptions::kSafeBrowsingAvailableName, + flag_descriptions::kSafeBrowsingAvailableDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(safe_browsing::kSafeBrowsingAvailableOnIOS)}, }; // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 21c88acf..3d38215 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -327,6 +327,11 @@ "When enabled, the first time the renderer crashes, the page is reloaded " "instead of showing the SadTab"; +const char kSafeBrowsingAvailableName[] = "Make Safe Browsing available"; +const char kSafeBrowsingAvailableDescription[] = + "When enabled, navigation URLs are compared to Safe Browsing blocklists, " + "subject to an opt-out preference."; + const char kSaveCardInfobarMessagesUIName[] = "Save Card Infobar Messages UI"; const char kSaveCardInfobarMessagesUIDescription[] = "When enabled, Save Card Infobar uses the new Messages UI.";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 16b0b8d5..054474d4 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -279,6 +279,10 @@ extern const char kReloadSadTabName[]; extern const char kReloadSadTabDescription[]; +// Title and description for the flag that makes Safe Browsing available. +extern const char kSafeBrowsingAvailableName[]; +extern const char kSafeBrowsingAvailableDescription[]; + // Title and description for the flag that enables Messages UI on // SaveCard Infobars. extern const char kSaveCardInfobarMessagesUIName[];
diff --git a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_coordinator.mm index 3fdfd2c..2671b53b 100644 --- a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_coordinator.mm
@@ -62,13 +62,12 @@ // Init and start Google settings coordinator. GoogleServicesSettingsMode mode = GoogleServicesSettingsModeAdvancedSigninSettings; - self.googleServicesSettingsCoordinator = [[GoogleServicesSettingsCoordinator - alloc] - initWithBaseViewController:self.advancedSettingsSigninNavigationController - browser:self.browser - mode:mode]; - self.googleServicesSettingsCoordinator.baseNavigationController = - self.advancedSettingsSigninNavigationController; + self.googleServicesSettingsCoordinator = + [[GoogleServicesSettingsCoordinator alloc] + initWithBaseNavigationController: + self.advancedSettingsSigninNavigationController + browser:self.browser + mode:mode]; [self.googleServicesSettingsCoordinator start]; // Create the mediator.
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.h b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.h index 65af37d..971ce39 100644 --- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.h +++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.h
@@ -52,11 +52,12 @@ promoAction; // Returns a coordinator for first run sign-in workflow. -// |viewController| presents the sign-in. Will be responsible for dismissing -// itself upon sign-in completion. -+ (instancetype)firstRunCoordinatorWithBaseViewController: - (UINavigationController*)viewController - browser:(Browser*)browser; +// |navigationController| presents the sign-in. Will be responsible for +// dismissing itself upon sign-in completion. ++ (instancetype)firstRunCoordinatorWithBaseNavigationController: + (UINavigationController*)navigationController + browser: + (Browser*)browser; // Returns a coordinator for upgrade sign-in workflow. // |viewController| presents the sign-in.
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm index 99432bf..2259bbbe 100644 --- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator.mm
@@ -37,18 +37,18 @@ logger:logger]; } -+ (instancetype)firstRunCoordinatorWithBaseViewController: - (UINavigationController*)viewController - browser:(Browser*)browser { ++ (instancetype)firstRunCoordinatorWithBaseNavigationController: + (UINavigationController*)navigationController + browser: + (Browser*)browser { UserSigninLogger* logger = [[FirstRunSigninLogger alloc] initWithAccessPoint:AccessPoint::ACCESS_POINT_START_PAGE promoAction:PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO]; return [[UserSigninCoordinator alloc] - initWithBaseViewController:viewController - browser:browser - identity:nil - signinIntent:UserSigninIntentFirstRun - logger:logger]; + initWithBaseNavigationController:navigationController + browser:browser + signinIntent:UserSigninIntentFirstRun + logger:logger]; } + (instancetype)
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.h b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.h index a564ebc..177ad5b 100644 --- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.h +++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.h
@@ -36,6 +36,13 @@ logger:(UserSigninLogger*)logger NS_DESIGNATED_INITIALIZER; +// Convenience initializer using UINavigationController. +- (instancetype)initWithBaseNavigationController: + (UINavigationController*)navigationController + browser:(Browser*)browser + signinIntent:(UserSigninIntent)signinIntent + logger:(UserSigninLogger*)logger; + @end #endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_SIGNIN_USER_SIGNIN_USER_SIGNIN_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.mm index b14eff1..f0b0bc0 100644 --- a/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.mm +++ b/ios/chrome/browser/ui/authentication/signin/user_signin/user_signin_coordinator.mm
@@ -59,8 +59,25 @@ @implementation UserSigninCoordinator +@synthesize baseNavigationController = _baseNavigationController; + #pragma mark - Public +- (instancetype)initWithBaseNavigationController: + (UINavigationController*)navigationController + browser:(Browser*)browser + signinIntent:(UserSigninIntent)signinIntent + logger:(UserSigninLogger*)logger { + if (self = [self initWithBaseViewController:navigationController + browser:browser + identity:nil + signinIntent:signinIntent + logger:logger]) { + _baseNavigationController = navigationController; + } + return self; +} + - (instancetype)initWithBaseViewController:(UIViewController*)viewController browser:(Browser*)browser identity:(ChromeIdentity*)identity
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index 3924d45..173ff136 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -2278,7 +2278,7 @@ kToolsMenuGuide, kTabSwitcherGuide, kTranslateInfobarOptionsGuide, - kSearchButtonGuide, + kNewTabButtonGuide, kSecondaryToolbarGuide, kVoiceSearchButtonGuide, ];
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm index 197d3f51..f44be16a 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.mm +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -184,7 +184,7 @@ IsSplitToolbarMode() ? BubbleArrowDirectionDown : BubbleArrowDirectionUp; NSString* text = l10n_util::GetNSString(IDS_IOS_LONG_PRESS_TOOLBAR_IPH_PROMOTION_TEXT); - CGPoint searchButtonAnchor = + CGPoint tabGridButtonAnchor = IsRegularXRegularSizeClass() && !base::FeatureList::IsEnabled(kChangeTabSwitcherPosition) ? [self anchorPointToGuide:kTabStripTabSwitcherGuide @@ -203,7 +203,7 @@ voiceOverAnnouncement: l10n_util::GetNSString( IDS_IOS_LONG_PRESS_TOOLBAR_IPH_PROMOTION_VOICE_OVER) - anchorPoint:searchButtonAnchor]; + anchorPoint:tabGridButtonAnchor]; if (!presenter) return; @@ -246,8 +246,8 @@ BubbleArrowDirection arrowDirection = BubbleArrowDirectionDown; NSString* text = l10n_util::GetNSStringWithFixup( IDS_IOS_BOTTOM_TOOLBAR_IPH_PROMOTION_TEXT); - CGPoint searchButtonAnchor = - [self anchorPointToGuide:kSearchButtonGuide direction:arrowDirection]; + CGPoint newTabButtonAnchor = [self anchorPointToGuide:kNewTabButtonGuide + direction:arrowDirection]; // If the feature engagement tracker does not consider it valid to display // the tip, then end early to prevent the potential reassignment of the @@ -260,7 +260,7 @@ voiceOverAnnouncement: l10n_util::GetNSString( IDS_IOS_BOTTOM_TOOLBAR_IPH_PROMOTION_VOICE_OVER) - anchorPoint:searchButtonAnchor]; + anchorPoint:newTabButtonAnchor]; if (!presenter) return;
diff --git a/ios/chrome/browser/ui/commands/popup_menu_commands.h b/ios/chrome/browser/ui/commands/popup_menu_commands.h index c67b40b5..0c49aa9 100644 --- a/ios/chrome/browser/ui/commands/popup_menu_commands.h +++ b/ios/chrome/browser/ui/commands/popup_menu_commands.h
@@ -26,8 +26,8 @@ - (void)showTabGridButtonPopup; // Shows the popup for the tab grid button in the tab strip. - (void)showTabStripTabGridButtonPopup; -// Shows the popup for the search button. -- (void)showSearchButtonPopup; +// Shows the popup for the new tab button. +- (void)showNewTabButtonPopup; // Dismisses the currently presented popup. - (void)dismissPopupMenuAnimated:(BOOL)animated;
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h index 3d02332..138057e 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h
@@ -21,11 +21,6 @@ // Shared instance of this singleton. + (instancetype)sharedInstance; -// Whether the @"focusOmniboxFromSearchButton" selector has been called on the -// location bar coordinator. This is the method swizzled by the methods below. -@property(nonatomic, assign, readonly) - BOOL locationBarCoordinatorSearchButtonMethodCalled; - // Resets the stored additionalSuggestions helper with |URL|. - (void)resetAdditionalSuggestionsHelperWithURL:(const GURL&)URL; // Returns the stored additionalSuggestionsHelper.
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm index 147d9f37..c0bc2e3 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.mm
@@ -8,7 +8,6 @@ #include "components/ntp_snippets/content_suggestion.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.h" -#include "ios/testing/scoped_block_swizzler.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -19,8 +18,6 @@ ntp_snippets::MockContentSuggestionsProvider* _provider; std::unique_ptr<ntp_snippets::AdditionalSuggestionsHelper> _additionalSuggestionsHelper; - std::unique_ptr<ScopedBlockSwizzler> _swizzler; - __block BOOL _tapped; } + (instancetype)sharedInstance { @@ -56,8 +53,4 @@ service->RegisterProvider(std::move(provider)); } -- (BOOL)locationBarCoordinatorSearchButtonMethodCalled { - return _tapped; -} - @end
diff --git a/ios/chrome/browser/ui/coordinators/chrome_coordinator.h b/ios/chrome/browser/ui/coordinators/chrome_coordinator.h index 9510daa..7e7f928b 100644 --- a/ios/chrome/browser/ui/coordinators/chrome_coordinator.h +++ b/ios/chrome/browser/ui/coordinators/chrome_coordinator.h
@@ -47,7 +47,8 @@ // Parent coordinator can set this to allow the child coordinator to push their // view controller to the navigationController instead of presenting it if // needed. This is usually the same object as |baseViewController|. -@property(weak, nonatomic) UINavigationController* baseNavigationController; +@property(weak, nonatomic, readonly) + UINavigationController* baseNavigationController; // The coordinator's BrowserState. @property(assign, nonatomic, readonly) ChromeBrowserState* browserState;
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm index 55a4b26..5f85d10 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -306,20 +306,6 @@ #pragma mark - OmniboxFocuser -- (void)focusOmniboxFromSearchButton { - // TODO(crbug.com/931284): Temporary workaround for intermediate broken state - // in the NTP. Remove this once crbug.com/899827 is fixed. - if (self.webState) { - NewTabPageTabHelper* NTPHelper = - NewTabPageTabHelper::FromWebState(self.webState); - if (NTPHelper && NTPHelper->IsActive() && NTPHelper->IgnoreLoadRequests()) { - return; - } - } - [self.omniboxCoordinator setNextFocusSourceAsSearchButton]; - [self focusOmnibox]; -} - - (void)focusOmniboxFromFakebox { [self.omniboxCoordinator focusOmnibox]; }
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.h b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.h index ad5c3a5d..22cbe54 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.h +++ b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.h
@@ -54,8 +54,6 @@ - (void)updateOmniboxState; // Use this method to make the omnibox first responder. - (void)focusOmnibox; -// Marks the next omnibox focus event source as the search button. -- (void)setNextFocusSourceAsSearchButton; // Use this method to resign |textField| as the first responder. - (void)endEditing; // Creates a child popup coordinator. The popup coordinator is linked to the
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm index 144f24e..18bf751 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm
@@ -121,11 +121,6 @@ _editView->UpdateAppearance(); } -- (void)setNextFocusSourceAsSearchButton { - OmniboxEditModel* model = _editView->model(); - model->set_focus_source(OmniboxFocusSource::SEARCH_BUTTON); -} - - (BOOL)isOmniboxFirstResponder { return [self.textField isFirstResponder]; }
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn index 08f1269..b1c48dd 100644 --- a/ios/chrome/browser/ui/popup_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -117,6 +117,8 @@ "//ios/chrome/browser/ui/popup_menu/cells", "//ios/chrome/browser/ui/popup_menu/public:popup_menu_ui", "//ios/chrome/browser/ui/toolbar/test", + "//ios/chrome/browser/web", + "//ios/chrome/browser/web:feature_flags", "//ios/chrome/browser/web:test_support", "//ios/chrome/browser/web:web_internal", "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm index 544cfb2a..e4b43161 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -123,10 +123,10 @@ fromNamedGuide:kTabSwitcherGuide]; } -- (void)showSearchButtonPopup { +- (void)showNewTabButtonPopup { base::RecordAction(base::UserMetricsAction("MobileToolbarShowNewTabMenu")); - [self presentPopupOfType:PopupMenuTypeSearch - fromNamedGuide:kSearchButtonGuide]; + [self presentPopupOfType:PopupMenuTypeNewTab + fromNamedGuide:kNewTabButtonGuide]; } - (void)showTabStripTabGridButtonPopup {
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm index fcef641c..a6c14b1 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
@@ -432,7 +432,7 @@ case PopupMenuTypeTabStripTabGrid: [self createTabGridMenuItems]; break; - case PopupMenuTypeSearch: + case PopupMenuTypeNewTab: [self createSearchMenuItems]; break; }
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm index 01b1eb3d..9ed9352 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/ui/popup_menu/popup_menu_mediator.h" +#include "base/test/scoped_feature_list.h" #include "base/time/default_clock.h" #include "components/feature_engagement/test/mock_tracker.h" #include "components/language/ios/browser/ios_language_detection_tab_helper.h" @@ -23,6 +24,8 @@ #import "ios/chrome/browser/ui/toolbar/test/toolbar_test_web_state.h" #include "ios/chrome/browser/web/chrome_web_client.h" #import "ios/chrome/browser/web/chrome_web_test.h" +#include "ios/chrome/browser/web/features.h" +#import "ios/chrome/browser/web/font_size_tab_helper.h" #include "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #include "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" @@ -363,3 +366,25 @@ queue->CancelAllRequests(); EXPECT_TRUE(HasItem(consumer, kToolsMenuReadLater, /*enabled=*/YES)); } + +// Tests that the "Text Zoom..." button is disabled on non-HTML pages. +TEST_F(PopupMenuMediatorTest, TextTextZoomDisabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(web::kWebPageTextAccessibility); + + CreateMediator(PopupMenuTypeToolsMenu, /*is_incognito=*/NO, + /*trigger_incognito_hint=*/NO); + mediator_.webStateList = web_state_list_.get(); + + FakePopupMenuConsumer* consumer = [[FakePopupMenuConsumer alloc] init]; + mediator_.popupMenu = consumer; + FontSizeTabHelper::CreateForWebState(web_state_list_->GetWebStateAt(0)); + SetUpActiveWebState(); + EXPECT_TRUE(HasItem(consumer, kToolsMenuTextZoom, /*enabled=*/YES)); + + web_state_->SetContentIsHTML(false); + // Fake a navigationFinished to force the popup menu items to update. + web::FakeNavigationContext context; + web_state_->OnNavigationFinished(&context); + EXPECT_TRUE(HasItem(consumer, kToolsMenuTextZoom, /*enabled=*/NO)); +}
diff --git a/ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h b/ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h index 391e3b2..f3a33594 100644 --- a/ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h +++ b/ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h
@@ -13,7 +13,7 @@ PopupMenuTypeNavigationBackward, PopupMenuTypeNavigationForward, PopupMenuTypeTabGrid, - PopupMenuTypeSearch, + PopupMenuTypeNewTab, PopupMenuTypeTabStripTabGrid, };
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.h b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.h index 325253b8..1da4102 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.h +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.h
@@ -43,9 +43,11 @@ // |viewController|: navigation controller. // |browser|: browser. // |mode|: mode to display the Google services settings. -- (instancetype)initWithBaseViewController:(UIViewController*)viewController - browser:(Browser*)browser - mode:(GoogleServicesSettingsMode)mode +- (instancetype)initWithBaseNavigationController: + (UINavigationController*)navigationController + browser:(Browser*)browser + mode: + (GoogleServicesSettingsMode)mode NS_DESIGNATED_INITIALIZER; @end
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm index 849a240..d0f21da 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
@@ -64,10 +64,15 @@ @implementation GoogleServicesSettingsCoordinator -- (instancetype)initWithBaseViewController:(UIViewController*)viewController - browser:(Browser*)browser - mode:(GoogleServicesSettingsMode)mode { - if ([super initWithBaseViewController:viewController browser:browser]) { +@synthesize baseNavigationController = _baseNavigationController; + +- (instancetype)initWithBaseNavigationController: + (UINavigationController*)navigationController + browser:(Browser*)browser + mode:(GoogleServicesSettingsMode) + mode { + if ([super initWithBaseViewController:navigationController browser:browser]) { + _baseNavigationController = navigationController; _mode = mode; } return self; @@ -241,10 +246,8 @@ - (void)openManageSyncSettings { DCHECK(!self.manageSyncSettingsCoordinator); self.manageSyncSettingsCoordinator = [[ManageSyncSettingsCoordinator alloc] - initWithBaseViewController:self.viewController - browser:self.browser]; - self.manageSyncSettingsCoordinator.baseNavigationController = - self.baseNavigationController; + initWithBaseNavigationController:self.baseNavigationController + browser:self.browser]; self.manageSyncSettingsCoordinator.delegate = self; [self.manageSyncSettingsCoordinator start]; }
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.h b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.h index f92e756..5145e34 100644 --- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.h +++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.h
@@ -23,6 +23,19 @@ // relies on GoogleServicesSettingsCoordinator to commit the sync changes. @interface ManageSyncSettingsCoordinator : ChromeCoordinator +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + NS_UNAVAILABLE; +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + browserState:(ChromeBrowserState*)browserState + NS_UNAVAILABLE; +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + browser:(Browser*)browser NS_UNAVAILABLE; + +- (instancetype)initWithBaseNavigationController: + (UINavigationController*)navigationController + browser:(Browser*)browser + NS_DESIGNATED_INITIALIZER; + // Delegate. @property(nonatomic, weak) id<ManageSyncSettingsCoordinatorDelegate> delegate;
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm index 49a1167..af9be5123 100644 --- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm +++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
@@ -61,6 +61,18 @@ @implementation ManageSyncSettingsCoordinator +@synthesize baseNavigationController = _baseNavigationController; + +- (instancetype)initWithBaseNavigationController: + (UINavigationController*)navigationController + browser:(Browser*)browser { + if (self = [super initWithBaseViewController:navigationController + browser:browser]) { + _baseNavigationController = navigationController; + } + return self; +} + - (void)start { DCHECK(self.baseNavigationController); self.mediator = [[ManageSyncSettingsMediator alloc]
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm index 0edc17e..fbdf106c2 100644 --- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -366,10 +366,9 @@ } self.googleServicesSettingsCoordinator = [[GoogleServicesSettingsCoordinator alloc] - initWithBaseViewController:self - browser:self.browser - mode:GoogleServicesSettingsModeSettings]; - self.googleServicesSettingsCoordinator.baseNavigationController = self; + initWithBaseNavigationController:self + browser:self.browser + mode:GoogleServicesSettingsModeSettings]; self.googleServicesSettingsCoordinator.delegate = self; [self.googleServicesSettingsCoordinator start]; }
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm index 0b005fc..4b8ce94 100644 --- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -922,11 +922,9 @@ DCHECK(!_googleServicesSettingsCoordinator); _googleServicesSettingsCoordinator = [[GoogleServicesSettingsCoordinator alloc] - initWithBaseViewController:self.navigationController - browser:_browser - mode:GoogleServicesSettingsModeSettings]; - _googleServicesSettingsCoordinator.baseNavigationController = - self.navigationController; + initWithBaseNavigationController:self.navigationController + browser:_browser + mode:GoogleServicesSettingsModeSettings]; _googleServicesSettingsCoordinator.delegate = self; [_googleServicesSettingsCoordinator start]; }
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm index 95e5c1f..b6bd11b 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm
@@ -101,8 +101,8 @@ } // Returns a matcher for the search button. -id<GREYMatcher> SearchButton() { - return grey_accessibilityID(kToolbarSearchButtonIdentifier); +id<GREYMatcher> NewTabButton() { + return grey_accessibilityID(kToolbarNewTabButtonIdentifier); } // Returns a matcher for the tab grid button. @@ -233,7 +233,7 @@ // Those buttons are hidden by the keyboard. CheckVisibilityInToolbar(BackButton(), ButtonVisibilityNone); CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilityNone); - CheckVisibilityInToolbar(SearchButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(NewTabButton(), ButtonVisibilityNone); CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityNone); CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilityNone); } else { @@ -245,7 +245,7 @@ CheckVisibilityInToolbar(BackButton(), ButtonVisibilitySecondary); CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilitySecondary); - CheckVisibilityInToolbar(SearchButton(), ButtonVisibilitySecondary); + CheckVisibilityInToolbar(NewTabButton(), ButtonVisibilitySecondary); CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilitySecondary); CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilitySecondary); } @@ -263,7 +263,7 @@ CheckVisibilityInToolbar(BackButton(), ButtonVisibilityNone); CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilityNone); - CheckVisibilityInToolbar(SearchButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(NewTabButton(), ButtonVisibilityNone); CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityNone); CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilityNone); } else { @@ -275,7 +275,7 @@ CheckVisibilityInToolbar(BackButton(), ButtonVisibilityPrimary); CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilityPrimary); - CheckVisibilityInToolbar(SearchButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(NewTabButton(), ButtonVisibilityNone); CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityPrimary); CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilityPrimary); } @@ -296,7 +296,7 @@ CheckVisibilityInToolbar(BackButton(), ButtonVisibilityPrimary); CheckVisibilityInToolbar(ForwardButton(), ButtonVisibilityPrimary); - CheckVisibilityInToolbar(SearchButton(), ButtonVisibilityNone); + CheckVisibilityInToolbar(NewTabButton(), ButtonVisibilityNone); CheckVisibilityInToolbar(TabGridButton(), ButtonVisibilityNone); CheckVisibilityInToolbar(ToolsMenuButton(), ButtonVisibilityPrimary); @@ -586,16 +586,16 @@ assertWithMatcher:grey_not(grey_enabled())]; } -// Tests that tapping the omnibox button focuses the omnibox. -- (void)testOmniboxButton { +// Tests that tapping the NewTab button opens a new tab. +- (void)testNewTabButton { if (![ChromeEarlGrey isSplitToolbarMode]) { - EARL_GREY_TEST_SKIPPED(@"No omnibox button to tap."); + EARL_GREY_TEST_SKIPPED(@"No button to tap."); } [ChromeEarlGrey waitForMainTabCount:1]; [[EarlGrey selectElementWithMatcher:grey_accessibilityID( - kToolbarSearchButtonIdentifier)] + kToolbarNewTabButtonIdentifier)] performAction:grey_tap()]; [ChromeEarlGrey waitForMainTabCount:2]; @@ -652,7 +652,7 @@ [ChromeEarlGrey openNewTab]; // Check that the bottom toolbar is visible. - [[EarlGrey selectElementWithMatcher:SearchButton()] + [[EarlGrey selectElementWithMatcher:NewTabButton()] assertWithMatcher:grey_sufficientlyVisible()]; }
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view.h b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view.h index c0d1e08..aa845a6 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view.h +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view.h
@@ -37,8 +37,8 @@ @property(nonatomic, strong, readonly) ToolbarButton* bookmarkButton; // Button to display the tools menu. @property(nonatomic, strong, readonly) ToolbarToolsMenuButton* toolsMenuButton; -// Button to display the tools menu. -@property(nonatomic, strong, readonly) ToolbarButton* searchButton; +// Button to create a new tab. +@property(nonatomic, strong, readonly) ToolbarButton* openNewTabButton; // Separator between the toolbar and the content. @property(nonatomic, strong, readonly) UIView* separator;
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm index bbb8a02..0269d7a2 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm
@@ -92,14 +92,14 @@ // Adds the layout guide to the buttons. self.view.toolsMenuButton.guideName = kToolsMenuGuide; self.view.tabGridButton.guideName = kTabSwitcherGuide; - self.view.searchButton.guideName = kSearchButtonGuide; + self.view.openNewTabButton.guideName = kNewTabButtonGuide; self.view.forwardButton.guideName = kForwardButtonGuide; self.view.backButton.guideName = kBackButtonGuide; // Add navigation popup menu triggers. [self addLongPressGestureToView:self.view.backButton]; [self addLongPressGestureToView:self.view.forwardButton]; - [self addLongPressGestureToView:self.view.searchButton]; + [self addLongPressGestureToView:self.view.openNewTabButton]; [self addLongPressGestureToView:self.view.tabGridButton]; [self addLongPressGestureToView:self.view.toolsMenuButton]; @@ -247,8 +247,8 @@ case PopupMenuTypeNavigationBackward: selectedButton = self.view.backButton; break; - case PopupMenuTypeSearch: - selectedButton = self.view.searchButton; + case PopupMenuTypeNewTab: + selectedButton = self.view.openNewTabButton; break; case PopupMenuTypeTabGrid: selectedButton = self.view.tabGridButton; @@ -271,7 +271,7 @@ - (void)updateUIForMenuDismissed { self.view.backButton.spotlighted = NO; self.view.forwardButton.spotlighted = NO; - self.view.searchButton.spotlighted = NO; + self.view.openNewTabButton.spotlighted = NO; self.view.tabGridButton.spotlighted = NO; self.view.toolsMenuButton.spotlighted = NO; @@ -343,7 +343,7 @@ - (void)addStandardActionsForAllButtons { for (ToolbarButton* button in self.view.allButtons) { if (button != self.view.toolsMenuButton && - button != self.view.searchButton) { + button != self.view.openNewTabButton) { [button addTarget:self.dispatcher action:@selector(cancelOmniboxEdit) forControlEvents:UIControlEventTouchUpInside]; @@ -375,7 +375,7 @@ base::RecordAction(base::UserMetricsAction("MobileToolbarShowStackView")); } else if (sender == self.view.shareButton) { base::RecordAction(base::UserMetricsAction("MobileToolbarShareMenu")); - } else if (sender == self.view.searchButton) { + } else if (sender == self.view.openNewTabButton) { base::RecordAction(base::UserMetricsAction("MobileToolbarNewTabShortcut")); } else { NOTREACHED(); @@ -399,8 +399,8 @@ [self.dispatcher showNavigationHistoryBackPopupMenu]; } else if (gesture.view == self.view.forwardButton) { [self.dispatcher showNavigationHistoryForwardPopupMenu]; - } else if (gesture.view == self.view.searchButton) { - [self.dispatcher showSearchButtonPopup]; + } else if (gesture.view == self.view.openNewTabButton) { + [self.dispatcher showNewTabButtonPopup]; } else if (gesture.view == self.view.tabGridButton) { [self.dispatcher showTabGridButtonPopup]; } else if (gesture.view == self.view.toolsMenuButton) {
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h index 1958371d..39e21cc 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h
@@ -51,8 +51,8 @@ - (ToolbarButton*)stopButton; // Bookmark ToolbarButton. - (ToolbarButton*)bookmarkButton; -// ToolbarButton to focus the omnibox. -- (ToolbarButton*)searchButton; +// ToolbarButton to create a new tab. +- (ToolbarButton*)openNewTabButton; // Button to cancel the edit of the location bar. - (UIButton*)cancelButton;
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm index f9327fb..6a92702 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm
@@ -168,28 +168,27 @@ return bookmarkButton; } -// TODO(crbug.com/974751): Rename this as the button is no longer for search. -- (ToolbarButton*)searchButton { +- (ToolbarButton*)openNewTabButton { UIImage* buttonImage = [UIImage imageNamed:@"toolbar_new_tab_page"]; - ToolbarSearchButton* searchButton = + ToolbarSearchButton* newTabButton = [ToolbarSearchButton toolbarButtonWithImage:buttonImage]; - [searchButton addTarget:self.actionHandler + [newTabButton addTarget:self.actionHandler action:@selector(searchAction:) forControlEvents:UIControlEventTouchUpInside]; BOOL isIncognito = self.style == INCOGNITO; - [self configureButton:searchButton width:kAdaptiveToolbarButtonWidth]; + [self configureButton:newTabButton width:kAdaptiveToolbarButtonWidth]; - searchButton.accessibilityLabel = + newTabButton.accessibilityLabel = l10n_util::GetNSString(isIncognito ? IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB : IDS_IOS_TOOLS_MENU_NEW_TAB); - searchButton.accessibilityIdentifier = kToolbarSearchButtonIdentifier; + newTabButton.accessibilityIdentifier = kToolbarNewTabButtonIdentifier; - searchButton.visibilityMask = + newTabButton.visibilityMask = self.visibilityConfiguration.searchButtonVisibility; - return searchButton; + return newTabButton; } - (UIButton*)cancelButton {
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm index 3f9c6426..5dee3c6 100644 --- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm
@@ -432,7 +432,8 @@ #pragma mark - AdaptiveToolbarView -- (ToolbarButton*)searchButton { +- (ToolbarButton*)openNewTabButton { return nil; } + @end
diff --git a/ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h b/ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h index 631eeb1..de4f4826 100644 --- a/ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h +++ b/ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h
@@ -12,8 +12,6 @@ // Give focus to the omnibox, if it is visible. No-op if it is not visible. If // current page is an NTP, first focus the NTP fakebox. - (void)focusOmnibox; -// Set next focus source as SEARCH_BUTTON and then call -focusOmnibox. -- (void)focusOmniboxFromSearchButton; // Focus the omnibox but skip the NTP check. - (void)focusOmniboxFromFakebox; // Cancel omnibox edit (from shield tap or cancel button tap).
diff --git a/ios/chrome/browser/ui/toolbar/public/toolbar_constants.h b/ios/chrome/browser/ui/toolbar/public/toolbar_constants.h index c62f059b..ca70302d 100644 --- a/ios/chrome/browser/ui/toolbar/public/toolbar_constants.h +++ b/ios/chrome/browser/ui/toolbar/public/toolbar_constants.h
@@ -88,8 +88,8 @@ extern NSString* const kToolbarStackButtonIdentifier; // Accessibility identifier of the share button. extern NSString* const kToolbarShareButtonIdentifier; -// Accessibility identifier of the omnibox button. -extern NSString* const kToolbarSearchButtonIdentifier; +// Accessibility identifier of the NewTab button. +extern NSString* const kToolbarNewTabButtonIdentifier; // Accessibility identifier of the cancel omnibox edit button. extern NSString* const kToolbarCancelOmniboxEditButtonIdentifier;
diff --git a/ios/chrome/browser/ui/toolbar/public/toolbar_constants.mm b/ios/chrome/browser/ui/toolbar/public/toolbar_constants.mm index 0bb3bcd..d83187a 100644 --- a/ios/chrome/browser/ui/toolbar/public/toolbar_constants.mm +++ b/ios/chrome/browser/ui/toolbar/public/toolbar_constants.mm
@@ -60,8 +60,8 @@ @"kToolbarStackButtonIdentifier"; NSString* const kToolbarShareButtonIdentifier = @"kToolbarShareButtonIdentifier"; -NSString* const kToolbarSearchButtonIdentifier = - @"kToolbarSearchButtonIdentifier"; +NSString* const kToolbarNewTabButtonIdentifier = + @"kToolbarNewTabButtonIdentifier"; NSString* const kToolbarCancelOmniboxEditButtonIdentifier = @"kToolbarCancelOmniboxEditButtonIdentifier";
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm index 6e25db01..47736553 100644 --- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm
@@ -47,8 +47,8 @@ @property(nonatomic, strong, readwrite) ToolbarToolsMenuButton* toolsMenuButton; // Button to display the tab grid, redefined as readwrite. @property(nonatomic, strong, readwrite) ToolbarTabGridButton* tabGridButton; -// Button to focus the omnibox, redefined as readwrite. -@property(nonatomic, strong, readwrite) ToolbarButton* searchButton; +// Button to create a new tab, redefined as readwrite. +@property(nonatomic, strong, readwrite) ToolbarButton* openNewTabButton; @end @@ -60,7 +60,7 @@ @synthesize backButton = _backButton; @synthesize forwardButton = _forwardButton; @synthesize toolsMenuButton = _toolsMenuButton; -@synthesize searchButton = _searchButton; +@synthesize openNewTabButton = _openNewTabButton; @synthesize tabGridButton = _tabGridButton; #pragma mark - Public @@ -111,7 +111,7 @@ self.backButton = [self.buttonFactory backButton]; self.forwardButton = [self.buttonFactory forwardButton]; - self.searchButton = [self.buttonFactory searchButton]; + self.openNewTabButton = [self.buttonFactory openNewTabButton]; self.tabGridButton = [self.buttonFactory tabGridButton]; self.toolsMenuButton = [self.buttonFactory toolsMenuButton]; @@ -122,8 +122,8 @@ CGAffineTransformMakeTranslation(textDirection * kToolsMenuOffset, 0); self.allButtons = @[ - self.backButton, self.forwardButton, self.searchButton, self.tabGridButton, - self.toolsMenuButton + self.backButton, self.forwardButton, self.openNewTabButton, + self.tabGridButton, self.toolsMenuButton ]; self.separator = [[UIView alloc] init];
diff --git a/ios/chrome/browser/ui/util/layout_guide_names.h b/ios/chrome/browser/ui/util/layout_guide_names.h index d3422d5..69c8527 100644 --- a/ios/chrome/browser/ui/util/layout_guide_names.h +++ b/ios/chrome/browser/ui/util/layout_guide_names.h
@@ -39,8 +39,8 @@ extern GuideName* const kBackButtonGuide; // A guide that is constrained to match the frame of the forward button's image. extern GuideName* const kForwardButtonGuide; -// A guide that is constrained to match the frame of the Search button. -extern GuideName* const kSearchButtonGuide; +// A guide that is constrained to match the frame of the NewTab button. +extern GuideName* const kNewTabButtonGuide; // A guide that is constrained to match the frame of the TabSwitcher button's // image. extern GuideName* const kTabSwitcherGuide;
diff --git a/ios/chrome/browser/ui/util/layout_guide_names.mm b/ios/chrome/browser/ui/util/layout_guide_names.mm index 0a7bb75..a7a2b70e 100644 --- a/ios/chrome/browser/ui/util/layout_guide_names.mm +++ b/ios/chrome/browser/ui/util/layout_guide_names.mm
@@ -19,7 +19,7 @@ GuideName* const kOmniboxTextFieldGuide = @"kOmniboxTextFieldGuide"; GuideName* const kBackButtonGuide = @"kBackButtonGuide"; GuideName* const kForwardButtonGuide = @"kForwardButtonGuide"; -GuideName* const kSearchButtonGuide = @"kSearchButtonGuide"; +GuideName* const kNewTabButtonGuide = @"kNewTabButtonGuide"; GuideName* const kTabSwitcherGuide = @"kTabSwitcherGuide"; GuideName* const kTabStripTabSwitcherGuide = @"kTabStripTabSwitcherGuide"; GuideName* const kToolsMenuGuide = @"kToolsMenuGuide";
diff --git a/ios/third_party/material_components_ios/BUILD.gn b/ios/third_party/material_components_ios/BUILD.gn index a94b3d0..1c247fb 100644 --- a/ios/third_party/material_components_ios/BUILD.gn +++ b/ios/third_party/material_components_ios/BUILD.gn
@@ -126,6 +126,7 @@ "src/components/Chips/src/MDCChipCollectionViewCell.h", "src/components/Chips/src/MDCChipCollectionViewFlowLayout.h", "src/components/Chips/src/MDCChipField.h", + "src/components/Chips/src/MDCChipFieldDelegate.h", "src/components/Chips/src/MDCChipView.h", "src/components/Chips/src/MaterialChips.h", "src/components/Chips/src/Theming/MDCChipView+MaterialTheming.h", @@ -254,7 +255,6 @@ "src/components/ProgressView/src/MaterialProgressView.h", "src/components/ProgressView/src/Theming/MDCProgressView+MaterialTheming.h", "src/components/ProgressView/src/Theming/MaterialProgressView+Theming.h", - "src/components/ProgressView/src/private/MDCProgressViewMotionSpec.h", "src/components/Ripple/src/MDCRippleTouchController.h", "src/components/Ripple/src/MDCRippleView.h", "src/components/Ripple/src/MDCStatefulRippleView.h", @@ -577,7 +577,6 @@ "src/components/Palettes/src/private", "src/components/ProgressView/src", "src/components/ProgressView/src/Theming", - "src/components/ProgressView/src/private", "src/components/Ripple/src", "src/components/Ripple/src/private", "src/components/ShadowElevations/src", @@ -835,6 +834,7 @@ "src/components/Chips/src/MDCChipCollectionViewFlowLayout.m", "src/components/Chips/src/MDCChipField.h", "src/components/Chips/src/MDCChipField.m", + "src/components/Chips/src/MDCChipFieldDelegate.h", "src/components/Chips/src/MDCChipView.h", "src/components/Chips/src/MDCChipView.m", "src/components/Chips/src/MaterialChips.h", @@ -1034,8 +1034,6 @@ "src/components/ProgressView/src/Theming/MDCProgressView+MaterialTheming.h", "src/components/ProgressView/src/Theming/MDCProgressView+MaterialTheming.m", "src/components/ProgressView/src/Theming/MaterialProgressView+Theming.h", - "src/components/ProgressView/src/private/MDCProgressViewMotionSpec.h", - "src/components/ProgressView/src/private/MDCProgressViewMotionSpec.m", "src/components/Ripple/src/MDCRippleTouchController.h", "src/components/Ripple/src/MDCRippleTouchController.m", "src/components/Ripple/src/MDCRippleView.h",
diff --git a/ios/web/web_state/web_state_observer_inttest.mm b/ios/web/web_state/web_state_observer_inttest.mm index 2378404..bc9ed3a 100644 --- a/ios/web/web_state/web_state_observer_inttest.mm +++ b/ios/web/web_state/web_state_observer_inttest.mm
@@ -17,7 +17,6 @@ #import "base/test/ios/wait_util.h" #include "ios/testing/embedded_test_server_handlers.h" #include "ios/web/common/features.h" -#include "ios/web/navigation/web_kit_constants.h" #include "ios/web/navigation/wk_navigation_util.h" #import "ios/web/public/navigation/navigation_context.h" #import "ios/web/public/navigation/navigation_item.h" @@ -1070,7 +1069,7 @@ EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _)) .WillOnce(VerifyErrorFinishedContext( web_state(), GURL(webkit_rewritten_url_spec), &context, &nav_id, - /*committed=*/false, kWebKitErrorCannotShowUrl)); + /*committed=*/false, net::ERR_FAILED)); EXPECT_CALL(observer_, PageLoaded(web_state(), PageLoadCompletionStatus::FAILURE));
diff --git a/ios/web_view/internal/autofill/cwv_autofill_data_manager_unittest.mm b/ios/web_view/internal/autofill/cwv_autofill_data_manager_unittest.mm index b793b46..571b1eb 100644 --- a/ios/web_view/internal/autofill/cwv_autofill_data_manager_unittest.mm +++ b/ios/web_view/internal/autofill/cwv_autofill_data_manager_unittest.mm
@@ -247,7 +247,8 @@ password_store_->AddLogin(test_password); NSArray<CWVPassword*>* fetched_passwords = FetchPasswords(); EXPECT_EQ(1ul, fetched_passwords.count); - EXPECT_EQ(test_password, *[fetched_passwords[0] internalPasswordForm]); + EXPECT_THAT(test_password, password_manager::MatchesFormExceptStore( + *[fetched_passwords[0] internalPasswordForm])); } // Tests CWVAutofillDataManager properly deletes passwords.
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni index b7dbd7a31..98c78e5 100644 --- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni +++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -30,7 +30,6 @@ "//mojo/public/cpp/bindings/tests/chromium_typemaps.gni", "//sandbox/mac/mojom/typemaps.gni", "//services/media_session/public/cpp/typemaps.gni", - "//services/network/public/cpp/typemaps.gni", "//services/proxy_resolver/public/cpp/typemaps.gni", "//services/resource_coordinator/public/cpp/typemaps.gni", "//services/service_manager/public/cpp/typemaps.gni",
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index c25dded..e11992b 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -93,6 +93,7 @@ DeleteCallback delete_callback, const ResourceRequest& resource_request, bool ignore_isolated_world_origin, + bool skip_cors_enabled_scheme_check, mojo::PendingRemote<mojom::URLLoaderClient> client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, mojom::URLLoaderFactory* network_loader_factory, @@ -111,7 +112,8 @@ traffic_annotation_(traffic_annotation), origin_access_list_(origin_access_list), factory_bound_origin_access_list_(factory_bound_origin_access_list), - preflight_controller_(preflight_controller) { + preflight_controller_(preflight_controller), + skip_cors_enabled_scheme_check_(skip_cors_enabled_scheme_check) { if (ignore_isolated_world_origin) request_.isolated_world_origin = base::nullopt; @@ -422,7 +424,7 @@ } void CorsURLLoader::StartRequest() { - if (fetch_cors_flag_ && + if (fetch_cors_flag_ && !skip_cors_enabled_scheme_check_ && !base::Contains(url::GetCorsEnabledSchemes(), request_.url.scheme())) { HandleComplete(URLLoaderCompletionStatus( CorsErrorStatus(mojom::CorsError::kCorsDisabledScheme)));
diff --git a/services/network/cors/cors_url_loader.h b/services/network/cors/cors_url_loader.h index 3f47a81..daa86393 100644 --- a/services/network/cors/cors_url_loader.h +++ b/services/network/cors/cors_url_loader.h
@@ -46,6 +46,7 @@ DeleteCallback delete_callback, const ResourceRequest& resource_request, bool ignore_isolated_world_origin, + bool skip_cors_enabled_scheme_check, mojo::PendingRemote<mojom::URLLoaderClient> client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, mojom::URLLoaderFactory* network_loader_factory, @@ -181,6 +182,9 @@ const OriginAccessList* const factory_bound_origin_access_list_; PreflightController* preflight_controller_; + // Flag to specify if the CORS-enabled scheme check should be applied. + const bool skip_cors_enabled_scheme_check_; + // Used to run asynchronous class instance bound callbacks safely. base::WeakPtrFactory<CorsURLLoader> weak_factory_{this};
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 631ddc9b..a453272 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -81,16 +81,23 @@ std::unique_ptr<URLLoaderFactory> network_loader_factory) : network_loader_factory_(std::move(network_loader_factory), std::move(params->overridden_factory_receiver)), - overriding_factory_(std::move(params->overriding_factory)) {} + overriding_factory_(std::move(params->overriding_factory)), + skip_cors_enabled_scheme_check_( + params->skip_cors_enabled_scheme_check) {} FactoryOverride(const FactoryOverride&) = delete; FactoryOverride& operator=(const FactoryOverride&) = delete; mojom::URLLoaderFactory* get() { return overriding_factory_.get(); } + bool ShouldSkipCorsEnabledSchemeCheck() { + return skip_cors_enabled_scheme_check_; + } + private: ExposedNetworkLoaderFactory network_loader_factory_; mojo::Remote<mojom::URLLoaderFactory> overriding_factory_; + bool skip_cors_enabled_scheme_check_; }; bool CorsURLLoaderFactory::allow_external_preflights_for_testing_ = false; @@ -182,9 +189,11 @@ std::move(receiver), process_id_, routing_id, request_id, options, base::BindOnce(&CorsURLLoaderFactory::DestroyURLLoader, base::Unretained(this)), - resource_request, ignore_isolated_world_origin_, std::move(client), - traffic_annotation, inner_url_loader_factory, origin_access_list_, - factory_bound_origin_access_list_.get(), + resource_request, ignore_isolated_world_origin_, + factory_override_ && + factory_override_->ShouldSkipCorsEnabledSchemeCheck(), + std::move(client), traffic_annotation, inner_url_loader_factory, + origin_access_list_, factory_bound_origin_access_list_.get(), context_->cors_preflight_controller()); auto* raw_loader = loader.get(); OnLoaderCreated(std::move(loader));
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc index a365dbfa..d1865a2 100644 --- a/services/network/cors/cors_url_loader_unittest.cc +++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -328,7 +328,8 @@ void ResetFactory(base::Optional<url::Origin> initiator, uint32_t process_id, bool is_trusted, - bool ignore_isolated_world_origin) { + bool ignore_isolated_world_origin, + bool skip_cors_enabled_scheme_check) { test_url_loader_factory_ = std::make_unique<TestURLLoaderFactory>(); test_url_loader_factory_receiver_ = std::make_unique<mojo::Receiver<mojom::URLLoaderFactory>>( @@ -337,12 +338,15 @@ auto factory_params = network::mojom::URLLoaderFactoryParams::New(); if (initiator) { factory_params->request_initiator_site_lock = *initiator; - factory_params->factory_bound_access_patterns = - network::mojom::CorsOriginAccessPatterns::New(); - factory_params->factory_bound_access_patterns->source_origin = *initiator; - for (const auto& item : factory_bound_allow_patterns_) { - factory_params->factory_bound_access_patterns->allow_patterns.push_back( - item.Clone()); + if (!initiator->opaque()) { + factory_params->factory_bound_access_patterns = + network::mojom::CorsOriginAccessPatterns::New(); + factory_params->factory_bound_access_patterns->source_origin = + *initiator; + for (const auto& item : factory_bound_allow_patterns_) { + factory_params->factory_bound_access_patterns->allow_patterns + .push_back(item.Clone()); + } } } factory_params->is_trusted = is_trusted; @@ -352,6 +356,8 @@ factory_params->factory_override = mojom::URLLoaderFactoryOverride::New(); factory_params->factory_override->overriding_factory = test_url_loader_factory_receiver_->BindNewPipeAndPassRemote(); + factory_params->factory_override->skip_cors_enabled_scheme_check = + skip_cors_enabled_scheme_check; auto resource_scheduler_client = base::MakeRefCounted<ResourceSchedulerClient>( process_id, ++last_issued_route_id, &resource_scheduler_, @@ -368,7 +374,8 @@ uint32_t process_id) { auto params = network::mojom::URLLoaderFactoryParams::New(); ResetFactory(initiator, process_id, params->is_trusted, - params->ignore_isolated_world_origin); + params->ignore_isolated_world_origin, + false /* skip_cors_enabled_scheme_check */); } NetworkContext* network_context() { return network_context_.get(); } @@ -692,6 +699,57 @@ client().completion_status().cors_error_status->cors_error); } +TEST_F(CorsURLLoaderTest, CorsEnabledSameCustomSchemeRequest) { + // Custom scheme should not be permitted by default. + const GURL origin("my-scheme://foo/index.html"); + const GURL url("my-scheme://bar/baz.png"); + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); + RunUntilComplete(); + + EXPECT_FALSE(IsNetworkLoaderStarted()); + EXPECT_FALSE(client().has_received_redirect()); + EXPECT_FALSE(client().has_received_response()); + EXPECT_EQ(net::ERR_FAILED, client().completion_status().error_code); + ASSERT_TRUE(client().completion_status().cors_error_status); + EXPECT_EQ(mojom::CorsError::kCorsDisabledScheme, + client().completion_status().cors_error_status->cors_error); + + // Scheme check can be skipped via the factory params. + auto params = network::mojom::URLLoaderFactoryParams::New(); + ResetFactory(url::Origin::Create(origin), mojom::kBrowserProcessId, + params->is_trusted, params->ignore_isolated_world_origin, + true /* skip_cors_enabled_scheme_check */); + + // "Access-Control-Allow-Origin: *" accepts the custom scheme. + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); + RunUntilCreateLoaderAndStartCalled(); + + NotifyLoaderClientOnReceiveResponse({"Access-Control-Allow-Origin: *"}); + NotifyLoaderClientOnComplete(net::OK); + + RunUntilComplete(); + + EXPECT_TRUE(IsNetworkLoaderStarted()); + EXPECT_FALSE(client().has_received_redirect()); + EXPECT_TRUE(client().has_received_response()); + EXPECT_EQ(net::OK, client().completion_status().error_code); + + // "Access-Control-Allow-Origin: null" accepts the custom scheme as a custom + // scheme is an opaque origin. + CreateLoaderAndStart(origin, url, mojom::RequestMode::kCors); + RunUntilCreateLoaderAndStartCalled(); + + NotifyLoaderClientOnReceiveResponse({"Access-Control-Allow-Origin: null"}); + NotifyLoaderClientOnComplete(net::OK); + + RunUntilComplete(); + + EXPECT_TRUE(IsNetworkLoaderStarted()); + EXPECT_FALSE(client().has_received_redirect()); + EXPECT_TRUE(client().has_received_response()); + EXPECT_EQ(net::OK, client().completion_status().error_code); +} + TEST_F(CorsURLLoaderTest, StripUsernameAndPassword) { const GURL origin("http://example.com"); const GURL url("http://foo:bar@other.com/foo.png"); @@ -1280,7 +1338,8 @@ const GURL url("http://other.com/foo.png"); ResetFactory(main_world_origin, kRendererProcessId, false /* trusted */, - false /* ignore_isolated_world_origin */); + false /* ignore_isolated_world_origin */, + false /* skip_cors_enabled_scheme_check */); AddAllowListEntryForOrigin(isolated_world_origin, url.scheme(), url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); @@ -1323,7 +1382,8 @@ const GURL new_url("http://other.com/bar.png"); ResetFactory(main_world_origin, kRendererProcessId, false /* trusted */, - false /* ignore_isolated_world_origin */); + false /* ignore_isolated_world_origin */, + false /* skip_cors_enabled_scheme_check */); AddAllowListEntryForOrigin(isolated_world_origin, url.scheme(), url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); @@ -1376,7 +1436,8 @@ const GURL url("http://other.com/foo.png"); ResetFactory(main_world_origin, kRendererProcessId, false /* trusted */, - true /* ignore_isolated_world_origin */); + true /* ignore_isolated_world_origin */, + false /* skip_cors_enabled_scheme_check */); AddAllowListEntryForOrigin(isolated_world_origin, url.scheme(), url.host(), mojom::CorsDomainMatchMode::kDisallowSubdomains); @@ -2013,7 +2074,8 @@ for (bool is_trusted : {false, true}) { bool ignore_isolated_world_origin = true; // This is the default. ResetFactory(base::nullopt, kRendererProcessId, is_trusted, - ignore_isolated_world_origin); + ignore_isolated_world_origin, + false /* skip_cors_enabled_scheme_check */); BadMessageTestHelper bad_message_helper; @@ -2060,7 +2122,8 @@ // NetworkIsolationKey, CorsURLLoaderFactory does not reject the request. TEST_F(CorsURLLoaderTest, RestrictedPrefetchSucceedsWithNIK) { ResetFactory(base::nullopt, kRendererProcessId, true /* is_trusted */, - true /* ignore_isolated_world_origin */); + true /* ignore_isolated_world_origin */, + false /* skip_cors_enabled_scheme_check */); BadMessageTestHelper bad_message_helper; @@ -2100,7 +2163,8 @@ // make use of their TrustedParams' |network_isolation_key|. TEST_F(CorsURLLoaderTest, RestrictedPrefetchFailsWithoutNIK) { ResetFactory(base::nullopt, kRendererProcessId, true /* is_trusted */, - true /* ignore_isolated_world_origin */); + true /* ignore_isolated_world_origin */, + false /* skip_cors_enabled_scheme_check */); BadMessageTestHelper bad_message_helper;
diff --git a/services/network/public/cpp/OWNERS b/services/network/public/cpp/OWNERS index 12614fd..999eb16 100644 --- a/services/network/public/cpp/OWNERS +++ b/services/network/public/cpp/OWNERS
@@ -4,8 +4,6 @@ per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS per-file *_mojom_traits*.*=set noparent per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS -per-file *.typemap=set noparent -per-file *.typemap=file://ipc/SECURITY_OWNERS per-file manifest.cc=set noparent per-file manifest.cc=file://ipc/SECURITY_OWNERS per-file manifest.h=set noparent
diff --git a/services/network/public/cpp/address_family.typemap b/services/network/public/cpp/address_family.typemap deleted file mode 100644 index 3f37ac73..0000000 --- a/services/network/public/cpp/address_family.typemap +++ /dev/null
@@ -1,15 +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. - -mojom = "//services/network/public/mojom/address_family.mojom" -public_headers = [ "//net/base/address_family.h" ] -traits_headers = - [ "/services/network/public/cpp/address_family_mojom_traits.h" ] -sources = [ - "//services/network/public/cpp/address_family_mojom_traits.cc", -] -type_mappings = [ "network.mojom.AddressFamily=::net::AddressFamily" ] -public_deps = [ - "//net", -]
diff --git a/services/network/public/cpp/address_family_mojom_traits.h b/services/network/public/cpp/address_family_mojom_traits.h index 645e7a4f..568ca5b7 100644 --- a/services/network/public/cpp/address_family_mojom_traits.h +++ b/services/network/public/cpp/address_family_mojom_traits.h
@@ -6,6 +6,7 @@ #define SERVICES_NETWORK_PUBLIC_CPP_ADDRESS_FAMILY_MOJOM_TRAITS_H_ #include "mojo/public/cpp/bindings/enum_traits.h" +#include "net/base/address_family.h" #include "services/network/public/mojom/address_family.mojom.h" namespace mojo {
diff --git a/services/network/public/cpp/address_list.typemap b/services/network/public/cpp/address_list.typemap deleted file mode 100644 index 78c7f3a..0000000 --- a/services/network/public/cpp/address_list.typemap +++ /dev/null
@@ -1,9 +0,0 @@ -# Copyright 2018 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. - -mojom = "//services/network/public/mojom/address_list.mojom" -public_headers = [ "//net/base/address_list.h" ] -traits_headers = [ "//services/network/public/cpp/address_list_mojom_traits.h" ] -type_mappings = [ "network.mojom.AddressList=::net::AddressList" ] -public_deps = [ "//net" ]
diff --git a/services/network/public/cpp/cookie_manager.typemap b/services/network/public/cpp/cookie_manager.typemap deleted file mode 100644 index 2e43fdf..0000000 --- a/services/network/public/cpp/cookie_manager.typemap +++ /dev/null
@@ -1,31 +0,0 @@ -mojom = "//services/network/public/mojom/cookie_manager.mojom" -public_headers = [ - "//ipc/ipc_message_utils.h", - "//net/cookies/cookie_options.h", - "//net/cookies/canonical_cookie.h", - "//net/cookies/cookie_change_dispatcher.h", - "//net/cookies/cookie_constants.h", -] -traits_headers = - [ "//services/network/public/cpp/cookie_manager_mojom_traits.h" ] -sources = [ - "//services/network/public/cpp/cookie_manager_mojom_traits.cc", -] -public_deps = [ - "//net", -] -type_mappings = [ - "network.mojom.CookiePriority=::net::CookiePriority", - "network.mojom.CookieSameSite=::net::CookieSameSite", - "network.mojom.CookieSameSiteContext=::net::CookieOptions::SameSiteCookieContext", - "network.mojom.CookieAccessSemantics=::net::CookieAccessSemantics", - "network.mojom.CookieOptions=::net::CookieOptions", - "network.mojom.CanonicalCookie=::net::CanonicalCookie", - "network.mojom.CookieInclusionStatusWarningReason=::net::CanonicalCookie::CookieInclusionStatus::WarningReason", - "network.mojom.CookieInclusionStatus=::net::CanonicalCookie::CookieInclusionStatus[move_only]", - "network.mojom.CookieWithStatus=::net::CookieWithStatus", - "network.mojom.CookieAndLineWithStatus=::net::CookieAndLineWithStatus", - "network.mojom.CookieChangeCause=::net::CookieChangeCause", - "network.mojom.CookieChangeInfo=::net::CookieChangeInfo", - "network.mojom.CookieSourceScheme=::net::CookieSourceScheme", -]
diff --git a/services/network/public/cpp/cors_error_status.typemap b/services/network/public/cpp/cors_error_status.typemap deleted file mode 100644 index 8e07b29..0000000 --- a/services/network/public/cpp/cors_error_status.typemap +++ /dev/null
@@ -1,14 +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. - -mojom = "//services/network/public/mojom/url_loader.mojom" -public_headers = [ "//services/network/public/cpp/cors/cors_error_status.h" ] -traits_headers = [ "//services/network/public/cpp/network_ipc_param_traits.h" ] -deps = [ - "//net", -] -public_deps = [ - "//services/network/public/cpp:cpp_base", -] -type_mappings = [ "network.mojom.CorsErrorStatus=::network::CorsErrorStatus" ]
diff --git a/services/network/public/cpp/cross_origin_embedder_policy.typemap b/services/network/public/cpp/cross_origin_embedder_policy.typemap deleted file mode 100644 index 986f520e..0000000 --- a/services/network/public/cpp/cross_origin_embedder_policy.typemap +++ /dev/null
@@ -1,14 +0,0 @@ -# Copyright 2020 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. - -mojom = "//services/network/public/mojom/cross_origin_embedder_policy.mojom" -public_headers = - [ "//services/network/public/cpp/cross_origin_embedder_policy.h" ] -traits_headers = [ - "//services/network/public/cpp/cross_origin_embedder_policy_mojom_traits.h", -] -sources = [] -type_mappings = [ - "network.mojom.CrossOriginEmbedderPolicy=network::CrossOriginEmbedderPolicy", -]
diff --git a/services/network/public/cpp/default_credentials.typemap b/services/network/public/cpp/default_credentials.typemap deleted file mode 100644 index 09530f0..0000000 --- a/services/network/public/cpp/default_credentials.typemap +++ /dev/null
@@ -1,17 +0,0 @@ -mojom = "//services/network/public/mojom/default_credentials.mojom" -public_headers = [ - "//ipc/ipc_message_utils.h", - "//net/http/http_auth_preferences.h", -] -traits_headers = [ - "//services/network/public/cpp/default_credentials_mojom_traits.h", -] -sources = [ - "//services/network/public/cpp/default_credentials_mojom_traits.cc", -] -public_deps = [ - "//net", -] -type_mappings = [ - "network.mojom.DefaultCredentials=net::HttpAuthPreferences::DefaultCredentials", -]
diff --git a/services/network/public/cpp/digitally_signed.typemap b/services/network/public/cpp/digitally_signed.typemap deleted file mode 100644 index a2c3781b..0000000 --- a/services/network/public/cpp/digitally_signed.typemap +++ /dev/null
@@ -1,19 +0,0 @@ -# Copyright 2018 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. - -mojom = "//services/network/public/mojom/digitally_signed.mojom" -public_headers = [ "//net/cert/signed_certificate_timestamp.h" ] -traits_headers = - [ "//services/network/public/cpp/digitally_signed_mojom_traits.h" ] -sources = [ - "//services/network/public/cpp/digitally_signed_mojom_traits.cc", -] -type_mappings = [ - "network.mojom.HashAlgorithm=::net::ct::DigitallySigned::HashAlgorithm", - "network.mojom.SignatureAlgorithm=::net::ct::DigitallySigned::SignatureAlgorithm", - "network.mojom.DigitallySigned=::net::ct::DigitallySigned", -] -public_deps = [ - "//net", -]
diff --git a/services/network/public/cpp/host_resolver.typemap b/services/network/public/cpp/host_resolver.typemap deleted file mode 100644 index e081e71..0000000 --- a/services/network/public/cpp/host_resolver.typemap +++ /dev/null
@@ -1,29 +0,0 @@ -# Copyright 2018 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. - -mojom = "//services/network/public/mojom/host_resolver.mojom" -public_headers = [ - "//net/dns/dns_config.h", - "//net/dns/dns_config_overrides.h", - "//net/dns/host_resolver.h", - "//net/dns/host_resolver_source.h", - "//net/dns/public/resolve_error_info.h", - "//net/dns/public/dns_query_type.h", -] -traits_headers = - [ "//services/network/public/cpp/host_resolver_mojom_traits.h" ] -sources = [ - "//services/network/public/cpp/host_resolver_mojom_traits.cc", -] -public_deps = [ - "//net", -] -type_mappings = [ - "network.mojom.DnsConfigOverrides=::net::DnsConfigOverrides", - "network.mojom.DnsQueryType=::net::DnsQueryType", - "network.mojom.ResolveErrorInfo=::net::ResolveErrorInfo", - "network.mojom.ResolveHostParameters.Source=::net::HostResolverSource", - "network.mojom.MdnsListenClient.UpdateType=::net::HostResolver::MdnsListener::Delegate::UpdateType", - "network.mojom.SecureDnsMode=::net::DnsConfig::SecureDnsMode", -]
diff --git a/services/network/public/cpp/host_resolver_mojom_traits.cc b/services/network/public/cpp/host_resolver_mojom_traits.cc index 1dfb0baaa..307dd56 100644 --- a/services/network/public/cpp/host_resolver_mojom_traits.cc +++ b/services/network/public/cpp/host_resolver_mojom_traits.cc
@@ -7,6 +7,7 @@ #include "mojo/public/cpp/base/time_mojom_traits.h" #include "services/network/public/cpp/ip_address_mojom_traits.h" #include "services/network/public/cpp/ip_endpoint_mojom_traits.h" +#include "services/network/public/mojom/host_resolver.mojom.h" namespace mojo {
diff --git a/services/network/public/cpp/host_resolver_mojom_traits.h b/services/network/public/cpp/host_resolver_mojom_traits.h index 084ca52..cae8e0e 100644 --- a/services/network/public/cpp/host_resolver_mojom_traits.h +++ b/services/network/public/cpp/host_resolver_mojom_traits.h
@@ -13,6 +13,7 @@ #include "base/time/time.h" #include "mojo/public/cpp/bindings/array_traits.h" #include "mojo/public/cpp/bindings/enum_traits.h" +#include "mojo/public/cpp/bindings/struct_ptr.h" #include "mojo/public/cpp/bindings/struct_traits.h" #include "net/base/address_family.h" #include "net/base/ip_address.h" @@ -22,7 +23,8 @@ #include "net/dns/dns_hosts.h" #include "net/dns/host_resolver.h" #include "net/dns/public/dns_query_type.h" -#include "services/network/public/mojom/host_resolver.mojom.h" +#include "services/network/public/mojom/host_resolver.mojom-forward.h" +#include "services/network/public/mojom/host_resolver.mojom-shared.h" namespace mojo { @@ -47,9 +49,9 @@ static base::Optional<std::vector<network::mojom::DnsHostPtr>> hosts( const net::DnsConfigOverrides& overrides); - static network::mojom::DnsConfigOverrides::Tristate - append_to_multi_label_name(const net::DnsConfigOverrides& overrides); - static network::mojom::DnsConfigOverrides::Tristate randomize_ports( + static network::mojom::DnsConfigOverrides_Tristate append_to_multi_label_name( + const net::DnsConfigOverrides& overrides); + static network::mojom::DnsConfigOverrides_Tristate randomize_ports( const net::DnsConfigOverrides& overrides); static int ndots(const net::DnsConfigOverrides& overrides) { @@ -65,9 +67,9 @@ return overrides.attempts.value_or(-1); } - static network::mojom::DnsConfigOverrides::Tristate rotate( + static network::mojom::DnsConfigOverrides_Tristate rotate( const net::DnsConfigOverrides& overrides); - static network::mojom::DnsConfigOverrides::Tristate use_local_ipv6( + static network::mojom::DnsConfigOverrides_Tristate use_local_ipv6( const net::DnsConfigOverrides& overrides); static base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> @@ -76,7 +78,7 @@ static network::mojom::OptionalSecureDnsMode secure_dns_mode( const net::DnsConfigOverrides& overrides); - static network::mojom::DnsConfigOverrides::Tristate + static network::mojom::DnsConfigOverrides_Tristate allow_dns_over_https_upgrade(const net::DnsConfigOverrides& overrides); static const base::Optional<std::vector<std::string>>& @@ -96,21 +98,21 @@ }; template <> -struct EnumTraits<network::mojom::ResolveHostParameters::Source, +struct EnumTraits<network::mojom::ResolveHostParameters_Source, net::HostResolverSource> { - static network::mojom::ResolveHostParameters::Source ToMojom( + static network::mojom::ResolveHostParameters_Source ToMojom( net::HostResolverSource input); - static bool FromMojom(network::mojom::ResolveHostParameters::Source input, + static bool FromMojom(network::mojom::ResolveHostParameters_Source input, net::HostResolverSource* output); }; template <> -struct EnumTraits<network::mojom::MdnsListenClient::UpdateType, +struct EnumTraits<network::mojom::MdnsListenClient_UpdateType, net::HostResolver::MdnsListener::Delegate::UpdateType> { - static network::mojom::MdnsListenClient::UpdateType ToMojom( + static network::mojom::MdnsListenClient_UpdateType ToMojom( net::HostResolver::MdnsListener::Delegate::UpdateType input); static bool FromMojom( - network::mojom::MdnsListenClient::UpdateType input, + network::mojom::MdnsListenClient_UpdateType input, net::HostResolver::MdnsListener::Delegate::UpdateType* output); };
diff --git a/services/network/public/cpp/host_resolver_mojom_traits_unittest.cc b/services/network/public/cpp/host_resolver_mojom_traits_unittest.cc index dbd9cab..ee172ed 100644 --- a/services/network/public/cpp/host_resolver_mojom_traits_unittest.cc +++ b/services/network/public/cpp/host_resolver_mojom_traits_unittest.cc
@@ -9,6 +9,7 @@ #include "net/base/net_errors.h" #include "services/network/public/cpp/ip_address_mojom_traits.h" #include "services/network/public/cpp/ip_endpoint_mojom_traits.h" +#include "services/network/public/mojom/host_resolver.mojom.h" #include "testing/gtest/include/gtest/gtest.h" namespace network {
diff --git a/services/network/public/cpp/http_request_headers.typemap b/services/network/public/cpp/http_request_headers.typemap deleted file mode 100644 index ad4a917..0000000 --- a/services/network/public/cpp/http_request_headers.typemap +++ /dev/null
@@ -1,13 +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. - -mojom = "//services/network/public/mojom/http_request_headers.mojom" -public_headers = [ "//net/http/http_request_headers.h" ] -traits_headers = - [ "//services/network/public/cpp/http_request_headers_mojom_traits.h" ] -public_deps = [ - "//net", - "//services/network/public/cpp:cpp_base", -] -type_mappings = [ "network.mojom.HttpRequestHeaders=::net::HttpRequestHeaders" ]
diff --git a/services/network/public/cpp/ip_address.typemap b/services/network/public/cpp/ip_address.typemap deleted file mode 100644 index 4adb33590..0000000 --- a/services/network/public/cpp/ip_address.typemap +++ /dev/null
@@ -1,9 +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. - -mojom = "//services/network/public/mojom/ip_address.mojom" -public_headers = [ "//net/base/ip_address.h" ] -traits_headers = [ "//services/network/public/cpp/ip_address_mojom_traits.h" ] -type_mappings = [ "network.mojom.IPAddress=::net::IPAddress" ] -public_deps = [ "//net" ]
diff --git a/services/network/public/cpp/ip_endpoint.typemap b/services/network/public/cpp/ip_endpoint.typemap deleted file mode 100644 index 204e6b7..0000000 --- a/services/network/public/cpp/ip_endpoint.typemap +++ /dev/null
@@ -1,9 +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. - -mojom = "//services/network/public/mojom/ip_endpoint.mojom" -public_headers = [ "//net/base/ip_endpoint.h" ] -traits_headers = [ "//services/network/public/cpp/ip_endpoint_mojom_traits.h" ] -type_mappings = [ "network.mojom.IPEndPoint=::net::IPEndPoint" ] -public_deps = [ "//net" ]
diff --git a/services/network/public/cpp/load_timing_info.typemap b/services/network/public/cpp/load_timing_info.typemap deleted file mode 100644 index c2636ee..0000000 --- a/services/network/public/cpp/load_timing_info.typemap +++ /dev/null
@@ -1,15 +0,0 @@ -# Copyright 2018 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. - -mojom = "//services/network/public/mojom/load_timing_info.mojom" -public_headers = [ "//net/base/load_timing_info.h" ] -traits_headers = - [ "//services/network/public/cpp/load_timing_info_mojom_traits.h" ] -sources = [ - "//services/network/public/cpp/load_timing_info_mojom_traits.cc", -] -type_mappings = [ - "network.mojom.LoadTimingInfo=net::LoadTimingInfo", - "network.mojom.LoadTimingInfoConnectTiming=net::LoadTimingInfo::ConnectTiming", -]
diff --git a/services/network/public/cpp/load_timing_info_mojom_traits.h b/services/network/public/cpp/load_timing_info_mojom_traits.h index 87c0f39..c118264 100644 --- a/services/network/public/cpp/load_timing_info_mojom_traits.h +++ b/services/network/public/cpp/load_timing_info_mojom_traits.h
@@ -7,7 +7,7 @@ #include "mojo/public/cpp/bindings/struct_traits.h" #include "net/base/load_timing_info.h" -#include "services/network/public/mojom/load_timing_info.mojom.h" +#include "services/network/public/mojom/load_timing_info.mojom-shared.h" namespace mojo {
diff --git a/services/network/public/cpp/mutable_network_traffic_annotation_tag.typemap b/services/network/public/cpp/mutable_network_traffic_annotation_tag.typemap deleted file mode 100644 index d2d8772..0000000 --- a/services/network/public/cpp/mutable_network_traffic_annotation_tag.typemap +++ /dev/null
@@ -1,13 +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. - -mojom = "//services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom" -public_headers = [ "//net/traffic_annotation/network_traffic_annotation.h" ] -traits_headers = [ "//services/network/public/cpp/" + - "mutable_network_traffic_annotation_tag_mojom_traits.h" ] -deps = [ - "//net/traffic_annotation", -] -type_mappings = [ "network.mojom.MutableNetworkTrafficAnnotationTag=" + - "::net::MutableNetworkTrafficAnnotationTag" ]
diff --git a/services/network/public/cpp/mutable_partial_network_traffic_annotation_tag.typemap b/services/network/public/cpp/mutable_partial_network_traffic_annotation_tag.typemap deleted file mode 100644 index c38c890..0000000 --- a/services/network/public/cpp/mutable_partial_network_traffic_annotation_tag.typemap +++ /dev/null
@@ -1,14 +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. - -mojom = "//services/network/public/mojom/mutable_partial_network_traffic_annotation_tag.mojom" -public_headers = [ "//net/traffic_annotation/network_traffic_annotation.h" ] -traits_headers = - [ "//services/network/public/cpp/" + - "mutable_partial_network_traffic_annotation_tag_mojom_traits.h" ] -deps = [ - "//net/traffic_annotation", -] -type_mappings = [ "network.mojom.MutablePartialNetworkTrafficAnnotationTag=" + - "::net::MutablePartialNetworkTrafficAnnotationTag" ]
diff --git a/services/network/public/cpp/net_log.typemap b/services/network/public/cpp/net_log.typemap deleted file mode 100644 index 6449f57..0000000 --- a/services/network/public/cpp/net_log.typemap +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2019 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. - -mojom = "//services/network/public/mojom/net_log.mojom" -public_headers = [ - "//net/log/net_log_capture_mode.h", - "//net/log/net_log_event_type.h", -] -traits_headers = [ "/services/network/public/cpp/net_log_mojom_traits.h" ] -sources = [ "//services/network/public/cpp/net_log_mojom_traits.cc" ] -type_mappings = [ - "network.mojom.NetLogCaptureMode=::net::NetLogCaptureMode", - "network.mojom.NetLogEventPhase=::net::NetLogEventPhase", -] -public_deps = [ "//net" ]
diff --git a/services/network/public/cpp/net_log_mojom_traits.h b/services/network/public/cpp/net_log_mojom_traits.h index f9e13f2..6ef895a3 100644 --- a/services/network/public/cpp/net_log_mojom_traits.h +++ b/services/network/public/cpp/net_log_mojom_traits.h
@@ -6,7 +6,9 @@ #define SERVICES_NETWORK_PUBLIC_CPP_NET_LOG_MOJOM_TRAITS_H_ #include "mojo/public/cpp/bindings/enum_traits.h" -#include "services/network/public/mojom/net_log.mojom.h" +#include "net/log/net_log_capture_mode.h" +#include "net/log/net_log_event_type.h" +#include "services/network/public/mojom/net_log.mojom-shared.h" namespace mojo {
diff --git a/services/network/public/cpp/network_interface.typemap b/services/network/public/cpp/network_interface.typemap deleted file mode 100644 index 6433cfb..0000000 --- a/services/network/public/cpp/network_interface.typemap +++ /dev/null
@@ -1,10 +0,0 @@ -# Copyright 2018 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. - -mojom = "//services/network/public/mojom/network_interface.mojom" -public_headers = [ "//net/base/network_interfaces.h" ] -traits_headers = - [ "//services/network/public/cpp/network_interface_mojom_traits.h" ] -public_deps = [ "//net" ] -type_mappings = [ "network.mojom.NetworkInterface=::net::NetworkInterface" ]
diff --git a/services/network/public/cpp/network_isolation_key.typemap b/services/network/public/cpp/network_isolation_key.typemap deleted file mode 100644 index a83a435..0000000 --- a/services/network/public/cpp/network_isolation_key.typemap +++ /dev/null
@@ -1,13 +0,0 @@ -# Copyright 2019 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.↵ - -mojom = "//services/network/public/mojom/network_isolation_key.mojom" -public_headers = [ "//net/base/network_isolation_key.h" ] -traits_headers = - [ "//services/network/public/cpp/network_isolation_key_mojom_traits.h" ] -public_deps = [ - "//net", -] -type_mappings = - [ "network.mojom.NetworkIsolationKey=::net::NetworkIsolationKey" ]
diff --git a/services/network/public/cpp/network_param.typemap b/services/network/public/cpp/network_param.typemap deleted file mode 100644 index ca29d0a..0000000 --- a/services/network/public/cpp/network_param.typemap +++ /dev/null
@@ -1,46 +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. - -mojom = "//services/network/public/mojom/network_param.mojom" -public_headers = [ - "//net/base/auth.h", - "//net/base/host_port_pair.h", - "//net/cert/cert_verify_result.h", - "//net/cert/ct_verify_result.h", - "//net/cert/x509_certificate.h", - "//net/http/http_request_headers.h", - "//net/http/http_response_headers.h", - "//net/http/http_version.h", - "//net/ssl/ssl_cert_request_info.h", - "//net/ssl/ssl_info.h", -] -traits_headers = [ - "//services/network/public/cpp/net_ipc_param_traits.h", - "//services/network/public/cpp/network_param_mojom_traits.h", -] - -sources = [ - "//services/network/public/cpp/network_param_mojom_traits.cc", -] - -deps = [ - "//ipc", -] - -public_deps = [ - "//net", - "//services/network/public/cpp:cpp_base", -] -type_mappings = [ - "network.mojom.AuthChallengeInfo=::net::AuthChallengeInfo", - "network.mojom.AuthCredentials=::net::AuthCredentials", - "network.mojom.CertVerifyResult=::net::CertVerifyResult", - "network.mojom.CTVerifyResult=::net::ct::CTVerifyResult", - "network.mojom.HostPortPair=::net::HostPortPair", - "network.mojom.HttpResponseHeaders=::scoped_refptr<::net::HttpResponseHeaders>[nullable_is_same_type]", - "network.mojom.HttpVersion=::net::HttpVersion", - "network.mojom.SSLCertRequestInfo=::scoped_refptr<::net::SSLCertRequestInfo>[nullable_is_same_type]", - "network.mojom.SSLInfo=::net::SSLInfo", - "network.mojom.X509Certificate=::scoped_refptr<::net::X509Certificate>[nullable_is_same_type]", -]
diff --git a/services/network/public/cpp/network_types.typemap b/services/network/public/cpp/network_types.typemap deleted file mode 100644 index 4a03345..0000000 --- a/services/network/public/cpp/network_types.typemap +++ /dev/null
@@ -1,22 +0,0 @@ -# Copyright 2018 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. - -mojom = "//services/network/public/mojom/network_types.mojom" -public_deps = [ - "//net", -] -public_headers = [ - "//net/cert/ct_policy_status.h", - "//net/http/http_response_info.h", - "//net/nqe/effective_connection_type.h", -] -traits_headers = [ "//services/network/public/cpp/network_ipc_param_traits.h" ] -deps = [ - "//services/network/public/cpp:cpp_base", -] -type_mappings = [ - "network.mojom.ConnectionInfo=::net::HttpResponseInfo::ConnectionInfo", - "network.mojom.CTPolicyCompliance=::net::ct::CTPolicyCompliance", - "network.mojom.EffectiveConnectionType=::net::EffectiveConnectionType", -]
diff --git a/services/network/public/cpp/origin_policy.typemap b/services/network/public/cpp/origin_policy.typemap deleted file mode 100644 index 39e545e..0000000 --- a/services/network/public/cpp/origin_policy.typemap +++ /dev/null
@@ -1,11 +0,0 @@ -# Copyright 2019 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. - -mojom = "//services/network/public/mojom/origin_policy_manager.mojom" -public_headers = [ "//services/network/public/cpp/origin_policy.h" ] -traits_headers = [ "//services/network/public/cpp/network_ipc_param_traits.h" ] -deps = [ - "//url/mojom:url_mojom_gurl", -] -type_mappings = [ "network.mojom.OriginPolicy=::network::OriginPolicy" ]
diff --git a/services/network/public/cpp/p2p.typemap b/services/network/public/cpp/p2p.typemap deleted file mode 100644 index 600b50c..0000000 --- a/services/network/public/cpp/p2p.typemap +++ /dev/null
@@ -1,23 +0,0 @@ -# Copyright 2018 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. - -mojom = "//services/network/public/mojom/p2p.mojom" - -public_headers = [ "//services/network/public/cpp/p2p_socket_type.h" ] - -traits_headers = [ "//services/network/public/cpp/p2p_param_traits.h" ] - -public_deps = [ - "//services/network/public/mojom:mutable_network_traffic_annotation_interface", - "//third_party/webrtc_overrides:webrtc_component", -] - -type_mappings = [ - "network.mojom.P2PPacketInfo=::network::P2PPacketInfo", - "network.mojom.P2PSendPacketMetrics=::network::P2PSendPacketMetrics", - "network.mojom.P2PPortRange=::network::P2PPortRange", - "network.mojom.P2PHostAndIPEndPoint=::network::P2PHostAndIPEndPoint", - "network.mojom.P2PSocketOption=::network::P2PSocketOption", - "network.mojom.P2PSocketType=::network::P2PSocketType", -]
diff --git a/services/network/public/cpp/p2p_param_traits.h b/services/network/public/cpp/p2p_param_traits.h index 9572939..88a5120 100644 --- a/services/network/public/cpp/p2p_param_traits.h +++ b/services/network/public/cpp/p2p_param_traits.h
@@ -15,7 +15,6 @@ #include "net/base/ip_address.h" #include "net/base/network_change_notifier.h" #include "net/base/network_interfaces.h" -#include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/public/cpp/p2p_socket_type.h" #include "third_party/webrtc/rtc_base/async_packet_socket.h"
diff --git a/services/network/public/cpp/proxy_config.typemap b/services/network/public/cpp/proxy_config.typemap deleted file mode 100644 index 9c9b1c5..0000000 --- a/services/network/public/cpp/proxy_config.typemap +++ /dev/null
@@ -1,23 +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. - -mojom = "//services/network/public/mojom/proxy_config.mojom" -public_headers = [ - "//net/proxy_resolution/proxy_bypass_rules.h", - "//net/proxy_resolution/proxy_config.h", - "//net/proxy_resolution/proxy_list.h", -] -traits_headers = [ "//services/network/public/cpp/proxy_config_mojom_traits.h" ] -deps = [ - "//net:net", - "//services/network/public/mojom:mojom_shared", -] -type_mappings = [ - "network.mojom.ProxyBypassRules=::net::ProxyBypassRules", - "network.mojom.ProxyList=::net::ProxyList", - "network.mojom.ProxyRulesType=::net::ProxyConfig::ProxyRules::Type", - "network.mojom.ProxyRules=::net::ProxyConfig::ProxyRules", - "network.mojom.ProxyConfig=::net::ProxyConfig", - "network.mojom.ProxyConfigWithAnnotation=::net::ProxyConfigWithAnnotation", -]
diff --git a/services/network/public/cpp/proxy_config_mojom_traits.h b/services/network/public/cpp/proxy_config_mojom_traits.h index 6d60b0d..b429344 100644 --- a/services/network/public/cpp/proxy_config_mojom_traits.h +++ b/services/network/public/cpp/proxy_config_mojom_traits.h
@@ -10,6 +10,7 @@ #include "mojo/public/cpp/base/big_string_mojom_traits.h" #include "net/proxy_resolution/proxy_bypass_rules.h" #include "net/proxy_resolution/proxy_config.h" +#include "net/proxy_resolution/proxy_config_with_annotation.h" #include "net/proxy_resolution/proxy_list.h" #include "services/network/public/mojom/proxy_config.mojom-shared.h" #include "url/mojom/url_gurl_mojom_traits.h"
diff --git a/services/network/public/cpp/proxy_config_with_annotation.typemap b/services/network/public/cpp/proxy_config_with_annotation.typemap deleted file mode 100644 index 5c4e29a5..0000000 --- a/services/network/public/cpp/proxy_config_with_annotation.typemap +++ /dev/null
@@ -1,16 +0,0 @@ -# Copyright 2018 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. - -mojom = "//services/network/public/mojom/proxy_config_with_annotation.mojom" -public_headers = [ "//net/proxy_resolution/proxy_config_with_annotation.h" ] -traits_headers = [ - "//services/network/public/cpp/proxy_config_with_annotation_mojom_traits.h", -] -deps = [ - "//net:net", - "//services/network/public/mojom:mojom_shared", -] -type_mappings = [ - "network.mojom.ProxyConfigWithAnnotation=::net::ProxyConfigWithAnnotation", -]
diff --git a/services/network/public/cpp/site_for_cookies.typemap b/services/network/public/cpp/site_for_cookies.typemap deleted file mode 100644 index 7b1a7c8..0000000 --- a/services/network/public/cpp/site_for_cookies.typemap +++ /dev/null
@@ -1,12 +0,0 @@ -# Copyright 2019 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.↵ - -mojom = "//services/network/public/mojom/site_for_cookies.mojom" -public_headers = [ "//net/cookies/site_for_cookies.h" ] -traits_headers = - [ "//services/network/public/cpp/site_for_cookies_mojom_traits.h" ] -public_deps = [ - "//net", -] -type_mappings = [ "network.mojom.SiteForCookies=::net::SiteForCookies" ]
diff --git a/services/network/public/cpp/typemaps.gni b/services/network/public/cpp/typemaps.gni deleted file mode 100644 index 2922835..0000000 --- a/services/network/public/cpp/typemaps.gni +++ /dev/null
@@ -1,35 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//services/network/public/cpp/features.gni") - -typemaps = [ - "//services/network/public/cpp/address_family.typemap", - "//services/network/public/cpp/address_list.typemap", - "//services/network/public/cpp/cookie_manager.typemap", - "//services/network/public/cpp/cross_origin_embedder_policy.typemap", - "//services/network/public/cpp/default_credentials.typemap", - "//services/network/public/cpp/cors_error_status.typemap", - "//services/network/public/cpp/digitally_signed.typemap", - "//services/network/public/cpp/http_request_headers.typemap", - "//services/network/public/cpp/host_resolver.typemap", - "//services/network/public/cpp/ip_address.typemap", - "//services/network/public/cpp/ip_endpoint.typemap", - "//services/network/public/cpp/load_timing_info.typemap", - "//services/network/public/cpp/mutable_network_traffic_annotation_tag.typemap", - "//services/network/public/cpp/mutable_partial_network_traffic_annotation_tag.typemap", - "//services/network/public/cpp/net_log.typemap", - "//services/network/public/cpp/network_interface.typemap", - "//services/network/public/cpp/network_isolation_key.typemap", - "//services/network/public/cpp/network_param.typemap", - "//services/network/public/cpp/network_types.typemap", - "//services/network/public/cpp/origin_policy.typemap", - "//services/network/public/cpp/p2p.typemap", - "//services/network/public/cpp/proxy_config.typemap", - "//services/network/public/cpp/proxy_config_with_annotation.typemap", - "//services/network/public/cpp/site_for_cookies.typemap", - "//services/network/public/cpp/url_loader_completion_status.typemap", - "//services/network/public/cpp/url_request.typemap", - "//services/network/public/cpp/url_request_redirect_info.typemap", -]
diff --git a/services/network/public/cpp/url_loader_completion_status.typemap b/services/network/public/cpp/url_loader_completion_status.typemap deleted file mode 100644 index c4b7e5d3..0000000 --- a/services/network/public/cpp/url_loader_completion_status.typemap +++ /dev/null
@@ -1,15 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//services/network/public/mojom/url_loader.mojom" -public_headers = - [ "//services/network/public/cpp/url_loader_completion_status.h" ] -traits_headers = [ "//services/network/public/cpp/network_ipc_param_traits.h" ] -deps = [ - "//net", -] -public_deps = [ - "//services/network/public/cpp:cpp_base", -] -type_mappings = [ "network.mojom.URLLoaderCompletionStatus=::network::URLLoaderCompletionStatus" ]
diff --git a/services/network/public/cpp/url_request.typemap b/services/network/public/cpp/url_request.typemap deleted file mode 100644 index cec7cad..0000000 --- a/services/network/public/cpp/url_request.typemap +++ /dev/null
@@ -1,30 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//services/network/public/mojom/url_loader.mojom" -public_headers = [ - "//base/memory/scoped_refptr.h", - "//services/network/public/cpp/data_element.h", - "//services/network/public/cpp/resource_request.h", - "//services/network/public/cpp/resource_request_body.h", -] -traits_headers = [ - "//services/network/public/cpp/network_ipc_param_traits.h", - "//services/network/public/cpp/url_request_mojom_traits.h", - "//services/network/public/cpp/network_isolation_key_mojom_traits.h", - "//url/mojom/origin_mojom_traits.h", - "//url/mojom/url_gurl_mojom_traits.h", -] -public_deps = [ - "//base", - "//services/network/public/cpp:cpp_base", -] -type_mappings = [ - "network.mojom.TrustedUrlRequestParams=::network::ResourceRequest::TrustedParams", - "network.mojom.URLRequest=::network::ResourceRequest", - "network.mojom.URLRequestBody=::scoped_refptr<::network::ResourceRequestBody>[nullable_is_same_type,copyable_pass_by_value]", - "network.mojom.URLRequestReferrerPolicy=::net::URLRequest::ReferrerPolicy", - "network.mojom.RequestPriority=::net::RequestPriority", - "network.mojom.DataElement=::network::DataElement[move_only]", -]
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h index a8de298..b16e58c 100644 --- a/services/network/public/cpp/url_request_mojom_traits.h +++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -27,6 +27,7 @@ #include "services/network/public/mojom/data_pipe_getter.mojom.h" #include "services/network/public/mojom/trust_tokens.mojom.h" #include "services/network/public/mojom/url_loader.mojom-shared.h" +#include "url/mojom/url_gurl_mojom_traits.h" namespace mojo {
diff --git a/services/network/public/cpp/url_request_redirect_info.typemap b/services/network/public/cpp/url_request_redirect_info.typemap deleted file mode 100644 index 25add786..0000000 --- a/services/network/public/cpp/url_request_redirect_info.typemap +++ /dev/null
@@ -1,11 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//services/network/public/mojom/url_loader.mojom" -public_headers = [ "//net/url_request/redirect_info.h" ] -traits_headers = [ "//services/network/public/cpp/network_ipc_param_traits.h" ] -public_deps = [ - "//net:net", -] -type_mappings = [ "network.mojom.URLRequestRedirectInfo=::net::RedirectInfo" ]
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index 0aba89b..5a24bf3e 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -19,6 +19,67 @@ ] public_deps = [ "//url/mojom:url_mojom_gurl" ] + + shared_cpp_typemaps = [ + { + types = [ + { + mojom = "network.mojom.IPAddress" + cpp = "::net::IPAddress" + }, + ] + traits_headers = + [ "//services/network/public/cpp/ip_address_mojom_traits.h" ] + traits_public_deps = [ + "//net", + "//services/network/public/cpp:cpp_base", + ] + }, + { + types = [ + { + mojom = "network.mojom.IPEndPoint" + cpp = "::net::IPEndPoint" + }, + ] + traits_headers = + [ "//services/network/public/cpp/ip_endpoint_mojom_traits.h" ] + traits_public_deps = [ + "//net", + "//services/network/public/cpp:cpp_base", + ] + }, + ] + + cpp_typemaps = [ + { + types = [ + { + mojom = "network.mojom.AddressFamily" + cpp = "::net::AddressFamily" + }, + ] + traits_headers = + [ "//services/network/public/cpp/address_family_mojom_traits.h" ] + traits_sources = + [ "//services/network/public/cpp/address_family_mojom_traits.cc" ] + traits_public_deps = [ "//net" ] + }, + { + types = [ + { + mojom = "network.mojom.AddressList" + cpp = "::net::AddressList" + }, + ] + traits_headers = + [ "//services/network/public/cpp/address_list_mojom_traits.h" ] + traits_public_deps = [ "//net" ] + }, + ] + cpp_typemaps += shared_cpp_typemaps + + blink_cpp_typemaps = shared_cpp_typemaps } # As with mojom_ip_address, this is a separate target to avoid a circular @@ -37,6 +98,21 @@ export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1" export_header_blink = "third_party/blink/public/platform/web_common.h" } + + cpp_typemaps = [ + { + types = [ + { + mojom = "network.mojom.NetworkIsolationKey" + cpp = "::net::NetworkIsolationKey" + }, + ] + traits_headers = [ + "//services/network/public/cpp/network_isolation_key_mojom_traits.h", + ] + traits_public_deps = [ "//net" ] + }, + ] } # These interfaces are put in their own target to avoid a circular dependency, @@ -66,6 +142,33 @@ "mutable_network_traffic_annotation_tag.mojom", "mutable_partial_network_traffic_annotation_tag.mojom", ] + + mutable_network_traffic_annotation_tag_typemap = { + types = [ + { + mojom = "network.mojom.MutableNetworkTrafficAnnotationTag" + cpp = "::net::MutableNetworkTrafficAnnotationTag" + }, + ] + traits_headers = [ "//services/network/public/cpp/mutable_network_traffic_annotation_tag_mojom_traits.h" ] + traits_public_deps = [ "//net/traffic_annotation" ] + } + + cpp_typemaps = [ + mutable_network_traffic_annotation_tag_typemap, + { + types = [ + { + mojom = "network.mojom.MutablePartialNetworkTrafficAnnotationTag" + cpp = "::net::MutablePartialNetworkTrafficAnnotationTag" + }, + ] + traits_headers = [ "//services/network/public/cpp/mutable_partial_network_traffic_annotation_tag_mojom_traits.h" ] + traits_public_deps = [ "//net/traffic_annotation" ] + }, + ] + + blink_cpp_typemaps = [ mutable_network_traffic_annotation_tag_typemap ] } # These interfaces are put in their own target to avoid a circular dependency, @@ -103,6 +206,67 @@ export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1" export_header_blink = "third_party/blink/public/platform/web_common.h" } + + cpp_typemaps = [ + { + types = [ + { + mojom = "network.mojom.AuthChallengeInfo" + cpp = "::net::AuthChallengeInfo" + }, + { + mojom = "network.mojom.AuthCredentials" + cpp = "::net::AuthCredentials" + }, + { + mojom = "network.mojom.CertVerifyResult" + cpp = "::net::CertVerifyResult" + }, + { + mojom = "network.mojom.CTVerifyResult" + cpp = "::net::ct::CTVerifyResult" + }, + { + mojom = "network.mojom.HostPortPair" + cpp = "::net::HostPortPair" + }, + { + mojom = "network.mojom.HttpResponseHeaders" + cpp = "::scoped_refptr<::net::HttpResponseHeaders>" + nullable_is_same_type = true + }, + { + mojom = "network.mojom.HttpVersion" + cpp = "::net::HttpVersion" + }, + { + mojom = "network.mojom.SSLCertRequestInfo" + cpp = "::scoped_refptr<::net::SSLCertRequestInfo>" + nullable_is_same_type = true + }, + { + mojom = "network.mojom.SSLInfo" + cpp = "::net::SSLInfo" + }, + { + mojom = "network.mojom.X509Certificate" + cpp = "::scoped_refptr<::net::X509Certificate>" + nullable_is_same_type = true + }, + ] + traits_headers = [ + "//services/network/public/cpp/net_ipc_param_traits.h", + "//services/network/public/cpp/network_param_mojom_traits.h", + ] + traits_sources = + [ "//services/network/public/cpp/network_param_mojom_traits.cc" ] + traits_public_deps = [ + "//ipc", + "//net", + "//services/network/public/cpp:cpp_base", + ] + }, + ] } mojom("mojom") { @@ -203,4 +367,380 @@ if (builtin_cert_verifier_feature_supported) { enabled_features += [ "is_builtin_cert_verifier_feature_supported" ] } + + # Typemaps which apply to both Blink and non-Blink bindings. + shared_cpp_typemaps = [ + { + types = [ + { + mojom = "network.mojom.CrossOriginEmbedderPolicy" + cpp = "::network::CrossOriginEmbedderPolicy" + }, + ] + traits_headers = [ "//services/network/public/cpp/cross_origin_embedder_policy_mojom_traits.h" ] + }, + { + types = [ + { + mojom = "network.mojom.TrustedUrlRequestParams" + cpp = "::network::ResourceRequest::TrustedParams" + }, + { + mojom = "network.mojom.URLRequest" + cpp = "::network::ResourceRequest" + }, + { + mojom = "network.mojom.URLRequestBody" + cpp = "::scoped_refptr<::network::ResourceRequestBody>" + nullable_is_same_type = true + copyable_pass_by_value = true + }, + { + mojom = "network.mojom.URLRequestReferrerPolicy" + cpp = "::net::URLRequest::ReferrerPolicy" + }, + { + mojom = "network.mojom.RequestPriority" + cpp = "::net::RequestPriority" + }, + { + mojom = "network.mojom.DataElement" + cpp = "::network::DataElement" + move_only = true + }, + ] + traits_headers = [ + "//services/network/public/cpp/network_ipc_param_traits.h", + "//services/network/public/cpp/url_request_mojom_traits.h", + "//services/network/public/cpp/network_isolation_key_mojom_traits.h", + ] + traits_public_deps = [ + "//base", + "//services/network/public/cpp:cpp_base", + "//url/mojom:url_mojom_gurl", + ] + }, + { + types = [ + { + mojom = "network.mojom.HttpRequestHeaders" + cpp = "::net::HttpRequestHeaders" + }, + ] + traits_headers = [ + "//services/network/public/cpp/http_request_headers_mojom_traits.h", + ] + traits_public_deps = [ + "//net", + "//services/network/public/cpp:cpp_base", + ] + }, + { + types = [ + { + mojom = "network.mojom.NetworkInterface" + cpp = "::net::NetworkInterface" + }, + ] + traits_headers = + [ "//services/network/public/cpp/network_interface_mojom_traits.h" ] + traits_public_deps = [ + "//net", + "//services/network/public/cpp:cpp_base", + ] + }, + { + types = [ + { + mojom = "network.mojom.SiteForCookies" + cpp = "::net::SiteForCookies" + }, + ] + traits_headers = + [ "//services/network/public/cpp/site_for_cookies_mojom_traits.h" ] + traits_public_deps = [ + "//net", + "//services/network/public/cpp:cpp_base", + ] + }, + { + types = [ + { + mojom = "network.mojom.P2PPacketInfo" + cpp = "::network::P2PPacketInfo" + }, + { + mojom = "network.mojom.P2PSendPacketMetrics" + cpp = "::network::P2PSendPacketMetrics" + }, + { + mojom = "network.mojom.P2PPortRange" + cpp = "::network::P2PPortRange" + }, + { + mojom = "network.mojom.P2PHostAndIPEndPoint" + cpp = "::network::P2PHostAndIPEndPoint" + }, + { + mojom = "network.mojom.P2PSocketOption" + cpp = "::network::P2PSocketOption" + }, + { + mojom = "network.mojom.P2PSocketType" + cpp = "::network::P2PSocketType" + }, + ] + traits_headers = [ "//services/network/public/cpp/p2p_param_traits.h" ] + traits_public_deps = [ + "//services/network/public/cpp:cpp_base", + "//third_party/webrtc_overrides:webrtc_component", + ] + }, + ] + + # Typemaps applied only to non-Blink bindings + cpp_typemaps = [ + { + types = [ + { + mojom = "network.mojom.CookiePriority" + cpp = "::net::CookiePriority" + }, + { + mojom = "network.mojom.CookieSameSite" + cpp = "::net::CookieSameSite" + }, + { + mojom = "network.mojom.CookieSameSiteContext" + cpp = "::net::CookieOptions::SameSiteCookieContext" + }, + { + mojom = "network.mojom.CookieAccessSemantics" + cpp = "::net::CookieAccessSemantics" + }, + { + mojom = "network.mojom.CookieOptions" + cpp = "::net::CookieOptions" + }, + { + mojom = "network.mojom.CanonicalCookie" + cpp = "::net::CanonicalCookie" + }, + { + mojom = "network.mojom.CookieInclusionStatusWarningReason" + cpp = "::net::CanonicalCookie::CookieInclusionStatus::WarningReason" + }, + { + mojom = "network.mojom.CookieInclusionStatus" + cpp = "::net::CanonicalCookie::CookieInclusionStatus" + move_only = true + }, + { + mojom = "network.mojom.CookieWithStatus" + cpp = "::net::CookieWithStatus" + }, + { + mojom = "network.mojom.CookieAndLineWithStatus" + cpp = "::net::CookieAndLineWithStatus" + }, + { + mojom = "network.mojom.CookieChangeCause" + cpp = "::net::CookieChangeCause" + }, + { + mojom = "network.mojom.CookieChangeInfo" + cpp = "::net::CookieChangeInfo" + }, + { + mojom = "network.mojom.CookieSourceScheme" + cpp = "::net::CookieSourceScheme" + }, + ] + traits_headers = + [ "//services/network/public/cpp/cookie_manager_mojom_traits.h" ] + traits_sources = + [ "//services/network/public/cpp/cookie_manager_mojom_traits.cc" ] + traits_public_deps = [ "//net" ] + }, + { + types = [ + { + mojom = "network.mojom.DefaultCredentials" + cpp = "::net::HttpAuthPreferences::DefaultCredentials" + }, + ] + traits_headers = + [ "//services/network/public/cpp/default_credentials_mojom_traits.h" ] + traits_sources = [ + "//services/network/public/cpp/default_credentials_mojom_traits.cc", + ] + traits_public_deps = [ "//net" ] + }, + { + types = [ + { + mojom = "network.mojom.CTPolicyCompliance" + cpp = "::net::ct::CTPolicyCompliance" + }, + { + mojom = "network.mojom.ConnectionInfo" + cpp = "::net::HttpResponseInfo::ConnectionInfo" + }, + { + mojom = "network.mojom.CorsErrorStatus" + cpp = "::network::CorsErrorStatus" + }, + { + mojom = "network.mojom.EffectiveConnectionType" + cpp = "::net::EffectiveConnectionType" + }, + { + mojom = "network.mojom.OriginPolicy" + cpp = "::network::OriginPolicy" + }, + { + mojom = "network.mojom.URLLoaderCompletionStatus" + cpp = "::network::URLLoaderCompletionStatus" + }, + { + mojom = "network.mojom.URLRequestRedirectInfo" + cpp = "::net::RedirectInfo" + }, + ] + traits_headers = + [ "//services/network/public/cpp/network_ipc_param_traits.h" ] + traits_public_deps = [ + "//net", + "//services/network/public/cpp:cpp_base", + ] + }, + { + types = [ + { + mojom = "network.mojom.HashAlgorithm" + cpp = "::net::ct::DigitallySigned::HashAlgorithm" + }, + { + mojom = "network.mojom.SignatureAlgorithm" + cpp = "::net::ct::DigitallySigned::SignatureAlgorithm" + }, + { + mojom = "network.mojom.DigitallySigned" + cpp = "::net::ct::DigitallySigned" + }, + ] + traits_headers = + [ "//services/network/public/cpp/digitally_signed_mojom_traits.h" ] + traits_sources = + [ "//services/network/public/cpp/digitally_signed_mojom_traits.cc" ] + traits_public_deps = [ "//net" ] + }, + { + types = [ + { + mojom = "network.mojom.DnsConfigOverrides" + cpp = "::net::DnsConfigOverrides" + }, + { + mojom = "network.mojom.DnsQueryType" + cpp = "::net::DnsQueryType" + }, + { + mojom = "network.mojom.ResolveErrorInfo" + cpp = "::net::ResolveErrorInfo" + }, + { + mojom = "network.mojom.ResolveHostParameters.Source" + cpp = "::net::HostResolverSource" + }, + { + mojom = "network.mojom.MdnsListenClient.UpdateType" + cpp = "::net::HostResolver::MdnsListener::Delegate::UpdateType" + }, + { + mojom = "network.mojom.SecureDnsMode" + cpp = "::net::DnsConfig::SecureDnsMode" + }, + ] + traits_headers = + [ "//services/network/public/cpp/host_resolver_mojom_traits.h" ] + traits_sources = + [ "//services/network/public/cpp/host_resolver_mojom_traits.cc" ] + traits_public_deps = [ "//net" ] + }, + { + types = [ + { + mojom = "network.mojom.LoadTimingInfo" + cpp = "::net::LoadTimingInfo" + }, + { + mojom = "network.mojom.LoadTimingInfoConnectTiming" + cpp = "::net::LoadTimingInfo::ConnectTiming" + }, + ] + traits_headers = + [ "//services/network/public/cpp/load_timing_info_mojom_traits.h" ] + traits_sources = + [ "//services/network/public/cpp/load_timing_info_mojom_traits.cc" ] + traits_public_deps = [ "//net" ] + }, + { + types = [ + { + mojom = "network.mojom.NetLogCaptureMode" + cpp = "::net::NetLogCaptureMode" + }, + { + mojom = "network.mojom.NetLogEventPhase" + cpp = "::net::NetLogEventPhase" + }, + ] + traits_headers = + [ "//services/network/public/cpp/net_log_mojom_traits.h" ] + traits_sources = + [ "//services/network/public/cpp/net_log_mojom_traits.cc" ] + traits_public_deps = [ "//net" ] + }, + { + types = [ + { + mojom = "network.mojom.ProxyBypassRules" + cpp = "::net::ProxyBypassRules" + }, + { + mojom = "network.mojom.ProxyList" + cpp = "::net::ProxyList" + }, + { + mojom = "network.mojom.ProxyRulesType" + cpp = "::net::ProxyConfig::ProxyRules::Type" + }, + { + mojom = "network.mojom.ProxyRules" + cpp = "::net::ProxyConfig::ProxyRules" + }, + { + mojom = "network.mojom.ProxyConfig" + cpp = "::net::ProxyConfig" + }, + ] + traits_headers = + [ "//services/network/public/cpp/proxy_config_mojom_traits.h" ] + traits_public_deps = [ "//net" ] + }, + { + types = [ + { + mojom = "network.mojom.ProxyConfigWithAnnotation" + cpp = "::net::ProxyConfigWithAnnotation" + }, + ] + traits_headers = [ "//services/network/public/cpp/proxy_config_with_annotation_mojom_traits.h" ] + traits_public_deps = [ "//net" ] + }, + ] + cpp_typemaps += shared_cpp_typemaps + + blink_cpp_typemaps = shared_cpp_typemaps }
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index b74677d..88d890a7 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -563,6 +563,10 @@ // A receiver for the replaced "internal" URLLoaderFactory. pending_receiver<URLLoaderFactory>? overridden_factory_receiver; + + // Specifies if we should accept unknown schemes for CORS-enabled requests + // so that the |overriding_factory| can provide content for custom schemes. + bool skip_cors_enabled_scheme_check = false; }; struct ClientSecurityState {
diff --git a/testing/scripts/run_android_wpt.py b/testing/scripts/run_android_wpt.py index efdea2f..8b01a6f 100755 --- a/testing/scripts/run_android_wpt.py +++ b/testing/scripts/run_android_wpt.py
@@ -58,10 +58,6 @@ WEBLAYER_SHELL_PKG = 'org.chromium.weblayer.shell' WEBLAYER_SUPPORT_PKG = 'org.chromium.weblayer.support' -# This avoids having to update the hosts file on device. -HOST_RESOLVER_ARGS = ['--host-resolver-rules=MAP nonexistent.*.test ~NOTFOUND,' - ' MAP *.test 127.0.0.1'] - # List of supported products. PRODUCTS = ['android_weblayer', 'android_webview', 'chrome_android'] @@ -117,15 +113,8 @@ "--no-capture-stdio", "--no-manifest-download", "--no-fail-on-unexpected", - #TODO(aluo): Tune this as tests are stabilized - "--timeout-multiplier", - "0.25", ]) - # Lets weblayer know it's running in test mode. - if self.options.product == 'android_weblayer': - rest_args.extend(["--binary-arg=--run-web-tests"]) - # Default to the apk's package name for chrome_android if not self.options.package_name: if self.options.product == 'chrome_android':
diff --git a/third_party/blink/common/devtools/OWNERS b/third_party/blink/common/devtools/OWNERS deleted file mode 100644 index d5fefd8..0000000 --- a/third_party/blink/common/devtools/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -per-file *_mojom_traits*.*=set noparent -per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/common/devtools/device_emulation_params_mojom_traits.cc b/third_party/blink/common/devtools/device_emulation_params_mojom_traits.cc deleted file mode 100644 index ce76fc8..0000000 --- a/third_party/blink/common/devtools/device_emulation_params_mojom_traits.cc +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2020 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 "third_party/blink/public/common/devtools/device_emulation_params_mojom_traits.h" - -#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h" - -namespace mojo { - -bool StructTraits<blink::mojom::DeviceEmulationParamsDataView, - blink::WebDeviceEmulationParams>:: - Read(blink::mojom::DeviceEmulationParamsDataView data, - blink::WebDeviceEmulationParams* params) { - if (!data.ReadScreenPosition(¶ms->screen_position)) - return false; - if (!data.ReadScreenSize(¶ms->screen_size)) - return false; - if (!data.ReadViewPosition(¶ms->view_position)) - return false; - if (!data.ReadViewSize(¶ms->view_size)) - return false; - params->device_scale_factor = data.device_scale_factor(); - params->scale = data.scale(); - if (!data.ReadViewportOffset(¶ms->viewport_offset)) - return false; - params->viewport_scale = data.viewport_scale(); - if (!data.ReadScreenOrientationType(¶ms->screen_orientation_type)) - return false; - params->screen_orientation_angle = data.screen_orientation_angle(); - return true; -} - -} // namespace mojo
diff --git a/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc b/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc index 207dd06f..d0365bd 100644 --- a/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc +++ b/third_party/blink/common/scheduler/web_scheduler_tracked_feature.cc
@@ -47,8 +47,6 @@ return "ServiceWorker-controlled page"; case WebSchedulerTrackedFeature::kOutstandingIndexedDBTransaction: return "outstanding IndexedDB transaction"; - case WebSchedulerTrackedFeature::kHasScriptableFramesInMultipleTabs: - return "has scriptable frames in multiple tabs"; case WebSchedulerTrackedFeature::kRequestedGeolocationPermission: return "requested geolocation permission"; case WebSchedulerTrackedFeature::kRequestedNotificationsPermission:
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index f4cecb6..2e338cb 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -307,6 +307,7 @@ "web/web_context_menu_data.h", "web/web_crypto_normalize.h", "web/web_custom_element.h", + "web/web_device_emulation_params.h", "web/web_document.h", "web/web_document_loader.h", "web/web_dom_activity_logger.h",
diff --git a/third_party/blink/public/blink_typemaps.gni b/third_party/blink/public/blink_typemaps.gni index a96c2e6..397290a7 100644 --- a/third_party/blink/public/blink_typemaps.gni +++ b/third_party/blink/public/blink_typemaps.gni
@@ -5,8 +5,6 @@ typemaps = [ "//gpu/ipc/common/mailbox_holder_for_blink.typemap", "//gpu/ipc/common/sync_token.typemap", - "//services/network/public/cpp/cross_origin_embedder_policy.typemap", - "//services/network/public/cpp/url_request.typemap", "//services/viz/public/cpp/compositing/begin_frame_args_for_blink.typemap", "//services/viz/public/cpp/compositing/compositor_frame_for_blink.typemap", "//services/viz/public/cpp/compositing/frame_sink_id.typemap",
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index 0181ec0..c9936f6 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -60,7 +60,6 @@ "css/navigation_controls.h", "css/preferred_color_scheme.h", "device_memory/approximated_device_memory.h", - "devtools/web_device_emulation_params.h", "dom_storage/session_storage_namespace_id.h", "experiments/memory_ablation_experiment.h", "feature_policy/document_policy.h",
diff --git a/third_party/blink/public/common/devtools/OWNERS b/third_party/blink/public/common/devtools/OWNERS deleted file mode 100644 index 7aebc8abb..0000000 --- a/third_party/blink/public/common/devtools/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -per-file *_mojom_traits*.*=set noparent -per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS -per-file *.typemap=set noparent -per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/public/common/devtools/device_emulation_params.typemap b/third_party/blink/public/common/devtools/device_emulation_params.typemap deleted file mode 100644 index 4397465..0000000 --- a/third_party/blink/public/common/devtools/device_emulation_params.typemap +++ /dev/null
@@ -1,19 +0,0 @@ -# Copyright 2020 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. - -mojom = - "//third_party/blink/public/mojom/devtools/device_emulation_params.mojom" -public_headers = [ - "//third_party/blink/public/common/devtools/web_device_emulation_params.h", - "//third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h", - "//ui/gfx/geometry/point_f.h", - "//ui/gfx/geometry/size.h", -] -traits_headers = [ "//third_party/blink/public/common/devtools/device_emulation_params_mojom_traits.h" ] -sources = [ - "//third_party/blink/common/devtools/device_emulation_params_mojom_traits.cc", -] -public_deps = [ "//base" ] -type_mappings = - [ "blink.mojom.DeviceEmulationParams=::blink::WebDeviceEmulationParams" ]
diff --git a/third_party/blink/public/common/devtools/device_emulation_params_mojom_traits.h b/third_party/blink/public/common/devtools/device_emulation_params_mojom_traits.h deleted file mode 100644 index 81c8c0a..0000000 --- a/third_party/blink/public/common/devtools/device_emulation_params_mojom_traits.h +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2020 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 THIRD_PARTY_BLINK_PUBLIC_COMMON_DEVTOOLS_DEVICE_EMULATION_PARAMS_MOJOM_TRAITS_H_ -#define THIRD_PARTY_BLINK_PUBLIC_COMMON_DEVTOOLS_DEVICE_EMULATION_PARAMS_MOJOM_TRAITS_H_ - -#include <utility> - -#include "third_party/blink/public/common/devtools/web_device_emulation_params.h" -#include "third_party/blink/public/mojom/devtools/device_emulation_params.mojom.h" - -namespace mojo { - -template <> -struct BLINK_COMMON_EXPORT - StructTraits<blink::mojom::DeviceEmulationParamsDataView, - blink::WebDeviceEmulationParams> { - static blink::mojom::ScreenPosition screen_position( - const blink::WebDeviceEmulationParams& params) { - return params.screen_position; - } - - static gfx::Size screen_size(const blink::WebDeviceEmulationParams& params) { - return params.screen_size; - } - - static base::Optional<gfx::Point> view_position( - const blink::WebDeviceEmulationParams& params) { - return params.view_position; - } - - static gfx::Size view_size(const blink::WebDeviceEmulationParams& params) { - return params.view_size; - } - - static float device_scale_factor( - const blink::WebDeviceEmulationParams& params) { - return params.device_scale_factor; - } - - static float scale(const blink::WebDeviceEmulationParams& params) { - return params.scale; - } - - static gfx::PointF viewport_offset( - const blink::WebDeviceEmulationParams& params) { - return params.viewport_offset; - } - - static float viewport_scale(const blink::WebDeviceEmulationParams& params) { - return params.viewport_scale; - } - - static blink::mojom::ScreenOrientationType screen_orientation_type( - const blink::WebDeviceEmulationParams& params) { - return params.screen_orientation_type; - } - - static int screen_orientation_angle( - const blink::WebDeviceEmulationParams& params) { - return params.screen_orientation_angle; - } - - static bool Read(blink::mojom::DeviceEmulationParamsDataView data, - blink::WebDeviceEmulationParams* params); -}; - -} // namespace mojo - -#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_DEVTOOLS_DEVICE_EMULATION_PARAMS_MOJOM_TRAITS_H_
diff --git a/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h b/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h index ea0603ec..834011e 100644 --- a/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h +++ b/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
@@ -44,13 +44,6 @@ kOutstandingIndexedDBTransaction = 17, - // Whether there are other pages which can potentially synchronously script - // the current one (e.g. due to window.open being used). - // This is a conservative estimation which doesn't take into account the - // origin, so it may be true if the related page is cross-origin. - // Recorded only for the main frame. - kHasScriptableFramesInMultipleTabs = 18, - // Whether the page tried to request a permission regardless of the outcome. // TODO(altimin): Track this more accurately depending on the data. // See permission.mojom for more details.
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 21c4e81..1e90874 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -41,7 +41,6 @@ "crash/crash_memory_metrics_reporter.mojom", "credentialmanager/credential_manager.mojom", "devtools/console_message.mojom", - "devtools/device_emulation_params.mojom", "devtools/devtools_agent.mojom", "devtools/devtools_frontend.mojom", "devtools/inspector_issue.mojom",
diff --git a/third_party/blink/public/mojom/devtools/device_emulation_params.mojom b/third_party/blink/public/mojom/devtools/device_emulation_params.mojom deleted file mode 100644 index 991ad4a..0000000 --- a/third_party/blink/public/mojom/devtools/device_emulation_params.mojom +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2020 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. - -module blink.mojom; - -import "ui/gfx/geometry/mojom/geometry.mojom"; - -enum ScreenPosition { - kDesktop, - kMobile, -}; - -enum ScreenOrientationType { - kUndefined = 0, - kPortraitPrimary, - kPortraitSecondary, - kLandscapePrimary, - kLandscapeSecondary, -}; - -struct DeviceEmulationParams { - ScreenPosition screen_position; - - // Emulated screen size. Typically full / physical size of the device screen - // in DIP. Empty size means using default value: original one for kDesktop - // screen position, equal to |view_size| for kMobile. - gfx.mojom.Size screen_size; - - // Position of view on the screen. Missing position means using default value: - // original one for kDesktop screen position, (0, 0) for kMobile. - gfx.mojom.Point? view_position; - - // Emulated view size. A width or height of 0 means no override in that - // dimension, but the other can still be applied. When both are 0, then the - // |scale| will be applied to the view instead. - gfx.mojom.Size view_size; - - // If zero, the original device scale factor is preserved. - float device_scale_factor; - - // Scale the contents of the main frame. The view's size will be scaled by - // this number when they are not specified in |view_size|. - float scale = 1; - - // If present, forced viewport offset for screenshots during emulation. - gfx.mojom.PointF? viewport_offset; - - // Viewport scale for screenshots during emulation, 0 for current. - float viewport_scale; - - // Optional screen orientation type, with WebScreenOrientationUndefined - // value meaning no emulation necessary. - ScreenOrientationType screen_orientation_type; - - // Screen orientation angle, used together with screenOrientationType. - int32 screen_orientation_angle; -};
diff --git a/third_party/blink/public/public_typemaps.gni b/third_party/blink/public/public_typemaps.gni index 5c49197..0a428d8 100644 --- a/third_party/blink/public/public_typemaps.gni +++ b/third_party/blink/public/public_typemaps.gni
@@ -4,7 +4,6 @@ # These are typemaps which are exposed by Blink to its embedder. typemaps = [ - "//third_party/blink/public/common/devtools/device_emulation_params.typemap", "//third_party/blink/public/common/fetch/fetch_api_request_body.typemap", "//third_party/blink/public/common/fetch/fetch_api_request_headers.typemap", "//third_party/blink/public/common/indexeddb/indexed_db_default.typemap",
diff --git a/third_party/blink/public/common/devtools/web_device_emulation_params.h b/third_party/blink/public/web/web_device_emulation_params.h similarity index 80% rename from third_party/blink/public/common/devtools/web_device_emulation_params.h rename to third_party/blink/public/web/web_device_emulation_params.h index bff3b08..f5f1088b 100644 --- a/third_party/blink/public/common/devtools/web_device_emulation_params.h +++ b/third_party/blink/public/web/web_device_emulation_params.h
@@ -2,25 +2,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_DEVTOOLS_WEB_DEVICE_EMULATION_PARAMS_H_ -#define THIRD_PARTY_BLINK_PUBLIC_COMMON_DEVTOOLS_WEB_DEVICE_EMULATION_PARAMS_H_ +#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_DEVICE_EMULATION_PARAMS_H_ +#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_DEVICE_EMULATION_PARAMS_H_ #include "base/optional.h" -#include "third_party/blink/public/mojom/devtools/device_emulation_params.mojom-shared.h" +#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h" +#include "third_party/blink/public/platform/web_rect.h" +#include "third_party/blink/public/platform/web_size.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point_f.h" -#include "ui/gfx/geometry/size.h" namespace blink { // All sizes are measured in device independent pixels. struct WebDeviceEmulationParams { - mojom::ScreenPosition screen_position; + enum ScreenPosition { kDesktop, kMobile, kScreenPositionLast = kMobile }; + + ScreenPosition screen_position; // Emulated screen size. Typically full / physical size of the device screen // in DIP. Empty size means using default value: original one for kDesktop // screen position, equal to |view_size| for kMobile. - gfx::Size screen_size; + WebSize screen_size; // Position of view on the screen. Missing position means using default value: // original one for kDesktop screen position, (0, 0) for kMobile. @@ -29,7 +32,7 @@ // Emulated view size. A width or height of 0 means no override in that // dimension, but the other can still be applied. When both are 0, then the // |scale| will be applied to the view instead. - gfx::Size view_size; + WebSize view_size; // If zero, the original device scale factor is preserved. float device_scale_factor; @@ -47,18 +50,18 @@ // Optional screen orientation type, with WebScreenOrientationUndefined // value meaning no emulation necessary. - mojom::ScreenOrientationType screen_orientation_type; + WebScreenOrientationType screen_orientation_type; // Screen orientation angle, used together with screenOrientationType. int screen_orientation_angle; WebDeviceEmulationParams() - : screen_position(mojom::ScreenPosition::kDesktop), + : screen_position(kDesktop), device_scale_factor(0), scale(1), viewport_offset(-1, -1), viewport_scale(0), - screen_orientation_type(mojom::ScreenOrientationType::kUndefined), + screen_orientation_type(kWebScreenOrientationUndefined), screen_orientation_angle(0) {} };
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h index 3e5c9bb0..406c19b 100644 --- a/third_party/blink/public/web/web_view.h +++ b/third_party/blink/public/web/web_view.h
@@ -354,10 +354,12 @@ // Developer tools ----------------------------------------------------- - // Enables device emulation as specified in params, or disables if params are - // null. - virtual void SetDeviceEmulation( - const base::Optional<WebDeviceEmulationParams>& params) = 0; + // Enables device emulation as specified in params. + virtual void EnableDeviceEmulation(const WebDeviceEmulationParams&) = 0; + + // Cancel emulation started via |enableDeviceEmulation| call. + virtual void DisableDeviceEmulation() = 0; + // Context menu --------------------------------------------------------
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py b/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py index 9c651b6..11c0aef 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py
@@ -97,7 +97,8 @@ "double": "double", "unrestricted double": "double", } - return TypeInfo(cxx_type[real_type.keyword_typename]) + return TypeInfo( + cxx_type[real_type.keyword_typename], const_ref_fmt="{}") if real_type.is_string: return TypeInfo( @@ -129,19 +130,11 @@ has_null_value=True) elif "AllowShared" in real_type.extended_attributes: return TypeInfo( - "DOM{}".format(real_type.keyword_typename), - member_fmt="Member<{}>", - ref_fmt="MaybeShared<{}>", - const_ref_fmt="const MaybeShared<{}>", - value_fmt="MaybeShared<{}>", + "MaybeShared<DOM{}>".format(real_type.keyword_typename), has_null_value=True) else: return TypeInfo( - "DOM{}".format(real_type.keyword_typename), - member_fmt="Member<{}>", - ref_fmt="NotShared<{}>", - const_ref_fmt="const NotShared<{}>", - value_fmt="NotShared<{}>", + "NotShared<DOM{}>".format(real_type.keyword_typename), has_null_value=True) if real_type.is_symbol:
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py b/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py index 4781d5f..6b5c5731 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py
@@ -114,21 +114,32 @@ member = cg_context.dict_member blink_member_name = _blink_member_name(member) + name = blink_member_name.get_api + blink_type = blink_type_info(member.idl_type) - func_def = CxxFuncDefNode( - name=blink_member_name.get_api, + if blink_type.ref_t != blink_type.const_ref_t: + func_def = CxxFuncDefNode( + name=name, arg_decls=[], return_type=blink_type.ref_t) + func_def.set_base_template_vars(cg_context.template_bindings()) + func_def.body.extend([ + TextNode(_format("DCHECK({}());", blink_member_name.has_api)), + TextNode(_format("return {};", blink_member_name.value_var)), + ]) + else: + func_def = None + + const_func_def = CxxFuncDefNode( + name=name, arg_decls=[], - return_type=blink_type_info(member.idl_type).ref_t, + return_type=blink_type.const_ref_t, const=True) - func_def.set_base_template_vars(cg_context.template_bindings()) - body = func_def.body - - body.extend([ + const_func_def.set_base_template_vars(cg_context.template_bindings()) + const_func_def.body.extend([ TextNode(_format("DCHECK({}());", blink_member_name.has_api)), TextNode(_format("return {};", blink_member_name.value_var)), ]) - return func_def + return ListNode([func_def, const_func_def]) def make_dict_member_has_def(cg_context): @@ -789,5 +800,5 @@ def generate_dictionaries(web_idl_database): - dictionary = web_idl_database.find("OriginTrialsTestDictionary") + dictionary = web_idl_database.find("RTCQuicStreamWriteParameters") generate_dictionary(dictionary)
diff --git a/third_party/blink/renderer/core/css/resolver/font_builder.cc b/third_party/blink/renderer/core/css/resolver/font_builder.cc index 05b4e523a..e196127 100644 --- a/third_party/blink/renderer/core/css/resolver/font_builder.cc +++ b/third_party/blink/renderer/core/css/resolver/font_builder.cc
@@ -422,8 +422,7 @@ FontSelector* font_selector = document_->GetStyleEngine().GetFontSelector(); UpdateAdjustedSize(description, style, font_selector); - style.SetFontDescription(description); - style.GetFont().Update(font_selector); + style.SetFontInternal(Font(description, font_selector)); flags_ = 0; } @@ -441,10 +440,9 @@ UpdateComputedSize(font_description, document_style); font_description.SetOrientation(document_style.ComputeFontOrientation()); - document_style.SetFontDescription(font_description); FontSelector* font_selector = document_->GetStyleEngine().GetFontSelector(); - document_style.GetFont().Update(font_selector); + document_style.SetFontInternal(Font(font_description, font_selector)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 5360018..32f3704b 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -51,7 +51,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/context_menu_data/edit_flags.h" -#include "third_party/blink/public/common/devtools/web_device_emulation_params.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/input/web_keyboard_event.h" #include "third_party/blink/public/common/page/launching_process_state.h" @@ -70,6 +69,7 @@ #include "third_party/blink/public/platform/web_url_response.h" #include "third_party/blink/public/web/web_console_message.h" #include "third_party/blink/public/web/web_context_menu_data.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_document_loader.h" #include "third_party/blink/public/web/web_form_element.h" @@ -9911,8 +9911,8 @@ TEST_F(DeviceEmulationTest, DeviceSizeInvalidatedOnResize) { WebDeviceEmulationParams params; - params.screen_position = mojom::ScreenPosition::kMobile; - web_view_helper_.GetWebView()->SetDeviceEmulation(params); + params.screen_position = WebDeviceEmulationParams::kMobile; + web_view_helper_.GetWebView()->EnableDeviceEmulation(params); TestResize(WebSize(700, 500), "300x300"); TestResize(WebSize(710, 500), "400x300"); @@ -9923,7 +9923,7 @@ TestResize(WebSize(690, 490), "200x200"); TestResize(WebSize(800, 600), "400x400"); - web_view_helper_.GetWebView()->SetDeviceEmulation(base::nullopt); + web_view_helper_.GetWebView()->DisableDeviceEmulation(); } TEST_F(DeviceEmulationTest, PointerAndHoverTypes) {
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index ca83daa..43fc2bb 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1476,10 +1476,14 @@ fullscreen_controller_->DidExitFullscreen(); } -void WebViewImpl::SetWebFrameWidget(WebFrameWidget* widget) { +void WebViewImpl::SetMainFrameWidgetBase(WebFrameWidgetBase* widget) { web_widget_ = widget; } +WebFrameWidgetBase* WebViewImpl::MainFrameWidgetBase() { + return web_widget_; +} + void WebViewImpl::SetSuppressFrameRequestsWorkaroundFor704763Only( bool suppress_frame_requests) { AsView().page->Animator().SetSuppressFrameRequestsWorkaroundFor704763Only( @@ -2859,13 +2863,18 @@ return device_emulation_transform_; } -void WebViewImpl::SetDeviceEmulation( - const base::Optional<WebDeviceEmulationParams>& params) { +void WebViewImpl::EnableDeviceEmulation( + const WebDeviceEmulationParams& params) { TransformationMatrix device_emulation_transform = - dev_tools_emulator_->SetDeviceEmulation(params); + dev_tools_emulator_->EnableDeviceEmulation(params); SetDeviceEmulationTransform(device_emulation_transform); } +void WebViewImpl::DisableDeviceEmulation() { + dev_tools_emulator_->DisableDeviceEmulation(); + SetDeviceEmulationTransform(TransformationMatrix()); +} + void WebViewImpl::PerformCustomContextMenuAction(unsigned action) { if (AsView().page) { AsView().page->GetContextMenuController().CustomContextMenuItemSelected(
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index 503f1769..60cfa74 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -94,6 +94,7 @@ class WebRemoteFrame; class WebSettingsImpl; class WebViewClient; +class WebFrameWidgetBase; struct WebTextAutosizerPageInfo; @@ -194,8 +195,8 @@ WebHitTestResult HitTestResultForTap(const gfx::Point&, const WebSize&) override; uint64_t CreateUniqueIdentifierForRequest() override; - void SetDeviceEmulation( - const base::Optional<WebDeviceEmulationParams>&) override; + void EnableDeviceEmulation(const WebDeviceEmulationParams&) override; + void DisableDeviceEmulation() override; void PerformCustomContextMenuAction(unsigned action) override; void DidCloseContextMenu() override; void CancelPagePopup() override; @@ -428,7 +429,8 @@ void DidEnterFullscreen(); void DidExitFullscreen(); - void SetWebFrameWidget(WebFrameWidget* widget); + void SetMainFrameWidgetBase(WebFrameWidgetBase* widget); + WebFrameWidgetBase* MainFrameWidgetBase(); private: FRIEND_TEST_ALL_PREFIXES(WebFrameTest, DivScrollIntoEditableTest); @@ -715,7 +717,7 @@ // The WebWidget for the main frame. This is expected to be unset when the // WebWidget destroys itself. - WebFrameWidget* web_widget_ = nullptr; + WeakPersistent<WebFrameWidgetBase> web_widget_; // We defer commits when transitioning to a new page. ChromeClientImpl calls // StopDeferringCommits() to release this when a new page is loaded.
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index 0c33a9c..558c9b1 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -48,7 +48,6 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" -#include "third_party/blink/public/common/devtools/web_device_emulation_params.h" #include "third_party/blink/public/common/frame/frame_owner_element_type.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/input/web_keyboard_event.h" @@ -63,6 +62,7 @@ #include "third_party/blink/public/public_buildflags.h" #include "third_party/blink/public/web/web_autofill_client.h" #include "third_party/blink/public/web/web_console_message.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_element.h" #include "third_party/blink/public/web/web_frame.h" @@ -2358,15 +2358,15 @@ float page_scale_expected = web_view_impl->PageScaleFactor(); WebDeviceEmulationParams params; - params.screen_position = mojom::ScreenPosition::kDesktop; + params.screen_position = WebDeviceEmulationParams::kDesktop; params.device_scale_factor = 0; params.scale = 1; - web_view_impl->SetDeviceEmulation(params); + web_view_impl->EnableDeviceEmulation(params); web_view_impl->SetPageScaleFactor(2); - web_view_impl->SetDeviceEmulation(base::nullopt); + web_view_impl->DisableDeviceEmulation(); EXPECT_EQ(page_scale_expected, web_view_impl->PageScaleFactor()); } @@ -4966,14 +4966,14 @@ WebDeviceEmulationParams emulation_params; emulation_params.scale = 2.f; - web_view_impl->SetDeviceEmulation(emulation_params); + web_view_impl->EnableDeviceEmulation(emulation_params); expected_matrix.MakeIdentity().Scale(2.f); EXPECT_EQ(expected_matrix, web_view_impl->GetDeviceEmulationTransform()); // Device metrics offset and scale are applied before viewport override. emulation_params.viewport_offset = gfx::PointF(5, 10); emulation_params.viewport_scale = 1.5f; - web_view_impl->SetDeviceEmulation(emulation_params); + web_view_impl->EnableDeviceEmulation(emulation_params); expected_matrix.MakeIdentity() .Scale(1.5f) .Translate(-5, -10) @@ -5005,7 +5005,7 @@ WebDeviceEmulationParams emulation_params; emulation_params.viewport_offset = gfx::PointF(50, 55); emulation_params.viewport_scale = 2.f; - web_view_impl->SetDeviceEmulation(emulation_params); + web_view_impl->EnableDeviceEmulation(emulation_params); expected_matrix.MakeIdentity() .Scale(2.f) .Translate(-50, -55) @@ -5190,17 +5190,17 @@ EXPECT_NE(nullptr, frame_view->LayoutViewport()->VerticalScrollbar()); WebDeviceEmulationParams params; - params.screen_position = mojom::ScreenPosition::kMobile; + params.screen_position = WebDeviceEmulationParams::kMobile; params.device_scale_factor = 0; params.scale = 1; - web_view->SetDeviceEmulation(params); + web_view->EnableDeviceEmulation(params); // The visual viewport should now proivde the scrollbars instead of the view. EXPECT_TRUE(frame_view->VisualViewportSuppliesScrollbars()); EXPECT_EQ(nullptr, frame_view->LayoutViewport()->VerticalScrollbar()); - web_view->SetDeviceEmulation(base::nullopt); + web_view->DisableDeviceEmulation(); // The view should once again provide the scrollbars. EXPECT_FALSE(frame_view->VisualViewportSuppliesScrollbars());
diff --git a/third_party/blink/renderer/core/frame/frame_overlay_test.cc b/third_party/blink/renderer/core/frame/frame_overlay_test.cc index 82cfce5..62132d7 100644 --- a/third_party/blink/renderer/core/frame/frame_overlay_test.cc +++ b/third_party/blink/renderer/core/frame/frame_overlay_test.cc
@@ -8,7 +8,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/devtools/web_device_emulation_params.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -116,7 +116,7 @@ TEST_P(FrameOverlayTest, DeviceEmulationScale) { WebDeviceEmulationParams params; params.scale = 1.5; - GetWebView()->SetDeviceEmulation(params); + GetWebView()->EnableDeviceEmulation(params); GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( DocumentUpdateReason::kTest);
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc index 90bb1ef..c0d594d 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -13,13 +13,13 @@ #include "cc/trees/transform_node.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/devtools/web_device_emulation_params.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/platform/web_coalesced_input_event.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" #include "third_party/blink/public/web/web_ax_context.h" #include "third_party/blink/public/web/web_context_menu_data.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_local_frame_client.h" #include "third_party/blink/public/web/web_script_source.h" @@ -2593,7 +2593,7 @@ WebDeviceEmulationParams params; params.viewport_offset = gfx::PointF(); params.viewport_scale = 1.f; - WebView()->SetDeviceEmulation(params); + WebView()->EnableDeviceEmulation(params); UpdateAllLifecyclePhasesExceptPaint(); EXPECT_FALSE(visual_viewport.GetDeviceEmulationTransformNode()); @@ -2603,7 +2603,7 @@ // Set device mulation with viewport offset should repaint visual viewport. params.viewport_offset = gfx::PointF(314, 159); - WebView()->SetDeviceEmulation(params); + WebView()->EnableDeviceEmulation(params); UpdateAllLifecyclePhasesExceptPaint(); EXPECT_TRUE(GetFrame()->View()->VisualViewportNeedsRepaint()); @@ -2617,7 +2617,7 @@ // Change device emulation with scale should not repaint visual viewport. params.viewport_offset = gfx::PointF(); params.viewport_scale = 1.5f; - WebView()->SetDeviceEmulation(params); + WebView()->EnableDeviceEmulation(params); UpdateAllLifecyclePhasesExceptPaint(); EXPECT_FALSE(GetFrame()->View()->VisualViewportNeedsRepaint()); @@ -2629,7 +2629,7 @@ // Set an identity device emulation transform and ensure the transform // paint property node is cleared and repaint visual viewport. - WebView()->SetDeviceEmulation(WebDeviceEmulationParams()); + WebView()->EnableDeviceEmulation(WebDeviceEmulationParams()); UpdateAllLifecyclePhasesExceptPaint(); EXPECT_TRUE(GetFrame()->View()->VisualViewportNeedsRepaint()); EXPECT_FALSE(visual_viewport.GetDeviceEmulationTransformNode()); @@ -2685,21 +2685,21 @@ WebDeviceEmulationParams params; params.viewport_offset = gfx::PointF(); params.viewport_scale = 1.5f; - WebView()->SetDeviceEmulation(params); + WebView()->EnableDeviceEmulation(params); UpdateAllLifecyclePhases(); ASSERT_EQ(scrollbar, GetFrame()->View()->RootCcLayer()->children().back().get()); check_scrollbar(scrollbar, 1.5f); params.viewport_scale = 1.f; - WebView()->SetDeviceEmulation(params); + WebView()->EnableDeviceEmulation(params); UpdateAllLifecyclePhases(); ASSERT_EQ(scrollbar, GetFrame()->View()->RootCcLayer()->children().back().get()); check_scrollbar(scrollbar, 1.f); params.viewport_scale = 0.75f; - WebView()->SetDeviceEmulation(params); + WebView()->EnableDeviceEmulation(params); UpdateAllLifecyclePhases(); ASSERT_EQ(scrollbar, GetFrame()->View()->RootCcLayer()->children().back().get());
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc index 241e51c..74d7118 100644 --- a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc +++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
@@ -30,7 +30,7 @@ std::move(widget)), web_view_(&web_view), self_keep_alive_(PERSISTENT_FROM_HERE, this) { - web_view_->SetWebFrameWidget(this); + web_view_->SetMainFrameWidgetBase(this); } WebViewFrameWidget::~WebViewFrameWidget() = default; @@ -39,7 +39,7 @@ GetPage()->WillCloseAnimationHost(nullptr); // Closing the WebViewFrameWidget happens in response to the local main frame // being detached from the Page/WebViewImpl. - web_view_->SetWebFrameWidget(nullptr); + web_view_->SetMainFrameWidgetBase(nullptr); web_view_ = nullptr; WebFrameWidgetBase::Close(); self_keep_alive_.Clear();
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc index 6835a35..9755fc7 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
@@ -99,112 +99,9 @@ : nullptr; if (Is3d()) { - CanvasResourceProvider::ResourceUsage usage; - if (SharedGpuContext::IsGpuCompositingEnabled()) { - if (LowLatencyEnabled()) { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedDirect3DResourceUsage; - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedCompositedResourceUsage; - } - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kSoftwareCompositedResourceUsage; - } - - uint8_t presentation_mode = - CanvasResourceProvider::kDefaultPresentationMode; - if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) { - presentation_mode |= - CanvasResourceProvider::kAllowImageChromiumPresentationMode; - } - if (RenderingContext() && RenderingContext()->UsingSwapChain()) { - DCHECK(LowLatencyEnabled()); - // Allow swap chain presentation only if 3d context is using a swap - // chain since we'll be importing it as a passthrough texture. - presentation_mode |= - CanvasResourceProvider::kAllowSwapChainPresentationMode; - } - - base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderUsage", - usage); - ReplaceResourceProvider(CanvasResourceProvider::Create( - Size(), usage, SharedGpuContext::ContextProviderWrapper(), - 0 /* msaa_sample_count */, FilterQuality(), ColorParams(), - presentation_mode, std::move(dispatcher), - RenderingContext()->IsOriginTopLeft())); - if (ResourceProvider() && ResourceProvider()->IsValid()) { - base::UmaHistogramBoolean( - "Blink.Canvas.ResourceProviderIsAccelerated", - ResourceProvider()->IsAccelerated()); - base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType", - ResourceProvider()->GetType()); - } + CreateCanvasResourceProvider3D(hint, dispatcher); } else { - DCHECK(Is2d()); - const bool want_acceleration = - hint == kPreferAcceleration && ShouldAccelerate2dContext(); - - CanvasResourceProvider::ResourceUsage usage; - if (want_acceleration) { - if (LowLatencyEnabled()) { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedDirect2DResourceUsage; - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedCompositedResourceUsage; - } - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kSoftwareCompositedResourceUsage; - } - - uint8_t presentation_mode = - CanvasResourceProvider::kDefaultPresentationMode; - // Allow GMB image resources if the runtime feature is enabled or if - // we want to use it for low latency mode. - if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() || - (base::FeatureList::IsEnabled( - features::kLowLatencyCanvas2dImageChromium) && - LowLatencyEnabled() && want_acceleration)) { - presentation_mode |= - CanvasResourceProvider::kAllowImageChromiumPresentationMode; - } - // Allow swap chains only if the runtime feature is enabled and we're - // in low latency mode too. - if (base::FeatureList::IsEnabled( - features::kLowLatencyCanvas2dSwapChain) && - LowLatencyEnabled() && want_acceleration) { - presentation_mode |= - CanvasResourceProvider::kAllowSwapChainPresentationMode; - } - - // It is important to not use the context's IsOriginTopLeft() here - // because that denotes the current state and could change after the - // new resource provider is created e.g. due to switching between - // unaccelerated and accelerated modes during tab switching. - const bool is_origin_top_left = - !want_acceleration || LowLatencyEnabled(); - - base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderUsage", - usage); - ReplaceResourceProvider(CanvasResourceProvider::Create( - Size(), usage, SharedGpuContext::ContextProviderWrapper(), - GetMSAASampleCountFor2dContext(), FilterQuality(), ColorParams(), - presentation_mode, std::move(dispatcher), is_origin_top_left)); - - if (ResourceProvider()) { - if (ResourceProvider()->IsValid()) { - base::UmaHistogramBoolean( - "Blink.Canvas.ResourceProviderIsAccelerated", - ResourceProvider()->IsAccelerated()); - base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType", - ResourceProvider()->GetType()); - } - ResourceProvider()->SetFilterQuality(FilterQuality()); - ResourceProvider()->SetResourceRecyclingEnabled(true); - } + CreateCanvasResourceProvider2D(hint, dispatcher); } } if (!ResourceProvider()) @@ -213,6 +110,111 @@ return ResourceProvider(); } +void CanvasRenderingContextHost::CreateCanvasResourceProvider3D( + AccelerationHint hint, + base::WeakPtr<CanvasResourceDispatcher> dispatcher) { + DCHECK(Is3d()); + + uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode; + if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) { + presentation_mode |= + CanvasResourceProvider::kAllowImageChromiumPresentationMode; + } + + CanvasResourceProvider::ResourceUsage usage; + if (SharedGpuContext::IsGpuCompositingEnabled()) { + if (LowLatencyEnabled() && RenderingContext() && + RenderingContext()->UsingSwapChain()) { + // Allow swap chain presentation only if 3d context is using a swap + // chain since we'll be importing it as a passthrough texture. + usage = CanvasResourceProvider::ResourceUsage:: + kAcceleratedDirect3DResourceUsage; + presentation_mode |= + CanvasResourceProvider::kAllowSwapChainPresentationMode; + } else { + usage = CanvasResourceProvider::ResourceUsage:: + kAcceleratedCompositedResourceUsage; + } + } else { + usage = + CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage; + } + + base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderUsage", usage); + ReplaceResourceProvider(CanvasResourceProvider::Create( + Size(), usage, SharedGpuContext::ContextProviderWrapper(), + 0 /* msaa_sample_count */, FilterQuality(), ColorParams(), + presentation_mode, std::move(dispatcher), + RenderingContext()->IsOriginTopLeft())); + if (ResourceProvider() && ResourceProvider()->IsValid()) { + base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated", + ResourceProvider()->IsAccelerated()); + base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType", + ResourceProvider()->GetType()); + } +} + +void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( + AccelerationHint hint, + base::WeakPtr<CanvasResourceDispatcher> dispatcher) { + DCHECK(Is2d()); + const bool want_acceleration = + hint == kPreferAcceleration && ShouldAccelerate2dContext(); + + uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode; + // Allow GMB image resources if the runtime feature is enabled or if + // we want to use it for low latency mode. + if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() || + (base::FeatureList::IsEnabled( + features::kLowLatencyCanvas2dImageChromium) && + LowLatencyEnabled() && want_acceleration)) { + presentation_mode |= + CanvasResourceProvider::kAllowImageChromiumPresentationMode; + } + + CanvasResourceProvider::ResourceUsage usage; + if (want_acceleration) { + if (LowLatencyEnabled() && + base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain)) { + // Allow swap chains only if the runtime feature is enabled and we're + // in low latency mode too. + usage = CanvasResourceProvider::ResourceUsage:: + kAcceleratedDirect2DResourceUsage; + presentation_mode |= + CanvasResourceProvider::kAllowSwapChainPresentationMode; + } else { + usage = CanvasResourceProvider::ResourceUsage:: + kAcceleratedCompositedResourceUsage; + } + } else { + usage = + CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage; + } + + // It is important to not use the context's IsOriginTopLeft() here + // because that denotes the current state and could change after the + // new resource provider is created e.g. due to switching between + // unaccelerated and accelerated modes during tab switching. + const bool is_origin_top_left = !want_acceleration || LowLatencyEnabled(); + + base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderUsage", usage); + ReplaceResourceProvider(CanvasResourceProvider::Create( + Size(), usage, SharedGpuContext::ContextProviderWrapper(), + GetMSAASampleCountFor2dContext(), FilterQuality(), ColorParams(), + presentation_mode, std::move(dispatcher), is_origin_top_left)); + + if (ResourceProvider()) { + if (ResourceProvider()->IsValid()) { + base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated", + ResourceProvider()->IsAccelerated()); + base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType", + ResourceProvider()->GetType()); + } + ResourceProvider()->SetFilterQuality(FilterQuality()); + ResourceProvider()->SetResourceRecyclingEnabled(true); + } +} + CanvasColorParams CanvasRenderingContextHost::ColorParams() const { if (RenderingContext()) return RenderingContext()->ColorParams();
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h index be22ce7b..e0503886 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h
@@ -110,6 +110,13 @@ scoped_refptr<StaticBitmapImage> CreateTransparentImage(const IntSize&) const; + void CreateCanvasResourceProvider2D( + AccelerationHint hint, + base::WeakPtr<CanvasResourceDispatcher> dispatcher); + void CreateCanvasResourceProvider3D( + AccelerationHint hint, + base::WeakPtr<CanvasResourceDispatcher> dispatcher); + bool did_fail_to_create_resource_provider_ = false; bool did_record_canvas_size_to_uma_ = false; HostType host_type_ = kNone;
diff --git a/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc index 1dd6703..279776c 100644 --- a/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc
@@ -236,7 +236,7 @@ } void CSSPreloadScanner::EmitRule(const SegmentedString& source) { - if (DeprecatedEqualIgnoringCase(rule_, "import")) { + if (EqualIgnoringASCIICase(rule_, "import")) { String url = ParseCSSStringOrURL(rule_value_.ToString()); TextPosition position = TextPosition(source.CurrentLine(), source.CurrentColumn()); @@ -250,7 +250,7 @@ requests_->push_back(std::move(request)); } state_ = kInitial; - } else if (DeprecatedEqualIgnoringCase(rule_, "charset")) + } else if (EqualIgnoringASCIICase(rule_, "charset")) state_ = kInitial; else state_ = kDoneParsingImportRules;
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc index 6ce0ad9..b36be7c8 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc +++ b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
@@ -6,7 +6,6 @@ #include <algorithm> -#include "third_party/blink/public/mojom/devtools/device_emulation_params.mojom-blink.h" #include "third_party/blink/public/web/web_settings.h" #include "third_party/blink/renderer/core/events/web_input_event_conversion.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" @@ -63,6 +62,7 @@ DevToolsEmulator::DevToolsEmulator(WebViewImpl* web_view) : web_view_(web_view), + device_metrics_enabled_(false), emulate_mobile_enabled_(false), is_overlay_scrollbars_enabled_(false), is_orientation_event_enabled_(false), @@ -110,14 +110,16 @@ void DevToolsEmulator::SetTextAutosizingEnabled(bool enabled) { embedder_text_autosizing_enabled_ = enabled; - bool emulate_mobile_enabled = emulation_params_ && emulate_mobile_enabled_; + bool emulate_mobile_enabled = + device_metrics_enabled_ && emulate_mobile_enabled_; if (!emulate_mobile_enabled) web_view_->GetPage()->GetSettings().SetTextAutosizingEnabled(enabled); } void DevToolsEmulator::SetDeviceScaleAdjustment(float device_scale_adjustment) { embedder_device_scale_adjustment_ = device_scale_adjustment; - bool emulate_mobile_enabled = emulation_params_ && emulate_mobile_enabled_; + bool emulate_mobile_enabled = + device_metrics_enabled_ && emulate_mobile_enabled_; if (!emulate_mobile_enabled) { web_view_->GetPage()->GetSettings().SetDeviceScaleAdjustment( device_scale_adjustment); @@ -129,7 +131,8 @@ return; embedder_prefer_compositing_to_lcd_text_enabled_ = enabled; - bool emulate_mobile_enabled = emulation_params_ && emulate_mobile_enabled_; + bool emulate_mobile_enabled = + device_metrics_enabled_ && emulate_mobile_enabled_; if (!emulate_mobile_enabled) { web_view_->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled( enabled); @@ -138,14 +141,16 @@ void DevToolsEmulator::SetViewportStyle(WebViewportStyle style) { embedder_viewport_style_ = style; - bool emulate_mobile_enabled = emulation_params_ && emulate_mobile_enabled_; + bool emulate_mobile_enabled = + device_metrics_enabled_ && emulate_mobile_enabled_; if (!emulate_mobile_enabled) web_view_->GetPage()->GetSettings().SetViewportStyle(style); } void DevToolsEmulator::SetPluginsEnabled(bool enabled) { embedder_plugins_enabled_ = enabled; - bool emulate_mobile_enabled = emulation_params_ && emulate_mobile_enabled_; + bool emulate_mobile_enabled = + device_metrics_enabled_ && emulate_mobile_enabled_; if (!emulate_mobile_enabled) web_view_->GetPage()->GetSettings().SetPluginsEnabled(enabled); } @@ -178,7 +183,8 @@ void DevToolsEmulator::SetMainFrameResizesAreOrientationChanges(bool value) { embedder_main_frame_resizes_are_orientation_changes_ = value; - bool emulate_mobile_enabled = emulation_params_ && emulate_mobile_enabled_; + bool emulate_mobile_enabled = + device_metrics_enabled_ && emulate_mobile_enabled_; if (!emulate_mobile_enabled) { web_view_->GetPage() ->GetSettings() @@ -210,40 +216,35 @@ web_view_->GetPage()->GetSettings().SetPrimaryHoverType(hover_type); } -TransformationMatrix DevToolsEmulator::SetDeviceEmulation( - const base::Optional<blink::WebDeviceEmulationParams>& params) { - if (!params) { - DisableDeviceEmulation(); - return TransformationMatrix(); - } - if (emulation_params_ && emulation_params_->view_size == params->view_size && - emulation_params_->screen_position == params->screen_position && - emulation_params_->device_scale_factor == params->device_scale_factor && - emulation_params_->scale == params->scale && - emulation_params_->viewport_offset == params->viewport_offset && - emulation_params_->viewport_scale == params->viewport_scale) { +TransformationMatrix DevToolsEmulator::EnableDeviceEmulation( + const WebDeviceEmulationParams& params) { + if (device_metrics_enabled_ && + emulation_params_.view_size == params.view_size && + emulation_params_.screen_position == params.screen_position && + emulation_params_.device_scale_factor == params.device_scale_factor && + emulation_params_.scale == params.scale && + emulation_params_.viewport_offset == params.viewport_offset && + emulation_params_.viewport_scale == params.viewport_scale) { return ComputeRootLayerTransform(); } - if (!emulation_params_ || - emulation_params_->device_scale_factor != params->device_scale_factor) { + if (emulation_params_.device_scale_factor != params.device_scale_factor || + !device_metrics_enabled_) GetMemoryCache()->EvictResources(); - } emulation_params_ = params; + device_metrics_enabled_ = true; web_view_->GetPage()->GetSettings().SetDeviceScaleAdjustment( - calculateDeviceScaleAdjustment(params->view_size.width(), - params->view_size.height(), - params->device_scale_factor)); + calculateDeviceScaleAdjustment(params.view_size.width, + params.view_size.height, + params.device_scale_factor)); - if (params->screen_position == mojom::blink::ScreenPosition::kMobile) { + if (params.screen_position == WebDeviceEmulationParams::kMobile) EnableMobileEmulation(); - } else { + else DisableMobileEmulation(); - } - web_view_->SetCompositorDeviceScaleFactorOverride( - params->device_scale_factor); + web_view_->SetCompositorDeviceScaleFactorOverride(params.device_scale_factor); // TODO(wjmaclean): Tell all local frames in the WebView's frame tree, not // just a local main frame. @@ -253,18 +254,18 @@ document->MediaQueryAffectingValueChanged(); } - if (params->viewport_offset.x() >= 0) - return ForceViewport(params->viewport_offset, params->viewport_scale); - - return ResetViewport(); + if (params.viewport_offset.x() >= 0) + return ForceViewport(params.viewport_offset, params.viewport_scale); + else + return ResetViewport(); } void DevToolsEmulator::DisableDeviceEmulation() { - if (!emulation_params_) + if (!device_metrics_enabled_) return; GetMemoryCache()->EvictResources(); - emulation_params_ = base::nullopt; + device_metrics_enabled_ = false; web_view_->GetPage()->GetSettings().SetDeviceScaleAdjustment( embedder_device_scale_adjustment_); DisableMobileEmulation(); @@ -415,8 +416,8 @@ // Apply device emulation transform first, so that it is affected by the // viewport override. ApplyViewportOverride(&transform); - if (emulation_params_) - transform.Scale(emulation_params_->scale); + if (device_metrics_enabled_) + transform.Scale(emulation_params_.scale); return transform; } @@ -436,7 +437,7 @@ } float DevToolsEmulator::InputEventsScaleForEmulation() { - return emulation_params_ ? emulation_params_->scale : 1.0; + return device_metrics_enabled_ ? emulation_params_.scale : 1.0; } void DevToolsEmulator::SetTouchEventEmulationEnabled(bool enabled,
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_emulator.h b/third_party/blink/renderer/core/inspector/dev_tools_emulator.h index 464155a..67aeaa498 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_emulator.h +++ b/third_party/blink/renderer/core/inspector/dev_tools_emulator.h
@@ -7,9 +7,9 @@ #include <memory> #include "base/optional.h" -#include "third_party/blink/public/common/devtools/web_device_emulation_params.h" #include "third_party/blink/public/platform/pointer_properties.h" #include "third_party/blink/public/platform/web_viewport_style.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" @@ -47,11 +47,11 @@ void SetPrimaryHoverType(HoverType); void SetMainFrameResizesAreOrientationChanges(bool); - // Sets the parameters for emulation (enables emulation if it hasn't been - // previously enabled and disables it if params is null). - // Returns the emulation transform to be used as a result. - TransformationMatrix SetDeviceEmulation( - const base::Optional<blink::WebDeviceEmulationParams>& params); + // Enables and/or sets the parameters for emulation. Returns the emulation + // transform to be used as a result. + TransformationMatrix EnableDeviceEmulation(const WebDeviceEmulationParams&); + // Disables emulation. + void DisableDeviceEmulation(); bool ResizeIsDeviceSizeChange(); void SetTouchEventEmulationEnabled(bool, int max_touch_points); @@ -87,7 +87,6 @@ private: void EnableMobileEmulation(); void DisableMobileEmulation(); - void DisableDeviceEmulation(); // Enables viewport override and returns the emulation transform to be used. // The |position| is in CSS pixels, and |scale| is relative to a page scale of @@ -105,8 +104,9 @@ WebViewImpl* web_view_; + bool device_metrics_enabled_; bool emulate_mobile_enabled_; - base::Optional<blink::WebDeviceEmulationParams> emulation_params_; + WebDeviceEmulationParams emulation_params_; struct ViewportOverride { FloatPoint position;
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index a6f08dde..d4a8211 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -3361,10 +3361,10 @@ if (IsBox()) return false; // Non-LayoutBox objects (such as LayoutInline) don't necessarily create NG - // LayoutObjects, even if they are laid out by an NG container. Allow their - // fragments to be traversed, assuming that we're contained by an NG - // container. - DCHECK(RootInlineFormattingContext()); + // LayoutObjects. If they are laid out by an NG container, though, we may be + // allowed to traverse their fragments. Otherwise, bail now. + if (!IsInLayoutNGInlineFormattingContext()) + return false; } // Bail if we have an NGPaintFragment. NGPaintFragment will be removed, and we // will not attempt to add support for them here.
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc index 70e54c14..a8efe8b0 100644 --- a/third_party/blink/renderer/core/layout/scrollbars_test.cc +++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -1360,8 +1360,8 @@ // Turn on mobile emulator. WebDeviceEmulationParams params; - params.screen_position = mojom::ScreenPosition::kMobile; - WebView().SetDeviceEmulation(params); + params.screen_position = WebDeviceEmulationParams::kMobile; + WebView().EnableDeviceEmulation(params); // For root Scrollbar, mobile emulator will change them to page VisualViewport // scrollbar layer. @@ -1371,7 +1371,7 @@ EXPECT_TRUE(div_scrollable->VerticalScrollbar()->IsCustomScrollbar()); // Turn off mobile emulator. - WebView().SetDeviceEmulation(base::nullopt); + WebView().DisableDeviceEmulation(); EXPECT_TRUE(root_scrollable->VerticalScrollbar()); EXPECT_TRUE(root_scrollable->VerticalScrollbar()->IsCustomScrollbar()); @@ -1611,8 +1611,8 @@ // Turn on mobile emulator. WebDeviceEmulationParams params; - params.screen_position = mojom::ScreenPosition::kMobile; - WebView().SetDeviceEmulation(params); + params.screen_position = WebDeviceEmulationParams::kMobile; + WebView().EnableDeviceEmulation(params); // For root Scrollbar, mobile emulator will change them to page VisualViewport // scrollbar layer. @@ -1621,8 +1621,9 @@ // Ensure div scrollbar also change to mobile overlay theme. EXPECT_TRUE(div_scrollable->VerticalScrollbar()->IsOverlayScrollbar()); EXPECT_TRUE(div_scrollable->VerticalScrollbar()->IsSolidColor()); + // Turn off mobile emulator. - WebView().SetDeviceEmulation(base::nullopt); + WebView().DisableDeviceEmulation(); EXPECT_TRUE(root_scrollable->VerticalScrollbar()); EXPECT_FALSE(root_scrollable->VerticalScrollbar()->IsCustomScrollbar());
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index e4af0e7..a238c82 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -569,7 +569,18 @@ } } - new_image_content = ImageResourceContent::Fetch(params, document.Fetcher()); + if (lazy_image_load_state_ == LazyImageLoadState::kDeferred && + was_fully_deferred_ && !ShouldLoadImmediately(url)) { + // TODO(rajendrant): Remove this temporary workaround of creating a 1x1 + // placeholder to fix an intersection observer issue not firing with + // certain styles (https://crbug.com/992765). Instead + // NoImageResourceToLoad() should be skipped when the image is deferred. + // https://crbug.com/999209 + new_image_content = ImageResourceContent::CreateLazyImagePlaceholder(); + } else { + new_image_content = + ImageResourceContent::Fetch(params, document.Fetcher()); + } // If this load is starting while navigating away, treat it as an auditing // keepalive request, and don't report its results back to the element.
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index 455ede2..ff279d31 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -161,11 +161,6 @@ page->prev_related_page_ = opener; page->next_related_page_ = next; next->prev_related_page_ = page; - - // No need to update |prev| here as if |next| != |prev|, |prev| was already - // marked as having related pages. - next->UpdateHasRelatedPages(); - page->UpdateHasRelatedPages(); } OrdinaryPages().insert(page); @@ -315,9 +310,6 @@ main_frame_ = main_frame; page_scheduler_->SetIsMainFrameLocal(main_frame->IsLocalFrame()); - // |has_related_pages_| is only reported when the main frame is local, so make - // sure it's updated after the main frame changes. - UpdateHasRelatedPages(); } LocalFrame* Page::DeprecatedLocalMainFrame() const { @@ -865,8 +857,6 @@ mojom::blink::ScrollType::kProgrammatic, mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback()); - // Update |has_related_pages_| as features are reset after navigation. - UpdateHasRelatedPages(); } GetLinkHighlight().ResetForPageNavigation(); } @@ -949,10 +939,6 @@ prev->next_related_page_ = next; this->prev_related_page_ = nullptr; this->next_related_page_ = nullptr; - if (prev != this) - prev->UpdateHasRelatedPages(); - if (next != this) - next->UpdateHasRelatedPages(); } if (scrolling_coordinator_) @@ -1049,22 +1035,6 @@ return inside_portal_; } -void Page::UpdateHasRelatedPages() { - bool has_related_pages = next_related_page_ != this; - if (!has_related_pages) { - has_related_pages_.reset(); - } else { - LocalFrame* local_main_frame = DynamicTo<LocalFrame>(main_frame_.Get()); - // We want to record this only for the pages which have local main frame, - // which is fine as we are aggregating results across all processes. - if (!local_main_frame || !local_main_frame->IsAttached()) - return; - has_related_pages_ = local_main_frame->GetFrameScheduler()->RegisterFeature( - SchedulingPolicy::Feature::kHasScriptableFramesInMultipleTabs, - {SchedulingPolicy::RecordMetricsForBackForwardCache()}); - } -} - void Page::SetMediaFeatureOverride(const AtomicString& media_feature, const String& value) { if (!media_feature_overrides_) {
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h index b16f7f5f1..1074204d 100644 --- a/third_party/blink/renderer/core/page/page.h +++ b/third_party/blink/renderer/core/page/page.h
@@ -367,11 +367,8 @@ void SetPageScheduler(std::unique_ptr<PageScheduler>); - void UpdateHasRelatedPages(); - void InvalidateColorScheme(); void InvalidatePaint(); - // Typically, the main frame and Page should both be owned by the embedder, // which must call Page::willBeDestroyed() prior to destroying Page. This // call detaches the main frame and clears this pointer, thus ensuring that
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc index b14fbbf..aad1e1eb 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -74,8 +74,8 @@ public: ScrollingTest() : base_url_("http://www.test.com/") { helper_.Initialize(nullptr, nullptr, nullptr, &ConfigureSettings); - GetWebView()->MainFrameWidget()->Resize(IntSize(320, 240)); - GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + GetWebView()->MainFrameWidgetBase()->Resize(IntSize(320, 240)); + GetWebView()->MainFrameWidgetBase()->UpdateAllLifecyclePhases( DocumentUpdateReason::kTest); } @@ -93,7 +93,7 @@ } void ForceFullCompositingUpdate() { - GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + GetWebView()->MainFrameWidgetBase()->UpdateAllLifecyclePhases( DocumentUpdateReason::kTest); } @@ -193,7 +193,7 @@ INSTANTIATE_PAINT_TEST_SUITE_P(ScrollingTest); TEST_P(ScrollingTest, fastScrollingByDefault) { - GetWebView()->MainFrameWidget()->Resize(WebSize(800, 600)); + GetWebView()->MainFrameWidgetBase()->Resize(WebSize(800, 600)); LoadHTML("<div id='spacer' style='height: 1000px'></div>"); ForceFullCompositingUpdate(); @@ -1443,10 +1443,10 @@ // After an initial compositing update, we should have one scrolling update // recorded as PreFCP. - GetWebView()->MainFrameWidget()->RecordStartOfFrameMetrics(); + GetWebView()->MainFrameWidgetBase()->RecordStartOfFrameMetrics(); ForceFullCompositingUpdate(); - GetWebView()->MainFrameWidget()->RecordEndOfFrameMetrics(base::TimeTicks(), - 0); + GetWebView()->MainFrameWidgetBase()->RecordEndOfFrameMetrics( + base::TimeTicks(), 0); histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 1); histogram_tester.ExpectTotalCount( "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1); @@ -1456,10 +1456,10 @@ "Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 0); // An update with no scrolling changes should not cause a scrolling update. - GetWebView()->MainFrameWidget()->RecordStartOfFrameMetrics(); + GetWebView()->MainFrameWidgetBase()->RecordStartOfFrameMetrics(); ForceFullCompositingUpdate(); - GetWebView()->MainFrameWidget()->RecordEndOfFrameMetrics(base::TimeTicks(), - 0); + GetWebView()->MainFrameWidgetBase()->RecordEndOfFrameMetrics( + base::TimeTicks(), 0); histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 1); histogram_tester.ExpectTotalCount( "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1); @@ -1475,10 +1475,10 @@ auto* background = GetFrame()->GetDocument()->getElementById("bg"); background->removeAttribute(html_names::kStyleAttr); background->setInnerHTML("Some Text"); - GetWebView()->MainFrameWidget()->RecordStartOfFrameMetrics(); + GetWebView()->MainFrameWidgetBase()->RecordStartOfFrameMetrics(); ForceFullCompositingUpdate(); - GetWebView()->MainFrameWidget()->RecordEndOfFrameMetrics(base::TimeTicks(), - 0); + GetWebView()->MainFrameWidgetBase()->RecordEndOfFrameMetrics( + base::TimeTicks(), 0); histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 2); histogram_tester.ExpectTotalCount( "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 2); @@ -1490,10 +1490,10 @@ // Removing a scrollable area should cause a scrolling update. auto* scroller = GetFrame()->GetDocument()->getElementById("scroller"); scroller->removeAttribute(html_names::kStyleAttr); - GetWebView()->MainFrameWidget()->RecordStartOfFrameMetrics(); + GetWebView()->MainFrameWidgetBase()->RecordStartOfFrameMetrics(); ForceFullCompositingUpdate(); - GetWebView()->MainFrameWidget()->RecordEndOfFrameMetrics(base::TimeTicks(), - 0); + GetWebView()->MainFrameWidgetBase()->RecordEndOfFrameMetrics( + base::TimeTicks(), 0); histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 3); histogram_tester.ExpectTotalCount( "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 2);
diff --git a/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc b/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc index 83ce223..5466f5f 100644 --- a/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc +++ b/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
@@ -62,15 +62,13 @@ DCHECK(SVGResourcesCache::CachedResourcesForLayoutObject(object_)); DCHECK( SVGResourcesCache::CachedResourcesForLayoutObject(object_)->Filter()); - DCHECK(filter_recording_context_); - - if (filter_data_->ContentNeedsUpdate()) - filter_data_->UpdateContent(filter_recording_context_->EndContent()); - + if (filter_recording_context_) { + filter_data_->UpdateContent( + filter_recording_context_->GetPaintRecord(paint_info_)); + filter_recording_context_ = nullptr; + } PaintFilteredContent(paint_info_.context, object_, display_item_client_, filter_data_); - // Reset the paint info after the filter effect has been completed. - filter_paint_info_ = nullptr; filter_data_ = nullptr; } } @@ -172,8 +170,6 @@ if (!filter) return true; filter->ClearInvalidationMask(); - filter_recording_context_ = - std::make_unique<SVGFilterRecordingContext>(GetPaintInfo().context); filter_data_ = SVGFilterPainter(*filter).PrepareEffect(object_); // If we have no filter data (== the filter was invalid) or if we // don't need to update the source graphics, we can short-circuit @@ -182,13 +178,8 @@ return false; // Because the filter needs to cache its contents we replace the context // during filtering with the filter's context. - GraphicsContext* filter_context = filter_recording_context_->BeginContent(); - filter_paint_info_ = - std::make_unique<PaintInfo>(*filter_context, paint_info_); - // Because we cache the filter contents and do not invalidate on paint - // invalidation rect changes, we need to paint the entire filter region - // so elements outside the initial paint (due to scrolling, etc) paint. - filter_paint_info_->ApplyInfiniteCullRect(); + filter_recording_context_ = + std::make_unique<SVGFilterRecordingContext>(paint_info_); return true; }
diff --git a/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h b/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h index 3acec4f8..7b0223b6 100644 --- a/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h +++ b/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h
@@ -93,7 +93,8 @@ ~ScopedSVGPaintState(); const PaintInfo& GetPaintInfo() const { - return filter_paint_info_ ? *filter_paint_info_ : paint_info_; + return filter_recording_context_ ? filter_recording_context_->GetPaintInfo() + : paint_info_; } // Return true if these operations aren't necessary or if they are @@ -112,7 +113,6 @@ const LayoutObject& object_; PaintInfo paint_info_; const DisplayItemClient& display_item_client_; - std::unique_ptr<PaintInfo> filter_paint_info_; FilterData* filter_data_; base::Optional<ClipPathClipper> clip_path_clipper_; std::unique_ptr<SVGFilterRecordingContext> filter_recording_context_;
diff --git a/third_party/blink/renderer/core/paint/svg_container_painter.cc b/third_party/blink/renderer/core/paint/svg_container_painter.cc index e178f973..0da8574 100644 --- a/third_party/blink/renderer/core/paint/svg_container_painter.cc +++ b/third_party/blink/renderer/core/paint/svg_container_painter.cc
@@ -83,8 +83,7 @@ if (continue_rendering) { for (LayoutObject* child = layout_svg_container_.FirstChild(); child; child = child->NextSibling()) { - auto* foreign_object = DynamicTo<LayoutSVGForeignObject>(*child); - if (child->IsSVGForeignObject()) { + if (auto* foreign_object = DynamicTo<LayoutSVGForeignObject>(*child)) { SVGForeignObjectPainter(*foreign_object) .PaintLayer(paint_state.GetPaintInfo()); } else {
diff --git a/third_party/blink/renderer/core/paint/svg_filter_painter.cc b/third_party/blink/renderer/core/paint/svg_filter_painter.cc index 6000a5d..47552d0 100644 --- a/third_party/blink/renderer/core/paint/svg_filter_painter.cc +++ b/third_party/blink/renderer/core/paint/svg_filter_painter.cc
@@ -13,36 +13,37 @@ #include "third_party/blink/renderer/core/svg/svg_filter_element.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h" #include "third_party/blink/renderer/platform/graphics/filters/source_graphic.h" +#include "third_party/blink/renderer/platform/graphics/graphics_context.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" namespace blink { -GraphicsContext* SVGFilterRecordingContext::BeginContent() { - // Create a new context so the contents of the filter can be drawn and cached. - paint_controller_ = std::make_unique<PaintController>(); - context_ = std::make_unique<GraphicsContext>(*paint_controller_); - - // Use initial_context_'s current paint chunk properties so that any new +SVGFilterRecordingContext::SVGFilterRecordingContext( + const PaintInfo& initial_paint_info) + // Create a new context so the contents of the filter can be drawn and + // cached. + : paint_controller_(std::make_unique<PaintController>()), + context_(std::make_unique<GraphicsContext>(*paint_controller_)), + paint_info_(*context_, initial_paint_info) { + // Use initial_paint_info's current paint chunk properties so that any new // chunk created during painting the content will be in the correct state. paint_controller_->UpdateCurrentPaintChunkProperties( - nullptr, - initial_context_.GetPaintController().CurrentPaintChunkProperties()); - - return context_.get(); + nullptr, initial_paint_info.context.GetPaintController() + .CurrentPaintChunkProperties()); + // Because we cache the filter contents and do not invalidate on paint + // invalidation rect changes, we need to paint the entire filter region so + // elements outside the initial paint (due to scrolling, etc) paint. + paint_info_.ApplyInfiniteCullRect(); } -sk_sp<PaintRecord> SVGFilterRecordingContext::EndContent() { - // Use the context that contains the filtered content. - DCHECK(paint_controller_); - DCHECK(context_); - paint_controller_->CommitNewDisplayItems(); - sk_sp<PaintRecord> content = - paint_controller_->GetPaintArtifact().GetPaintRecord( - initial_context_.GetPaintController().CurrentPaintChunkProperties()); +SVGFilterRecordingContext::~SVGFilterRecordingContext() = default; - // Content is cached by the source graphic so temporaries can be freed. - paint_controller_ = nullptr; - context_ = nullptr; - return content; +sk_sp<PaintRecord> SVGFilterRecordingContext::GetPaintRecord( + const PaintInfo& initial_paint_info) { + paint_controller_->CommitNewDisplayItems(); + return paint_controller_->GetPaintArtifact().GetPaintRecord( + initial_paint_info.context.GetPaintController() + .CurrentPaintChunkProperties()); } FilterData* SVGFilterPainter::PrepareEffect(const LayoutObject& object) {
diff --git a/third_party/blink/renderer/core/paint/svg_filter_painter.h b/third_party/blink/renderer/core/paint/svg_filter_painter.h index 68dedd3..f38d6937 100644 --- a/third_party/blink/renderer/core/paint/svg_filter_painter.h +++ b/third_party/blink/renderer/core/paint/svg_filter_painter.h
@@ -7,30 +7,31 @@ #include <memory> #include "base/macros.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" +#include "third_party/blink/renderer/core/paint/paint_info.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { class FilterData; +class GraphicsContext; class LayoutObject; class LayoutSVGResourceFilter; +class PaintController; class SVGFilterRecordingContext { USING_FAST_MALLOC(SVGFilterRecordingContext); public: - explicit SVGFilterRecordingContext(GraphicsContext& initial_context) - : initial_context_(initial_context) {} + explicit SVGFilterRecordingContext(const PaintInfo&); + ~SVGFilterRecordingContext(); - GraphicsContext* BeginContent(); - sk_sp<PaintRecord> EndContent(); + const PaintInfo& GetPaintInfo() const { return paint_info_; } + sk_sp<PaintRecord> GetPaintRecord(const PaintInfo&); private: std::unique_ptr<PaintController> paint_controller_; std::unique_ptr<GraphicsContext> context_; - GraphicsContext& initial_context_; + PaintInfo paint_info_; DISALLOW_COPY_AND_ASSIGN(SVGFilterRecordingContext); };
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index c2f98f1..a1b2d36 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -253,6 +253,8 @@ friend class ColorPropertyFunctions; // Edits the background for media controls. friend class StyleAdjuster; + // Access to private SetFontInternal(). + friend class FontBuilder; // FIXME: When we stop resolving currentColor at style time, these can be // removed.
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 45fc0bd..5a22eb5a 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -32,12 +32,12 @@ #include "base/optional.h" #include "cc/layers/picture_layer.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "third_party/blink/public/common/devtools/web_device_emulation_params.h" #include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink.h" #include "third_party/blink/public/mojom/favicon/favicon_url.mojom-blink.h" #include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" +#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -283,7 +283,7 @@ // call. page->SetDefaultPageScaleLimits(1, 4); page->SetPageScaleFactor(1); - page->GetChromeClient().GetWebView()->SetDeviceEmulation(base::nullopt); + page->GetChromeClient().GetWebView()->DisableDeviceEmulation(); // Ensure timers are reset so timers such as EventHandler's |hover_timer_| do // not cause additional lifecycle updates. @@ -3504,7 +3504,7 @@ } WebDeviceEmulationParams params; params.scale = scale; - page->GetChromeClient().GetWebView()->SetDeviceEmulation(params); + page->GetChromeClient().GetWebView()->EnableDeviceEmulation(params); } void Internals::ResolveResourcePriority(ScriptPromiseResolver* resolver,
diff --git a/third_party/blink/renderer/platform/fonts/font.cc b/third_party/blink/renderer/platform/fonts/font.cc index db8806a..7a94148 100644 --- a/third_party/blink/renderer/platform/fonts/font.cc +++ b/third_party/blink/renderer/platform/fonts/font.cc
@@ -84,18 +84,6 @@ : 0); } -void Font::Update(FontSelector* font_selector) const { - // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr, - // but it ends up being reasonably safe (because inherited fonts in the render - // tree pick up the new style anyway. Other copies are transient, e.g., the - // state in the GraphicsContext, and won't stick around long enough to get you - // in trouble). Still, this is pretty disgusting, and could eventually be - // rectified by using RefPtrs for Fonts themselves. - if (!font_fallback_list_) - font_fallback_list_ = FontFallbackList::Create(nullptr); - font_fallback_list_->Invalidate(font_selector); -} - namespace { void DrawBlobs(cc::PaintCanvas* canvas,
diff --git a/third_party/blink/renderer/platform/fonts/font.h b/third_party/blink/renderer/platform/fonts/font.h index dc13958..2aeb6057 100644 --- a/third_party/blink/renderer/platform/fonts/font.h +++ b/third_party/blink/renderer/platform/fonts/font.h
@@ -79,8 +79,6 @@ return font_description_; } - void Update(FontSelector*) const; - enum CustomFontNotReadyAction { kDoNotPaintIfFontNotReady, kUseFallbackIfFontNotReady
diff --git a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc index e27e4a3..d00d1831 100644 --- a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc +++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
@@ -49,7 +49,7 @@ can_shape_word_by_word_(false), can_shape_word_by_word_computed_(false) {} -void FontFallbackList::Invalidate(FontSelector* font_selector) { +void FontFallbackList::Invalidate() { ReleaseFontData(); font_list_.clear(); cached_primary_simple_font_data_ = nullptr; @@ -57,8 +57,6 @@ has_loading_fallback_ = false; can_shape_word_by_word_ = false; can_shape_word_by_word_computed_ = false; - if (font_selector_ != font_selector) - font_selector_ = font_selector; font_selector_version_ = font_selector_ ? font_selector_->Version() : 0; generation_ = FontCache::GetFontCache()->Generation(); } @@ -238,7 +236,7 @@ unsigned realized_font_index) { if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) { if (!IsValid()) - Invalidate(font_selector_); + Invalidate(); } // This fallback font is already in our list. @@ -284,7 +282,7 @@ const FontDescription& font_description) { if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) { if (!IsValid()) - Invalidate(font_selector_); + Invalidate(); } if (!can_shape_word_by_word_computed_) {
diff --git a/third_party/blink/renderer/platform/fonts/font_fallback_list.h b/third_party/blink/renderer/platform/fonts/font_fallback_list.h index baba17f6..6ef8c377 100644 --- a/third_party/blink/renderer/platform/fonts/font_fallback_list.h +++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.h
@@ -49,7 +49,7 @@ ~FontFallbackList() { ReleaseFontData(); } bool IsValid() const; - void Invalidate(FontSelector*); + void Invalidate(); bool LoadingCustomFonts() const; bool ShouldSkipDrawing() const; @@ -62,7 +62,7 @@ ShapeCache* GetShapeCache(const FontDescription& font_description) { if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) { if (!IsValid()) - Invalidate(font_selector_); + Invalidate(); } if (!shape_cache_) { @@ -80,7 +80,7 @@ const FontDescription& font_description) { if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) { if (!IsValid()) - Invalidate(font_selector_); + Invalidate(); } if (!cached_primary_simple_font_data_) { @@ -113,7 +113,7 @@ Vector<scoped_refptr<FontData>, 1> font_list_; const SimpleFontData* cached_primary_simple_font_data_; - Persistent<FontSelector> font_selector_; + const Persistent<FontSelector> font_selector_; unsigned font_selector_version_; int family_index_; uint16_t generation_;
diff --git a/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc b/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc index 62d92b7..604a895 100644 --- a/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc +++ b/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
@@ -19,7 +19,6 @@ if (!Platform::Current()->GetSandboxSupport()) { LOG(ERROR) << "@font-face src: local() instantiation only available when " "connected to browser process."; - DCHECK(Platform::Current()->GetSandboxSupport()); return nullptr; }
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h index dd755d9d..3d76238 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
@@ -95,6 +95,9 @@ kMaxValue = kSwapChain, }; + using RestoreMatrixClipStackCb = + base::RepeatingCallback<void(cc::PaintCanvas*)>; + // todo(juanmihd@) Check whether SkFilterQuality is needed in all of this, or // just call setFilterQuality explicitly static std::unique_ptr<CanvasResourceProvider> CreateBitmapProvider( @@ -102,9 +105,6 @@ SkFilterQuality, const CanvasColorParams&); - using RestoreMatrixClipStackCb = - base::RepeatingCallback<void(cc::PaintCanvas*)>; - // Specifies whether the provider should rasterize paint commands on the CPU // or GPU. This is used to support software raster with GPU compositing enum class RasterMode {
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc index 3edfe29..e8a2159 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -37,14 +37,11 @@ return source; auto paint_image = source->PaintImageForCurrentFrame(); - auto provider = CanvasResourceProvider::Create( - source->Size(), - CanvasResourceProvider::ResourceUsage:: - kAcceleratedCompositedResourceUsage, - context_provider_wrapper, 0, kLow_SkFilterQuality, + auto provider = CanvasResourceProvider::CreateSharedImageProvider( + source->Size(), context_provider_wrapper, kLow_SkFilterQuality, CanvasColorParams(paint_image.GetSkImage()->imageInfo()), - CanvasResourceProvider::kDefaultPresentationMode, nullptr, - source->IsOriginTopLeft()); + source->IsOriginTopLeft(), CanvasResourceProvider::RasterMode::kGPU, + gpu::SHARED_IMAGE_USAGE_DISPLAY); if (!provider || !provider->IsAccelerated()) return nullptr;
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn index 0edd095..d868c46 100644 --- a/third_party/blink/renderer/platform/heap/BUILD.gn +++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -45,6 +45,8 @@ "blink_gc.h", "blink_gc_memory_dump_provider.cc", "blink_gc_memory_dump_provider.h", + "cancelable_task_scheduler.cc", + "cancelable_task_scheduler.h", "collection_support/heap_hash_table_backing.h", "collection_support/heap_linked_stack.h", "collection_support/heap_vector_backing.h", @@ -147,6 +149,7 @@ sources = [ "../testing/run_all_tests.cc", "blink_gc_memory_dump_provider_test.cc", + "cancelable_task_scheduler_test.cc", "card_table_test.cc", "collection_support/heap_linked_stack_test.cc", "concurrent_marking_test.cc",
diff --git a/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.cc b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.cc new file mode 100644 index 0000000..482d431 --- /dev/null +++ b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.cc
@@ -0,0 +1,127 @@ +// Copyright 2019 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 "third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h" + +#include "base/logging.h" +#include "base/macros.h" +#include "base/task_runner.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace blink { + +class CancelableTaskScheduler::TaskData { + USING_FAST_MALLOC(TaskData); + DISALLOW_COPY_AND_ASSIGN(TaskData); + + public: + TaskData(Task task, CancelableTaskScheduler* scheduler) + : task_(std::move(task)), scheduler_(scheduler), status_(kWaiting) {} + + ~TaskData() { + // The task runner is responsible for unregistering the task in case the + // task hasn't been cancelled. + if (TryCancel()) { + scheduler_->UnregisterAndSignal(this); + } + } + + void Run() { + if (TryRun()) { + std::move(task_).Run(); + scheduler_->UnregisterAndSignal(this); + } + } + + bool TryCancel() { + Status expected = kWaiting; + return status_.compare_exchange_strong(expected, kCancelled, + std::memory_order_acq_rel, + std::memory_order_acquire); + } + + private: + // Identifies the state a cancelable task is in: + // |kWaiting|: The task is scheduled and waiting to be executed. {TryRun} will + // succeed. + // |kCancelled|: The task has been cancelled. {TryRun} will fail. + // |kRunning|: The task is currently running and cannot be canceled anymore. + enum Status : uint8_t { kWaiting, kCancelled, kRunning }; + + bool TryRun() { + Status expected = kWaiting; + return status_.compare_exchange_strong(expected, kRunning, + std::memory_order_acq_rel, + std::memory_order_acquire); + } + + Task task_; + CancelableTaskScheduler* const scheduler_; + std::atomic<Status> status_; +}; + +CancelableTaskScheduler::CancelableTaskScheduler( + scoped_refptr<base::TaskRunner> task_runner) + : cond_var_(&lock_), task_runner_(std::move(task_runner)) {} + +CancelableTaskScheduler::~CancelableTaskScheduler() { + base::AutoLock lock(lock_); + CHECK(tasks_.IsEmpty()); +} + +void CancelableTaskScheduler::ScheduleTask(Task task) { + std::unique_ptr<TaskData> task_data = Register(std::move(task)); + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&TaskData::Run, std::move(task_data))); +} + +size_t CancelableTaskScheduler::CancelAndWait() { + size_t result = 0; + base::AutoLock lock(lock_); + while (!tasks_.IsEmpty()) { + result += RemoveCancelledTasks(); + if (!tasks_.IsEmpty()) { + cond_var_.Wait(); + } + } + return result; +} + +std::unique_ptr<CancelableTaskScheduler::TaskData> +CancelableTaskScheduler::Register(Task task) { + auto task_data = std::make_unique<TaskData>(std::move(task), this); + base::AutoLock lock(lock_); + tasks_.insert(task_data.get()); + return task_data; +} + +void CancelableTaskScheduler::UnregisterAndSignal(TaskData* task_data) { + base::AutoLock lock(lock_); + CHECK(tasks_.Contains(task_data)); + tasks_.erase(task_data); + cond_var_.Signal(); +} + +// This function is needed because WTF::HashSet::erase function invalidates +// all iterators. Returns number of removed tasks. +size_t CancelableTaskScheduler::RemoveCancelledTasks() { + WTF::Vector<TaskData*> to_be_removed; + // Assume worst case. + to_be_removed.ReserveCapacity(tasks_.size()); + for (TaskData* task : tasks_) { + if (task->TryCancel()) { + to_be_removed.push_back(task); + } + } + tasks_.RemoveAll(to_be_removed); + return to_be_removed.size(); +} + +size_t CancelableTaskScheduler::NumberOfTasksForTesting() const { + base::AutoLock lock(lock_); + return tasks_.size(); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h new file mode 100644 index 0000000..914ab57 --- /dev/null +++ b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h
@@ -0,0 +1,62 @@ +// Copyright 2019 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CANCELABLE_TASK_SCHEDULER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CANCELABLE_TASK_SCHEDULER_H_ + +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "base/synchronization/condition_variable.h" +#include "base/synchronization/lock.h" +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" + +namespace base { +class TaskRunner; +} + +namespace blink { + +// CancelableTaskScheduler allows for scheduling tasks that can be cancelled +// before they are invoked. User is responsible for synchronizing completion of +// tasks and destruction of CancelableTaskScheduler. +class PLATFORM_EXPORT CancelableTaskScheduler final { + USING_FAST_MALLOC(CancelableTaskScheduler); + + public: + using Task = WTF::CrossThreadOnceFunction<void()>; + + explicit CancelableTaskScheduler(scoped_refptr<base::TaskRunner>); + ~CancelableTaskScheduler(); + + // Schedules task to run on TaskRunner. + void ScheduleTask(Task); + // Cancels all not yet started tasks and waits for running ones to complete. + // Returns number of cancelled (not executed) tasks. + size_t CancelAndWait(); + + private: + class TaskData; + template <class T> + friend class CancelableTaskSchedulerTest; + + std::unique_ptr<TaskData> Register(Task); + void UnregisterAndSignal(TaskData*); + + size_t RemoveCancelledTasks(); + + size_t NumberOfTasksForTesting() const; + + WTF::HashSet<TaskData*> tasks_; + mutable base::Lock lock_; + base::ConditionVariable cond_var_; + scoped_refptr<base::TaskRunner> task_runner_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CANCELABLE_TASK_SCHEDULER_H_
diff --git a/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc new file mode 100644 index 0000000..97f4c8b --- /dev/null +++ b/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc
@@ -0,0 +1,96 @@ +// Copyright 2019 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 "third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h" + +#include <atomic> + +#include "base/memory/scoped_refptr.h" +#include "base/task_runner.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" +#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h" +#include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h" +#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" + +namespace blink { + +class ParallelTaskRunner : public base::TaskRunner { + public: + bool PostDelayedTask(const base::Location& location, + base::OnceClosure task, + base::TimeDelta) override { + worker_pool::PostTask(location, WTF::CrossThreadBindOnce(std::move(task))); + return true; + } + + void RunUntilIdle() {} +}; + +template <class Runner> +class CancelableTaskSchedulerTest : public TestSupportingGC { + public: + using Task = CancelableTaskScheduler::Task; + + void ScheduleTask(Task callback) { + scheduler_.ScheduleTask(std::move(callback)); + } + + void RunTaskRunner() { task_runner_->RunUntilIdle(); } + size_t CancelAndWait() { return scheduler_.CancelAndWait(); } + + size_t NumberOfRegisteredTasks() const { + return scheduler_.NumberOfTasksForTesting(); + } + + private: + scoped_refptr<Runner> task_runner_ = base::MakeRefCounted<Runner>(); + CancelableTaskScheduler scheduler_{task_runner_}; +}; + +using RunnerTypes = + ::testing::Types<scheduler::FakeTaskRunner, ParallelTaskRunner>; +TYPED_TEST_SUITE(CancelableTaskSchedulerTest, RunnerTypes); + +TYPED_TEST(CancelableTaskSchedulerTest, EmptyCancelTasks) { + const size_t cancelled = this->CancelAndWait(); + EXPECT_EQ(0u, cancelled); + EXPECT_EQ(0u, this->NumberOfRegisteredTasks()); +} + +TYPED_TEST(CancelableTaskSchedulerTest, RunAndCancelTasks) { + static constexpr size_t kNumberOfTasks = 10u; + + const auto callback = [](std::atomic<int>* i) { ++(*i); }; + std::atomic<int> var{0}; + + for (size_t i = 0; i < kNumberOfTasks; ++i) { + this->ScheduleTask( + WTF::CrossThreadBindOnce(callback, WTF::CrossThreadUnretained(&var))); + EXPECT_GE(i + 1, this->NumberOfRegisteredTasks()); + } + + this->RunTaskRunner(); + // Tasks will remove themselves after running + EXPECT_LE(0u, this->NumberOfRegisteredTasks()); + + const size_t cancelled = this->CancelAndWait(); + EXPECT_EQ(0u, this->NumberOfRegisteredTasks()); + EXPECT_EQ(kNumberOfTasks, var + cancelled); +} + +TEST(CancelableTaskSchedulerTest, RemoveTasksFromQueue) { + auto task_runner = base::MakeRefCounted<scheduler::FakeTaskRunner>(); + CancelableTaskScheduler scheduler{task_runner}; + int var = 0; + scheduler.ScheduleTask(WTF::CrossThreadBindOnce( + [](int* var) { ++(*var); }, WTF::CrossThreadUnretained(&var))); + auto tasks = task_runner->TakePendingTasksForTesting(); + // Clearing the task queue should destroy all cancelable closures, which in + // turn will notify CancelableTaskScheduler to remove corresponding tasks. + tasks.clear(); + EXPECT_EQ(0, var); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc index dbfab3a..b1c28d9 100644 --- a/third_party/blink/renderer/platform/heap/heap.cc +++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -264,11 +264,11 @@ namespace { -template <typename Worklist, typename Callback, typename YieldPredicate> -bool DrainWorklist(Worklist* worklist, - Callback callback, - YieldPredicate should_yield, - int task_id) { +template <typename Worklist, typename Callback> +bool DrainWorklistWithDeadline(base::TimeTicks deadline, + Worklist* worklist, + Callback callback, + int task_id) { const size_t kDeadlineCheckInterval = 1250; size_t processed_callback_count = 0; @@ -276,34 +276,15 @@ while (worklist->Pop(task_id, &item)) { callback(item); if (++processed_callback_count == kDeadlineCheckInterval) { - if (should_yield()) + if (deadline <= base::TimeTicks::Now()) { return false; + } processed_callback_count = 0; } } return true; } -template <typename Worklist, typename Callback> -bool DrainWorklistWithDeadline(base::TimeTicks deadline, - Worklist* worklist, - Callback callback, - int task_id) { - return DrainWorklist( - worklist, std::move(callback), - [deadline]() { return deadline <= base::TimeTicks::Now(); }, task_id); -} - -template <typename Worklist, typename Callback> -bool DrainWorklistWithYielding(base::JobDelegate* delegate, - Worklist* worklist, - Callback callback, - int task_id) { - return DrainWorklist( - worklist, std::move(callback), - [delegate]() { return delegate->ShouldYield(); }, task_id); -} - } // namespace bool ThreadHeap::InvokeEphemeronCallbacks(MarkingVisitor* visitor, @@ -432,19 +413,14 @@ !write_barrier_worklist_->IsGlobalPoolEmpty(); } -size_t ThreadHeap::ConcurrentMarkingGlobalWorkSize() const { - return marking_worklist_->GlobalPoolSize() + - write_barrier_worklist_->GlobalPoolSize(); -} - bool ThreadHeap::AdvanceConcurrentMarking(ConcurrentMarkingVisitor* visitor, - base::JobDelegate* delegate) { + base::TimeTicks deadline) { bool finished; do { // Iteratively mark all objects that are reachable from the objects // currently pushed onto the marking worklist. - finished = DrainWorklistWithYielding( - delegate, marking_worklist_.get(), + finished = DrainWorklistWithDeadline( + deadline, marking_worklist_.get(), [visitor](const MarkingItem& item) { HeapObjectHeader* header = HeapObjectHeader::FromPayload(item.base_object_payload); @@ -456,8 +432,8 @@ if (!finished) break; - finished = DrainWorklistWithYielding( - delegate, write_barrier_worklist_.get(), + finished = DrainWorklistWithDeadline( + deadline, write_barrier_worklist_.get(), [visitor](HeapObjectHeader* header) { DCHECK(!ConcurrentMarkingVisitor::IsInConstruction(header)); GCInfo::From(header->GcInfoIndex()).trace(visitor, header->Payload());
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h index 1cd00cea4..953dd78 100644 --- a/third_party/blink/renderer/platform/heap/heap.h +++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -310,11 +310,8 @@ // Returns true if concurrent markers will have work to steal bool HasWorkForConcurrentMarking() const; - // Returns the amount of work currently available for stealing (there could be - // work remaining even if this is 0). - size_t ConcurrentMarkingGlobalWorkSize() const; // Returns true if marker is done - bool AdvanceConcurrentMarking(ConcurrentMarkingVisitor*, base::JobDelegate*); + bool AdvanceConcurrentMarking(ConcurrentMarkingVisitor*, base::TimeTicks); // Conservatively checks whether an address is a pointer in any of the // thread heaps. If so marks the object pointed to as live.
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index 995da10..b1c9113 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -49,6 +49,7 @@ #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h" +#include "third_party/blink/renderer/platform/heap/cancelable_task_scheduler.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap_buildflags.h" @@ -97,6 +98,19 @@ namespace { +// Concurrent marking should stop every once in a while to flush private +// segments to v8 marking worklist. It should also stop to avoid priority +// inversion. +// +// TODO(omerkatz): What is a good value to set here? +constexpr base::TimeDelta kConcurrentMarkingStepDuration = + base::TimeDelta::FromMilliseconds(2); +// Number of concurrent marking tasks to use. +// +// TODO(omerkatz): kNumberOfMarkingTasks should be set heuristically +// instead of a constant. +constexpr uint8_t kNumberOfConcurrentMarkingTasks = 3u; + constexpr size_t kMaxTerminationGCLoops = 20; // Helper function to convert a byte count to a KB count, capping at @@ -207,7 +221,9 @@ asan_fake_stack_(__asan_get_current_fake_stack()), #endif incremental_marking_scheduler_( - std::make_unique<IncrementalMarkingScheduler>(this)) { + std::make_unique<IncrementalMarkingScheduler>(this)), + marker_scheduler_(std::make_unique<CancelableTaskScheduler>( + base::MakeRefCounted<WorkerPoolTaskRunner>())) { DCHECK(CheckThread()); DCHECK(!**thread_specific_); **thread_specific_ = this; @@ -736,10 +752,9 @@ SetGCState(kNoGCScheduled); if (base::FeatureList::IsEnabled( blink::features::kBlinkHeapConcurrentMarking)) { - // Stop concurrent markers and wait synchronously until they have all - // returned. - marker_handle_.Cancel(); - DCHECK_EQ(0U, active_markers_); + // Stop concurrent markers + marker_scheduler_->CancelAndWait(); + active_markers_ = 0; available_concurrent_marking_task_ids_.clear(); } #if DCHECK_IS_ON() @@ -1183,7 +1198,27 @@ EnableIncrementalMarkingBarrier(); if (base::FeatureList::IsEnabled( blink::features::kBlinkHeapConcurrentMarking)) { + // No active concurrent markers yet, so it is safe to write to + // concurrently_marked_bytes_ without a lock. + concurrently_marked_bytes_ = 0; current_gc_data_.visitor->FlushMarkingWorklists(); + // Check that the marking worklist has enough private segments for all + // concurrent marking tasks. + const uint8_t max_concurrent_task_id = + WorklistTaskId::ConcurrentThreadBase + + kNumberOfConcurrentMarkingTasks; + static_assert( + MarkingWorklist::kNumTasks == WriteBarrierWorklist::kNumTasks, + "Marking worklist and write-barrier worklist should be the " + "same size"); + static_assert(max_concurrent_task_id <= MarkingWorklist::kNumTasks, + "Number of concurrent marking tasks should not exceed " + "number of tasks in worlkist"); + // Initialize concurrent marking task ids. + for (uint8_t i = WorklistTaskId::ConcurrentThreadBase; + i < max_concurrent_task_id; ++i) { + available_concurrent_marking_task_ids_.push_back(i); + } ScheduleConcurrentMarking(); } SetGCState(kIncrementalMarkingStepScheduled); @@ -1240,16 +1275,11 @@ bool ThreadState::ConcurrentMarkingStep() { current_gc_data_.visitor->FlushMarkingWorklists(); if (Heap().HasWorkForConcurrentMarking()) { - // Notifies the scheduler that max concurrency might have increased. - // This will adjust the number of markers if necessary. - marker_handle_.NotifyConcurrencyIncrease(); + ScheduleConcurrentMarking(); return false; } - base::AutoLock lock(concurrent_marker_lock_); - // !HasWorkForConcurrentMarking() is checked after |active_markers_| == 0 - // because active markers can otherwise flush work and return. - return active_markers_.load(std::memory_order_relaxed) == 0 && - !Heap().HasWorkForConcurrentMarking(); + base::AutoLock lock(concurrent_marker_bootstrapping_lock_); + return active_markers_ == 0; } void ThreadState::IncrementalMarkingFinalize() { @@ -1760,57 +1790,32 @@ } void ThreadState::ScheduleConcurrentMarking() { + base::AutoLock lock(concurrent_marker_bootstrapping_lock_); + DCHECK(base::FeatureList::IsEnabled( blink::features::kBlinkHeapConcurrentMarking)); - DCHECK_EQ(0U, active_markers_); - // No active concurrent markers yet, so it is safe to write to - // concurrently_marked_bytes_ without a lock. - concurrently_marked_bytes_ = 0; - - const uint8_t max_concurrent_task_id = MarkingWorklist::kNumTasks; - // Initialize concurrent marking task ids. - for (uint8_t i = WorklistTaskId::ConcurrentThreadBase; - i < max_concurrent_task_id; ++i) { - available_concurrent_marking_task_ids_.push_back(i); + for (uint8_t i = active_markers_; i < kNumberOfConcurrentMarkingTasks; ++i) { + marker_scheduler_->ScheduleTask(WTF::CrossThreadBindOnce( + &ThreadState::PerformConcurrentMark, WTF::CrossThreadUnretained(this))); } - // |USER_VISIBLE| is used to minimize marking on foreground thread. - marker_handle_ = base::PostJob( - FROM_HERE, {base::ThreadPool(), base::TaskPriority::USER_VISIBLE}, - ConvertToBaseRepeatingCallback( - WTF::CrossThreadBindRepeating(&ThreadState::PerformConcurrentMark, - WTF::CrossThreadUnretained(this))), - ConvertToBaseRepeatingCallback(WTF::CrossThreadBindRepeating( - [](ThreadState* state) -> size_t { - // We need to account for local segments in addition to - // ConcurrentMarkingGlobalWorkSize(). - return std::min<size_t>( - state->Heap().ConcurrentMarkingGlobalWorkSize() + - state->active_markers_.load(std::memory_order_relaxed), - MarkingWorklist::kNumTasks - - WorklistTaskId::ConcurrentThreadBase); - }, - WTF::CrossThreadUnretained(this)))); + active_markers_ = kNumberOfConcurrentMarkingTasks; } -void ThreadState::PerformConcurrentMark(base::JobDelegate* job) { +void ThreadState::PerformConcurrentMark() { VLOG(2) << "[state:" << this << "] [threadid:" << CurrentThread() << "] " << "ConcurrentMark"; ThreadHeapStatsCollector::EnabledConcurrentScope stats_scope( Heap().stats_collector(), ThreadHeapStatsCollector::kConcurrentMarkingStep); - if (!Heap().HasWorkForConcurrentMarking()) - return; - uint8_t task_id; { - base::AutoLock lock(concurrent_marker_lock_); + base::AutoLock lock(concurrent_marker_bootstrapping_lock_); DCHECK(!available_concurrent_marking_task_ids_.IsEmpty()); task_id = available_concurrent_marking_task_ids_.back(); available_concurrent_marking_task_ids_.pop_back(); - active_markers_.fetch_add(1, std::memory_order_relaxed); } std::unique_ptr<ConcurrentMarkingVisitor> concurrent_visitor = @@ -1822,15 +1827,26 @@ this, GetMarkingMode(Heap().Compaction()->IsCompacting()), task_id); - Heap().AdvanceConcurrentMarking(concurrent_visitor.get(), job); - concurrent_visitor->FlushWorklists(); + const bool finished = Heap().AdvanceConcurrentMarking( + concurrent_visitor.get(), + base::TimeTicks::Now() + kConcurrentMarkingStepDuration); + concurrent_visitor->FlushWorklists(); { - base::AutoLock lock(concurrent_marker_lock_); - active_markers_.fetch_sub(1, std::memory_order_relaxed); + base::AutoLock lock(concurrent_marker_bootstrapping_lock_); + // When marking is done, flush visitor worklists and decrement number of + // active markers so we know how many markers are left concurrently_marked_bytes_ += concurrent_visitor->marked_bytes(); available_concurrent_marking_task_ids_.push_back(task_id); + if (finished) { + --active_markers_; + return; + } } + + // Reschedule this marker + marker_scheduler_->ScheduleTask(WTF::CrossThreadBindOnce( + &ThreadState::PerformConcurrentMark, WTF::CrossThreadUnretained(this))); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/thread_state.h b/third_party/blink/renderer/platform/heap/thread_state.h index 2abc3e9a..f41cd05 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.h +++ b/third_party/blink/renderer/platform/heap/thread_state.h
@@ -63,6 +63,7 @@ class IncrementalMarkingScope; } // namespace incremental_marking_test +class CancelableTaskScheduler; class MarkingVisitor; class PersistentNode; class PersistentRegion; @@ -517,7 +518,7 @@ // terminated and the worklist is empty) bool ConcurrentMarkingStep(); void ScheduleConcurrentMarking(); - void PerformConcurrentMark(base::JobDelegate* job); + void PerformConcurrentMark(); // Schedule helpers. void ScheduleIdleLazySweep(); @@ -627,11 +628,11 @@ std::unique_ptr<IncrementalMarkingScheduler> incremental_marking_scheduler_; - base::Lock concurrent_marker_lock_; + std::unique_ptr<CancelableTaskScheduler> marker_scheduler_; Vector<uint8_t> available_concurrent_marking_task_ids_; - std::atomic<size_t> active_markers_{0}; + uint8_t active_markers_ = 0; + base::Lock concurrent_marker_bootstrapping_lock_; size_t concurrently_marked_bytes_ = 0; - base::JobHandle marker_handle_; base::JobHandle sweeper_handle_; std::atomic_bool has_unswept_pages_{false};
diff --git a/third_party/blink/renderer/platform/mojo/blink_typemaps.gni b/third_party/blink/renderer/platform/mojo/blink_typemaps.gni index fe45924..22ecc78 100644 --- a/third_party/blink/renderer/platform/mojo/blink_typemaps.gni +++ b/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
@@ -5,13 +5,6 @@ typemaps = [ "//media/capture/mojom/video_capture_types.typemap", "//media/mojo/mojom/audio_parameters.typemap", - "//services/network/public/cpp/http_request_headers.typemap", - "//services/network/public/cpp/ip_address.typemap", - "//services/network/public/cpp/ip_endpoint.typemap", - "//services/network/public/cpp/network_interface.typemap", - "//services/network/public/cpp/mutable_network_traffic_annotation_tag.typemap", - "//services/network/public/cpp/site_for_cookies.typemap", - "//services/network/public/cpp/p2p.typemap", "//third_party/blink/common/feature_policy/feature_policy.typemap", "//third_party/blink/common/frame/frame_policy.typemap", "//third_party/blink/public/common/loader/url_loader_factory_bundle.typemap",
diff --git a/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc b/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc index d56af279..7b3d7265 100644 --- a/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc +++ b/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
@@ -15,7 +15,6 @@ case Feature::kDedicatedWorkerOrWorklet: case Feature::kOutstandingNetworkRequest: case Feature::kOutstandingIndexedDBTransaction: - case Feature::kHasScriptableFramesInMultipleTabs: case Feature::kBroadcastChannel: case Feature::kIndexedDBConnection: case Feature::kWebGL:
diff --git a/third_party/blink/renderer/platform/wtf/linked_hash_set.h b/third_party/blink/renderer/platform/wtf/linked_hash_set.h index 087fdef..9af16a1 100644 --- a/third_party/blink/renderer/platform/wtf/linked_hash_set.h +++ b/third_party/blink/renderer/platform/wtf/linked_hash_set.h
@@ -1109,6 +1109,9 @@ IncomingValueType&& value); template <typename IncomingValueType> + AddResult InsertBefore(const_iterator it, IncomingValueType&& value); + + template <typename IncomingValueType> AddResult AppendOrMoveToLast(IncomingValueType&&); template <typename IncomingValueType> @@ -1218,6 +1221,15 @@ template <typename T, typename Allocator> template <typename IncomingValueType> typename NewLinkedHashSet<T, Allocator>::AddResult +NewLinkedHashSet<T, Allocator>::InsertBefore(const_iterator it, + IncomingValueType&& value) { + return InsertOrMoveBefore(it, std::forward<IncomingValueType>(value), + MoveType::kDontMove); +} + +template <typename T, typename Allocator> +template <typename IncomingValueType> +typename NewLinkedHashSet<T, Allocator>::AddResult NewLinkedHashSet<T, Allocator>::AppendOrMoveToLast(IncomingValueType&& value) { return InsertOrMoveBefore(end(), std::forward<IncomingValueType>(value), MoveType::kMoveIfValueExists);
diff --git a/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc b/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc index fb0adc6a..0c7622c 100644 --- a/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc +++ b/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc
@@ -119,10 +119,11 @@ using Set = NewLinkedHashSet<int>; Set set; - set.InsertBefore(1, 1); + set.InsertBefore(set.begin(), 1); set.InsertBefore(10, 3); set.InsertBefore(3, 2); - set.InsertBefore(10, 5); + set.InsertBefore(set.end(), 6); + set.InsertBefore(--set.end(), 5); set.InsertBefore(5, 4); Set::const_iterator it = set.begin(); @@ -136,6 +137,8 @@ ++it; EXPECT_EQ(*it, 5); ++it; + EXPECT_EQ(*it, 6); + ++it; EXPECT_TRUE(it == set.end()); }
diff --git a/third_party/blink/renderer/platform/wtf/text/string_builder.h b/third_party/blink/renderer/platform/wtf/text/string_builder.h index a853cc40..1af5205 100644 --- a/third_party/blink/renderer/platform/wtf/text/string_builder.h +++ b/third_party/blink/renderer/platform/wtf/text/string_builder.h
@@ -160,6 +160,14 @@ AtomicString ToAtomicString(); String Substring(unsigned start, unsigned length) const; + operator StringView() const { + if (Is8Bit()) { + return StringView(Characters8(), length()); + } else { + return StringView(Characters16(), length()); + } + } + unsigned length() const { return length_; } bool IsEmpty() const { return !length_; }
diff --git a/third_party/blink/renderer/platform/wtf/text/string_view.h b/third_party/blink/renderer/platform/wtf/text/string_view.h index 074461cf..06611ab 100644 --- a/third_party/blink/renderer/platform/wtf/text/string_view.h +++ b/third_party/blink/renderer/platform/wtf/text/string_view.h
@@ -58,12 +58,12 @@ StringView(StringImpl&, unsigned offset); StringView(StringImpl&, unsigned offset, unsigned length); - // From a String, implemented in String.h + // From a String, implemented in wtf_string.h inline StringView(const String&, unsigned offset, unsigned length); inline StringView(const String&, unsigned offset); inline StringView(const String&); - // From an AtomicString, implemented in AtomicString.h + // From an AtomicString, implemented in atomic_string.h inline StringView(const AtomicString&, unsigned offset, unsigned length); inline StringView(const AtomicString&, unsigned offset); inline StringView(const AtomicString&);
diff --git a/third_party/blink/web_tests/FlagExpectations/composite-after-paint b/third_party/blink/web_tests/FlagExpectations/composite-after-paint index c2374cb7..a5641ac 100644 --- a/third_party/blink/web_tests/FlagExpectations/composite-after-paint +++ b/third_party/blink/web_tests/FlagExpectations/composite-after-paint
@@ -35,6 +35,9 @@ crbug.com/918155 virtual/prefer_compositing_to_lcd_text/scrollbars/overlay-scrollbar-over-child-layer-nested.html [ Pass ] crbug.com/1039401 virtual/scroll_customization/fast/scrolling/scrollbar-mousedown-mouseup.html [ Pass ] paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html [ Pass ] +crbug.com/957674 external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Pass ] +crbug.com/957674 virtual/scalefactor200/external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Pass ] +crbug.com/957674 virtual/scalefactor200withoutzoom/external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Pass ] virtual/android/fullscreen/video-overlay-scroll.html [ Failure ] virtual/android/rootscroller/fixed-chaining-with-implicit-pointer-events-none.html [ Failure ] @@ -157,3 +160,11 @@ compositing/gestures/gesture-tapHighlight-composited-img.html [ Pass Failure ] http/tests/images/image-decode-in-frame.html [ Pass Failure ] + +# Paint Timing failures +crbug.com/1063079 external/wpt/paint-timing/fcp-only/fcp-opacity-descendant.html [ Pass Failure ] +crbug.com/1063079 virtual/paint-timing/external/wpt/paint-timing/fcp-only/fcp-opacity-descendant.html [ Pass Failure ] +crbug.com/1063079 external/wpt/paint-timing/fcp-only/fcp-opacity.html [ Pass Failure ] +crbug.com/1063079 virtual/paint-timing/external/wpt/paint-timing/fcp-only/fcp-opacity.html [ Pass Failure ] +crbug.com/1063079 external/wpt/paint-timing/fcp-only/fcp-pseudo-element-opacity.html [ Pass Failure ] +crbug.com/1063079 virtual/paint-timing/external/wpt/paint-timing/fcp-only/fcp-pseudo-element-opacity.html [ Pass Failure ] \ No newline at end of file
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 98cc0546..3d9cd62 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2231,6 +2231,9 @@ crbug.com/123456 [ Mac ] virtual/form-controls-refresh-disabled/fast/forms/select/menulist-onchange-fired-with-key-up-down.html [ Skip ] crbug.com/123456 [ Mac ] virtual/form-controls-refresh-disabled/fast/forms/select/popup-with-display-none-optgroup.html [ Skip ] +crbug.com/1056027 [ Fuchsia ] virtual/text-antialias/small-caps-aat.html [ Failure Pass ] +crbug.com/1057339 [ Fuchsia ] virtual/text-antialias/international/rtl-mark.html [ Failure Pass ] + crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/hyphen-min-preferred-width-mock.html [ Skip ] crbug.com/652964 [ Win ] virtual/text-antialias/hyphens/hyphen-min-preferred-width-mock.html [ Skip ] crbug.com/652964 [ Linux ] virtual/text-antialias/hyphens/hyphens-align.html [ Skip ] @@ -2984,6 +2987,8 @@ crbug.com/1053965 external/wpt/css/css-values/ex-unit-004.html [ Failure ] +crbug.com/947951 [ Win ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch.html [ Pass Timeout ] + # ====== New tests from wpt-importer added here ====== crbug.com/626703 [ Linux ] external/wpt/css/css-text/line-break/line-break-strict-015.xht [ Failure ] crbug.com/626703 [ Mac ] external/wpt/css/css-text/line-break/line-break-strict-015.xht [ Failure ] @@ -3085,7 +3090,6 @@ crbug.com/626703 [ Mac10.10 ] external/wpt/WebCryptoAPI/derive_bits_keys/hkdf.https.any.html?1001-2000 [ Failure Timeout ] crbug.com/626703 [ Mac10.10 ] external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html [ Failure Timeout ] crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/dom/idlharness.https.html?include=HTML.\* [ Failure Timeout ] -crbug.com/626703 [ Win7 ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch.html [ Timeout ] crbug.com/626703 [ Win7 ] external/wpt/content-security-policy/object-src/object-src-no-url-allowed.html [ Timeout ] crbug.com/626703 [ Win7 ] external/wpt/content-security-policy/plugin-types/plugintypes-nourl-allowed.html [ Timeout ] crbug.com/626703 [ Mac10.11 ] virtual/cascade/external/wpt/css/css-paint-api/parse-input-arguments-018.https.html [ Failure ] @@ -5578,6 +5582,12 @@ crbug.com/915352 [ Mac10.10 ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html [ Pass Failure ] crbug.com/915352 [ Mac10.11 ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html [ Pass Failure ] +# Paint Timing failures +crbug.com/1062984 virtual/paint-timing/external/wpt/paint-timing/border-image.html [ Pass Failure ] +crbug.com/1062984 virtual/paint-timing/external/wpt/paint-timing/fcp-only/fcp-video-poster.html [ Pass Failure ] +crbug.com/1062984 virtual/paint-timing/external/wpt/paint-timing/replaced-content-image.html [ Pass Failure ] +crbug.com/1062984 virtual/paint-timing/external/wpt/paint-timing/mask-image.html [ Pass Failure ] + # Sheriff 2019-03-01 crbug.com/937416 http/tests/devtools/resource-tree/resource-tree-htmlimports.js [ Pass Failure ] @@ -5991,10 +6001,16 @@ crbug.com/997669 [ Win ] http/tests/devtools/search/sources-search-scope-in-files.js [ Pass Crash ] crbug.com/626703 external/wpt/css/css-paint-api/custom-property-animation-on-main-thread.https.html [ Pass Failure ] +crbug.com/999209 virtual/lazyload-image/http/tests/lazyload/style-dimension.html [ Timeout ] + crbug.com/1015130 external/wpt/largest-contentful-paint/first-paint-equals-lcp-text.html [ Failure Pass ] crbug.com/1015130 virtual/scalefactor200/external/wpt/largest-contentful-paint/first-paint-equals-lcp-text.html [ Failure Pass ] crbug.com/1015130 virtual/scalefactor200withoutzoom/external/wpt/largest-contentful-paint/first-paint-equals-lcp-text.html [ Failure Pass ] +crbug.com/957674 external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Failure ] +crbug.com/957674 virtual/scalefactor200/external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Failure ] +crbug.com/957674 virtual/scalefactor200withoutzoom/external/wpt/largest-contentful-paint/invisible-images-composited-2.html [ Failure ] + crbug.com/1000051 media/controls/volume-slider.html [ Failure Timeout Pass ] crbug.com/1000051 virtual/audio-service/media/controls/volume-slider.html [ Failure Timeout Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-subpixel-clip-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-subpixel-clip-ref.html deleted file mode 100644 index 098e827..0000000 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-subpixel-clip-ref.html +++ /dev/null
@@ -1,11 +0,0 @@ -<!DOCTYPE html> -<head> - <title>Images with loading='lazy' load under subpixel-offset clips</title> - <link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> - <link rel="help" href="https://html.spec.whatwg.org/#lazy-loading-attributes"> -</head> -<div style="height: 3.7499995rem; "></div> -<div style="position: relative; font-size: 0; background: lightblue"> - <img loading="lazy" data-sizes="auto" src="resources/image.png" - title="" width="1600"> -</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-subpixel-clip.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-subpixel-clip.html deleted file mode 100644 index 0eb20d6..0000000 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-subpixel-clip.html +++ /dev/null
@@ -1,14 +0,0 @@ -<!DOCTYPE html> -<head> - <title>Images with loading='lazy' load under subpixel-offset clips</title> - <link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org"> - <link rel="help" href="https://html.spec.whatwg.org/#lazy-loading-attributes"> - <link rel="match" href="image-loading-subpixel-clip-ref.html"> -</head> -<div style="height: 3.7499995rem"></div> -<div style="overflow: hidden"> - <div style="position: relative; font-size: 0; background: lightblue"> - <img loading="lazy" data-sizes="auto" src="resources/image.png" - title="" width="1600"> - </div> -</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/original-referrer-policy-applied.sub-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/original-referrer-policy-applied.sub-expected.txt new file mode 100644 index 0000000..55c98d0a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/original-referrer-policy-applied.sub-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Test that when deferred iframe is loaded, it uses the referrer-policy specified at parse time. +FAIL Test that when deferred img is loaded, it uses the referrer-policy specified at parse time. assert_unreached: The image load should not fail, by sending the wrong referer header. Reached unreachable code +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images-composited-1.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images-composited-1.html new file mode 100644 index 0000000..495645a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images-composited-1.html
@@ -0,0 +1,25 @@ +<!DOCTYPE HTML> +<title>Largest Contentful Paint: invisible images are not observable</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/invisible-images.js"></script> +<style> + .opacity0 { + opacity: 0; + } + .visibilityHidden { + visibility: hidden; + } + .displayNone { + display: none; + } + .composited { + will-change: transform; + } +</style> +<img src='/images/blue.png' class='opacity0 composited' id='opacity0'/> +<img src='/images/green.png' class='visibilityHidden composited' id='visibilityHidden'/> +<img src='/images/red.png' class='displayNone composited' id='displayNone'/> +<div class='opacity0 composited'><img src='/images/yellow.png' id='divOpacity0'/></div> +<div class='visibilityHidden composited'><img src='/images/yellow.png' id='divVisibilityHidden'/></div> +<div class='displayNone composited'><img src='/images/yellow.png' id='divDisplayNone'/></div>
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images-composited-2.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images-composited-2.html new file mode 100644 index 0000000..8ab32eb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images-composited-2.html
@@ -0,0 +1,26 @@ +<!DOCTYPE HTML> +<title>Largest Contentful Paint: invisible images are not observable</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/invisible-images.js"></script> +<style> + .opacity0 { + opacity: 0; + } + .visibilityHidden { + visibility: hidden; + } + .displayNone { + display: none; + } + .composited { + will-change: transform; + } + img { + border: 2px solid black; + will-change: transform; + } +</style> +<div class='opacity0 composited'><img src='/images/yellow.png' id='divOpacity0'/></div> +<div class='visibilityHidden composited'><img src='/images/yellow.png' id='divVisibilityHidden'/></div> +<div class='displayNone composited'><img src='/images/yellow.png' id='divDisplayNone'/></div>
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images-composited.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images-composited.html deleted file mode 100644 index f652180d..0000000 --- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images-composited.html +++ /dev/null
@@ -1,56 +0,0 @@ -<!DOCTYPE HTML> -<meta charset=utf-8> -<head> -<title>Largest Contentful Paint: invisible images are not observable</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<style> - .opacity0 { - opacity: 0; - } - .visibilityHidden { - visibility: hidden; - } - .displayNone { - display: none; - } - .composited { - will-change: transform; - } -</style> -</head> -<body> -<script> - async_test(t => { - assert_precondition(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented"); - const observer = new PerformanceObserver( - t.step_func(entryList => { - entryList.getEntries().forEach(entry => { - // May receive a text entry. Ignore that entry. - if (!entry.url) { - return; - } - // The images should not have caused an entry, so fail test. - assert_unreached('Should not have received an entry! Received one with id ' - + entryList.getEntries()[0].id); - }); - }) - ); - observer.observe({type: 'largest-contentful-paint', buffered: true}); - // Images have been added but should not cause entries to be dispatched. - // Wait for 500ms and end test, ensuring no entry was created. - t.step_timeout(() => { - t.done(); - }, 500); - }, 'Images with opacity: 0, visibility: hidden, or display: none are not observable by LargestContentfulPaint.'); -</script> -<img src='/images/blue.png' class='opacity0 composited' id='opacity0'/> -<img src='/images/green.png' class='visibilityHidden composited' id='visibilityHidden'/> -<img src='/images/red.png' class='displayNone composited' id='displayNone'/> -<div class='opacity0 composited'><img class='composited' src='/images/yellow.png' id='divOpacity0'/></div> -<div class='visibilityHidden composited'><img class='composited' src='/images/yellow.png' id='divVisibilityHidden'/></div> -<div class='displayNone composited'><img src='/images/yellow.png' id='divDisplayNone'/></div> -<div class='opacity0 composited'><img src='/images/yellow.png' id='divOpacity0Composited'/></div> -<div class='visibilityHidden composited'><img src='/images/yellow.png' id='divVisibilityHiddenComposited'/></div> -<div class='displayNone composited'><img src='/images/yellow.png' id='divDisplayNoneComposited'/></div> -</body>
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images.html b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images.html index 4932466..997d70f7 100644 --- a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images.html +++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/invisible-images.html
@@ -1,9 +1,8 @@ <!DOCTYPE HTML> -<meta charset=utf-8> -<head> <title>Largest Contentful Paint: invisible images are not observable</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="resources/invisible-images.js"></script> <style> .opacity0 { opacity: 0; @@ -15,36 +14,9 @@ display: none; } </style> -</head> -<body> -<script> - async_test(t => { - assert_precondition(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented"); - const observer = new PerformanceObserver( - t.step_func(entryList => { - entryList.getEntries().forEach(entry => { - // May receive a text entry. Ignore that entry. - if (!entry.url) { - return; - } - // The images should not have caused an entry, so fail test. - assert_unreached('Should not have received an entry! Received one with id ' - + entryList.getEntries()[0].id); - }); - }) - ); - observer.observe({type: 'largest-contentful-paint', buffered: true}); - // Images have been added but should not cause entries to be dispatched. - // Wait for 500ms and end test, ensuring no entry was created. - t.step_timeout(() => { - t.done(); - }, 500); - }, 'Images with opacity: 0, visibility: hidden, or display: none are not observable by LargestContentfulPaint.'); -</script> <img src='/images/blue.png' class='opacity0' id='opacity0'/> <img src='/images/green.png' class='visibilityHidden' id='visibilityHidden'/> <img src='/images/red.png' class='displayNone' id='displayNone'/> <div class='opacity0'><img src='/images/yellow.png' id='divOpacity0'/></div> <div class='visibilityHidden'><img src='/images/yellow.png' id='divVisibilityHidden'/></div> <div class='displayNone'><img src='/images/yellow.png' id='divDisplayNone'/></div> -</body>
diff --git a/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/invisible-images.js b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/invisible-images.js new file mode 100644 index 0000000..fd13e945 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/largest-contentful-paint/resources/invisible-images.js
@@ -0,0 +1,22 @@ +async_test(t => { + assert_precondition(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented"); + const observer = new PerformanceObserver( + t.step_func(entryList => { + entryList.getEntries().forEach(entry => { + // May receive a text entry. Ignore that entry. + if (!entry.url) { + return; + } + // The images should not have caused an entry, so fail test. + assert_unreached('Should not have received an entry! Received one with id ' + + entryList.getEntries()[0].id); + }); + }) + ); + observer.observe({type: 'largest-contentful-paint', buffered: true}); + // Images have been added but should not cause entries to be dispatched. + // Wait for 500ms and end test, ensuring no entry was created. + t.step_timeout(() => { + t.done(); + }, 500); +}, 'Images with opacity: 0, visibility: hidden, or display: none are not observable by LargestContentfulPaint.');
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_lostpointercapture_for_disconnected_node_in_shadow_dom.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_lostpointercapture_for_disconnected_node_in_shadow_dom.html new file mode 100644 index 0000000..f03f98a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_lostpointercapture_for_disconnected_node_in_shadow_dom.html
@@ -0,0 +1,128 @@ +<!doctype html> +<html> + <head> + <title>Lostpointercapture fires on document when target in shadow dom is removed</title> + <meta name="viewport" content="width=device-width"> + <link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=810882"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-actions.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + </head> + <body onload="onLoad()"> + <template id="template"> + <style> + #content{ + height:100px; + width:100px; + background-color: lightgrey; + } + </style> + <div id="content"></div> + </template> + <h1>Pointer Events - lostpointercapture when capturing element in shadow dom is removed</h1> + <h4> + Test Description: + This test checks if lostpointercapture is fired at the document when the capturing node that is in shadow dom is removed from the shadow dom. + Complete the following actions: + <ol> + <li>Press left mouse button over "Set Capture" button. Pointer should be captured by the gray rectangle which is in shadow dom.</li> + <li>Gray rectangle will be removed from shadow dom.</li> + <li>"lostpointercapture" should be received on the document not on the gray rectangle.</li> + </ol> + </h4> + <div id="shadowhost"></div> + <br> + <input type="button" id="btnCapture" value="Set Capture"> + <div id="log"></div> + <script> + var logDiv = document.getElementById("log"); + function logMessage(message){ + var log = document.createElement("div"); + var messageNode = document.createTextNode(message); + log.appendChild(messageNode); + logDiv.appendChild(log); + } + var events = []; + + var host = document.getElementById("shadowhost"); + var shadowRoot = host.attachShadow({mode: "open"}); + var template = document.getElementById("template"); + var node = template.content.cloneNode(true); + shadowRoot.appendChild(node); + + var content = host.shadowRoot.getElementById("content"); + var captureButton = document.getElementById("btnCapture"); + + captureButton.addEventListener("pointerdown", function(event){ + logMessage("Pointer will be captured by the shadow dom gray rectangle."); + content.setPointerCapture(event.pointerId); + events.push("pointerdown@captureButton"); + }); + content.addEventListener("gotpointercapture", function(event){ + logMessage("Gray rectangle received pointercapture."); + logMessage("Removing gray rectangle from shadow dom.") + content.parentNode.removeChild(content); + events.push("gotpointercapture@content"); + }); + content.addEventListener("lostpointercapture", function(event){ + logMessage("Test Failed! The element removed from shadow dom should not receive lostpointercapture.") + events.push("lostpointercapture@content"); + if(window.promise_test && shadow_dom_test){ + shadow_dom_test.step(function(){ + assert_unreached("lostpointercapture must be fired on the document, not the capturing element"); + reject_test("lostpointercapture must not be dispatched on the disconnected node"); + shadow_dom_test.done(); + }); + } + }); + document.addEventListener("lostpointercapture", function(event){ + logMessage("Test Passed! Document received lostpointercapture."); + events.push("lostpointercapture@document"); + if(window.promise_test && shadow_dom_test){ + shadow_dom_test.step(function(){ + assert_array_equals(events, ["pointerdown@captureButton", + "gotpointercapture@content", + "lostpointercapture@document"]); + resolve_test(); + shadow_dom_test.done(); + }); + } + }); + + var shadow_dom_test = null; + var resolve_test = null; + var reject_test = null; + + function cleanup(){ + events = []; + shadow_dom_test = null; + resolve_test = null; + reject_test = null; + } + + function onLoad(){ + if(window.promise_test){ + promise_test(function(t){ + return new Promise(function(resolve, reject){ + shadow_dom_test = t; + resolve_test = resolve; + reject_test = reject; + t.add_cleanup(function(){ + cleanup(); + }); + var actions = new test_driver.Actions(); + var actions_promise = actions + .pointerMove(0, 0, {origin:captureButton}) + .pointerDown({button: actions.ButtonType.LEFT}) + .pointerUp({button: actions.ButtonType.LEFT}) + .send(); + }); + }, "lostpointercapture is dispatched on the document when shadow dom capturing element is removed"); + } + } + </script> + </body> +</html> +
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_lostpointercapture_for_disconnected_shadow_host.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_lostpointercapture_for_disconnected_shadow_host.html new file mode 100644 index 0000000..4b5c9f6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_lostpointercapture_for_disconnected_shadow_host.html
@@ -0,0 +1,136 @@ +<!doctype html> +<html> + <head> + <title>Lostpointercapture fires on document when target in shadow dom is removed</title> + <meta name="viewport" content="width=device-width"> + <link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=810882"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-actions.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <style> + #shadowhost{ + height:200px; + width:200px; + background-color:magenta; + } + </style> + </head> + <body onload="onLoad()"> + <template id="template"> + <style> + #content{ + height:100px; + width:100px; + background-color: lightgrey; + } + </style> + <div id="content"></div> + </template> + <h1>Pointer Events - lostpointercapture when capturing element in shadow dom is removed by removing the shadow host</h1> + <h4> + Test Description: + This test checks if lostpointercapture is fired at the document when the capturing node is removed from the document by removing the shadow host. + The shadow host is colored magenta and the shadow dom element is colored gray. + Complete the following actions: + <ol> + <li>Press left mouse button over "Set Capture" button. Pointer should be captured by the gray rectangle.</li> + <li>Shadow host magenta rectangle including the gray rectangle will be removed from shadow dom.</li> + <li>"lostpointercapture" should be received on the document not on the gray rectangle.</li> + </ol> + </h4> + <div id="shadowhost"></div> + <br> + <input type="button" id="btnCapture" value="Set Capture"> + <div id="log"></div> + <script> + var logDiv = document.getElementById("log"); + function logMessage(message){ + var log = document.createElement("div"); + var messageNode = document.createTextNode(message); + log.appendChild(messageNode); + logDiv.appendChild(log); + } + var events = []; + + var host = document.getElementById("shadowhost"); + var shadowRoot = host.attachShadow({mode: "open"}); + var template = document.getElementById("template"); + var node = template.content.cloneNode(true); + shadowRoot.appendChild(node); + + var content = host.shadowRoot.getElementById("content"); + var captureButton = document.getElementById("btnCapture"); + + captureButton.addEventListener("pointerdown", function(event){ + logMessage("Pointer will be captured by the shadow dom gray rectangle."); + content.setPointerCapture(event.pointerId); + events.push("pointerdown@captureButton"); + }); + content.addEventListener("gotpointercapture", function(event){ + logMessage("Gray rectangle received pointercapture."); + logMessage("Removing magenta rectangle (which includes gray rectangle) from shadow dom.") + host.parentNode.removeChild(host); + events.push("gotpointercapture@content"); + }); + content.addEventListener("lostpointercapture", function(event){ + logMessage("Test Failed! The element removed from shadow dom should not receive lostpointercapture.") + events.push("lostpointercapture@content"); + if(window.promise_test && shadow_dom_test){ + shadow_dom_test.step(function(){ + assert_unreached("lostpointercapture must be fired on the document, not the capturing element"); + reject_test("lostpointercapture must not be dispatched on the disconnected node"); + shadow_dom_test.done(); + }); + } + }); + document.addEventListener("lostpointercapture", function(event){ + logMessage("Test Passed! Document received lostpointercapture."); + events.push("lostpointercapture@document"); + if(window.promise_test && shadow_dom_test){ + shadow_dom_test.step(function(){ + assert_array_equals(events, ["pointerdown@captureButton", + "gotpointercapture@content", + "lostpointercapture@document"]); + resolve_test(); + shadow_dom_test.done(); + }); + } + }); + + var shadow_dom_test = null; + var resolve_test = null; + var reject_test = null; + + function cleanup(){ + events = []; + shadow_dom_test = null; + resolve_test = null; + reject_test = null; + } + + function onLoad(){ + if(window.promise_test){ + promise_test(function(t){ + return new Promise(function(resolve, reject){ + shadow_dom_test = t; + resolve_test = resolve; + reject_test = reject; + t.add_cleanup(function(){ + cleanup(); + }); + var actions = new test_driver.Actions(); + var actions_promise = actions + .pointerMove(0, 0, {origin:captureButton}) + .pointerDown({button: actions.ButtonType.LEFT}) + .pointerUp({button: actions.ButtonType.LEFT}) + .send(); + }); + }, "lostpointercapture is dispatched on the document when shadow host is removed"); + } + } + </script> + </body> +</html> +
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercapture-in-custom-element.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercapture-in-custom-element.html new file mode 100644 index 0000000..e8f143b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercapture-in-custom-element.html
@@ -0,0 +1,123 @@ +<!DOCTYPE html> +<html> + <head> + <title>PointerCapture for Custome Shadow DOM</title> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width"> + <link rel="help" href= "https://bugs.chromium.org/p/chromium/issues/detail?id=810882"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-actions.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script> + class WC extends HTMLElement{ + constructor(){ + super(); + let template = document.getElementById('template-wc'); + let node = template.content.cloneNode(true) ; + + let shadowRoot = this.attachShadow({mode: 'open'}); + shadowRoot.appendChild(node); + } + } + customElements.define("wc-wc", WC); + </script> + </head> + <body onload="onLoad()"> + <template id="template-wc"> + <style> + #content{ + height:50px; + width:50px; + background-color: magenta; + } + </style> + <div id="content"></div> + </template> + <h4>PointerCapture by Custom Element's Shadow DOM</h4> + The magenta box below is part of a custom element's Shadow DOM. + <ul> + <li> Click left mouse button inside the box and keep mouse button depressed</li> + <li> Move the mouse</li> + <li> There should be a message stating <em>Pointer was captured by custom element's Shadow DOM!</em></li> + <li> Release left mouse button</li> + <li> There should be a message stating <em>Pointer was released by custom element's Shadow DOM!</em></li> + </ul> + + <wc-wc id="wc-wc"></wc-wc> + <div id="log"></div> + <script> + var logDiv = document.getElementById("log"); + function logMessage(message){ + var log = document.createElement("div"); + var messageNode = document.createTextNode(message); + log.appendChild(messageNode); + logDiv.appendChild(log); + } + var events = []; + + var content = document.getElementById("wc-wc") + .shadowRoot.getElementById("content"); + + content.addEventListener("pointerdown", function(e){ + content.setPointerCapture(e.pointerId); + events.push("pointerdown@content"); + }); + content.addEventListener("gotpointercapture", function(e){ + logMessage("Pointer was captured by custom element's Shadow DOM!"); + events.push("gotpointercapture@content"); + }); + content.addEventListener("pointerup", function(e){ + content.releasePointerCapture(e.pointerId); + events.push("pointerup@content"); + }); + content.addEventListener("lostpointercapture", function(e){ + logMessage("Pointer was released by custom element's Shadow DOM!"); + events.push("lostpointercapture@content"); + if(window.promise_test && wc_shadow_dom_test){ + wc_shadow_dom_test.step(function(){ + assert_array_equals(events, ["pointerdown@content", + "gotpointercapture@content", "pointerup@content", + "lostpointercapture@content"]); + resolve_test(); + wc_shadow_dom_test.done(); + }); + } + }); + + var wc_shadow_dom_test = null; + var resolve_test = null; + var reject_test = null; + + function cleanup(){ + events = []; + shadow_dom_test = null; + resolve_test = null; + reject_test = null; + } + + function onLoad(){ + if(window.promise_test){ + promise_test(function(t){ + return new Promise(function(resolve, reject){ + wc_shadow_dom_test = t; + resolve_test = resolve; + reject_test = reject; + t.add_cleanup(function(){ + cleanup(); + }); + var contentRect = content.getBoundingClientRect(); + var actions = new test_driver.Actions(); + var actions_promise = actions + .pointerMove(contentRect.x, contentRect.y) + .pointerDown({button: actions.ButtonType.LEFT}) + .pointerUp({button: actions.ButtonType.LEFT}) + .send(); + }); + }, "PointerCapture works for custom element Shadow DOM."); + } + } + </script> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercapture-in-shadow-dom.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercapture-in-shadow-dom.html new file mode 100644 index 0000000..8279665f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_pointercapture-in-shadow-dom.html
@@ -0,0 +1,114 @@ +<!DOCTYPE html> +<html> + <head> + <title>PointerCapture for Shadow DOM Elements</title> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width"> + <link rel="help" href= "https://bugs.chromium.org/p/chromium/issues/detail?id=810882"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-actions.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + </head> + <body onload="onLoad()"> + <template id="template"> + <style> + #content{ + height:100px; + width:100px; + background-color: lightgrey; + } + </style> + <div id="content"></div> + </template> + <h4>PointerCapture by Shadow DOM element</h4> + The light gray box below is part of Shadow DOM. + <ul> + <li> Click left mouse button inside the box and keep mouse button depressed </li> + <li> Move the mouse </li> + <li> There should be a message stating <em>Pointer was captured by Shadow DOM!</em></li> + <li> Release left mouse button + <li> There should be a message stating <em>Pointer was released by Shadow DOM!</em></li> + </ul> + <div id="shadowhost"></div> + <div id="log"></div> + <script> + var logDiv = document.getElementById("log"); + function logMessage(message){ + var log = document.createElement("div"); + var messageNode = document.createTextNode(message); + log.appendChild(messageNode); + logDiv.appendChild(log); + } + var events = []; + + var host = document.getElementById("shadowhost"); + var shadowRoot = host.attachShadow({mode: "open"}); + var template = document.getElementById("template"); + var node = template.content.cloneNode(true); + shadowRoot.appendChild(node); + + var content = host.shadowRoot.getElementById("content"); + + content.addEventListener("pointerdown", function(e){ + content.setPointerCapture(e.pointerId); + events.push("pointerdown@content"); + }); + content.addEventListener("gotpointercapture", function(e){ + logMessage("Pointer was captured by Shadow DOM!"); + events.push("gotpointercapture@content"); + }); + content.addEventListener("pointerup", function(e){ + content.releasePointerCapture(e.pointerId); + events.push("pointerup@content"); + }); + content.addEventListener("lostpointercapture", function(e){ + logMessage("Pointer was released by Shadow DOM!"); + events.push("lostpointercapture@content"); + if(window.promise_test && shadow_dom_test){ + shadow_dom_test.step(function(){ + assert_array_equals(events, ["pointerdown@content", + "gotpointercapture@content", "pointerup@content", + "lostpointercapture@content"]); + resolve_test(); + shadow_dom_test.done(); + }); + } + }); + + var shadow_dom_test = null; + var resolve_test = null; + var reject_test = null; + + function cleanup(){ + events = []; + shadow_dom_test = null; + resolve_test = null; + reject_test = null; + } + + function onLoad(){ + if(window.promise_test){ + promise_test(function(t){ + return new Promise(function(resolve, reject){ + shadow_dom_test = t; + resolve_test = resolve; + reject_test = reject; + t.add_cleanup(function(){ + cleanup(); + }); + var contentRect = content.getBoundingClientRect(); + var actions = new test_driver.Actions(); + var actions_promise = actions + .pointerMove(contentRect.x, contentRect.y) + .pointerDown({button: actions.ButtonType.LEFT}) + .pointerUp({button: actions.ButtonType.LEFT}) + .send(); + }); + }, "PointerCapture works for Shadow DOM element."); + } + } + </script> + </body> +</html>
diff --git a/third_party/closure_compiler/externs/passwords_private.js b/third_party/closure_compiler/externs/passwords_private.js index a9d16618..e4e47b6 100644 --- a/third_party/closure_compiler/externs/passwords_private.js +++ b/third_party/closure_compiler/externs/passwords_private.js
@@ -223,6 +223,12 @@ chrome.passwordsPrivate.isOptedInForAccountStorage = function(callback) {}; /** + * Triggers the opt-in or opt-out flow for the account storage. + * @param {boolean} optIn + */ +chrome.passwordsPrivate.optInForAccountStorage = function(optIn) {}; + +/** * Requests the latest compromised credentials. * @param {function(!Array<!chrome.passwordsPrivate.CompromisedCredential>):void} * callback
diff --git a/third_party/expat/BUILD.gn b/third_party/expat/BUILD.gn index 6c0c63e..1bddfcb0 100644 --- a/third_party/expat/BUILD.gn +++ b/third_party/expat/BUILD.gn
@@ -41,11 +41,6 @@ public_configs = [ ":expat_public_config" ] configs += [ ":expat_internal_config" ] - # TODO(thakis): Remove this once clang no longer crashes when building - # libexpat with -Oz. - configs -= [ "//build/config/compiler:default_optimization" ] - configs += [ "//build/config/compiler:optimize_max" ] - defines = [ "_LIB" ] if (is_win) { # expat expects to define WIN32_LEAN_AND_MEAN itself
diff --git a/third_party/polymer/v3_0/chromium.patch b/third_party/polymer/v3_0/chromium.patch index 08847d9..640e4587 100644 --- a/third_party/polymer/v3_0/chromium.patch +++ b/third_party/polymer/v3_0/chromium.patch
@@ -195,3 +195,42 @@ /** * @struct +diff --git a/components-chromium/paper-tooltip/paper-tooltip.js b/components-chromium/paper-tooltip/paper-tooltip.js +index 853eee199025..303d1bbdfc78 100644 +--- a/components-chromium/paper-tooltip/paper-tooltip.js ++++ b/components-chromium/paper-tooltip/paper-tooltip.js +@@ -311,12 +311,16 @@ Polymer({ + + /** + * Returns the target element that this tooltip is anchored to. It is +- * either the element given by the `for` attribute, or the immediate parent +- * of the tooltip. ++ * either the element given by the `for` attribute, the element manually ++ * specified through the `target` attribute, or the immediate parent of ++ * the tooltip. + * + * @type {Node} + */ + get target() { ++ if (this._manualTarget) ++ return this._manualTarget; ++ + var parentNode = dom(this).parentNode; + // If the parentNode is a document fragment, then we need to use the host. + var ownerRoot = dom(this).getOwnerRoot(); +@@ -331,6 +335,15 @@ Polymer({ + return target; + }, + ++ /** ++ * Sets the target element that this tooltip will be anchored to. ++ * @param {Node} target ++ */ ++ set target(target) { ++ this._manualTarget = target; ++ this._findTarget(); ++ }, ++ + /** + * @return {void} + */
diff --git a/third_party/polymer/v3_0/components-chromium/paper-tooltip/paper-tooltip.js b/third_party/polymer/v3_0/components-chromium/paper-tooltip/paper-tooltip.js index 853eee19..303d1bb 100644 --- a/third_party/polymer/v3_0/components-chromium/paper-tooltip/paper-tooltip.js +++ b/third_party/polymer/v3_0/components-chromium/paper-tooltip/paper-tooltip.js
@@ -311,12 +311,16 @@ /** * Returns the target element that this tooltip is anchored to. It is - * either the element given by the `for` attribute, or the immediate parent - * of the tooltip. + * either the element given by the `for` attribute, the element manually + * specified through the `target` attribute, or the immediate parent of + * the tooltip. * * @type {Node} */ get target() { + if (this._manualTarget) + return this._manualTarget; + var parentNode = dom(this).parentNode; // If the parentNode is a document fragment, then we need to use the host. var ownerRoot = dom(this).getOwnerRoot(); @@ -332,6 +336,15 @@ }, /** + * Sets the target element that this tooltip will be anchored to. + * @param {Node} target + */ + set target(target) { + this._manualTarget = target; + this._findTarget(); + }, + + /** * @return {void} */ attached: function() {
diff --git a/third_party/robolectric/BUILD.gn b/third_party/robolectric/BUILD.gn index 07575f856..1b0c4032 100644 --- a/third_party/robolectric/BUILD.gn +++ b/third_party/robolectric/BUILD.gn
@@ -413,7 +413,6 @@ "robolectric/utils/reflector/src/main/java/org/robolectric/util/reflector/WeakerHashMap.java", "robolectric/utils/reflector/src/main/java/org/robolectric/util/reflector/WithType.java", "robolectric/utils/src/main/java/org/robolectric/AndroidMetadata.java", - "robolectric/utils/src/main/java/org/robolectric/AndroidMetadata.java", "robolectric/utils/src/main/java/org/robolectric/util/Clock.java", "robolectric/utils/src/main/java/org/robolectric/util/Consumer.java", "robolectric/utils/src/main/java/org/robolectric/util/Join.java", @@ -559,6 +558,10 @@ java_library("shadows_core_java") { output_name = "shadows-core-3.2" + # Disable java headers since this target fails to compile with: + # error: An exception occurred in org.robolectric.annotation.processing.RobolectricProcessor: + enable_turbine = false + # Skip platform checks since we must depend on accessibility_test_framework_java # here which requires_android. bypass_platform_checks = true @@ -1085,6 +1088,11 @@ # Skip platform checks since we must depend on android_support_multidex_java # here which requires_android. bypass_platform_checks = true + + # Disable java headers since this target fails to compile with: + # error: An exception occurred in org.robolectric.annotation.processing.RobolectricProcessor: + enable_turbine = false + skip_jetify = true testonly = true processor_args_javac = [ "org.robolectric.annotation.processing.shadowPackage=org.robolectric.shadows.multidex" ] @@ -1127,6 +1135,10 @@ # and google_play_services_library here which both requires_android. bypass_platform_checks = true + # Disable java headers since this target fails to compile with: + # error: An exception occurred in org.robolectric.annotation.processing.RobolectricProcessor: + enable_turbine = false + testonly = true skip_jetify = true processor_args_javac = [ "org.robolectric.annotation.processing.shadowPackage=org.robolectric.shadows.gms" ]
diff --git a/third_party/robolectric/OWNERS b/third_party/robolectric/OWNERS index b84d7996..1981c0c 100644 --- a/third_party/robolectric/OWNERS +++ b/third_party/robolectric/OWNERS
@@ -1,4 +1,6 @@ agrieve@chromium.org bjoyce@chromium.org jbudorick@chromium.org +wnwen@chromium.org + # COMPONENT: Test>Android
diff --git a/tools/android/tracing/systrace-extract-startup.py b/tools/android/tracing/systrace-extract-startup.py index c45ed08..2d6d6f69 100755 --- a/tools/android/tracing/systrace-extract-startup.py +++ b/tools/android/tracing/systrace-extract-startup.py
@@ -227,9 +227,9 @@ NAVIGATION_COMMIT_EVENT_NAME = 'Navigation StartToCommit' STARTUP_EVENT_NAMES = [ - 'Startup.BrowserMainEntryPoint', - 'ChromeApplication.onCreate', - 'ContentShellApplication.onCreate'] + 'Startup.BrowserMainEntryPoint', 'ChromeApplication.onCreate', + 'ContentShellApplication.onCreate' + ] def ParseTrace(file_path):
diff --git a/tools/chrome_proxy/webdriver/bypass.py b/tools/chrome_proxy/webdriver/bypass.py deleted file mode 100644 index 2c4d752..0000000 --- a/tools/chrome_proxy/webdriver/bypass.py +++ /dev/null
@@ -1,343 +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 common -from common import TestDriver -from common import IntegrationTest -from decorators import ChromeVersionEqualOrAfterM - - -class Bypass(IntegrationTest): - - # Ensure Chrome does not use Data Saver for block-once, but does use Data - # Saver for a subsequent request. - def testBlockOnce(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL('http://check.googlezip.net/blocksingle/') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - if response.url == "http://check.googlezip.net/image.png": - self.assertHasProxyHeaders(response) - else: - self.assertNotHasChromeProxyViaHeader(response) - - # Ensure Chrome does not use Data Saver for block=0, which uses the default - # proxy retry delay. - def testBypass(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL('http://check.googlezip.net/block/') - for response in t.GetHTTPResponses(): - self.assertNotHasChromeProxyViaHeader(response) - - # Load another page and check that Data Saver is not used. - t.LoadURL('http://check.googlezip.net/test.html') - for response in t.GetHTTPResponses(): - self.assertNotHasChromeProxyViaHeader(response) - - # Ensure Chrome does not use Data Saver for HTTPS requests. - def testHttpsBypass(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - - # Load HTTP page and check that Data Saver is used. - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - - # Load HTTPS page and check that Data Saver is not used. - t.LoadURL('https://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Verify that CORS requests receive a block-once from the data reduction - # proxy by checking that those requests are retried without data reduction - # proxy. CORS tests needs to be verified with and without OutOfBlinkCors - # feature, since this feature affects sending CORS blocked response headers to - # the renderer in different ways. - def testCorsBypass(self): - self.VerifyCorsTestWithOutOfBlinkCors(True) - - def testCorsBypassWithoutOutOfBlinkCors(self): - # Verifies CORS behavior without OutOfBlinkCors feature. This feature is - # currently under experimentation and once it is fully enabled this test can - # be removed. - self.VerifyCorsTestWithOutOfBlinkCors(False) - - def VerifyProxyServesPageWithoutBypass(self, test_driver): - drp_responses = 0 - test_driver.LoadURL('http://check.googlezip.net/test.html') - for response in test_driver.GetHTTPResponses(): - self.assertHasProxyHeaders(response) - drp_responses += 1 - self.assertNotEqual(0, drp_responses) - test_driver.SleepUntilHistogramHasEntry('PageLoad.Clients.' - 'DataReductionProxy.ParseTiming.NavigationToFirstContentfulPaint') - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BlockTypePrimary')) - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BlockTypeFallback')) - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BypassTypePrimary')) - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BypassTypeFallback')) - - def VerifyCorsTestWithOutOfBlinkCors(self, is_out_of_blink_cors_feature_on): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - if is_out_of_blink_cors_feature_on: - test_driver.EnableChromeFeature('OutOfBlinkCors') - else: - test_driver.DisableChromeFeature('OutOfBlinkCors') - - # The CORS test page makes a cross-origin XHR request to a resource for - # which DRP requests to bypass proxy for the current request. This 502 - # block-once bypass will not be received by the DRP bypass logic in the - # renderer if proper response headers (Access-Control-Allow-Origin and - # Access-Control-Allow-Headers) are not present. - # This test verifies that the bypass logic received one block-once bypass, - # and the request is retried without DRP. The 502 bypass response cannot - # be verified to contain proper response headers set by the DRP since only - # the retried response will be picked up by the webdriver. - test_driver.LoadURL('http://www.gstatic.com/chrome/googlezip/cors/') - - test_driver.SleepUntilHistogramHasEntry( - 'DataReductionProxy.BlockTypePrimary') - # Verify that one request received block-once(bucket=0), and no other - # bypasses or fallbacks are received. Explicit checks for response headers - # content-type=text/plain, Access-Control-Allow-Origin, - # Access-Control-Allow-Headers, Via, Chrome-Proxy cannot be added, since - # webdriver does not get the headers for 502 response. However, since - # BlockTypePrimary is checked for one block-once entry, we know the DRP - # bypass logic has picked it up. - blocked = test_driver.GetHistogram('DataReductionProxy.BlockTypePrimary') - self.assertEqual(1, blocked['count']) - self.assertEqual(blocked['buckets'][0]['low'], 0) - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BlockTypeFallback')) - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BypassTypePrimary')) - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BypassTypeFallback')) - cors_requests = 0 - same_origin_requests = 0 - for response in test_driver.GetHTTPResponses(): - # The cross-origin XHR request is a CORS request. - if response.request_type == 'XHR': - self.assertNotHasChromeProxyViaHeader(response) - self.assertEqual(200, response.status) - cors_requests = cors_requests + 1 - else: - self.assertHasProxyHeaders(response) - same_origin_requests = same_origin_requests + 1 - # Verify that both CORS and same origin requests were seen. - self.assertNotEqual(0, same_origin_requests) - self.assertNotEqual(0, cors_requests) - - # Navigate to a different page to verify that later requests are not - # blocked. - self.VerifyProxyServesPageWithoutBypass(test_driver) - - # Tests that data reduction proxy bypasses are not blocked by CORB. Since the - # bypass/fallback handling is in the renderer process, CORB failures will skip - # the bypasses/fallbacks and the resource will not be retried without data - # reduction proxy. - def testBypassNotBlockedByCorb(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - - # The CORB test page loads an <img> to a cross-origin resource for which - # DRP requests to bypass proxy for the current request. This 502 - # block-once bypass will not be received by the DRP bypass logic in the - # renderer, if CORB blocks it based on mislabeled content-type or the - # actual type observed from sniffing the body. - test_driver.LoadURL('http://www.gstatic.com/chrome/googlezip/corb.html') - drp_responses = 0 - for response in test_driver.GetHTTPResponses(): - if response.ResponseHasViaHeader(): - self.assertHasProxyHeaders(response) - drp_responses += 1 - self.assertNotEqual(0, drp_responses) - test_driver.SleepUntilHistogramHasEntry( - 'DataReductionProxy.BlockTypePrimary') - # Verify that one request received block-once (bucket=0), and no other - # bypasses or fallbacks are received. - blocked = test_driver.GetHistogram('DataReductionProxy.BlockTypePrimary') - self.assertEqual(1, blocked['count']) - self.assertEqual(blocked['buckets'][0]['low'], 0) - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BlockTypeFallback')) - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BypassTypePrimary')) - self.assertEqual({}, - test_driver.GetHistogram('DataReductionProxy.BypassTypeFallback')) - - # Navigate to a different page to verify that later requests are not - # blocked. - self.VerifyProxyServesPageWithoutBypass(test_driver) - - # Verify that when an origin times out using Data Saver, the request is - # fetched directly and data saver is bypassed only for one request. - def testOriginTimeoutBlockOnce(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - - # Load URL that times out when the proxy server tries to access it. - test_driver.LoadURL('http://chromeproxy-test.appspot.com/blackhole') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Load HTTP page and check that Data Saver is used. - test_driver.LoadURL('http://check.googlezip.net/test.html') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - - # Verify that Chrome does not bypass the proxy when a response gets a missing - # via header. - @ChromeVersionEqualOrAfterM(67) - def testMissingViaHeaderNoBypassExperiment(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.EnableChromeFeature('DataReductionProxyRobustConnection' - '<DataReductionProxyRobustConnection') - t.AddChromeArg('--force-fieldtrials=DataReductionProxyRobustConnection/' - 'Enabled') - t.AddChromeArg('--force-fieldtrial-params=' - 'DataReductionProxyRobustConnection.Enabled:' - 'warmup_fetch_callback_enabled/true/' - 'bypass_missing_via_disabled/true') - t.AddChromeArg('--disable-data-reduction-proxy-warmup-url-fetch') - t.AddChromeArg('--data-reduction-proxy-http-proxies=' - # The chromeproxy-test server is a simple HTTP server. If it is served a - # proxy-request, it will respond with a 404 error page. It will not set - # the Via header on the response. - 'https://chromeproxy-test.appspot.com;http://compress.googlezip.net') - - # Loading this URL should not hit the actual check.googlezip.net origin. - # Instead, the test server proxy should fully handle the request and will - # respond with an error page. - t.LoadURL("http://check.googlezip.net/test.html") - for response in t.GetHTTPResponses(): - self.assertNotHasChromeProxyViaHeader(response) - - # Check the via bypass histograms are empty. - histogram = t.GetHistogram( - 'DataReductionProxy.BypassedBytes.MissingViaHeader4xx') - self.assertEqual(0, len(histogram)) - histogram = t.GetHistogram( - 'DataReductionProxy.BypassedBytes.MissingViaHeaderOther') - self.assertEqual(0, len(histogram)) - - # Check that the fetch used the proxy. - histogram = t.GetHistogram('DataReductionProxy.ProxySchemeUsed') - self.assertEqual(histogram['buckets'][0]['low'], 2) - self.assertEqual(histogram['buckets'][0]['high'], 3) - - # Verify that the Data Reduction Proxy understands the "exp" directive. - def testExpDirectiveBypass(self): - # If it was attempted to run with another experiment, skip this test. - if common.ParseFlags().browser_args and ('--data-reduction-proxy-experiment' - in common.ParseFlags().browser_args): - self.skipTest('This test cannot be run with other experiments.') - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.SetExperiment('client_test_bypass') - - # Verify that loading a page other than the specific exp directive test - # page loads through the proxy without being bypassed. - test_driver.LoadURL('http://check.googlezip.net/test.html') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - - # Verify that loading the exp directive test page with - # "exp=client_test_bypass" triggers a bypass. - test_driver.LoadURL('http://check.googlezip.net/exp/') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Verify that loading the same test page without setting - #{ }"exp=client_test_bypass" loads through the proxy without being bypassed. - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - - test_driver.LoadURL('http://check.googlezip.net/exp/') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - - # Data Saver uses a HTTPS proxy by default, if that fails it will fall back to - # a HTTP proxy. - def testBadHTTPSFallback(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.AddChromeArg('--data-reduction-proxy-http-proxies=' - 'http://compress.googlezip.net') - - test_driver.LoadURL('http://check.googlezip.net/fallback/') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertEqual(80, response.port) - - # Get the client type with the first request, then check bypass on the - # appropriate test page - def testClientTypeBypass(self): - clientType = '' - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - # Page that should not bypass. - test_driver.LoadURL('http://check.googlezip.net/test.html') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - if 'chrome-proxy' in response.request_headers: - chrome_proxy_header = response.request_headers['chrome-proxy'] - chrome_proxy_directives = chrome_proxy_header.split(',') - for directive in chrome_proxy_directives: - if 'c=' in directive: - clientType = directive[3:] - self.assertTrue(clientType) - - clients = ['android', 'webview', 'ios', 'linux', 'win', 'chromeos'] - for client in clients: - with TestDriver() as test_driver: - test_driver.LoadURL('http://check.googlezip.net/chrome-proxy-header/' - 'c_%s/' %client) - responses = test_driver.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - if client in clientType: - self.assertNotHasChromeProxyViaHeader(response) - - def testHTTPSubresourcesOnHTTPSPage(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.LoadURL( - 'https://check.googlezip.net/previews/mixed_images.html') - responses = test_driver.GetHTTPResponses() - self.assertEqual(3, len(responses)) - for response in responses: - if response.url.startswith('http://'): - self.assertHasProxyHeaders(response) - elif response.url.startswith('https://'): - self.assertNotHasChromeProxyViaHeader(response) - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/client_config.py b/tools/chrome_proxy/webdriver/client_config.py deleted file mode 100644 index 048c67e3..0000000 --- a/tools/chrome_proxy/webdriver/client_config.py +++ /dev/null
@@ -1,108 +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 common -from common import TestDriver -from common import IntegrationTest -from decorators import ChromeVersionEqualOrAfterM -from decorators import SkipIfForcedBrowserArg -import json - - -class ClientConfig(IntegrationTest): - # Ensure client config is fetched at the start of the Chrome session, and the - # session ID is correctly set in the chrome-proxy request header. - def testClientConfig(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.SleepUntilHistogramHasEntry( - 'DataReductionProxy.ConfigService.FetchResponseCode') - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - # Verify that the proxy server honored the session ID. - self.assertHasProxyHeaders(response) - self.assertEqual(200, response.status) - - # Ensure Chrome uses a direct connection when no valid client config is given. - @SkipIfForcedBrowserArg('data-reduction-proxy-config-url') - def testNoClientConfigUseDirect(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - # The test server won't respond with a valid client config. - t.UseNetLog() - t.AddChromeArg('--data-reduction-proxy-config-url=' - 'https://chromeproxy-test.appspot.com') - t.SleepUntilHistogramHasEntry( - 'DataReductionProxy.ConfigService.FetchResponseCode') - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Ensure client config is fetched at the start of the Chrome session, and the - # variations ID is set in the request. - # Disabled on android because the net log is not copied yet. crbug.com/761507 - @ChromeVersionEqualOrAfterM(62) - def testClientConfigVariationsHeader(self): - with TestDriver() as t: - t.UseNetLog() - t.AddChromeArg('--enable-spdy-proxy-auth') - # Force set the variations ID, so they are send along with the client - # config fetch request. - t.AddChromeArg('--force-variation-ids=42') - - t.LoadURL('http://check.googlezip.net/test.html') - - variation_header_count = 0 - - # Look for the request made to data saver client config server. - data = t.StopAndGetNetLog() - for i in data["events"]: - dumped_event = json.dumps(i) - if dumped_event.find("datasaver.") !=-1 and\ - dumped_event.find(".googleapis.com") !=-1 and\ - dumped_event.find("clientConfigs") != -1 and\ - dumped_event.find("headers") != -1 and\ - dumped_event.find("accept-encoding") != -1 and\ - dumped_event.find("x-client-data") !=-1: - variation_header_count = variation_header_count + 1 - - # Variation IDs are set. x-client-data should be present in the request - # headers. - self.assertLessEqual(1, variation_header_count) - - # Ensure client config is fetched at the start of the Chrome session, and the - # variations ID is not set in the request. - # Disabled on android because the net log is not copied yet. crbug.com/761507 - @ChromeVersionEqualOrAfterM(62) - def testClientConfigNoVariationsHeader(self): - with TestDriver() as t: - t.UseNetLog() - t.AddChromeArg('--enable-spdy-proxy-auth') - - t.LoadURL('http://check.googlezip.net/test.html') - - variation_header_count = 0 - - # Look for the request made to data saver client config server. - data = t.StopAndGetNetLog() - for i in data["events"]: - dumped_event = json.dumps(i) - if dumped_event.find("datasaver.") !=-1 and\ - dumped_event.find(".googleapis.com") !=-1 and\ - dumped_event.find("clientConfigs") != -1 and\ - dumped_event.find("headers") != -1 and\ - dumped_event.find("accept-encoding") != -1 and\ - dumped_event.find("x-client-data") !=-1: - variation_header_count = variation_header_count + 1 - - # Variation IDs are not set. x-client-data should not be present in the - # request headers. - self.assertEqual(0, variation_header_count) - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/fallback.py b/tools/chrome_proxy/webdriver/fallback.py deleted file mode 100644 index cf61ae51..0000000 --- a/tools/chrome_proxy/webdriver/fallback.py +++ /dev/null
@@ -1,67 +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 common -from common import TestDriver -from common import IntegrationTest - -class Fallback(IntegrationTest): - - # Ensure that when a carrier blocks using the secure proxy, requests fallback - # to the HTTP proxy server. - def testSecureProxyProbeFallback(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - - # Set the secure proxy check URL to the google.com favicon, which will be - # interpreted as a secure proxy check failure since the response body is - # not "OK". The google.com favicon is used because it will load reliably - # fast, and there have been problems with chromeproxy-test.appspot.com - # being slow and causing tests to flake. - test_driver.AddChromeArg( - '--data-reduction-proxy-secure-proxy-check-url=' - 'http://www.google.com/favicon.ico') - - # Start chrome to begin the secure proxy check - test_driver.LoadURL('about:blank') - - self.assertTrue( - test_driver.SleepUntilHistogramHasEntry("DataReductionProxy.ProbeURL")) - - test_driver.LoadURL('http://check.googlezip.net/test.html') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - # Verify that DataReductionProxy.ProbeURL histogram has one entry in - # FAILED_PROXY_DISABLED, which is bucket=1. - histogram = test_driver.GetBrowserHistogram('DataReductionProxy.ProbeURL') - self.assertGreaterEqual(histogram['count'], 1) - self.assertGreaterEqual(histogram['buckets'][0]['low'], 1) - for response in responses: - self.assertHasProxyHeaders(response) - # TODO(rajendrant): Fix the correct protocol received. - # self.assertEqual(u'http/2+quic/43', response.protocol) - - # DataSaver uses a https proxy by default, if that fails it will fall back to - # a http proxy; and if that fails, it will fall back to a direct connection - def testHTTPToDirectFallback(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.AddChromeArg('--data-reduction-proxy-http-proxies=' - 'http://nonexistent.googlezip.net;' - 'http://compress.googlezip.net') - - test_driver.LoadURL('http://check.googlezip.net/fallback/') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertEqual(80, response.port) - - test_driver.LoadURL('http://check.googlezip.net/block/') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/html5.py b/tools/chrome_proxy/webdriver/html5.py deleted file mode 100644 index 36fdf32..0000000 --- a/tools/chrome_proxy/webdriver/html5.py +++ /dev/null
@@ -1,29 +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 common -from common import TestDriver -from common import IntegrationTest - - -class HTML5(IntegrationTest): - # This test site has a div with id="pointsPanel" that is rendered if the - # browser is capable of using HTML5. - def testHTML5(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL('http://html5test.com/') - t.WaitForJavascriptExpression( - 'document.getElementsByClassName("pointsPanel")', 15) - checked_main_page = False - for response in t.GetHTTPResponses(): - # Site has a lot on it, just check the main page. - if (response.url == 'http://html5test.com/' - or response.url == 'http://html5test.com/index.html'): - self.assertHasProxyHeaders(response) - checked_main_page = True - if not checked_main_page: - self.fail("Did not check any page!") -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/lite_page.py b/tools/chrome_proxy/webdriver/lite_page.py deleted file mode 100644 index 4fb3c123..0000000 --- a/tools/chrome_proxy/webdriver/lite_page.py +++ /dev/null
@@ -1,286 +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 common -from common import ParseFlags -from common import TestDriver -from common import IntegrationTest -from decorators import AndroidOnly -from decorators import ChromeVersionBeforeM -from decorators import ChromeVersionEqualOrAfterM -from urlparse import urlparse - -import time - -# These are integration tests for server provided previews and the -# protocol that supports them. -class LitePage(IntegrationTest): - - # Verifies that a Lite Page is served for slow connection if any copyright - # restricted country blacklist is ignored. - # Note: this test is for the CPAT protocol change in M-61. - @ChromeVersionEqualOrAfterM(61) - def testLitePageWithoutCopyrightRestriction(self): - # If it was attempted to run with another experiment, skip this test. - if common.ParseFlags().browser_args and ('--data-reduction-proxy-experiment' - in common.ParseFlags().browser_args): - self.skipTest('This test cannot be run with other experiments.') - with TestDriver() as test_driver: - test_driver.EnableChromeFeature('Previews') - test_driver.EnableChromeFeature('DataReductionProxyDecidesTransform') - test_driver.SetExperiment('ignore_preview_blacklist') - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.AddChromeArg('--force-effective-connection-type=2G') - - test_driver.LoadURL('http://check.googlezip.net/test.html') - - lite_page_responses = 0 - checked_chrome_proxy_header = False - for response in test_driver.GetHTTPResponses(): - if response.request_headers: - # Verify client sends ignore directive on main frame request. - self.assertIn('exp=ignore_preview_blacklist', - response.request_headers['chrome-proxy']) - self.assertEqual('2G', response.request_headers['chrome-proxy-ect']) - checked_chrome_proxy_header = True - if response.url.endswith('html'): - self.assertTrue(self.checkLitePageResponse(response)) - lite_page_responses = lite_page_responses + 1 - # Expect no fallback page policy - if 'chrome-proxy' in response.response_headers: - self.assertNotIn('page-policies', - response.response_headers['chrome-proxy']) - else: - # No subresources should accept transforms. - self.assertNotIn('chrome-proxy-accept-transform', - response.request_headers) - self.assertTrue(checked_chrome_proxy_header) - - # Verify that a Lite Page response for the main frame was seen. - self.assertEqual(1, lite_page_responses) - - self.assertPreviewShownViaHistogram(test_driver, 'LitePage') - - # Checks that a Nano Lite Page does not have an error when scrolling to the - # bottom of the page and is able to load all resources. Nano pages don't - # request additional resources when scrolling. This test is only run on - # Android because it depends on window size of the browser. - @AndroidOnly - @ChromeVersionEqualOrAfterM(65) - def testLitePageNano(self): - # If it was attempted to run with another experiment, skip this test. - if common.ParseFlags().browser_args and ('--data-reduction-proxy-experiment' - in common.ParseFlags().browser_args): - self.skipTest('This test cannot be run with other experiments.') - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.EnableChromeFeature('Previews') - test_driver.EnableChromeFeature('DataReductionProxyDecidesTransform') - # Need to force 2G speed to get lite-page response. - test_driver.AddChromeArg('--force-effective-connection-type=2G') - # Set exp=client_test_nano to force Nano response. - test_driver.SetExperiment('client_test_nano') - - # This page is long and has many media resources. - test_driver.LoadURL('http://check.googlezip.net/metrics/index.html') - time.sleep(2) - - lite_page_responses = 0 - btf_response = 0 - image_responses = 0 - for response in test_driver.GetHTTPResponses(): - # Verify that a Lite Page response for the main frame was seen. - if response.url.endswith('html'): - if (self.checkLitePageResponse(response)): - lite_page_responses = lite_page_responses + 1 - # Keep track of BTF responses. - u = urlparse(response.url) - if u.path == "/b": - btf_response = btf_response + 1 - # Keep track of image responses. - if response.url.startswith("data:image"): - image_responses = image_responses + 1 - # Some video requests don't go through Flywheel. - if 'content-type' in response.response_headers and ('video/mp4' - in response.response_headers['content-type']): - continue - # Make sure non-video requests are proxied. - self.assertHasProxyHeaders(response) - # Make sure there are no 4XX or 5xx status codes. - self.assertLess(response.status, 400) - - self.assertEqual(1, lite_page_responses) - self.assertEqual(1, btf_response) - self.assertGreater(1, image_responses) - - # Tests that the stale previews UI is shown on a stale Lite page. - # The stale timestamp histogram is not logged with the new UI unless the page - # info dialog is opened which can't be done in a ChromeDriver test. - @AndroidOnly - @ChromeVersionEqualOrAfterM(65) - @ChromeVersionBeforeM(76) - def testStaleLitePageNano(self): - # If it was attempted to run with another experiment, skip this test. - if common.ParseFlags().browser_args and ('--data-reduction-proxy-experiment' - in common.ParseFlags().browser_args): - self.skipTest('This test cannot be run with other experiments.') - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.EnableChromeFeature('Previews') - test_driver.EnableChromeFeature('DataReductionProxyDecidesTransform') - test_driver.DisableChromeFeature('AndroidOmniboxPreviewsBadge') - test_driver.AddChromeArg('--force-effective-connection-type=2G') - # Set exp=client_test_nano to force Lite page response. - test_driver.SetExperiment('client_test_nano') - # LoadURL waits for onLoadFinish so the Previews UI will be showing by - # then since it's triggered on commit. - test_driver.LoadURL( - 'http://check.googlezip.net/cacheable/test.html?age_seconds=360') - - test_driver.SleepUntilHistogramHasEntry( - 'Previews.StalePreviewTimestampShown') - histogram = test_driver.GetBrowserHistogram( - 'Previews.StalePreviewTimestampShown') - self.assertEqual(1, histogram['count']) - # Check that there is a single entry in the 'Timestamp Shown' bucket. - self.assertEqual( - {'count': 1, 'high': 1, 'low': 0}, - histogram['buckets'][0]) - - # Go to a non stale page and check that the stale timestamp is not shown. - test_driver.LoadURL( - 'http://check.googlezip.net/cacheable/test.html?age_seconds=0') - - histogram = test_driver.GetBrowserHistogram( - 'Previews.StalePreviewTimestampShown') - # Check that there is still a single entry in the 'Timestamp Shown' - # bucket. - self.assertEqual( - {'count': 1, 'high': 1, 'low': 0}, - histogram['buckets'][0]) - - # Verifies Lo-Fi fallback via the page-policies server directive. - # Note: this test is for the CPAT protocol change in M-61. - @ChromeVersionEqualOrAfterM(61) - @ChromeVersionBeforeM(74) - def testLitePageFallbackViaPagePolicies(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.EnableChromeFeature( - 'NetworkQualityEstimator<NetworkQualityEstimator') - test_driver.EnableChromeFeature('Previews') - test_driver.EnableChromeFeature('DataReductionProxyDecidesTransform') - test_driver.AddChromeArg('--force-fieldtrial-params=' - 'NetworkQualityEstimator.Enabled:' - 'force_effective_connection_type/Slow2G') - test_driver.AddChromeArg('--force-fieldtrials=' - 'NetworkQualityEstimator/Enabled/') - - test_driver.LoadURL('http://check.googlezip.net/lite-page-fallback') - - lite_page_responses = 0 - lofi_resource = 0 - for response in test_driver.GetHTTPResponses(): - self.assertEqual('Slow-2G', - response.request_headers['chrome-proxy-ect']) - - if response.url.endswith('html'): - # Verify that the server provides the fallback directive - self.assertIn('page-policies=empty-image', - response.response_headers['chrome-proxy']) - # Main resource should not accept and transform to lite page. - if self.checkLitePageResponse(response): - lite_page_responses = lite_page_responses + 1 - if response.url.endswith('png'): - if self.checkLoFiResponse(response, True): - lofi_resource = lofi_resource + 1 - - self.assertEqual(0, lite_page_responses) - self.assertNotEqual(0, lofi_resource) - - # Checks that the server does not provide a preview (neither Lite Page nor - # fallback to LoFi) for a fast connection. - # Note: this test is for the CPAT protocol change in M-61. - @ChromeVersionEqualOrAfterM(61) - def testPreviewNotProvidedForFastConnection(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.EnableChromeFeature( - 'NetworkQualityEstimator<NetworkQualityEstimator') - test_driver.EnableChromeFeature('NetworkService') - test_driver.EnableChromeFeature('Previews') - test_driver.EnableChromeFeature('DataReductionProxyDecidesTransform') - test_driver.AddChromeArg('--force-fieldtrial-params=' - 'NetworkQualityEstimator.Enabled:' - 'force_effective_connection_type/4G') - test_driver.AddChromeArg( - '--force-fieldtrials=' - 'NetworkQualityEstimator/Enabled/' - 'DataReductionProxyPreviewsBlackListTransition/Enabled/') - - test_driver.LoadURL('http://check.googlezip.net/test.html') - - checked_chrome_proxy_header = False - for response in test_driver.GetHTTPResponses(): - if response.request_headers: - self.assertEqual('4G', response.request_headers['chrome-proxy-ect']) - checked_chrome_proxy_header = True - if response.url.endswith('html'): - # Main resource should accept lite page but not be transformed. - self.assertEqual('lite-page', - response.request_headers['chrome-proxy-accept-transform']) - self.assertNotIn('chrome-proxy-content-transform', - response.response_headers) - # Expect no fallback page policy - if 'chrome-proxy' in response.response_headers: - self.assertNotIn('page-policies', - response.response_headers['chrome-proxy']) - else: - # No subresources should accept transforms. - self.assertNotIn('chrome-proxy-accept-transform', - response.request_headers) - - self.assertPreviewNotShownViaHistogram(test_driver, 'LoFi') - self.assertPreviewNotShownViaHistogram(test_driver, 'LitePage') - self.assertTrue(checked_chrome_proxy_header) - - # Checks the default of whether server previews are enabled or not - # based on whether running on Android (enabled) or not (disabled). - # This is a regression test that the DataReductionProxyDecidesTransform - # Feature is not enabled by default for non-Android platforms. - @ChromeVersionEqualOrAfterM(64) - def testDataReductionProxyDecidesTransformDefault(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - test_driver.EnableChromeFeature( - 'NetworkQualityEstimator<NetworkQualityEstimator') - test_driver.AddChromeArg('--force-fieldtrial-params=' - 'NetworkQualityEstimator.Enabled:' - 'force_effective_connection_type/2G') - test_driver.AddChromeArg( - '--force-fieldtrials=' - 'NetworkQualityEstimator/Enabled/' - 'DataReductionProxyPreviewsBlackListTransition/Enabled/') - - test_driver.LoadURL('http://check.googlezip.net/test.html') - - for response in test_driver.GetHTTPResponses(): - if not response.request_headers: - continue - self.assertEqual('2G', response.request_headers['chrome-proxy-ect']) - if response.url.endswith('html'): - if ParseFlags().android: - # CPAT provided on Android - self.assertIn('chrome-proxy-accept-transform', - response.request_headers) - else: - # CPAT NOT provided on Desktop - self.assertNotIn('chrome-proxy-accept-transform', - response.request_headers) - self.assertNotIn('chrome-proxy-content-transform', - response.response_headers) - continue - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/proxy_connection.py b/tools/chrome_proxy/webdriver/proxy_connection.py deleted file mode 100644 index d9f8fd0c..0000000 --- a/tools/chrome_proxy/webdriver/proxy_connection.py +++ /dev/null
@@ -1,143 +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 common -from common import TestDriver -from common import IntegrationTest -from decorators import ChromeVersionBetweenInclusiveM -from decorators import ChromeVersionEqualOrAfterM -from emulation_server import BlackHoleHandler -from emulation_server import InvalidTLSHandler -from emulation_server import TCPResetHandler -from emulation_server import TLSResetHandler - -class ProxyConnection(IntegrationTest): - - def VerifyWarmupHistogram(self, test_driver, is_secure_proxy): - is_histogram_found = False - for histogram_part in ['Core', 'NonCore']: - histogram_name = 'DataReductionProxy.WarmupURLFetcherCallback.' + \ - 'SuccessfulFetch.%s.%s' % ( - 'SecureProxy' if is_secure_proxy else 'InsecureProxy', - histogram_part) - histogram = test_driver.GetBrowserHistogram(histogram_name) - if histogram: - self.assertLessEqual(1, histogram['count']) - is_histogram_found = True - self.assertTrue(is_histogram_found) - - @ChromeVersionEqualOrAfterM(63) - def testTLSInjectionAfterHandshake(self): - port = common.GetOpenPort() - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - # The server should be 127.0.0.1, not localhost because the two are - # treated differently in Chrome internals. Using localhost invalidates the - # test. - t.AddChromeArg( - '--data-reduction-proxy-http-proxies=https://127.0.0.1:%d' % port) - t.AddChromeArg( - '--force-fieldtrials=DataReductionProxyConfigService/Disabled') - t.UseEmulationServer(InvalidTLSHandler, port=port) - - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - # Expect responses with a bypass on a bad proxy. If the test failed, the - # next assertion will fail because there will be no responses. - self.assertEqual(2, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - self.assertTrue( - t.SleepUntilHistogramHasEntry('DataReductionProxy.WarmupURL.NetError')) - self.VerifyWarmupHistogram(t, True) - - @ChromeVersionEqualOrAfterM(74) - def testTCPReset(self): - port = common.GetOpenPort() - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - # The server should be 127.0.0.1, not localhost because the two are - # treated differently in Chrome internals. Using localhost invalidates the - # test. - t.UseNetLog() - t.AddChromeArg( - '--data-reduction-proxy-http-proxies=http://127.0.0.1:%d' % port) - t.AddChromeArg( - '--force-fieldtrials=DataReductionProxyConfigService/Disabled') - t.UseEmulationServer(TCPResetHandler, port=port) - - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - # Expect responses with a bypass on a bad proxy. If the test failed, the - # next assertion will fail because there will be no responses. - self.assertEqual(2, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - self.assertTrue( - t.SleepUntilHistogramHasEntry('DataReductionProxy.WarmupURL.NetError', - sleep_intervals=10)) - self.VerifyWarmupHistogram(t, False) - - @ChromeVersionEqualOrAfterM(63) - def testTLSReset(self): - port = common.GetOpenPort() - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.AddChromeArg('--allow-insecure-localhost') - # The server should be 127.0.0.1, not localhost because the two are - # treated differently in Chrome internals. Using localhost invalidates the - # test. - t.AddChromeArg( - '--data-reduction-proxy-http-proxies=https://127.0.0.1:%d' % port) - t.AddChromeArg( - '--force-fieldtrials=DataReductionProxyConfigService/Disabled') - t.UseEmulationServer(TLSResetHandler, port=port) - - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - # Expect responses with a bypass on a bad proxy. If the test failed, the - # next assertion will fail because there will be no responses. - self.assertEqual(2, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - @ChromeVersionEqualOrAfterM(74) - def testTCPBlackhole(self): - port = common.GetOpenPort() - with TestDriver() as t: - t.UseNetLog() - t.AddChromeArg('--enable-spdy-proxy-auth') - t.EnableChromeFeature( - 'DataReductionProxyRobustConnection<DataReductionProxyRobustConnection') - t.AddChromeArg('--force-fieldtrials=' - 'DataReductionProxyRobustConnection/Enabled') - t.AddChromeArg('--force-fieldtrial-params=' - 'DataReductionProxyRobustConnection.Enabled:' - 'warmup_fetch_callback_enabled/true') - t.AddChromeArg('--force-effective-connection-type=4G') - # The server should be 127.0.0.1, not localhost because the two are - # treated differently in Chrome internals. Using localhost invalidates the - # test. - t.AddChromeArg( - '--data-reduction-proxy-http-proxies=http://127.0.0.1:%d' % port) - - t.UseEmulationServer(BlackHoleHandler, port=port) - # Start Chrome and wait for the warmup fetcher timeout (30 seconds). - t.LoadURL('data:,') - self.assertTrue( - t.SleepUntilHistogramHasEntry('DataReductionProxy.WarmupURL.NetError', - sleep_intervals=40)) - - # Check the WarmupURL Callback was called. - self.VerifyWarmupHistogram(t, False) - - # Verify DRP was not used. - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/quic.py b/tools/chrome_proxy/webdriver/quic.py deleted file mode 100644 index e458d69..0000000 --- a/tools/chrome_proxy/webdriver/quic.py +++ /dev/null
@@ -1,68 +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 time - -import common -from common import TestDriver -from common import IntegrationTest -from decorators import ChromeVersionEqualOrAfterM - - -class Quic(IntegrationTest): - - # Ensure Chrome uses DataSaver when QUIC is enabled. This test should pass - # even if QUIC is disabled on the server side. In that case, Chrome should - # fallback to using the non-QUIC proxies. - def testCheckPageWithQuicProxy(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - - # Enable QUIC (including for non-core HTTPS proxies). - t.AddChromeArg('--enable-quic') - t.AddChromeArg('--force-fieldtrials=DataReductionProxyUseQuic/Enabled') - t.AddChromeArg('--force-fieldtrial-params=' - 'DataReductionProxyUseQuic.Enabled:enable_quic_non_core_proxies/true') - # Enable usage of QUIC for non-core proxies via switch for older versions - # of Chrome (M-59 and prior). - t.AddChromeArg('--data-reduction-proxy-enable-quic-on-non-core-proxies') - - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - - # Ensure Chrome uses QUIC DataSaver proxy when QUIC is enabled. This test - # may fail if QUIC is disabled on the server side. - @ChromeVersionEqualOrAfterM(76) - def testCheckPageWithQuicProxyTransaction(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - - # Enable QUIC (including for non-core HTTPS proxies). - t.AddChromeArg('--enable-quic') - t.AddChromeArg('--force-fieldtrials=DataReductionProxyUseQuic/Enabled') - t.AddChromeArg('--force-fieldtrial-params=' - 'DataReductionProxyUseQuic.Enabled:enable_quic_non_core_proxies/true') - # Enable usage of QUIC for non-core proxies via switch for older versions - # of Chrome (M-59 and prior). - t.AddChromeArg('--data-reduction-proxy-enable-quic-on-non-core-proxies') - - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - t.SleepUntilHistogramHasEntry('PageLoad.Clients.DataReductionProxy.' - 'ParseTiming.NavigationToParseStart') - - # Verify that histogram DataReductionProxy.Quic.ProxyStatus has at least 1 - # sample. This sample must be in bucket 0 (QUIC_PROXY_STATUS_AVAILABLE). - proxy_status = t.GetHistogram('DataReductionProxy.Quic.ProxyStatus') - self.assertLessEqual(1, proxy_status['count']) - self.assertEqual(0, proxy_status['sum']) - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/reenable_after_bypass.py b/tools/chrome_proxy/webdriver/reenable_after_bypass.py deleted file mode 100644 index 3d0ade8..0000000 --- a/tools/chrome_proxy/webdriver/reenable_after_bypass.py +++ /dev/null
@@ -1,85 +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 time - -import common -from common import TestDriver -from common import IntegrationTest -from decorators import Slow - -class ReenableAfterBypass(IntegrationTest): - """Tests for ensuring that DRPs are reenabled after bypasses expire. - - These tests take a very long time to run since they wait for their respective - bypasses to expire. These tests have been separated out into their own file in - order to make it easier to run these tests separately from the others. - """ - - # Verify that longer bypasses triggered by the Data Reduction Proxy only last - # as long as they're supposed to, and that the proxy is used once again after - # the bypass has ended. - @Slow - def testReenableAfterSetBypass(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - - # Load URL that triggers a 20-second bypass of all proxies. - test_driver.LoadURL('http://check.googlezip.net/block20/') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Verify that the Data Reduction Proxy is still bypassed. - test_driver.LoadURL('http://check.googlezip.net/test.html') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Verify that the Data Reduction Proxy is no longer bypassed after 20 - # seconds. - time.sleep(20) - test_driver.LoadURL('http://check.googlezip.net/test.html') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - - # Verify that when the Data Reduction Proxy responds with the "block=0" - # directive, Chrome bypasses all proxies for the next 1-5 minutes. - @Slow - def testReenableAfterBypass(self): - with TestDriver() as test_driver: - test_driver.AddChromeArg('--enable-spdy-proxy-auth') - - # Load URL that triggers a bypass of all proxies that lasts between 1 and - # 5 minutes. - test_driver.LoadURL('http://check.googlezip.net/block/') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Verify that the Data Reduction Proxy is still bypassed after 30 seconds. - time.sleep(30) - test_driver.LoadURL('http://check.googlezip.net/test.html') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Verify that the Data Reduction Proxy is no longer bypassed 5 minutes - # after the original bypass was triggered. - time.sleep(60 * 4 + 30) - test_driver.LoadURL('http://check.googlezip.net/test.html') - responses = test_driver.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/safebrowsing.py b/tools/chrome_proxy/webdriver/safebrowsing.py deleted file mode 100644 index 730b619..0000000 --- a/tools/chrome_proxy/webdriver/safebrowsing.py +++ /dev/null
@@ -1,52 +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 common -from common import TestDriver -from common import IntegrationTest -from decorators import AndroidOnly -from decorators import NotAndroid -from decorators import ChromeVersionBeforeM -from decorators import ChromeVersionEqualOrAfterM - -from selenium.common.exceptions import TimeoutException - -class SafeBrowsing(IntegrationTest): - - @AndroidOnly - @ChromeVersionBeforeM(73) - def testSafeBrowsingOn(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - - # Starting in M63 LoadURL will timeout when the safebrowsing - # interstitial appears. - try: - t.LoadURL('http://testsafebrowsing.appspot.com/s/malware.html') - responses = t.GetHTTPResponses() - self.assertEqual(0, len(responses)) - except TimeoutException: - pass - - @AndroidOnly - @ChromeVersionEqualOrAfterM(74) - def testSafeBrowsingMalwareWithOnDeviceChecksOn(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - - # Starting in M63 LoadURL will timeout when the safebrowsing - # interstitial appears. - try: - t.LoadURL('http://testsafebrowsing.appspot.com/s/malware.html') - responses = t.GetHTTPResponses() - self.assertEqual(0, len(responses)) - except TimeoutException: - # Verify that on device safebrowsing records unsafe for mainframe - # request at bucket=0 - unsafe_resources = t.GetBrowserHistogram('SB2.ResourceTypes2.Unsafe') - self.assertEqual(1, unsafe_resources['count']) - self.assertEqual(1, unsafe_resources['buckets'][0]['count']) - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/smoke.py b/tools/chrome_proxy/webdriver/smoke.py deleted file mode 100644 index 463df71..0000000 --- a/tools/chrome_proxy/webdriver/smoke.py +++ /dev/null
@@ -1,173 +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 common -import time -from common import TestDriver -from common import IntegrationTest -from decorators import NotAndroid -from decorators import ChromeVersionBeforeM -from decorators import ChromeVersionEqualOrAfterM -import json - -class Smoke(IntegrationTest): - - # Ensure Chrome does not use DataSaver in Incognito mode. - # Clank does not honor the --incognito flag. - @NotAndroid - def testCheckPageWithIncognito(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.AddChromeArg('--incognito') - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Ensure Chrome does not use DataSaver when holdback is enabled. - @ChromeVersionBeforeM(74) - def testCheckPageWithHoldback(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.AddChromeArg('--force-fieldtrials=DataCompressionProxyHoldback/' - 'Enabled') - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - num_chrome_proxy_request_headers = 0 - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - if ('chrome-proxy' in response.request_headers): - num_chrome_proxy_request_headers += 1 - # DataSaver histograms must still be logged. - t.SleepUntilHistogramHasEntry('PageLoad.Clients.DataReductionProxy.' - 'ParseTiming.NavigationToParseStart') - self.assertEqual(num_chrome_proxy_request_headers, 0) - # Ensure that Chrome did not attempt to use DataSaver and got a bypass. - histogram = t.GetHistogram('DataReductionProxy.BypassedBytes.' - 'Status502HttpBadGateway', 5) - self.assertEqual(histogram, {}) - histogram = t.GetHistogram('DataReductionProxy.BlockTypePrimary', 5) - self.assertEqual(histogram, {}) - histogram = t.GetHistogram('DataReductionProxy.BypassTypePrimary', 5) - self.assertEqual(histogram, {}) - - # Ensure Chrome uses DataSaver in normal mode. - def testCheckPageWithNormalMode(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - num_chrome_proxy_request_headers = 0 - for response in responses: - self.assertHasProxyHeaders(response) - if ('chrome-proxy' in response.request_headers): - num_chrome_proxy_request_headers += 1 - t.SleepUntilHistogramHasEntry('PageLoad.Clients.DataReductionProxy.' - 'ParseTiming.NavigationToParseStart') - self.assertGreater(num_chrome_proxy_request_headers, 0) - - # Ensure pageload metric pingback with DataSaver. - @ChromeVersionBeforeM(79) - def testPingback(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.AddChromeArg('--enable-data-reduction-proxy-force-pingback') - t.LoadURL('http://check.googlezip.net/test.html') - t.LoadURL('http://check.googlezip.net/test.html') - t.SleepUntilHistogramHasEntry("DataReductionProxy.Pingback.Succeeded") - t.SleepUntilHistogramHasEntry("DataReductionProxy.Pingback.Attempted") - # Verify one pingback attempt that was successful. - attempted = t.GetBrowserHistogram('DataReductionProxy.Pingback.Attempted') - self.assertEqual(1, attempted['count']) - succeeded = t.GetBrowserHistogram('DataReductionProxy.Pingback.Succeeded') - self.assertEqual(1, succeeded['count']) - - # Ensure pageload metric pingback with DataSaver has the variations header. - @ChromeVersionEqualOrAfterM(62) - @ChromeVersionBeforeM(79) - def testPingbackHasVariations(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.AddChromeArg('--enable-data-reduction-proxy-force-pingback') - t.UseNetLog() - # Force set the variations ID, so they are send along with the pingback - # request. - t.AddChromeArg('--force-variation-ids=42') - t.LoadURL('http://check.googlezip.net/test.html') - t.LoadURL('http://check.googlezip.net/test.html') - t.SleepUntilHistogramHasEntry("DataReductionProxy.Pingback.Succeeded") - - # Look for the request made to data saver pingback server. - data = t.StopAndGetNetLog() - variation_header_count = 0 - for i in data["events"]: - dumped_event = json.dumps(i) - if dumped_event.find("datasaver.googleapis.com") !=-1 and\ - dumped_event.find("recordPageloadMetrics") != -1 and\ - dumped_event.find("headers") != -1 and\ - dumped_event.find("accept-encoding") != -1 and\ - dumped_event.find("x-client-data") !=-1: - variation_header_count = variation_header_count + 1 - - # Variation IDs are set. x-client-data should be present in the request - # headers. - self.assertLessEqual(1, variation_header_count) - - # Verify unique page IDs are sent in the Chrome-Proxy header. - @ChromeVersionEqualOrAfterM(59) - def testPageID(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - page_identifiers = [] - page_loads = 5 - - for i in range (0, page_loads): - t.LoadURL('http://check.googlezip.net/test.html') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - pid_in_page_count = 0 - page_id = '' - for response in responses: - if not response.request_headers: - continue - self.assertHasProxyHeaders(response) - self.assertEqual(200, response.status) - chrome_proxy_header = response.request_headers['chrome-proxy'] - chrome_proxy_directives = chrome_proxy_header.split(',') - for directive in chrome_proxy_directives: - if 'pid=' in directive: - pid_in_page_count = pid_in_page_count+1 - page_id = directive.split('=')[1] - self.assertNotEqual('', page_id) - self.assertNotIn(page_id, page_identifiers) - page_identifiers.append(page_id) - self.assertEqual(1, pid_in_page_count) - - # Ensure that block causes resources to load from the origin directly. - def testCheckBlockIsWorking(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL('http://check.googlezip.net/block') - responses = t.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertNotHasChromeProxyViaHeader(response) - - # Ensure image resources are compressed. - def testCheckImageIsCompressed(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL('http://check.googlezip.net/static') - # http://check.googlezip.net/static is a test page that has - # image resources. - responses = t.GetHTTPResponses() - self.assertNotEqual(0, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/video.py b/tools/chrome_proxy/webdriver/video.py deleted file mode 100644 index 653f2a1c..0000000 --- a/tools/chrome_proxy/webdriver/video.py +++ /dev/null
@@ -1,316 +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 time - -import common -from common import TestDriver -from common import IntegrationTest -from common import ParseFlags -from decorators import AndroidOnly -from decorators import Slow -from decorators import ChromeVersionEqualOrAfterM - -from selenium.webdriver.common.by import By - -class Video(IntegrationTest): - - # Returns the ofcl value in chrome-proxy header. - def getChromeProxyOFCL(self, response): - self.assertIn('chrome-proxy', response.response_headers) - chrome_proxy_header = response.response_headers['chrome-proxy'] - self.assertIn('ofcl=', chrome_proxy_header) - return chrome_proxy_header.split('ofcl=', 1)[1].split(',', 1)[0] - - # Check videos are proxied. - def testCheckVideoHasViaHeader(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL( - 'http://check.googlezip.net/cacheable/video/buck_bunny_tiny.html') - responses = t.GetHTTPResponses() - self.assertEqual(2, len(responses)) - for response in responses: - self.assertHasProxyHeaders(response) - - def testCheckVideoBypass(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL( - 'http://check.googlezip.net/blocksingle/blocksingle_embedded_video.html') - saw_video_response = False - for response in t.GetHTTPResponses(): - if 'video' in response.response_headers['content-type']: - self.assertNotHasChromeProxyViaHeader(response) - saw_video_response = True - else: - self.assertHasProxyHeaders(response) - self.assertTrue(saw_video_response, 'No video request seen in test!') - - # Videos fetched via an XHR request should not be proxied. - def testNoCompressionOnXHR(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - # The test will actually use Javascript, so use a site that won't have any - # resources on it that could interfere. - t.LoadURL('http://check.googlezip.net/connect') - t.ExecuteJavascript( - 'var xhr = new XMLHttpRequest();' - 'xhr.open("GET", "/cacheable/video/data/buck_bunny_tiny.mp4", false);' - 'xhr.send();' - 'return;' - ) - saw_video_response = False - for response in t.GetHTTPResponses(): - if 'video' in response.response_headers['content-type']: - self.assertNotHasChromeProxyViaHeader(response) - saw_video_response = True - else: - self.assertHasProxyHeaders(response) - self.assertTrue(saw_video_response, 'No video request seen in test!') - - @ChromeVersionEqualOrAfterM(64) - def testRangeRequest(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL('http://check.googlezip.net/report') - time.sleep(2) # wait for page load - t.ExecuteJavascript( - 'var xhr = new XMLHttpRequest();' - 'xhr.open("GET", "/metrics/local.png", false);' - 'xhr.setRequestHeader("Range", "bytes=0-2048");' - 'xhr.send();' - 'return;' - ) - saw_range_response = False - for response in t.GetHTTPResponses(): - self.assertHasProxyHeaders(response) - if response.response_headers['status']=='206': - saw_range_response = True - content_range = response.response_headers['content-range'] - self.assertTrue(content_range.startswith('bytes 0-2048/')) - compressed_full_content_length = int(content_range.split('/')[1]) - ofcl = int(self.getChromeProxyOFCL(response)) - # ofcl should be same as compressed full content length, since no - # compression for XHR. - self.assertEqual(ofcl, compressed_full_content_length) - # Wait and navigate away to trigger the metrics recording for previous - # page load. - time.sleep(1) - t.LoadURL('about:blank') - original_kb_histogram = t.GetBrowserHistogram('PageLoad.Clients.' - 'DataReductionProxy.Experimental.Bytes.Network.Original2') - compression_percent_histogram = t.GetBrowserHistogram('PageLoad.Clients.' - 'DataReductionProxy.Experimental.Bytes.Network.CompressionRatio2') - self.assertEqual(1, original_kb_histogram['count']) - self.assertEqual(1, compression_percent_histogram['count']) - # Verify the total page size is 3 KB, and compression ratio. - self.assertLessEqual(3, original_kb_histogram['sum']) - self.assertEqual(compression_percent_histogram['sum'], - compressed_full_content_length/ofcl*100) - self.assertTrue(saw_range_response, 'No range request was seen in test!') - - @ChromeVersionEqualOrAfterM(64) - def testRangeRequestInVideo(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL( - 'http://check.googlezip.net/cacheable/video/buck_bunny_tiny.html') - # Wait for the video to finish playing, plus some headroom. - time.sleep(5) - responses = t.GetHTTPResponses() - saw_range_response = False - for response in responses: - self.assertHasProxyHeaders(response) - if response.response_headers['status']=='206': - saw_range_response = True - content_range = response.response_headers['content-range'] - compressed_full_content_length = int(content_range.split('/')[1]) - ofcl = int(self.getChromeProxyOFCL(response)) - # ofcl should be greater than the compressed full content length. - self.assertGreater(ofcl, compressed_full_content_length) - self.assertTrue(saw_range_response, 'No range request was seen in test!') - - # Check the compressed video has the same frame count, width, height, and - # duration as uncompressed. - @Slow - def testVideoMetrics(self): - expected = { - 'duration': 3.068, - 'webkitDecodedFrameCount': 53.0, - 'videoWidth': 1280.0, - 'videoHeight': 720.0 - } - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL( - 'http://check.googlezip.net/cacheable/video/buck_bunny_tiny.html') - # Check request was proxied and we got a compressed video back. - for response in t.GetHTTPResponses(): - self.assertHasProxyHeaders(response) - if ('content-type' in response.response_headers - and 'video' in response.response_headers['content-type']): - self.assertEqual('video/webm', - response.response_headers['content-type']) - if ParseFlags().android: - t.FindElement(By.TAG_NAME, "video").click() - else: - t.ExecuteJavascriptStatement( - 'document.querySelectorAll("video")[0].play()') - # Wait for the video to finish playing, plus some headroom. - time.sleep(5) - # Check each metric against its expected value. - for metric in expected: - actual = float(t.ExecuteJavascriptStatement( - 'document.querySelectorAll("video")[0].%s' % metric)) - self.assertAlmostEqual(expected[metric], actual, msg="Compressed video " - "metric doesn't match expected! Metric=%s Expected=%f Actual=%f" - % (metric, expected[metric], actual), places=None, delta=0.01) - - # Check that the compressed video can be seeked. Use a slow network to ensure - # the entire video isn't downloaded before we have a chance to seek. - @Slow - @AndroidOnly - def testVideoSeeking(self): - with TestDriver(control_network_connection=True) as t: - t.SetNetworkConnection("2G") - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL( - 'http://check.googlezip.net/cacheable/video/'+ - 'buck_bunny_640x360_24fps.html') - # Play, pause, seek to 1s before the end, play again. - t.ExecuteJavascript( - ''' - window.testDone = false; - const v = document.getElementsByTagName("video")[0]; - let first = true; - v.onplaying = function() { - if (first) { - v.pause(); - first = false; - } else { - window.testDone = true; - } - }; - v.onpause = function() { - if (v.currentTime < v.duration) { - v.currentTime = v.duration-1; - v.play(); - } - }; - v.play(); - ''') - if ParseFlags().android: - # v.play() won't work on Android, so give it a click instead. - t.FindElement(By.TAG_NAME, "video").click() - t.WaitForJavascriptExpression('window.testDone', 15) - # Check request was proxied and we got a compressed video back. - # We expect to make multiple requests for the video: ensure they - # all have the same ETag. - video_etag = None - num_partial_requests = 0 - for response in t.GetHTTPResponses(): - self.assertHasProxyHeaders(response) - rh = response.response_headers - if ('content-type' in rh and 'video' in rh['content-type']): - self.assertIn('etag', rh), - self.assertEqual('video/webm', rh['content-type']) - if video_etag == None: - video_etag = rh['etag'] - else: - self.assertEqual(video_etag, rh['etag']) - if ('status' in rh and rh['status']=='206' and 'content-range' in rh - and rh['content-range'].startswith('bytes ') and - not rh['content-range'].startswith('bytes 0-')): - num_partial_requests += 1 - # Also make sure that we had at least one partial Range request. - self.assertGreaterEqual(num_partial_requests, 1) - - # Check the frames of a compressed video. - @Slow - def testVideoFrames(self): - self.instrumentedVideoTest('http://check.googlezip.net/cacheable/video/buck_bunny_640x360_24fps_video.html') - - # Check the audio volume of a compressed video. - # - # This test makes some assumptions about the way audio is decoded and - # processed in JavaScript on different platforms. Despite getting the same - # video bytes from the proxy across all platforms, different data is generated - # out of the window.AudioContext object. As of May 2017, there were only two - # known datasets, the second occurring on all tested Android devices. If this - # test fails on a new or different platform, examine whether the expected data - # is drastically different. See crbug.com/723031 for more information. - @Slow - def testVideoAudio(self): - alt_data = None - is_android = ParseFlags().android - if is_android: - alt_data = 'data/buck_bunny_640x360_24fps.mp4.expected_volume_alt.json' - self.instrumentedVideoTest('http://check.googlezip.net/cacheable/video/buck_bunny_640x360_24fps_audio.html', - alt_data=alt_data) - - def instrumentedVideoTest(self, url, alt_data=None): - """Run an instrumented video test. The given page is reloaded up to some - maximum number of times until a compressed video is seen by ChromeDriver by - inspecting the network logs. Once that happens, test.ready is set and that - will signal the Javascript test on the page to begin. Once it is complete, - check the results. - """ - # The maximum number of times to attempt to reload the page for a compressed - # video. - max_attempts = 10 - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.AddChromeArg('--autoplay-policy=no-user-gesture-required') - loaded_compressed_video = False - attempts = 0 - while not loaded_compressed_video and attempts < max_attempts: - t.LoadURL(url) - attempts += 1 - for resp in t.GetHTTPResponses(): - if ('content-type' in resp.response_headers - and resp.response_headers['content-type'] == 'video/webm'): - loaded_compressed_video = True - self.assertHasProxyHeaders(resp) - else: - # Take a breath before requesting again. - time.sleep(1) - if attempts >= max_attempts: - self.fail('Could not get a compressed video after %d tries' % attempts) - if alt_data != None: - t.ExecuteJavascriptStatement('test.expectedVolumeSrc = "%s"' % alt_data) - t.ExecuteJavascriptStatement('test.ready = true') - t.WaitForJavascriptExpression('test.video_ != undefined', 5) - # Click the video to start if Android. - if ParseFlags().android: - t.FindElement(By.ID, 'video').click() - else: - t.ExecuteJavascriptStatement('test.video_.play()') - waitTimeQuery = 'test.waitTime' - if ParseFlags().android: - waitTimeQuery = 'test.androidWaitTime' - wait_time = int(t.ExecuteJavascriptStatement(waitTimeQuery)) - t.WaitForJavascriptExpression('test.metrics.complete', wait_time) - metrics = t.ExecuteJavascriptStatement('test.metrics') - if not metrics['complete']: - self.fail('Test not complete after %d seconds.' % wait_time) - if metrics['failed']: - self.fail('Test failed! ' + metrics['detailedStatus']) - - # Make sure YouTube autoplays. - def testYoutube(self): - with TestDriver() as t: - t.AddChromeArg('--enable-spdy-proxy-auth') - t.LoadURL('http://data-saver-test.appspot.com/youtube') - if ParseFlags().android: - # Video won't auto play on Android, so give it a click. - t.FindElement(By.ID, 'player').click() - t.WaitForJavascriptExpression( - 'window.playerState == YT.PlayerState.PLAYING', 30) - for response in t.GetHTTPResponses(): - if not response.url.startswith('https'): - self.assertHasProxyHeaders(response) - -if __name__ == '__main__': - IntegrationTest.RunAllTests()
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 5df5260..759ab43 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -22542,6 +22542,7 @@ <int value="1459" label="PASSWORDSPRIVATE_STOPPASSWORDCHECK"/> <int value="1460" label="PASSWORDSPRIVATE_GETPASSWORDCHECKSTATUS"/> <int value="1461" label="TERMINALPRIVATE_OPENVMSHELLPROCESS"/> + <int value="1462" label="PASSWORDSPRIVATE_OPTINFORACCOUNTSTORAGE"/> </enum> <enum name="ExtensionIconState"> @@ -38499,6 +38500,7 @@ label="AutofillToolkitViewsCreditCardDialogsMac:disabled"/> <int value="-808486493" label="NewWallpaperPicker:disabled"/> <int value="-806480547" label="SyncDeviceInfoInTransportMode:enabled"/> + <int value="-805480822" label="RemoteCopyImageNotification:disabled"/> <int value="-803233334" label="AutofillRefreshStyleAndroid:disabled"/> <int value="-802348444" label="disable-site-engagement-service"/> <int value="-799931058" label="UseMultiloginEndpoint:disabled"/> @@ -39585,6 +39587,7 @@ <int value="513258875" label="WinrtSensorsImplementation:disabled"/> <int value="513356954" label="InstantTethering:disabled"/> <int value="513372959" label="ViewsProfileChooser:enabled"/> + <int value="514569020" label="RemoteCopyImageNotification:enabled"/> <int value="516603570" label="QuickAnswersRichUi:disabled"/> <int value="517429103" label="AutofillImportDynamicForms:enabled"/> <int value="517568645" label="AnimatedAppMenuIcon:disabled"/> @@ -54571,6 +54574,9 @@ </enum> <enum name="QueryWebAndAppActivityState"> + <obsolete> + Removed March 2020. + </obsolete> <int value="0" label="History recording enabled"/> <int value="1" label="History recording disabled"/> <int value="2" label="Request failed"/> @@ -63938,6 +63944,9 @@ </enum> <enum name="SyncSetupSettignsDisplayedSwaaState"> + <obsolete> + Removed March 2020. + </obsolete> <int value="0" label="On"/> <int value="1" label="Off due to custom encryption"/> <int value="2" label="Off due to history sync off"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 93e3396..e9778ec3 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -40440,6 +40440,34 @@ </summary> </histogram> +<histogram name="DomDistiller.Time.ActivelyViewingArticleBeforeDistilling" + units="ms" expires_after="2020-09-01"> + <owner>katie@chromium.org</owner> + <owner>chrome-a11y-core@chromium.org</owner> + <summary> + Records the amount of active time a user spent on a distillable page before + switching that page to Reader Mode. Active time is time that the article was + visible, not total time the page was open: the timer is paused when the page + is not visible. This is not recorded when the user opens a distillable page + but does not switch to Reader Mode from that page (via the omnibox icon or + menu option). + </summary> +</histogram> + +<histogram name="DomDistiller.Time.ActivelyViewingReaderModePage" units="ms" + expires_after="2020-09-01"> + <owner>katie@chromium.org</owner> + <owner>chrome-a11y-core@chromium.org</owner> + <summary> + Records the amount of active time a user spent on a Reader Mode page. Active + time is the time the Reader Mode page was visible, not the total time the + page was open: the timer is paused when the page is not visible. This is + recorded regardless of how a user enters the page: e.g. using the + forward/back buttons, entering the URL directly, or coming from a + distillable page all start the timer equally. + </summary> +</histogram> + <histogram name="DomDistiller.Time.ArticleProcessing" units="ms" expires_after="M77"> <owner>yfriedman@chromium.org</owner> @@ -147902,6 +147930,9 @@ <histogram name="Settings.SyncSetup.DisplayedSwaaState" enum="SyncSetupSettignsDisplayedSwaaState" expires_after="M85"> + <obsolete> + Removed March 2020. + </obsolete> <owner>msalama@chromium.org</owner> <owner>chrome-signin-team@google.com</owner> <summary> @@ -156567,6 +156598,27 @@ </summary> </histogram> +<histogram name="Startup.FirstWebContents.NonEmptyPaint3" units="ms" + expires_after="M85"> + <owner>etiennep@chromium.org</owner> + <owner>fdoray@chromium.org</owner> + <owner>gab@chromium.org</owner> + <summary> + [Desktop] Measure the elapsed time from the application start to the first + non empty paint of the first web contents. Only comprised of cases where the + initial foreground tab gets to complete its rendering task unimpeded (an + improvement over Startup.FirstWebContents.NonEmptyPaint). + + This is meant to replace Startup.FirstWebContents.NonEmptyPaint2, using + application start time instead of process creation time. Application start + time is recorded as early as possible in the startup process. On Android, + the application start is the time at which the Java code starts. On Windows, + application start is sampled from chrome.exe:main, before chrome.dll is + loaded. TODO(etiennep): Deprecate NonEmptyPaint2 in favor of this one once + stable. + </summary> +</histogram> + <histogram name="Startup.FirstWebContents.RenderProcessHostInit.ToNonEmptyPaint" units="ms" expires_after="M78"> @@ -156681,6 +156733,19 @@ <summary>Whether a startup is a resume (vs a cold start).</summary> </histogram> +<histogram name="Startup.LoadTime.ApplicationStartToChromeMain" units="ms" + expires_after="never"> +<!-- expires-never: used to diagnose regressions to Startup.FirstWebContents.NonEmptyPaint2 --> + + <owner>fdoray@chromium.org</owner> + <owner>etiennep@chromium.org</owner> + <owner>gab@chromium.org</owner> + <summary> + Time from the application start to the C++ ChromeMain() function being + invoked. + </summary> +</histogram> + <histogram name="Startup.LoadTime.ExeMainToDllMain" units="units" expires_after="2016-12-17"> <obsolete> @@ -156696,10 +156761,12 @@ </summary> </histogram> -<histogram name="Startup.LoadTime.ExeMainToDllMain2" units="units" - expires_after="never"> -<!-- expires-never: used to diagnose regressions to Startup.FirstWebContents.NonEmptyPaint2 --> - +<histogram name="Startup.LoadTime.ExeMainToDllMain2" units="ms" + expires_after="2020-03-12"> + <obsolete> + Removed 03/2020. Replaced with Startup.LoadTime.ApplicationStartToChromeMain + which applies to most platforms. + </obsolete> <owner>fdoray@chromium.org</owner> <owner>gab@chromium.org</owner> <summary> @@ -156707,6 +156774,19 @@ </summary> </histogram> +<histogram name="Startup.LoadTime.ProcessCreateToApplicationStart" units="ms" + expires_after="never"> +<!-- expires-never: used to diagnose regressions to Startup.FirstWebContents.NonEmptyPaint2 --> + + <owner>fdoray@chromium.org</owner> + <owner>etiennep@chromium.org</owner> + <owner>gab@chromium.org</owner> + <summary> + Time from the process creation to application start, i.e. time recorded as + early as possible in the startup process. + </summary> +</histogram> + <histogram name="Startup.LoadTime.ProcessCreateToDllMain" units="units" expires_after="2016-12-17"> <obsolete> @@ -156722,10 +156802,13 @@ </summary> </histogram> -<histogram name="Startup.LoadTime.ProcessCreateToDllMain2" units="units" - expires_after="never"> -<!-- expires-never: used to diagnose regressions to Startup.FirstWebContents.NonEmptyPaint2 --> - +<histogram name="Startup.LoadTime.ProcessCreateToDllMain2" units="ms" + expires_after="2020-03-12"> + <obsolete> + Removed 03/2020. Replaced with + Startup.LoadTime.ProcessCreateToApplicationStart which applies to most + platforms. + </obsolete> <owner>fdoray@chromium.org</owner> <owner>gab@chromium.org</owner> <summary>Time from the process creation to chrome.dll's main().</summary> @@ -156747,10 +156830,13 @@ </summary> </histogram> -<histogram name="Startup.LoadTime.ProcessCreateToExeMain2" units="units" +<histogram name="Startup.LoadTime.ProcessCreateToExeMain2" units="ms" expires_after="never"> -<!-- expires-never: used to diagnose regressions to Startup.FirstWebContents.NonEmptyPaint2 --> - + <obsolete> + Removed 03/2020. Now covered by + Startup.LoadTime.ProcessCreateToApplicationStart and + Startup.LoadTime.ApplicationStartToChromeMain. + </obsolete> <owner>fdoray@chromium.org</owner> <owner>gab@chromium.org</owner> <summary> @@ -177024,7 +177110,10 @@ </histogram> <histogram name="WebHistory.QueryWebAndAppActivity.State" - enum="QueryWebAndAppActivityState" expires_after="M85"> + enum="QueryWebAndAppActivityState" expires_after="M83"> + <obsolete> + Removed March 2020. + </obsolete> <owner>msalama@chromium.org</owner> <owner>chrome-signin-team@google.com</owner> <summary> @@ -198087,8 +198176,10 @@ <affected-histogram name="Startup.FirstWebContents.NonEmptyPaint2"/> <affected-histogram name="Startup.FirstWebContents.RenderProcessHostInit.ToNonEmptyPaint"/> + <affected-histogram name="Startup.LoadTime.ApplicationStartToChromeMain"/> <affected-histogram name="Startup.LoadTime.ExeMainToDllMain"/> <affected-histogram name="Startup.LoadTime.ExeMainToDllMain2"/> + <affected-histogram name="Startup.LoadTime.ProcessCreateToApplicationStart"/> <affected-histogram name="Startup.LoadTime.ProcessCreateToDllMain"/> <affected-histogram name="Startup.LoadTime.ProcessCreateToDllMain2"/> <affected-histogram name="Startup.LoadTime.ProcessCreateToExeMain"/>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 5f3b400..528375c 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -5424,6 +5424,22 @@ <metric name="Length"/> </event> +<event name="Media.GlobalMediaControls.ActionButtonPressed"> + <owner>steimel@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Records when a user presses a button in the Global Media Controls. Records + no more than 100 actions per source per session. Records which button was + pressed (e.g. play, pause, next track, picture-in-picture). + </summary> + <metric name="MediaSessionAction" enum="MediaSessionAction"> + <summary> + The action of the button that was pressed (e.g. play, pause, next track, + picture-in-picture). + </summary> + </metric> +</event> + <event name="Media.Learning.PredictionRecord"> <owner>liberato@chromium.org</owner> <summary>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 09c5751..07e0c7e 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -131,9 +131,8 @@ <item id="google_url_tracker" hash_code="5492492" type="0" deprecated="2019-08-01" content_hash_code="54474899" file_path=""/> <item id="headless_url_request" hash_code="29865866" type="0" deprecated="2018-07-10" content_hash_code="76700151" file_path=""/> <item id="hintsfetcher_gethintsrequest" hash_code="34557599" type="0" content_hash_code="57003380" os_list="linux,windows" file_path="components/optimization_guide/hints_fetcher.cc"/> - <item id="history_notice_utils_notice" hash_code="102595701" type="1" second_id="110307337" deprecated="2020-01-07" content_hash_code="130829410" file_path=""/> + <item id="history_notice_utils_notice" hash_code="102595701" type="1" second_id="110307337" content_hash_code="130829410" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/> <item id="history_notice_utils_popup" hash_code="80832574" type="1" second_id="110307337" content_hash_code="30618510" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/> - <item id="history_recording_enabled" hash_code="18918377" type="1" second_id="110307337" content_hash_code="24841534" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/> <item id="history_ui_favicon_request_handler_get_favicon" hash_code="17562717" type="0" content_hash_code="64054629" os_list="linux,windows" file_path="components/favicon/core/history_ui_favicon_request_handler_impl.cc"/> <item id="http_server_error_response" hash_code="32197336" type="0" content_hash_code="61082230" os_list="linux,windows" file_path="net/server/http_server.cc"/> <item id="https_server_previews_navigation" hash_code="35725390" type="0" content_hash_code="84423109" os_list="linux,windows" file_path="chrome/browser/previews/previews_lite_page_redirect_serving_url_loader.cc"/>
diff --git a/ui/accessibility/platform/ax_fragment_root_win.cc b/ui/accessibility/platform/ax_fragment_root_win.cc index 6f37698f..458625dc 100644 --- a/ui/accessibility/platform/ax_fragment_root_win.cc +++ b/ui/accessibility/platform/ax_fragment_root_win.cc
@@ -129,10 +129,26 @@ *focus = nullptr; - gfx::NativeViewAccessible focused_element = GetDelegate()->GetFocus(); - if (focused_element != nullptr) { + gfx::NativeViewAccessible focused_element = nullptr; + + // GetFocus() can return a node at the root of a subtree, for example when + // transitioning from Views into web content. In such cases we want to + // continue drilling to retrieve the actual focused element. + AXPlatformNode* node_to_test = this; + do { + gfx::NativeViewAccessible test_result = + node_to_test->GetDelegate()->GetFocus(); + if (test_result != nullptr && test_result != focused_element) { + focused_element = test_result; + node_to_test = + AXPlatformNode::FromNativeViewAccessible(focused_element); + } else { + node_to_test = nullptr; + } + } while (node_to_test); + + if (focused_element) focused_element->QueryInterface(IID_PPV_ARGS(focus)); - } return S_OK; }
diff --git a/ui/display/win/screen_win.cc b/ui/display/win/screen_win.cc index 7ef3f87..5899271 100644 --- a/ui/display/win/screen_win.cc +++ b/ui/display/win/screen_win.cc
@@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/metrics/histogram_functions.h" +#include "base/numerics/ranges.h" #include "base/stl_util.h" #include "base/win/win_util.h" #include "base/win/windows_version.h" @@ -24,6 +25,7 @@ #include "ui/display/win/screen_win_display.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/safe_integer_conversions.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/icc_profile.h" @@ -34,35 +36,25 @@ // TODO(robliao): http://crbug.com/615514 Remove when ScreenWin usage is // resolved with Desktop Aura and WindowTreeHost. -ScreenWin* g_screen_win_instance = nullptr; +ScreenWin* g_instance = nullptr; -// Gets the DPI for a particular monitor, or 0 if per-monitor DPI is nuot -// supported or can't be read. +// Gets the DPI for a particular monitor. int GetPerMonitorDPI(HMONITOR monitor) { - // Most versions of Windows we will encounter are DPI-aware. if (!base::win::IsProcessPerMonitorDpiAware()) return 0; static auto get_dpi_for_monitor_func = []() { - using GetDpiForMonitorPtr = decltype(::GetDpiForMonitor)*; - HMODULE shcore_dll = ::LoadLibrary(L"shcore.dll"); - if (shcore_dll) { - return reinterpret_cast<GetDpiForMonitorPtr>( - ::GetProcAddress(shcore_dll, "GetDpiForMonitor")); - } - return static_cast<GetDpiForMonitorPtr>(nullptr); + const HMODULE shcore_dll = ::LoadLibrary(L"shcore.dll"); + return reinterpret_cast<decltype(&::GetDpiForMonitor)>( + shcore_dll ? ::GetProcAddress(shcore_dll, "GetDpiForMonitor") + : nullptr); }(); - - if (!get_dpi_for_monitor_func) + UINT dpi_x, dpi_y; + if (!get_dpi_for_monitor_func || + !SUCCEEDED( + get_dpi_for_monitor_func(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y))) return 0; - UINT dpi_x; - UINT dpi_y; - if (!SUCCEEDED(get_dpi_for_monitor_func(monitor, MDT_EFFECTIVE_DPI, &dpi_x, - &dpi_y))) { - return 0; - } - DCHECK_EQ(dpi_x, dpi_y); return int{dpi_x}; } @@ -77,7 +69,7 @@ if (Display::HasForceDeviceScaleFactor()) return Display::GetForcedDeviceScaleFactor(); - int dpi = GetPerMonitorDPI(monitor); + const int dpi = GetPerMonitorDPI(monitor); if (!dpi) return GetDPIScale(); @@ -91,45 +83,42 @@ } bool GetPathInfo(HMONITOR monitor, DISPLAYCONFIG_PATH_INFO* path_info) { - LONG result; - uint32_t num_path_array_elements = 0; - uint32_t num_mode_info_array_elements = 0; - std::vector<DISPLAYCONFIG_PATH_INFO> path_infos; - std::vector<DISPLAYCONFIG_MODE_INFO> mode_infos; - // Get the monitor name. - MONITORINFOEXW view_info; - view_info.cbSize = sizeof(view_info); - if (!GetMonitorInfoW(monitor, &view_info)) + MONITORINFOEX monitor_info; + monitor_info.cbSize = sizeof(monitor_info); + if (!GetMonitorInfo(monitor, &monitor_info)) return false; // Get all path infos. + LONG result; + std::vector<DISPLAYCONFIG_PATH_INFO> path_infos; do { - if (GetDisplayConfigBufferSizes( - QDC_ONLY_ACTIVE_PATHS, &num_path_array_elements, - &num_mode_info_array_elements) != ERROR_SUCCESS) { + uint32_t path_elements, mode_elements; + if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &path_elements, + &mode_elements) != ERROR_SUCCESS) { return false; } - path_infos.resize(num_path_array_elements); - mode_infos.resize(num_mode_info_array_elements); - result = QueryDisplayConfig( - QDC_ONLY_ACTIVE_PATHS, &num_path_array_elements, path_infos.data(), - &num_mode_info_array_elements, mode_infos.data(), nullptr); + path_infos.resize(path_elements); + std::vector<DISPLAYCONFIG_MODE_INFO> mode_infos(mode_elements); + result = QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &path_elements, + path_infos.data(), &mode_elements, + mode_infos.data(), nullptr); + if (result == ERROR_SUCCESS) + path_infos.resize(path_elements); } while (result == ERROR_INSUFFICIENT_BUFFER); - // Iterate of the path infos and see if we find one with a matching name. + // Look for a path info with a matching name. if (result == ERROR_SUCCESS) { - for (uint32_t p = 0; p < num_path_array_elements; p++) { - DISPLAYCONFIG_SOURCE_DEVICE_NAME device_name; + for (const auto& info : path_infos) { + DISPLAYCONFIG_SOURCE_DEVICE_NAME device_name = {}; device_name.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; device_name.header.size = sizeof(device_name); - device_name.header.adapterId = path_infos[p].sourceInfo.adapterId; - device_name.header.id = path_infos[p].sourceInfo.id; - if (DisplayConfigGetDeviceInfo(&device_name.header) == ERROR_SUCCESS) { - if (wcscmp(view_info.szDevice, device_name.viewGdiDeviceName) == 0) { - *path_info = path_infos[p]; - return true; - } + device_name.header.adapterId = info.sourceInfo.adapterId; + device_name.header.id = info.sourceInfo.id; + if ((DisplayConfigGetDeviceInfo(&device_name.header) == ERROR_SUCCESS) && + (wcscmp(monitor_info.szDevice, device_name.viewGdiDeviceName) == 0)) { + *path_info = info; + return true; } } } @@ -137,20 +126,17 @@ } float GetMonitorSDRWhiteLevel(HMONITOR monitor) { - float ret = 200.0; // default value DISPLAYCONFIG_PATH_INFO path_info = {}; - if (!GetPathInfo(monitor, &path_info)) - return ret; - - DISPLAYCONFIG_SDR_WHITE_LEVEL white_level = {}; - white_level.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL; - white_level.header.size = sizeof(white_level); - white_level.header.adapterId = path_info.targetInfo.adapterId; - white_level.header.id = path_info.targetInfo.id; - if (DisplayConfigGetDeviceInfo(&white_level.header) != ERROR_SUCCESS) - return ret; - ret = white_level.SDRWhiteLevel * 80.0 / 1000.0; - return ret; + if (GetPathInfo(monitor, &path_info)) { + DISPLAYCONFIG_SDR_WHITE_LEVEL white_level = {}; + white_level.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL; + white_level.header.size = sizeof(white_level); + white_level.header.adapterId = path_info.targetInfo.adapterId; + white_level.header.id = path_info.targetInfo.id; + if (DisplayConfigGetDeviceInfo(&white_level.header) == ERROR_SUCCESS) + return white_level.SDRWhiteLevel * 80.0 / 1000.0; + } + return 200.0f; } void GetDisplaySettingsForDevice(const wchar_t* device_name, @@ -160,34 +146,33 @@ *frequency = 0; DEVMODE mode = {}; mode.dmSize = sizeof(mode); - if (::EnumDisplaySettings(device_name, ENUM_CURRENT_SETTINGS, &mode)) { - switch (mode.dmDisplayOrientation) { - case DMDO_DEFAULT: - *rotation = Display::ROTATE_0; - break; - case DMDO_90: - *rotation = Display::ROTATE_90; - break; - case DMDO_180: - *rotation = Display::ROTATE_180; - break; - case DMDO_270: - *rotation = Display::ROTATE_270; - break; - default: - NOTREACHED(); - } - *frequency = mode.dmDisplayFrequency; + if (!::EnumDisplaySettings(device_name, ENUM_CURRENT_SETTINGS, &mode)) + return; + switch (mode.dmDisplayOrientation) { + case DMDO_DEFAULT: + *rotation = Display::ROTATE_0; + break; + case DMDO_90: + *rotation = Display::ROTATE_90; + break; + case DMDO_180: + *rotation = Display::ROTATE_180; + break; + case DMDO_270: + *rotation = Display::ROTATE_270; + break; + default: + NOTREACHED(); } + *frequency = mode.dmDisplayFrequency; } std::vector<DisplayInfo> FindAndRemoveTouchingDisplayInfos( - const DisplayInfo& ref_display_info, + const DisplayInfo& parent_info, std::vector<DisplayInfo>* display_infos) { std::vector<DisplayInfo> touching_display_infos; - base::EraseIf(*display_infos, [&touching_display_infos, ref_display_info]( - const DisplayInfo& display_info) { - if (DisplayInfosTouch(ref_display_info, display_info)) { + base::EraseIf(*display_infos, [&](const auto& display_info) { + if (DisplayInfosTouch(parent_info, display_info)) { touching_display_infos.push_back(display_info); return true; } @@ -199,87 +184,77 @@ Display CreateDisplayFromDisplayInfo(const DisplayInfo& display_info, ColorProfileReader* color_profile_reader, bool hdr_enabled) { - Display display(display_info.id()); - float scale_factor = display_info.device_scale_factor(); + const float scale_factor = display_info.device_scale_factor(); + const gfx::Rect bounds = gfx::ScaleToEnclosingRect(display_info.screen_rect(), + 1.0f / scale_factor); + Display display(display_info.id(), bounds); display.set_device_scale_factor(scale_factor); - display.set_work_area( - gfx::ScaleToEnclosingRect(display_info.screen_work_rect(), - 1.0f / scale_factor)); - display.set_bounds(gfx::ScaleToEnclosingRect(display_info.screen_rect(), - 1.0f / scale_factor)); + display.set_work_area(gfx::ScaleToEnclosingRect( + display_info.screen_work_rect(), 1.0f / scale_factor)); display.set_rotation(display_info.rotation()); display.set_display_frequency(display_info.display_frequency()); - // Compute the DisplayColorSpace for this configuration. Note that it is - // important to specify that there is no alpha channel when it is not needed, - // so that DXGI_ALPHA_MODE_IGNORE is specified. Not doing so regresses power - // usage substantially. - // https://crbug.com/1057163 + // Compute the DisplayColorSpace for this configuration. + // When alpha is not needed, specify BGRX_8888 to get DXGI_ALPHA_MODE_IGNORE. + // This saves significant power (see https://crbug.com/1057163). gfx::DisplayColorSpaces color_spaces = display.color_spaces(); if (Display::HasForceDisplayColorProfile()) { color_spaces.SetOutputBufferFormats(gfx::BufferFormat::BGRX_8888, gfx::BufferFormat::BGRA_8888); - } else { - if (hdr_enabled) { - // This will map to DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 with - // DXGI_FORMAT_B8G8R8A8_UNORM. - const auto srgb = gfx::ColorSpace::CreateSRGB(); + } else if (hdr_enabled) { + const float sdr_white_level = display_info.sdr_white_level(); + color_spaces.SetSDRWhiteLevel(sdr_white_level); - // This will map to DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709. In that - // space, the brightness of (1,1,1) is 80 nits. That's where the magic - // constant of 80 comes in. - const auto scrgb_linear = gfx::ColorSpace::CreateSCRGBLinear( - 80.f / display_info.sdr_white_level()); + // This will map to DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 with + // DXGI_FORMAT_B8G8R8A8_UNORM. + const auto srgb = gfx::ColorSpace::CreateSRGB(); - // This will map to DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, with - // sRGB's (1,1,1) mapping to the specified number of nits. - const auto hdr10 = - gfx::ColorSpace::CreateHDR10(display_info.sdr_white_level()); + // This will map to DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709. In that + // space, the brightness of (1,1,1) is 80 nits. + constexpr float kScrgbWhiteLevel = 80.0f; + const auto scrgb_linear = + gfx::ColorSpace::CreateSCRGBLinear(kScrgbWhiteLevel / sdr_white_level); - // For sRGB content, use 8-bit formats. - color_spaces.SetOutputColorSpaceAndBufferFormat( - gfx::ContentColorUsage::kSRGB, /*needs_alpha=*/false, srgb, - gfx::BufferFormat::BGRX_8888); - color_spaces.SetOutputColorSpaceAndBufferFormat( - gfx::ContentColorUsage::kSRGB, /*needs_alpha=*/true, srgb, - gfx::BufferFormat::BGRA_8888); + // This will map to DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, with + // sRGB's (1,1,1) mapping to the specified number of nits. + const auto hdr10 = gfx::ColorSpace::CreateHDR10(sdr_white_level); - // Use HDR color spaces only when there is WCG or HDR content on the - // screen. - const gfx::ContentColorUsage content_color_usages[] = { - gfx::ContentColorUsage::kWideColorGamut, - gfx::ContentColorUsage::kHDR, - }; - for (const auto& usage : content_color_usages) { - // Using RGBA F16 backbuffers required by SCRGB linear causes - // stuttering on Windows RS3, but RGB10A2 with HDR10 color space works - // fine (see https://crbug.com/937108#c92). - if (base::win::GetVersion() > base::win::Version::WIN10_RS3) { - color_spaces.SetOutputColorSpaceAndBufferFormat( - usage, /*needs_alpha=*/false, scrgb_linear, - gfx::BufferFormat::RGBA_F16); - } else { - color_spaces.SetOutputColorSpaceAndBufferFormat( - usage, /*needs_alpha=*/false, hdr10, - gfx::BufferFormat::BGRA_1010102); - } - // Use RGBA F16 backbuffers for HDR if alpha channel is required. + // For sRGB content, use 8-bit formats. + constexpr bool kNeedsAlpha = true; + color_spaces.SetOutputColorSpaceAndBufferFormat( + gfx::ContentColorUsage::kSRGB, !kNeedsAlpha, srgb, + gfx::BufferFormat::BGRX_8888); + color_spaces.SetOutputColorSpaceAndBufferFormat( + gfx::ContentColorUsage::kSRGB, kNeedsAlpha, srgb, + gfx::BufferFormat::BGRA_8888); + + // Use HDR color spaces only when there is WCG or HDR content on the + // screen. + for (const auto& usage : {gfx::ContentColorUsage::kWideColorGamut, + gfx::ContentColorUsage::kHDR}) { + // Using RGBA F16 backbuffers required by SCRGB linear causes + // stuttering on Windows RS3, but RGB10A2 with HDR10 color space works + // fine (see https://crbug.com/937108#c92). + if (base::win::GetVersion() > base::win::Version::WIN10_RS3) { color_spaces.SetOutputColorSpaceAndBufferFormat( - usage, /*needs_alpha=*/true, scrgb_linear, - gfx::BufferFormat::RGBA_F16); + usage, !kNeedsAlpha, scrgb_linear, gfx::BufferFormat::RGBA_F16); + } else { + color_spaces.SetOutputColorSpaceAndBufferFormat( + usage, !kNeedsAlpha, hdr10, gfx::BufferFormat::BGRA_1010102); } - color_spaces.SetSDRWhiteLevel(display_info.sdr_white_level()); - - // We set these to 10 bpp because these are (ab)used by pages via media - // query APIs to detect HDR support. - display.set_color_depth(Display::kHDR10BitsPerPixel); - display.set_depth_per_component(Display::kHDR10BitsPerComponent); - } else { - color_spaces = gfx::DisplayColorSpaces( - color_profile_reader->GetDisplayColorSpace(display_info.id())); - color_spaces.SetOutputBufferFormats(gfx::BufferFormat::BGRX_8888, - gfx::BufferFormat::BGRA_8888); + // Use RGBA F16 backbuffers for HDR if alpha channel is required. + color_spaces.SetOutputColorSpaceAndBufferFormat( + usage, kNeedsAlpha, scrgb_linear, gfx::BufferFormat::RGBA_F16); } + + // These are (ab)used by pages via media query APIs to detect HDR support. + display.set_color_depth(Display::kHDR10BitsPerPixel); + display.set_depth_per_component(Display::kHDR10BitsPerComponent); + } else { + color_spaces = gfx::DisplayColorSpaces( + color_profile_reader->GetDisplayColorSpace(display_info.id())); + color_spaces.SetOutputBufferFormats(gfx::BufferFormat::BGRX_8888, + gfx::BufferFormat::BGRA_8888); } display.set_color_spaces(color_spaces); @@ -292,12 +267,12 @@ // // To do this, DisplayInfosToScreenWinDisplays reasons over monitors as a tree // using the primary monitor as the root. All monitors touching this root are -// considered a children. +// considered children. // -// This also presumes that all monitors are connected components. Windows, by UI -// construction restricts the layout of monitors to connected components except -// when DPI virtualization is happening. When this happens, we scale relative -// to (0, 0). +// This also presumes that all monitors are connected components. By UI +// construction, Windows restricts the layout of monitors to connected +// components except when DPI virtualization is happening. When this happens, we +// scale relative to (0, 0). // // Note that this does not handle cases where a scaled display may have // insufficient room to lay out its children. In these cases, a DIP point could @@ -310,19 +285,17 @@ // Find and extract the primary display. std::vector<DisplayInfo> display_infos_remaining = display_infos; auto primary_display_iter = std::find_if( - display_infos_remaining.begin(), display_infos_remaining.end(), []( - const DisplayInfo& display_info) { + display_infos_remaining.begin(), display_infos_remaining.end(), + [](const DisplayInfo& display_info) { return display_info.screen_rect().origin().IsOrigin(); }); - DCHECK(primary_display_iter != display_infos_remaining.end()) << - "Missing primary display."; + DCHECK(primary_display_iter != display_infos_remaining.end()); - std::vector<DisplayInfo> available_parents; - available_parents.push_back(*primary_display_iter); - DisplayLayoutBuilder builder(primary_display_iter->id()); - display_infos_remaining.erase(primary_display_iter); // Build the tree and determine DisplayPlacements along the way. - while (available_parents.size()) { + DisplayLayoutBuilder builder(primary_display_iter->id()); + std::vector<DisplayInfo> available_parents = {*primary_display_iter}; + display_infos_remaining.erase(primary_display_iter); + while (!available_parents.empty()) { const DisplayInfo parent = available_parents.back(); available_parents.pop_back(); for (const auto& child : @@ -338,15 +311,11 @@ displays.push_back(CreateDisplayFromDisplayInfo( display_info, color_profile_reader, hdr_enabled)); } - - std::unique_ptr<DisplayLayout> layout(builder.Build()); - layout->ApplyToDisplayList(&displays, nullptr, 0); + builder.Build()->ApplyToDisplayList(&displays, nullptr, 0); std::vector<ScreenWinDisplay> screen_win_displays; - const size_t num_displays = display_infos.size(); - for (size_t i = 0; i < num_displays; ++i) + for (size_t i = 0; i < display_infos.size(); ++i) screen_win_displays.emplace_back(displays[i], display_infos[i]); - return screen_win_displays; } @@ -366,32 +335,27 @@ } gfx::Vector2dF GetPixelsPerInchForPointerDevice(HANDLE source_device) { - gfx::Vector2dF pixels_per_inch; static const auto get_pointer_device_rects = reinterpret_cast<decltype(&::GetPointerDeviceRects)>( base::win::GetUser32FunctionPointer("GetPointerDeviceRects")); - if (!get_pointer_device_rects) - return pixels_per_inch; - RECT screen = {}; RECT device = {}; - if (get_pointer_device_rects(source_device, &device, &screen)) { - constexpr float kHimetricPerInch = 2540.f; - float himetric_to_pixel_ratio_x = - float{device.right - device.left} / float{screen.right - screen.left}; - float himetric_to_pixel_ratio_y = - float{device.bottom - device.top} / float{screen.bottom - screen.top}; - pixels_per_inch.set_x(kHimetricPerInch / himetric_to_pixel_ratio_x); - pixels_per_inch.set_y(kHimetricPerInch / himetric_to_pixel_ratio_y); - return pixels_per_inch; - } + if (!get_pointer_device_rects || + !get_pointer_device_rects(source_device, &device, &screen)) + return gfx::Vector2dF(); - return pixels_per_inch; + constexpr float kHimetricPerInch = 2540.0f; + float himetric_per_pixel_x = + float{device.right - device.left} / float{screen.right - screen.left}; + float himetric_per_pixel_y = + float{device.bottom - device.top} / float{screen.bottom - screen.top}; + return gfx::Vector2dF(kHimetricPerInch / himetric_per_pixel_x, + kHimetricPerInch / himetric_per_pixel_y); } // Returns physical pixels per inch based on 96 dpi monitor. gfx::Vector2dF GetDefaultMonitorPhysicalPixelsPerInch() { - int default_dpi = GetDPIFromScalingFactor(1.0); + const int default_dpi = GetDPIFromScalingFactor(1.0f); return gfx::Vector2dF(default_dpi, default_dpi); } @@ -399,16 +363,13 @@ HDC hdc, LPRECT rect, LPARAM data) { - std::vector<DisplayInfo>* display_infos = - reinterpret_cast<std::vector<DisplayInfo>*>(data); - DCHECK(display_infos); - + const MONITORINFOEX monitor_info = MonitorInfoFromHMONITOR(monitor); Display::Rotation rotation; int display_frequency; - MONITORINFOEX monitor_info = MonitorInfoFromHMONITOR(monitor); GetDisplaySettingsForDevice(monitor_info.szDevice, &rotation, &display_frequency); - // Get the count of pointer devices. + + // Retrieve PPI for |monitor| based on touch pointer device handles. static const auto get_pointer_devices = reinterpret_cast<decltype(&::GetPointerDevices)>( base::win::GetUser32FunctionPointer("GetPointerDevices")); @@ -416,28 +377,25 @@ if (get_pointer_devices) get_pointer_devices(&pointer_device_count, nullptr); - // Map touch pointer device to |monitor| and retrieve pixels per inch - // for the |monitor| based on pointer device handle. gfx::Vector2dF pixels_per_inch = GetDefaultMonitorPhysicalPixelsPerInch(); if (pointer_device_count != 0) { - // Get all pointer devices. std::vector<POINTER_DEVICE_INFO> pointer_devices(pointer_device_count); if (get_pointer_devices(&pointer_device_count, &pointer_devices.front())) { - for (uint32_t i = 0; i < pointer_device_count; i++) { - if (pointer_devices[i].pointerDeviceType == POINTER_DEVICE_TYPE_TOUCH && - pointer_devices[i].monitor == monitor) { - pixels_per_inch = - GetPixelsPerInchForPointerDevice(pointer_devices[i].device); + for (const auto& device : pointer_devices) { + if (device.pointerDeviceType == POINTER_DEVICE_TYPE_TOUCH && + device.monitor == monitor) { + pixels_per_inch = GetPixelsPerInchForPointerDevice(device.device); break; } } } } - display_infos->push_back( - DisplayInfo(monitor_info, GetMonitorScaleFactor(monitor), - GetMonitorSDRWhiteLevel(monitor), rotation, display_frequency, - pixels_per_inch)); + auto* display_infos = reinterpret_cast<std::vector<DisplayInfo>*>(data); + DCHECK(display_infos); + display_infos->emplace_back(monitor_info, GetMonitorScaleFactor(monitor), + GetMonitorSDRWhiteLevel(monitor), rotation, + display_frequency, pixels_per_inch); return TRUE; } @@ -445,22 +403,20 @@ std::vector<DisplayInfo> display_infos; EnumDisplayMonitors(nullptr, nullptr, EnumMonitorForDisplayInfoCallback, reinterpret_cast<LPARAM>(&display_infos)); - DCHECK_EQ(static_cast<size_t>(::GetSystemMetrics(SM_CMONITORS)), - display_infos.size()); + DCHECK_EQ(::GetSystemMetrics(SM_CMONITORS), int{display_infos.size()}); return display_infos; } -// Returns a point in |to_origin|'s coordinates and position scaled by -// |scale_factor|. +// Returns |point|, transformed from |from_origin|'s to |to_origin|'s +// coordinates, which differ by |scale_factor|. gfx::PointF ScalePointRelative(const gfx::Point& from_origin, const gfx::Point& to_origin, const float scale_factor, const gfx::PointF& point) { - gfx::Vector2d from_origin_vector(from_origin.x(), from_origin.y()); - gfx::Vector2d to_origin_vector(to_origin.x(), to_origin.y()); - gfx::PointF scaled_relative_point( - gfx::ScalePoint(point - from_origin_vector, scale_factor)); - return scaled_relative_point + to_origin_vector; + const gfx::PointF relative_point = point - from_origin.OffsetFromOrigin(); + const gfx::PointF scaled_relative_point = + gfx::ScalePoint(relative_point, scale_factor); + return scaled_relative_point + to_origin.OffsetFromOrigin(); } } // namespace @@ -468,8 +424,8 @@ ScreenWin::ScreenWin() : ScreenWin(true) {} ScreenWin::~ScreenWin() { - DCHECK_EQ(g_screen_win_instance, this); - g_screen_win_instance = nullptr; + DCHECK_EQ(g_instance, this); + g_instance = nullptr; } // static @@ -485,9 +441,8 @@ // static gfx::Point ScreenWin::DIPToScreenPoint(const gfx::Point& dip_point) { - const ScreenWinDisplay screen_win_display = - GetScreenWinDisplayVia(&ScreenWin::GetScreenWinDisplayNearestDIPPoint, - dip_point); + const ScreenWinDisplay screen_win_display = GetScreenWinDisplayVia( + &ScreenWin::GetScreenWinDisplayNearestDIPPoint, dip_point); const Display display = screen_win_display.display(); return gfx::ToFlooredPoint(ScalePointRelative( display.bounds().origin(), screen_win_display.pixel_bounds().origin(), @@ -502,8 +457,7 @@ // static gfx::Point ScreenWin::DIPToClientPoint(HWND hwnd, const gfx::Point& dip_point) { - float scale_factor = GetScaleFactorForHWND(hwnd); - return ScaleToFlooredPoint(dip_point, scale_factor); + return ScaleToFlooredPoint(dip_point, GetScaleFactorForHWND(hwnd)); } // static @@ -512,12 +466,13 @@ ? GetScreenWinDisplayVia(&ScreenWin::GetScreenWinDisplayNearestHWND, hwnd) : GetScreenWinDisplayVia( &ScreenWin::GetScreenWinDisplayNearestScreenRect, pixel_bounds); - float scale_factor = screen_win_display.display().device_scale_factor(); - gfx::Rect dip_rect = ScaleToEnclosingRect(pixel_bounds, 1.0f / scale_factor); + const float scale_factor = + 1.0f / screen_win_display.display().device_scale_factor(); + gfx::Rect dip_rect = ScaleToEnclosingRect(pixel_bounds, scale_factor); const Display display = screen_win_display.display(); dip_rect.set_origin(gfx::ToFlooredPoint(ScalePointRelative( screen_win_display.pixel_bounds().origin(), display.bounds().origin(), - 1.0f / scale_factor, gfx::PointF(pixel_bounds.origin())))); + scale_factor, gfx::PointF(pixel_bounds.origin())))); return dip_rect; } @@ -555,66 +510,53 @@ // static gfx::Size ScreenWin::DIPToScreenSize(HWND hwnd, const gfx::Size& dip_size) { - float scale_factor = GetScaleFactorForHWND(hwnd); // Always ceil sizes. Otherwise we may be leaving off part of the bounds. - return ScaleToCeiledSize(dip_size, scale_factor); + return ScaleToCeiledSize(dip_size, GetScaleFactorForHWND(hwnd)); } // static int ScreenWin::GetSystemMetricsForMonitor(HMONITOR monitor, int metric) { - if (!g_screen_win_instance) + if (!g_instance) return ::GetSystemMetrics(metric); + // Fall back to the primary display's HMONITOR. + if (!monitor) + monitor = MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY); + // We don't include fudge factors stemming from accessiblility features when // dealing with system metrics associated with window elements drawn by the // operating system, since we will not be doing scaling of those metrics // ourselves. - bool include_accessibility; - switch (metric) { - case SM_CXSIZEFRAME: - case SM_CYSIZEFRAME: - case SM_CXPADDEDBORDER: - include_accessibility = false; - break; - default: - include_accessibility = true; - break; - } - - // We'll want to use GetSafeMonitorScaleFactor(), so if the monitor is not - // specified pull up the primary display's HMONITOR. - if (!monitor) - monitor = MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY); - - float scale_factor = GetMonitorScaleFactor(monitor, include_accessibility); + const bool include_accessibility = (metric != SM_CXSIZEFRAME) && + (metric != SM_CYSIZEFRAME) && + (metric != SM_CXPADDEDBORDER); // We'll then pull up the system metrics scaled by the appropriate amount. - return GetSystemMetricsForScaleFactor(scale_factor, metric); + return g_instance->GetSystemMetricsForScaleFactor( + GetMonitorScaleFactor(monitor, include_accessibility), metric); } // static int ScreenWin::GetSystemMetricsInDIP(int metric) { - if (!g_screen_win_instance) - return ::GetSystemMetrics(metric); - - return GetSystemMetricsForScaleFactor(1.0f, metric); + return g_instance ? g_instance->GetSystemMetricsForScaleFactor(1.0f, metric) + : ::GetSystemMetrics(metric); } // static float ScreenWin::GetScaleFactorForHWND(HWND hwnd) { - if (!g_screen_win_instance) + if (!g_instance) return ScreenWinDisplay().display().device_scale_factor(); DCHECK(hwnd); - HWND rootHwnd = g_screen_win_instance->GetRootWindow(hwnd); + HWND root_hwnd = g_instance->GetRootWindow(hwnd); ScreenWinDisplay screen_win_display = - g_screen_win_instance->GetScreenWinDisplayNearestHWND(rootHwnd); + g_instance->GetScreenWinDisplayNearestHWND(root_hwnd); return screen_win_display.display().device_scale_factor(); } // static gfx::Vector2dF ScreenWin::GetPixelsPerInch(const gfx::PointF& point) { - ScreenWinDisplay screen_win_display = + const ScreenWinDisplay screen_win_display = GetScreenWinDisplayVia(&ScreenWin::GetScreenWinDisplayNearestDIPPoint, gfx::ToFlooredPoint(point)); return screen_win_display.pixels_per_inch(); @@ -625,7 +567,7 @@ if (Display::HasForceDeviceScaleFactor()) return GetDPIFromScalingFactor(Display::GetForcedDeviceScaleFactor()); - HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + const HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); int dpi = GetPerMonitorDPI(monitor); return dpi ? dpi : display::win::internal::GetDefaultSystemDPI(); } @@ -644,22 +586,19 @@ // static void ScreenWin::SetRequestHDRStatusCallback( RequestHDRStatusCallback request_hdr_status_callback) { - if (!g_screen_win_instance) - return; - g_screen_win_instance->request_hdr_status_callback_ = - std::move(request_hdr_status_callback); - g_screen_win_instance->request_hdr_status_callback_.Run(); + if (g_instance) { + g_instance->request_hdr_status_callback_ = + std::move(request_hdr_status_callback); + g_instance->request_hdr_status_callback_.Run(); + } } // static void ScreenWin::SetHDREnabled(bool hdr_enabled) { - if (!g_screen_win_instance) - return; - - if (g_screen_win_instance->hdr_enabled_ == hdr_enabled) - return; - g_screen_win_instance->hdr_enabled_ = hdr_enabled; - g_screen_win_instance->UpdateAllDisplaysAndNotify(); + if (g_instance && (g_instance->hdr_enabled_ != hdr_enabled)) { + g_instance->hdr_enabled_ = hdr_enabled; + g_instance->UpdateAllDisplaysAndNotify(); + } } HWND ScreenWin::GetHWNDFromNativeView(gfx::NativeView window) const { @@ -673,8 +612,8 @@ } ScreenWin::ScreenWin(bool initialize) { - DCHECK(!g_screen_win_instance); - g_screen_win_instance = this; + DCHECK(!g_instance); + g_instance = this; if (initialize) Initialize(); } @@ -682,8 +621,7 @@ gfx::Point ScreenWin::GetCursorScreenPoint() { POINT pt; ::GetCursorPos(&pt); - gfx::PointF cursor_pos_pixels(pt.x, pt.y); - return gfx::ToFlooredPoint(ScreenToDIPPoint(cursor_pos_pixels)); + return gfx::ToFlooredPoint(ScreenToDIPPoint(gfx::PointF(gfx::Point(pt)))); } bool ScreenWin::IsWindowUnderCursor(gfx::NativeWindow window) { @@ -694,12 +632,12 @@ } gfx::NativeWindow ScreenWin::GetWindowAtScreenPoint(const gfx::Point& point) { - gfx::Point point_in_pixels = DIPToScreenPoint(point); - return GetNativeWindowFromHWND(WindowFromPoint(point_in_pixels.ToPOINT())); + const gfx::Point screen_point = DIPToScreenPoint(point); + return GetNativeWindowFromHWND(WindowFromPoint(screen_point.ToPOINT())); } int ScreenWin::GetNumDisplays() const { - return static_cast<int>(screen_win_displays_.size()); + return int{screen_win_displays_.size()}; } const std::vector<Display>& ScreenWin::GetAllDisplays() const { @@ -707,31 +645,20 @@ } Display ScreenWin::GetDisplayNearestWindow(gfx::NativeWindow window) const { - if (!window) - return GetPrimaryDisplay(); - HWND window_hwnd = GetHWNDFromNativeView(window); - if (!window_hwnd) { - // When |window| isn't rooted to a display, we should just return the - // default display so we get some correct display information like the - // scaling factor. - return GetPrimaryDisplay(); - } - ScreenWinDisplay screen_win_display = - GetScreenWinDisplayNearestHWND(window_hwnd); - return screen_win_display.display(); + const HWND window_hwnd = window ? GetHWNDFromNativeView(window) : nullptr; + // When |window| isn't rooted to a display, we should just return the default + // display so we get some correct display information like the scaling factor. + return window_hwnd ? GetScreenWinDisplayNearestHWND(window_hwnd).display() + : GetPrimaryDisplay(); } Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const { - gfx::Point screen_point(DIPToScreenPoint(point)); - ScreenWinDisplay screen_win_display = - GetScreenWinDisplayNearestScreenPoint(screen_point); - return screen_win_display.display(); + const gfx::Point screen_point = DIPToScreenPoint(point); + return GetScreenWinDisplayNearestScreenPoint(screen_point).display(); } Display ScreenWin::GetDisplayMatching(const gfx::Rect& match_rect) const { - ScreenWinDisplay screen_win_display = - GetScreenWinDisplayNearestScreenRect(match_rect); - return screen_win_display.display(); + return GetScreenWinDisplayNearestScreenRect(match_rect).display(); } Display ScreenWin::GetPrimaryDisplay() const { @@ -747,14 +674,15 @@ } gfx::Rect ScreenWin::ScreenToDIPRectInWindow( - gfx::NativeView view, const gfx::Rect& screen_rect) const { - HWND hwnd = view ? GetHWNDFromNativeView(view) : nullptr; + gfx::NativeView view, + const gfx::Rect& screen_rect) const { + const HWND hwnd = view ? GetHWNDFromNativeView(view) : nullptr; return ScreenToDIPRect(hwnd, screen_rect); } gfx::Rect ScreenWin::DIPToScreenRectInWindow(gfx::NativeView view, const gfx::Rect& dip_rect) const { - HWND hwnd = view ? GetHWNDFromNativeView(view) : nullptr; + const HWND hwnd = view ? GetHWNDFromNativeView(view) : nullptr; return DIPToScreenRect(hwnd, dip_rect); } @@ -767,8 +695,8 @@ void ScreenWin::Initialize() { color_profile_reader_->UpdateIfNeeded(); - singleton_hwnd_observer_.reset(new gfx::SingletonHwndObserver( - base::BindRepeating(&ScreenWin::OnWndProc, base::Unretained(this)))); + singleton_hwnd_observer_ = std::make_unique<gfx::SingletonHwndObserver>( + base::BindRepeating(&ScreenWin::OnWndProc, base::Unretained(this))); UpdateFromDisplayInfos(GetDisplayInfosFromSystem()); RecordDisplayScaleFactors(); @@ -780,16 +708,15 @@ MONITORINFOEX ScreenWin::MonitorInfoFromScreenPoint( const gfx::Point& screen_point) const { - POINT initial_loc = { screen_point.x(), screen_point.y() }; - return MonitorInfoFromHMONITOR(::MonitorFromPoint(initial_loc, - MONITOR_DEFAULTTONEAREST)); + return MonitorInfoFromHMONITOR( + ::MonitorFromPoint(screen_point.ToPOINT(), MONITOR_DEFAULTTONEAREST)); } MONITORINFOEX ScreenWin::MonitorInfoFromScreenRect(const gfx::Rect& screen_rect) const { - RECT win_rect = screen_rect.ToRECT(); - return MonitorInfoFromHMONITOR(::MonitorFromRect(&win_rect, - MONITOR_DEFAULTTONEAREST)); + const RECT win_rect = screen_rect.ToRECT(); + return MonitorInfoFromHMONITOR( + ::MonitorFromRect(&win_rect, MONITOR_DEFAULTTONEAREST)); } MONITORINFOEX ScreenWin::MonitorInfoFromWindow(HWND hwnd, @@ -810,10 +737,9 @@ WPARAM wparam, LPARAM lparam) { if (message != WM_DISPLAYCHANGE && - !(message == WM_ACTIVATEAPP && wparam == TRUE) && - !(message == WM_SETTINGCHANGE && wparam == SPI_SETWORKAREA)) { + (message != WM_ACTIVATEAPP || wparam != TRUE) && + (message != WM_SETTINGCHANGE || wparam != SPI_SETWORKAREA)) return; - } color_profile_reader_->UpdateIfNeeded(); if (request_hdr_status_callback_) @@ -845,8 +771,7 @@ change_notifier_.NotifyDisplaysChanged(old_displays, displays_); } -ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestHWND(HWND hwnd) - const { +ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestHWND(HWND hwnd) const { return GetScreenWinDisplay(MonitorInfoFromWindow(hwnd, MONITOR_DEFAULTTONEAREST)); } @@ -865,11 +790,10 @@ const gfx::Point& dip_point) const { ScreenWinDisplay primary_screen_win_display; for (const auto& screen_win_display : screen_win_displays_) { - Display display = screen_win_display.display(); - const gfx::Rect dip_bounds = display.bounds(); + const gfx::Rect dip_bounds = screen_win_display.display().bounds(); if (dip_bounds.Contains(dip_point)) return screen_win_display; - else if (dip_bounds.origin().IsOrigin()) + if (dip_bounds.origin().IsOrigin()) primary_screen_win_display = screen_win_display; } return primary_screen_win_display; @@ -878,16 +802,15 @@ ScreenWinDisplay ScreenWin::GetScreenWinDisplayNearestDIPRect( const gfx::Rect& dip_rect) const { ScreenWinDisplay closest_screen_win_display; - int64_t closest_distance_squared = INT64_MAX; + int64_t closest_distance = INT64_MAX; for (const auto& screen_win_display : screen_win_displays_) { Display display = screen_win_display.display(); gfx::Rect dip_bounds = display.bounds(); if (dip_rect.Intersects(dip_bounds)) return screen_win_display; - int64_t distance_squared = SquaredDistanceBetweenRects(dip_rect, - dip_bounds); - if (distance_squared < closest_distance_squared) { - closest_distance_squared = distance_squared; + int64_t distance = SquaredDistanceBetweenRects(dip_rect, dip_bounds); + if (distance < closest_distance) { + closest_distance = distance; closest_screen_win_display = screen_win_display; } } @@ -895,27 +818,24 @@ } ScreenWinDisplay ScreenWin::GetPrimaryScreenWinDisplay() const { - MONITORINFOEX monitor_info = MonitorInfoFromWindow(nullptr, - MONITOR_DEFAULTTOPRIMARY); - ScreenWinDisplay screen_win_display = GetScreenWinDisplay(monitor_info); - Display display = screen_win_display.display(); + const ScreenWinDisplay screen_win_display = GetScreenWinDisplay( + MonitorInfoFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY)); // The Windows primary monitor is defined to have an origin of (0, 0). - DCHECK_EQ(0, display.bounds().origin().x()); - DCHECK_EQ(0, display.bounds().origin().y()); + DCHECK(screen_win_display.display().bounds().origin().IsOrigin()); return screen_win_display; } ScreenWinDisplay ScreenWin::GetScreenWinDisplay( const MONITORINFOEX& monitor_info) const { - int64_t id = DisplayInfo::DeviceIdFromDeviceName(monitor_info.szDevice); + const int64_t id = DisplayInfo::DeviceIdFromDeviceName(monitor_info.szDevice); for (const auto& screen_win_display : screen_win_displays_) { if (screen_win_display.display().id() == id) return screen_win_display; } // There is 1:1 correspondence between MONITORINFOEX and ScreenWinDisplay. - // If we make it here, it means we have no displays and we should hand out the - // default display. [Sometimes we get here anyway: crbug.com/768845] - // DCHECK_EQ(screen_win_displays_.size(), 0u); + // If we found no screens, either there are no screens, or we're in the midst + // of updating our screens (see crbug.com/768845); either way, hand out the + // default display. return ScreenWinDisplay(); } @@ -923,32 +843,25 @@ template <typename Getter, typename GetterType> ScreenWinDisplay ScreenWin::GetScreenWinDisplayVia(Getter getter, GetterType value) { - if (!g_screen_win_instance) - return ScreenWinDisplay(); - - return (g_screen_win_instance->*getter)(value); + return g_instance ? (g_instance->*getter)(value) : ScreenWinDisplay(); } -// static -int ScreenWin::GetSystemMetricsForScaleFactor(float scale_factor, int metric) { +int ScreenWin::GetSystemMetricsForScaleFactor(float scale_factor, + int metric) const { if (base::win::IsProcessPerMonitorDpiAware()) { - using GetSystemMetricsForDpiPtr = decltype(::GetSystemMetricsForDpi)*; - static const auto get_metric_for_dpi_func = - reinterpret_cast<GetSystemMetricsForDpiPtr>( + static const auto get_system_metrics_for_dpi = + reinterpret_cast<decltype(&::GetSystemMetricsForDpi)>( base::win::GetUser32FunctionPointer("GetSystemMetricsForDpi")); - if (get_metric_for_dpi_func) { - return get_metric_for_dpi_func(metric, - GetDPIFromScalingFactor(scale_factor)); + if (get_system_metrics_for_dpi) { + return get_system_metrics_for_dpi(metric, + GetDPIFromScalingFactor(scale_factor)); } } - // Fallback for when we're running Windows 8.1, which doesn't support - // GetSystemMetricsForDpi and yet does support per-process dpi awareness. - Display primary_display(g_screen_win_instance->GetPrimaryDisplay()); - int system_metrics_result = g_screen_win_instance->GetSystemMetrics(metric); - - return static_cast<int>(std::round(scale_factor * system_metrics_result / - primary_display.device_scale_factor())); + // Windows 8.1 doesn't support GetSystemMetricsForDpi(), yet does support + // per-process dpi awareness. + return gfx::ToRoundedInt(GetSystemMetrics(metric) * scale_factor / + GetPrimaryDisplay().device_scale_factor()); } void ScreenWin::RecordDisplayScaleFactors() const { @@ -958,8 +871,8 @@ screen_win_display.display().device_scale_factor(); // Multiply the reported value by 100 to display it as a percentage. Clamp // it so that if it's wildly out-of-band we won't send it to the backend. - const int reported_scale = std::min( - std::max(base::checked_cast<int>(scale_factor * 100), 0), 1000); + const int reported_scale = base::ClampToRange( + base::checked_cast<int>(scale_factor * 100), 0, 1000); if (!base::Contains(unique_scale_factors, reported_scale)) { unique_scale_factors.push_back(reported_scale); base::UmaHistogramSparse("UI.DeviceScale", reported_scale);
diff --git a/ui/display/win/screen_win.h b/ui/display/win/screen_win.h index 3b48b6b..40c388c 100644 --- a/ui/display/win/screen_win.h +++ b/ui/display/win/screen_win.h
@@ -136,7 +136,7 @@ // Set a callback to use to query the status of HDR. This callback will be // called when the status of HDR may have changed. - using RequestHDRStatusCallback = base::RepeatingCallback<void()>; + using RequestHDRStatusCallback = base::RepeatingClosure; static void SetRequestHDRStatusCallback( RequestHDRStatusCallback request_hdr_status_callback); @@ -226,7 +226,7 @@ // Returns the result of GetSystemMetrics for |metric| scaled to the specified // |scale_factor|. - static int GetSystemMetricsForScaleFactor(float scale_factor, int metric); + int GetSystemMetricsForScaleFactor(float scale_factor, int metric) const; void RecordDisplayScaleFactors() const;
diff --git a/ui/display/win/screen_win_unittest.cc b/ui/display/win/screen_win_unittest.cc index b477e94..1b4f154 100644 --- a/ui/display/win/screen_win_unittest.cc +++ b/ui/display/win/screen_win_unittest.cc
@@ -44,13 +44,13 @@ protected: // win::ScreenWin: HWND GetHWNDFromNativeView(gfx::NativeView window) const override { - // NativeView is only used as an identifier in this tests, so interchange - // NativeView with an HWND for convenience. + // NativeView is only used as an identifier in these tests, so interchange + // a NativeView for an HWND for convenience. return reinterpret_cast<HWND>(window); } gfx::NativeWindow GetNativeWindowFromHWND(HWND hwnd) const override { - // NativeWindow is only used as an identifier in this tests, so interchange + // NativeWindow is only used as an identifier in these tests, so interchange // an HWND for a NativeWindow for convenience. return reinterpret_cast<gfx::NativeWindow>(hwnd); }
diff --git a/ui/native_theme/common_theme.cc b/ui/native_theme/common_theme.cc index 66f0e23..df5da29 100644 --- a/ui/native_theme/common_theme.cc +++ b/ui/native_theme/common_theme.cc
@@ -5,6 +5,7 @@ #include "ui/native_theme/common_theme.h" #include "base/logging.h" +#include "base/optional.h" #include "third_party/skia/include/core/SkCanvas.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" @@ -17,182 +18,176 @@ namespace ui { -SkColor GetAuraColor(NativeTheme::ColorId color_id, - const NativeTheme* base_theme, - NativeTheme::ColorScheme color_scheme) { - if (color_scheme == NativeTheme::ColorScheme::kDefault) - color_scheme = base_theme->GetDefaultSystemColorScheme(); +namespace { - // High contrast overrides the normal colors for certain ColorIds to be much - // darker or lighter. - if (base_theme->UsesHighContrastColors()) { - switch (color_id) { - case NativeTheme::kColorId_ButtonUncheckedColor: - case NativeTheme::kColorId_MenuBorderColor: - case NativeTheme::kColorId_MenuSeparatorColor: - case NativeTheme::kColorId_SeparatorColor: - case NativeTheme::kColorId_UnfocusedBorderColor: - case NativeTheme::kColorId_TabBottomBorder: - return color_scheme == NativeTheme::ColorScheme::kDark ? SK_ColorWHITE - : SK_ColorBLACK; - case NativeTheme::kColorId_ButtonEnabledColor: - case NativeTheme::kColorId_FocusedBorderColor: - case NativeTheme::kColorId_ProminentButtonColor: - return color_scheme == NativeTheme::ColorScheme::kDark - ? gfx::kGoogleBlue100 - : gfx::kGoogleBlue900; - default: - break; - } +base::Optional<SkColor> GetHighContrastColor( + NativeTheme::ColorId color_id, + NativeTheme::ColorScheme color_scheme) { + switch (color_id) { + case NativeTheme::kColorId_ButtonUncheckedColor: + case NativeTheme::kColorId_MenuBorderColor: + case NativeTheme::kColorId_MenuSeparatorColor: + case NativeTheme::kColorId_SeparatorColor: + case NativeTheme::kColorId_UnfocusedBorderColor: + case NativeTheme::kColorId_TabBottomBorder: + return color_scheme == NativeTheme::ColorScheme::kDark ? SK_ColorWHITE + : SK_ColorBLACK; + case NativeTheme::kColorId_ButtonEnabledColor: + case NativeTheme::kColorId_FocusedBorderColor: + case NativeTheme::kColorId_ProminentButtonColor: + return color_scheme == NativeTheme::ColorScheme::kDark + ? gfx::kGoogleBlue100 + : gfx::kGoogleBlue900; + default: + return base::nullopt; } +} - if (color_scheme == NativeTheme::ColorScheme::kDark) { - switch (color_id) { - // Dialogs - case NativeTheme::kColorId_WindowBackground: - case NativeTheme::kColorId_DialogBackground: - case NativeTheme::kColorId_BubbleBackground: - return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, - 0.04f); - case NativeTheme::kColorId_DialogForeground: - return gfx::kGoogleGrey500; - case NativeTheme::kColorId_BubbleFooterBackground: - return SkColorSetRGB(0x32, 0x36, 0x39); +base::Optional<SkColor> GetDarkSchemeColor(NativeTheme::ColorId color_id) { + switch (color_id) { + // Dialogs + case NativeTheme::kColorId_WindowBackground: + case NativeTheme::kColorId_DialogBackground: + case NativeTheme::kColorId_BubbleBackground: + return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, 0.04f); + case NativeTheme::kColorId_DialogForeground: + return gfx::kGoogleGrey500; + case NativeTheme::kColorId_BubbleFooterBackground: + return SkColorSetRGB(0x32, 0x36, 0x39); - // FocusableBorder - case NativeTheme::kColorId_FocusedBorderColor: - return SkColorSetA(gfx::kGoogleBlue300, 0x4D); - case NativeTheme::kColorId_UnfocusedBorderColor: - return gfx::kGoogleGrey800; + // FocusableBorder + case NativeTheme::kColorId_FocusedBorderColor: + return SkColorSetA(gfx::kGoogleBlue300, 0x4D); + case NativeTheme::kColorId_UnfocusedBorderColor: + return gfx::kGoogleGrey800; - // Button - case NativeTheme::kColorId_ButtonBorderColor: - return gfx::kGoogleGrey800; - case NativeTheme::kColorId_ButtonEnabledColor: - case NativeTheme::kColorId_ProminentButtonColor: - return gfx::kGoogleBlue300; - case NativeTheme::kColorId_ButtonHoverColor: - return SkColorSetA(SK_ColorBLACK, 0x0A); - case NativeTheme::kColorId_ButtonInkDropShadowColor: - return SkColorSetA(SK_ColorBLACK, 0x7F); - case NativeTheme::kColorId_ButtonInkDropFillColor: - case NativeTheme::kColorId_ProminentButtonInkDropFillColor: - return SkColorSetA(SK_ColorWHITE, 0x0A); - case NativeTheme::kColorId_ProminentButtonInkDropShadowColor: - return SkColorSetA(gfx::kGoogleBlue300, 0x7F); - case NativeTheme::kColorId_ProminentButtonHoverColor: - return SkColorSetA(SK_ColorWHITE, 0x0A); - case NativeTheme::kColorId_ButtonUncheckedColor: - return gfx::kGoogleGrey500; - case NativeTheme::kColorId_TextOnProminentButtonColor: - return gfx::kGoogleGrey900; + // Button + case NativeTheme::kColorId_ButtonBorderColor: + return gfx::kGoogleGrey800; + case NativeTheme::kColorId_ButtonEnabledColor: + case NativeTheme::kColorId_ProminentButtonColor: + return gfx::kGoogleBlue300; + case NativeTheme::kColorId_ButtonHoverColor: + return SkColorSetA(SK_ColorBLACK, 0x0A); + case NativeTheme::kColorId_ButtonInkDropShadowColor: + return SkColorSetA(SK_ColorBLACK, 0x7F); + case NativeTheme::kColorId_ButtonInkDropFillColor: + case NativeTheme::kColorId_ProminentButtonInkDropFillColor: + return SkColorSetA(SK_ColorWHITE, 0x0A); + case NativeTheme::kColorId_ProminentButtonInkDropShadowColor: + return SkColorSetA(gfx::kGoogleBlue300, 0x7F); + case NativeTheme::kColorId_ProminentButtonHoverColor: + return SkColorSetA(SK_ColorWHITE, 0x0A); + case NativeTheme::kColorId_ButtonUncheckedColor: + return gfx::kGoogleGrey500; + case NativeTheme::kColorId_TextOnProminentButtonColor: + return gfx::kGoogleGrey900; - // MenuItem - case NativeTheme::kColorId_HighlightedMenuItemForegroundColor: - case NativeTheme::kColorId_MenuDropIndicator: - return gfx::kGoogleGrey200; - case NativeTheme::kColorId_MenuBorderColor: - case NativeTheme::kColorId_MenuSeparatorColor: - return gfx::kGoogleGrey800; - case NativeTheme::kColorId_HighlightedMenuItemBackgroundColor: - return SkColorSetRGB(0x32, 0x36, 0x39); - case NativeTheme::kColorId_MenuItemAlertBackgroundColor: - return gfx::kGoogleBlue300; - case NativeTheme::kColorId_MenuItemMinorTextColor: - return gfx::kGoogleGrey500; + // MenuItem + case NativeTheme::kColorId_HighlightedMenuItemForegroundColor: + case NativeTheme::kColorId_MenuDropIndicator: + return gfx::kGoogleGrey200; + case NativeTheme::kColorId_MenuBorderColor: + case NativeTheme::kColorId_MenuSeparatorColor: + return gfx::kGoogleGrey800; + case NativeTheme::kColorId_HighlightedMenuItemBackgroundColor: + return SkColorSetRGB(0x32, 0x36, 0x39); + case NativeTheme::kColorId_MenuItemAlertBackgroundColor: + return gfx::kGoogleBlue300; + case NativeTheme::kColorId_MenuItemMinorTextColor: + return gfx::kGoogleGrey500; - // Dropdown - case NativeTheme::kColorId_DropdownBackgroundColor: - return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, - 0.04f); - case NativeTheme::kColorId_DropdownForegroundColor: - return gfx::kGoogleGrey200; - case NativeTheme::kColorId_DropdownSelectedForegroundColor: - return gfx::kGoogleGrey200; + // Dropdown + case NativeTheme::kColorId_DropdownBackgroundColor: + return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, 0.04f); + case NativeTheme::kColorId_DropdownForegroundColor: + return gfx::kGoogleGrey200; + case NativeTheme::kColorId_DropdownSelectedForegroundColor: + return gfx::kGoogleGrey200; - // Label - case NativeTheme::kColorId_LabelEnabledColor: - case NativeTheme::kColorId_LabelTextSelectionColor: - return gfx::kGoogleGrey200; - case NativeTheme::kColorId_LabelSecondaryColor: - return gfx::kGoogleGrey500; - case NativeTheme::kColorId_LabelTextSelectionBackgroundFocused: - return gfx::kGoogleBlue800; + // Label + case NativeTheme::kColorId_LabelEnabledColor: + case NativeTheme::kColorId_LabelTextSelectionColor: + return gfx::kGoogleGrey200; + case NativeTheme::kColorId_LabelSecondaryColor: + return gfx::kGoogleGrey500; + case NativeTheme::kColorId_LabelTextSelectionBackgroundFocused: + return gfx::kGoogleBlue800; - // Link - case NativeTheme::kColorId_LinkEnabled: - case NativeTheme::kColorId_LinkPressed: - return gfx::kGoogleBlue300; + // Link + case NativeTheme::kColorId_LinkEnabled: + case NativeTheme::kColorId_LinkPressed: + return gfx::kGoogleBlue300; - // Separator - case NativeTheme::kColorId_SeparatorColor: - return gfx::kGoogleGrey800; + // Separator + case NativeTheme::kColorId_SeparatorColor: + return gfx::kGoogleGrey800; - // TabbedPane - case NativeTheme::kColorId_TabTitleColorActive: - return gfx::kGoogleBlue300; - case NativeTheme::kColorId_TabTitleColorInactive: - return gfx::kGoogleGrey500; - case NativeTheme::kColorId_TabBottomBorder: - return gfx::kGoogleGrey800; - case NativeTheme::kColorId_TabHighlightBackground: - return gfx::kGoogleGrey800; - case NativeTheme::kColorId_TabHighlightFocusedBackground: - return SkColorSetRGB(0x32, 0x36, 0x39); + // TabbedPane + case NativeTheme::kColorId_TabTitleColorActive: + return gfx::kGoogleBlue300; + case NativeTheme::kColorId_TabTitleColorInactive: + return gfx::kGoogleGrey500; + case NativeTheme::kColorId_TabBottomBorder: + return gfx::kGoogleGrey800; + case NativeTheme::kColorId_TabHighlightBackground: + return gfx::kGoogleGrey800; + case NativeTheme::kColorId_TabHighlightFocusedBackground: + return SkColorSetRGB(0x32, 0x36, 0x39); - // Table - case NativeTheme::kColorId_TableBackground: - case NativeTheme::kColorId_TableBackgroundAlternate: - return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, - 0.04f); - case NativeTheme::kColorId_TableText: - case NativeTheme::kColorId_TableSelectedText: - case NativeTheme::kColorId_TableSelectedTextUnfocused: - return gfx::kGoogleGrey200; + // Table + case NativeTheme::kColorId_TableBackground: + case NativeTheme::kColorId_TableBackgroundAlternate: + return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, 0.04f); + case NativeTheme::kColorId_TableText: + case NativeTheme::kColorId_TableSelectedText: + case NativeTheme::kColorId_TableSelectedTextUnfocused: + return gfx::kGoogleGrey200; - // Textfield - case NativeTheme::kColorId_TextfieldDefaultColor: - case NativeTheme::kColorId_TextfieldSelectionColor: - return gfx::kGoogleGrey200; - case NativeTheme::kColorId_TextfieldReadOnlyBackground: { - return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, - 0.04f); - } - case NativeTheme::kColorId_TextfieldSelectionBackgroundFocused: - return gfx::kGoogleBlue800; - - // Tooltip - case NativeTheme::kColorId_TooltipText: - return SkColorSetA(gfx::kGoogleGrey200, 0xDE); - - // Tree - case NativeTheme::kColorId_TreeBackground: - return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, - 0.04f); - case NativeTheme::kColorId_TreeText: - case NativeTheme::kColorId_TreeSelectedText: - case NativeTheme::kColorId_TreeSelectedTextUnfocused: - return gfx::kGoogleGrey200; - - // Material spinner/throbber - case NativeTheme::kColorId_ThrobberSpinningColor: - return gfx::kGoogleBlue300; - - // Alert icon colors - case NativeTheme::kColorId_AlertSeverityLow: - return gfx::kGoogleGreen300; - case NativeTheme::kColorId_AlertSeverityMedium: - return gfx::kGoogleYellow300; - case NativeTheme::kColorId_AlertSeverityHigh: - return gfx::kGoogleRed300; - - case NativeTheme::kColorId_DefaultIconColor: - return gfx::kGoogleGrey500; - default: - break; + // Textfield + case NativeTheme::kColorId_TextfieldDefaultColor: + case NativeTheme::kColorId_TextfieldSelectionColor: + return gfx::kGoogleGrey200; + case NativeTheme::kColorId_TextfieldReadOnlyBackground: { + return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, 0.04f); } - } + case NativeTheme::kColorId_TextfieldSelectionBackgroundFocused: + return gfx::kGoogleBlue800; + // Tooltip + case NativeTheme::kColorId_TooltipText: + return SkColorSetA(gfx::kGoogleGrey200, 0xDE); + + // Tree + case NativeTheme::kColorId_TreeBackground: + return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, 0.04f); + case NativeTheme::kColorId_TreeText: + case NativeTheme::kColorId_TreeSelectedText: + case NativeTheme::kColorId_TreeSelectedTextUnfocused: + return gfx::kGoogleGrey200; + + // Material spinner/throbber + case NativeTheme::kColorId_ThrobberSpinningColor: + return gfx::kGoogleBlue300; + + // Alert icon colors + case NativeTheme::kColorId_AlertSeverityLow: + return gfx::kGoogleGreen300; + case NativeTheme::kColorId_AlertSeverityMedium: + return gfx::kGoogleYellow300; + case NativeTheme::kColorId_AlertSeverityHigh: + return gfx::kGoogleRed300; + + case NativeTheme::kColorId_DefaultIconColor: + return gfx::kGoogleGrey500; + default: + return base::nullopt; + } +} + +SkColor GetDefaultColor(NativeTheme::ColorId color_id, + const NativeTheme* base_theme, + NativeTheme::ColorScheme color_scheme) { constexpr SkColor kPrimaryTextColor = gfx::kGoogleGrey900; @@ -495,11 +490,38 @@ NativeTheme::kColorId_BubbleFooterBackground); case NativeTheme::kColorId_NumColors: - break; + // Keeping the kColorId_NumColors case instead of using the default case + // allows ColorId additions to trigger compile error for an incomplete + // switch enumeration. + NOTREACHED(); + return gfx::kPlaceholderColor; + } +} + +} // namespace + +SkColor GetAuraColor(NativeTheme::ColorId color_id, + const NativeTheme* base_theme, + NativeTheme::ColorScheme color_scheme) { + if (color_scheme == NativeTheme::ColorScheme::kDefault) + color_scheme = base_theme->GetDefaultSystemColorScheme(); + + // High contrast overrides the normal colors for certain ColorIds to be much + // darker or lighter. + if (base_theme->UsesHighContrastColors()) { + base::Optional<SkColor> color = + GetHighContrastColor(color_id, color_scheme); + if (color.has_value()) + return color.value(); } - NOTREACHED(); - return gfx::kPlaceholderColor; + if (color_scheme == NativeTheme::ColorScheme::kDark) { + base::Optional<SkColor> color = GetDarkSchemeColor(color_id); + if (color.has_value()) + return color.value(); + } + + return GetDefaultColor(color_id, base_theme, color_scheme); } void CommonThemePaintMenuItemBackground(
diff --git a/ui/ozone/platform/drm/gpu/crtc_controller.cc b/ui/ozone/platform/drm/gpu/crtc_controller.cc index b483f77..a1bfaede 100644 --- a/ui/ozone/platform/drm/gpu/crtc_controller.cc +++ b/ui/ozone/platform/drm/gpu/crtc_controller.cc
@@ -80,8 +80,11 @@ } bool CrtcController::AssignOverlayPlanes(HardwareDisplayPlaneList* plane_list, - const DrmOverlayPlaneList& overlays) { - DCHECK(!is_disabled_); + const DrmOverlayPlaneList& overlays, + bool is_modesetting) { + // If we're in the process of modesetting, the CRTC is still disabled. + // Once the modeset is done, we expect it to be enabled. + DCHECK(is_modesetting || !is_disabled_); const DrmOverlayPlane* primary = DrmOverlayPlane::GetPrimaryPlane(overlays); if (primary && !drm_->plane_manager()->ValidatePrimarySize(*primary, mode_)) {
diff --git a/ui/ozone/platform/drm/gpu/crtc_controller.h b/ui/ozone/platform/drm/gpu/crtc_controller.h index 9742c4cb..bfc2bad 100644 --- a/ui/ozone/platform/drm/gpu/crtc_controller.h +++ b/ui/ozone/platform/drm/gpu/crtc_controller.h
@@ -51,7 +51,8 @@ bool Disable(); bool AssignOverlayPlanes(HardwareDisplayPlaneList* plane_list, - const DrmOverlayPlaneList& planes); + const DrmOverlayPlaneList& planes, + bool is_modesetting); // Returns a vector of format modifiers for the given fourcc format // on this CRTCs primary plane. A format modifier describes the
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller.cc index 7cc196a..6f24033 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_controller.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
@@ -90,10 +90,20 @@ const drmModeModeInfo& mode) { DCHECK(primary.buffer.get()); bool status = true; - for (const auto& controller : crtc_controllers_) + + GetDrmDevice()->plane_manager()->BeginFrame(&owned_hardware_planes_); + DrmOverlayPlaneList plane_list; + plane_list.push_back(primary.Clone()); + + for (const auto& controller : crtc_controllers_) { + status &= + controller->AssignOverlayPlanes(&owned_hardware_planes_, plane_list, + /*is_modesetting=*/true); + status &= controller->Modeset( primary, use_current_crtc_mode ? controller->mode() : mode, owned_hardware_planes_); + } is_disabled_ = false; ResetCursor(); @@ -176,12 +186,13 @@ bool status = true; for (const auto& controller : crtc_controllers_) { - status &= controller->AssignOverlayPlanes(&owned_hardware_planes_, - pending_planes); + status &= controller->AssignOverlayPlanes( + &owned_hardware_planes_, pending_planes, /*is_modesetting=*/false); } status &= GetDrmDevice()->plane_manager()->Commit( - &owned_hardware_planes_, page_flip_request, out_fence); + &owned_hardware_planes_, /*should_modeset=*/false, page_flip_request, + out_fence); return status; } @@ -357,6 +368,7 @@ // pending planes to the same values so that the callback keeps the correct // state. page_flip_request_ = nullptr; + owned_hardware_planes_.legacy_page_flips.clear(); current_planes_.clear(); current_planes_.push_back(primary.Clone()); time_of_last_flip_ = base::TimeTicks::Now();
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc index f451285..bdb7f9e 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
@@ -30,11 +30,18 @@ const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; -constexpr uint32_t kCrtcIdBase = 1; +constexpr uint32_t kCrtcIdBase = 100; constexpr uint32_t kPrimaryCrtc = kCrtcIdBase; constexpr uint32_t kSecondaryCrtc = kCrtcIdBase + 1; -constexpr uint32_t kConnectorIdBase = 10; -constexpr uint32_t kPlaneOffset = 1000; +constexpr uint32_t kConnectorIdBase = 200; +constexpr uint32_t kPlaneOffset = 300; +constexpr uint32_t kInFormatsBlobPropId = 400; + +constexpr uint32_t kActivePropId = 1000; +constexpr uint32_t kModePropId = 1001; +constexpr uint32_t kCrtcIdPropId = 2000; +constexpr uint32_t kTypePropId = 3010; +constexpr uint32_t kInFormatsPropId = 3011; const gfx::Size kDefaultModeSize(kDefaultMode.hdisplay, kDefaultMode.vdisplay); const gfx::Size kOverlaySize(kDefaultMode.hdisplay / 2, @@ -104,10 +111,6 @@ } void HardwareDisplayControllerTest::InitializeDrmDevice(bool use_atomic) { - constexpr uint32_t kTypePropId = 3010; - constexpr uint32_t kInFormatsPropId = 3011; - constexpr uint32_t kInFormatsBlobPropId = 400; - std::vector<ui::MockDrmDevice::CrtcProperties> crtc_properties(2); std::map<uint32_t, std::string> crtc_property_names = { {1000, "ACTIVE"}, @@ -116,7 +119,7 @@ std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(2); std::map<uint32_t, std::string> connector_property_names = { - {2000, "CRTC_ID"}, + {kCrtcIdPropId, "CRTC_ID"}, }; for (size_t i = 0; i < connector_properties.size(); ++i) { connector_properties[i].id = kConnectorIdBase + i; @@ -280,6 +283,39 @@ internal_modifiers.end()); } +TEST_F(HardwareDisplayControllerTest, CheckModesettingSetsProps) { + ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr); + + EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + + ui::DrmOverlayPlane plane2(CreateBuffer(), nullptr); + std::vector<ui::DrmOverlayPlane> planes = {}; + planes.push_back(plane2.Clone()); + + SchedulePageFlip(std::move(planes)); + + // Test props values after modesetting. + ui::DrmDevice::Property connector_prop_crtc_id = {}; + ui::ScopedDrmObjectPropertyPtr connector_props = + drm_->GetObjectProperties(kConnectorIdBase, DRM_MODE_OBJECT_CONNECTOR); + ui::GetDrmPropertyForName(drm_.get(), connector_props.get(), "CRTC_ID", + &connector_prop_crtc_id); + EXPECT_EQ(kCrtcIdPropId, connector_prop_crtc_id.id); + EXPECT_EQ(kCrtcIdBase, connector_prop_crtc_id.value); + + ui::DrmDevice::Property crtc_prop_for_name = {}; + ui::ScopedDrmObjectPropertyPtr crtc_props = + drm_->GetObjectProperties(kPrimaryCrtc, DRM_MODE_OBJECT_CRTC); + GetDrmPropertyForName(drm_.get(), crtc_props.get(), "ACTIVE", + &crtc_prop_for_name); + EXPECT_EQ(kActivePropId, crtc_prop_for_name.id); + EXPECT_EQ(1U, crtc_prop_for_name.value); + + GetDrmPropertyForName(drm_.get(), crtc_props.get(), "MODE_ID", + &crtc_prop_for_name); + EXPECT_EQ(kModePropId, crtc_prop_for_name.id); +} + TEST_F(HardwareDisplayControllerTest, CheckDisableResetsProps) { ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr); @@ -318,6 +354,7 @@ ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + EXPECT_EQ(1, drm_->get_commit_count()); ui::DrmOverlayPlane plane2(CreateBuffer(), nullptr); std::vector<ui::DrmOverlayPlane> planes; @@ -331,13 +368,14 @@ EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_); EXPECT_EQ(1, page_flips_); - EXPECT_EQ(1, drm_->get_commit_count()); + EXPECT_EQ(2, drm_->get_commit_count()); // Verify only the primary display have a valid framebuffer. EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID")); EXPECT_EQ(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID")); } TEST_F(HardwareDisplayControllerTest, CheckStateIfModesetFails) { + InitializeDrmDevice(/* use_atomic */ false); drm_->set_set_crtc_expectation(false); ui::DrmOverlayPlane plane(CreateBuffer(), nullptr); @@ -345,20 +383,6 @@ EXPECT_FALSE(controller_->Modeset(plane, kDefaultMode)); } -TEST_F(HardwareDisplayControllerTest, CheckStateIfPageFlipFails) { - drm_->set_commit_expectation(false); - - ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr); - - EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); - - ui::DrmOverlayPlane plane2(CreateBuffer(), nullptr); - std::vector<ui::DrmOverlayPlane> planes; - planes.push_back(plane2.Clone()); - EXPECT_DEATH_IF_SUPPORTED(SchedulePageFlip(std::move(planes)), - "SchedulePageFlip failed"); -} - TEST_F(HardwareDisplayControllerTest, CheckOverlayPresent) { ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr); ui::DrmOverlayPlane plane2( @@ -366,6 +390,7 @@ gfx::Rect(kOverlaySize), gfx::RectF(kDefaultModeSizeF), true, nullptr); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + EXPECT_EQ(1, drm_->get_commit_count()); std::vector<ui::DrmOverlayPlane> planes; planes.push_back(plane1.Clone()); @@ -375,7 +400,7 @@ drm_->RunCallbacks(); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_); EXPECT_EQ(1, page_flips_); - EXPECT_EQ(1, drm_->get_commit_count()); + EXPECT_EQ(2, drm_->get_commit_count()); // Verify both planes on the primary display have a valid framebuffer. EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID")); EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID")); @@ -388,13 +413,14 @@ gfx::Rect(kOverlaySize), gfx::RectF(kDefaultModeSizeF), true, nullptr); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + EXPECT_EQ(1, drm_->get_commit_count()); std::vector<ui::DrmOverlayPlane> planes; planes.push_back(plane1.Clone()); planes.push_back(plane2.Clone()); SchedulePageFlip(ui::DrmOverlayPlane::Clone(planes)); - EXPECT_EQ(1, drm_->get_commit_count()); + EXPECT_EQ(2, drm_->get_commit_count()); // Verify both planes on the primary display have a valid framebuffer. EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID")); EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID")); @@ -404,14 +430,14 @@ drm_->RunCallbacks(); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_); EXPECT_EQ(1, page_flips_); - EXPECT_EQ(2, drm_->get_commit_count()); + EXPECT_EQ(3, drm_->get_commit_count()); // Regular flips should continue on normally. SchedulePageFlip(ui::DrmOverlayPlane::Clone(planes)); drm_->RunCallbacks(); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_); EXPECT_EQ(2, page_flips_); - EXPECT_EQ(3, drm_->get_commit_count()); + EXPECT_EQ(4, drm_->get_commit_count()); // Verify both planes on the primary display have a valid framebuffer. EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID")); EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID")); @@ -442,7 +468,7 @@ ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); - EXPECT_EQ(2, drm_->get_set_crtc_call_count()); + EXPECT_EQ(2, drm_->get_commit_count()); ui::DrmOverlayPlane plane2(CreateBuffer(), nullptr); std::vector<ui::DrmOverlayPlane> planes; @@ -451,7 +477,7 @@ drm_->RunCallbacks(); EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_); EXPECT_EQ(1, page_flips_); - EXPECT_EQ(1, drm_->get_commit_count()); + EXPECT_EQ(3, drm_->get_commit_count()); // Verify only the displays have a valid framebuffer on the primary plane. // First display: EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID")); @@ -598,10 +624,10 @@ } TEST_F(HardwareDisplayControllerTest, FailPageFlipping) { - drm_->set_commit_expectation(false); - ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); + + drm_->set_commit_expectation(false); std::vector<ui::DrmOverlayPlane> planes; planes.push_back(plane1.Clone()); EXPECT_DEATH_IF_SUPPORTED(SchedulePageFlip(std::move(planes)),
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h index b1070a0d..b24007d6 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -97,7 +97,7 @@ uint32_t crtc_id); // Commit the plane states in |plane_list|. - // + // if |should_modeset| is set, it only modesets without page flipping. // If |page_flip_request| is null, this tests the plane configuration without // submitting it. // The fence returned in |out_fence| will signal when the currently scanned @@ -105,6 +105,7 @@ // |page_flip_request|. Note that the returned fence may be a nullptr // if the system doesn't support out fences. virtual bool Commit(HardwareDisplayPlaneList* plane_list, + bool should_modeset, scoped_refptr<PageFlipRequest> page_flip_request, std::unique_ptr<gfx::GpuFence>* out_fence) = 0;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc index 4ec9db7..5f4a4101 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
@@ -65,9 +65,32 @@ uint32_t framebuffer_id, uint32_t connector_id, const drmModeModeInfo& mode, - const HardwareDisplayPlaneList&) { - return drm_->SetCrtc(crtc_id, framebuffer_id, - std::vector<uint32_t>(1, connector_id), mode); + const HardwareDisplayPlaneList& plane_list) { + const int connector_idx = LookupConnectorIndex(connector_id); + DCHECK_GE(connector_idx, 0); + connectors_props_[connector_idx].crtc_id.value = crtc_id; + bool res = + AddPropertyIfValid(plane_list.atomic_property_set.get(), connector_id, + connectors_props_[connector_idx].crtc_id); + + const int crtc_idx = LookupCrtcIndex(crtc_id); + DCHECK_GE(crtc_idx, 0); + crtc_state_[crtc_idx].properties.active.value = 1UL; + ScopedDrmPropertyBlob mode_blob = + drm_->CreatePropertyBlob(&mode, sizeof(mode)); + crtc_state_[crtc_idx].properties.mode_id.value = + mode_blob ? mode_blob->id() : 0; + + res &= AddPropertyIfValid(plane_list.atomic_property_set.get(), crtc_id, + crtc_state_[crtc_idx].properties.active); + res &= AddPropertyIfValid(plane_list.atomic_property_set.get(), crtc_id, + crtc_state_[crtc_idx].properties.mode_id); + + DCHECK(res); + return Commit(const_cast<HardwareDisplayPlaneList*>(&plane_list), + /*should_modeset=*/true, + /*page_flip_request=*/nullptr, + /*out_fence=*/nullptr); } bool HardwareDisplayPlaneManagerAtomic::DisableModeset(uint32_t crtc_id, @@ -96,12 +119,19 @@ bool HardwareDisplayPlaneManagerAtomic::Commit( HardwareDisplayPlaneList* plane_list, + bool should_modeset, scoped_refptr<PageFlipRequest> page_flip_request, std::unique_ptr<gfx::GpuFence>* out_fence) { - bool test_only = !page_flip_request; + bool test_only = !should_modeset && !page_flip_request; + for (HardwareDisplayPlane* plane : plane_list->old_plane_list) { if (!base::Contains(plane_list->plane_list, plane)) { - // This plane is being released, so we need to zero it. + // |plane| is shared state between |old_plane_list| and |plane_list|. + // When we call BeginFrame(), we reset in_use since we need to be able to + // allocate the planes as needed. The current frame might not need to use + // |plane|, thus |plane->in_use()| would be false even though the previous + // frame used it. It's existence in |old_plane_list| is sufficient to + // signal that |plane| was in use previously. plane->set_in_use(false); HardwareDisplayPlaneAtomic* atomic_plane = static_cast<HardwareDisplayPlaneAtomic*>(plane); @@ -146,11 +176,10 @@ } uint32_t flags = 0; - if (test_only) { - flags = DRM_MODE_ATOMIC_TEST_ONLY; - } else { - flags = DRM_MODE_ATOMIC_NONBLOCK; - } + if (should_modeset) + flags = DRM_MODE_ATOMIC_ALLOW_MODESET; + else + flags = test_only ? DRM_MODE_ATOMIC_TEST_ONLY : DRM_MODE_ATOMIC_NONBLOCK; // After we perform the atomic commit, and if the caller has requested an // out-fence, the out_fence_fds vector will contain any provided out-fence
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h index 7567a9b..2aa11b73 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h
@@ -26,6 +26,7 @@ const HardwareDisplayPlaneList& plane_list) override; bool DisableModeset(uint32_t crtc_id, uint32_t connector) override; bool Commit(HardwareDisplayPlaneList* plane_list, + bool should_modeset, scoped_refptr<PageFlipRequest> page_flip_request, std::unique_ptr<gfx::GpuFence>* out_fence) override; bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc index 4bbd895..a09037c 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
@@ -63,8 +63,11 @@ bool HardwareDisplayPlaneManagerLegacy::Commit( HardwareDisplayPlaneList* plane_list, + bool should_modeset, scoped_refptr<PageFlipRequest> page_flip_request, std::unique_ptr<gfx::GpuFence>* out_fence) { + DCHECK(!should_modeset); + bool test_only = !page_flip_request; if (test_only) { for (HardwareDisplayPlane* plane : plane_list->plane_list) {
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h index 237689dd..668ffde7 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h
@@ -26,6 +26,7 @@ const HardwareDisplayPlaneList& plane_list) override; bool DisableModeset(uint32_t crtc_id, uint32_t connector) override; bool Commit(HardwareDisplayPlaneList* plane_list, + bool should_modeset, scoped_refptr<PageFlipRequest> page_flip_request, std::unique_ptr<gfx::GpuFence>* out_fence) override; bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc index a9c908f7..bcfa824 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -37,6 +37,7 @@ constexpr uint32_t kConnectorIdBase = 700; constexpr uint32_t kActivePropId = 1000; +constexpr uint32_t kModePropId = 1001; constexpr uint32_t kBackgroundColorPropId = 1002; constexpr uint32_t kCtmPropId = 1003; constexpr uint32_t kGammaLutPropId = 1004; @@ -121,7 +122,7 @@ size_t planes_per_crtc) { std::map<uint32_t, std::string> crtc_property_names = { {kActivePropId, "ACTIVE"}, - {1001, "MODE_ID"}, + {kModePropId, "MODE_ID"}, }; std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(1); @@ -226,8 +227,8 @@ state, assigns, crtc_properties_[crtc_idx].id)); scoped_refptr<ui::PageFlipRequest> page_flip_request = base::MakeRefCounted<ui::PageFlipRequest>(base::TimeDelta()); - ASSERT_TRUE( - fake_drm_->plane_manager()->Commit(state, page_flip_request, nullptr)); + ASSERT_TRUE(fake_drm_->plane_manager()->Commit( + state, /*should_modeset*/ false, page_flip_request, nullptr)); } uint64_t HardwareDisplayPlaneManagerTest::GetObjectPropertyValue( @@ -296,8 +297,6 @@ EXPECT_TRUE(fake_drm_->plane_manager()->Modeset( crtc_properties_[1].id, kFrameBuffer, kConnectorIdBase + 1, kDefaultMode, state)); - // TODO(markyacoub): Add a test that fails for kConnectorIdBase +2 when atomic - // modeset is enabled. EXPECT_TRUE(fake_drm_->plane_manager()->Modeset( crtc_properties_[2].id, kFrameBuffer, kConnectorIdBase + 3, kDefaultMode, state)); @@ -455,7 +454,7 @@ crtc_properties_[0].id, kFrameBuffer, connector_properties_[0].id, kDefaultMode, state)); - EXPECT_EQ(0, fake_drm_->get_commit_count()); + EXPECT_EQ(1, fake_drm_->get_commit_count()); } TEST_P(HardwareDisplayPlaneManagerAtomicTest, DisableModeset) { @@ -469,6 +468,40 @@ EXPECT_EQ(1, fake_drm_->get_commit_count()); } +TEST_P(HardwareDisplayPlaneManagerAtomicTest, CheckPropsAfterModeset) { + InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1); + fake_drm_->InitializeState(crtc_properties_, connector_properties_, + plane_properties_, property_names_, + /*use_atomic=*/true); + + constexpr uint32_t kFrameBuffer = 2; + ui::HardwareDisplayPlaneList state; + EXPECT_TRUE(fake_drm_->plane_manager()->Modeset( + crtc_properties_[0].id, kFrameBuffer, connector_properties_[0].id, + kDefaultMode, state)); + + // Test props values after modesetting. + ui::DrmDevice::Property connector_prop_crtc_id; + ui::ScopedDrmObjectPropertyPtr connector_props = + fake_drm_->GetObjectProperties(kConnectorIdBase, + DRM_MODE_OBJECT_CONNECTOR); + ui::GetDrmPropertyForName(fake_drm_.get(), connector_props.get(), "CRTC_ID", + &connector_prop_crtc_id); + EXPECT_EQ(kCrtcIdPropId, connector_prop_crtc_id.id); + + ui::DrmDevice::Property crtc_prop_for_name; + ui::ScopedDrmObjectPropertyPtr crtc_props = + fake_drm_->GetObjectProperties(kCrtcIdBase, DRM_MODE_OBJECT_CRTC); + ui::GetDrmPropertyForName(fake_drm_.get(), crtc_props.get(), "ACTIVE", + &crtc_prop_for_name); + EXPECT_EQ(kActivePropId, crtc_prop_for_name.id); + EXPECT_EQ(1U, crtc_prop_for_name.value); + + ui::GetDrmPropertyForName(fake_drm_.get(), crtc_props.get(), "MODE_ID", + &crtc_prop_for_name); + EXPECT_EQ(kModePropId, crtc_prop_for_name.id); +} + TEST_P(HardwareDisplayPlaneManagerAtomicTest, CheckPropsAfterDisable) { InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1); fake_drm_->InitializeState(crtc_properties_, connector_properties_, @@ -570,8 +603,8 @@ fake_drm_->plane_manager()->BeginFrame(&hdpl); EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes( &hdpl, assigns, crtc_properties_[0].id)); - EXPECT_TRUE( - fake_drm_->plane_manager()->Commit(&hdpl, page_flip_request, nullptr)); + EXPECT_TRUE(fake_drm_->plane_manager()->Commit( + &hdpl, /*should_modeset*/ false, page_flip_request, nullptr)); assigns.clear(); assigns.push_back(ui::DrmOverlayPlane(primary_buffer, nullptr)); fake_drm_->plane_manager()->BeginFrame(&hdpl); @@ -580,8 +613,8 @@ EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID")); EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID")); - EXPECT_TRUE( - fake_drm_->plane_manager()->Commit(&hdpl, page_flip_request, nullptr)); + EXPECT_TRUE(fake_drm_->plane_manager()->Commit( + &hdpl, /*should_modeset*/ false, page_flip_request, nullptr)); EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID")); EXPECT_EQ(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID")); } @@ -914,8 +947,8 @@ base::MakeRefCounted<ui::PageFlipRequest>(base::TimeDelta()); std::unique_ptr<gfx::GpuFence> out_fence; - EXPECT_TRUE(fake_drm_->plane_manager()->Commit(&state_, page_flip_request, - &out_fence)); + EXPECT_TRUE(fake_drm_->plane_manager()->Commit( + &state_, /*should_modeset*/ false, page_flip_request, &out_fence)); EXPECT_EQ(nullptr, out_fence); }
diff --git a/ui/ozone/platform/drm/gpu/mock_drm_device.cc b/ui/ozone/platform/drm/gpu/mock_drm_device.cc index ee36198..720f53fc 100644 --- a/ui/ozone/platform/drm/gpu/mock_drm_device.cc +++ b/ui/ozone/platform/drm/gpu/mock_drm_device.cc
@@ -434,8 +434,10 @@ return false; for (uint32_t i = 0; i < request->cursor; ++i) { - EXPECT_TRUE(ValidatePropertyValue(request->items[i].property_id, - request->items[i].value)); + bool res = ValidatePropertyValue(request->items[i].property_id, + request->items[i].value); + if (!res) + return false; } if (page_flip_request) @@ -446,9 +448,11 @@ // Only update values if not testing. for (uint32_t i = 0; i < request->cursor; ++i) { - EXPECT_TRUE(UpdateProperty(request->items[i].object_id, - request->items[i].property_id, - request->items[i].value)); + bool res = + UpdateProperty(request->items[i].object_id, + request->items[i].property_id, request->items[i].value); + if (!res) + return false; } return true;
diff --git a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc index 82d8478f..04d330f0 100644 --- a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc +++ b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
@@ -31,10 +31,18 @@ const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; -const uint32_t kPrimaryCrtc = 1; -const uint32_t kPrimaryConnector = 2; -const uint32_t kSecondaryCrtc = 3; -const uint32_t kSecondaryConnector = 4; +constexpr uint32_t kCrtcIdBase = 100; +constexpr uint32_t kPrimaryCrtc = kCrtcIdBase; +constexpr uint32_t kSecondaryCrtc = kCrtcIdBase + 1; + +constexpr uint32_t kConnectorIdBase = 200; +constexpr uint32_t kPrimaryConnector = kConnectorIdBase; +constexpr uint32_t kSecondaryConnector = kConnectorIdBase + 1; +constexpr uint32_t kPlaneIdBase = 300; +constexpr uint32_t kInFormatsBlobPropIdBase = 400; + +constexpr uint32_t kTypePropId = 3010; +constexpr uint32_t kInFormatsPropId = 3011; drmModeModeInfo Mode(uint16_t hdisplay, uint16_t vdisplay) { return {0, hdisplay, 0, 0, 0, 0, vdisplay, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; @@ -44,8 +52,16 @@ class ScreenManagerTest : public testing::Test { public: - ScreenManagerTest() {} - ~ScreenManagerTest() override {} + struct PlaneState { + std::vector<uint32_t> formats; + }; + + struct CrtcState { + std::vector<PlaneState> planes; + }; + + ScreenManagerTest() = default; + ~ScreenManagerTest() override = default; gfx::Rect GetPrimaryBounds() const { return gfx::Rect(0, 0, kDefaultMode.hdisplay, kDefaultMode.vdisplay); @@ -57,6 +73,95 @@ kDefaultMode.vdisplay); } + void InitializeDrmState(const std::vector<CrtcState>& crtc_states) { + std::vector<ui::MockDrmDevice::CrtcProperties> crtc_properties( + crtc_states.size()); + std::map<uint32_t, std::string> crtc_property_names = { + {1000, "ACTIVE"}, + {1001, "MODE_ID"}, + }; + + std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(2); + std::map<uint32_t, std::string> connector_property_names = { + {2000, "CRTC_ID"}, + }; + for (size_t i = 0; i < connector_properties.size(); ++i) { + connector_properties[i].id = kPrimaryConnector + i; + for (const auto& pair : connector_property_names) { + connector_properties[i].properties.push_back( + {/* .id = */ pair.first, /* .value = */ 0}); + } + } + + std::vector<ui::MockDrmDevice::PlaneProperties> plane_properties; + std::map<uint32_t, std::string> plane_property_names = { + // Add all required properties. + {3000, "CRTC_ID"}, + {3001, "CRTC_X"}, + {3002, "CRTC_Y"}, + {3003, "CRTC_W"}, + {3004, "CRTC_H"}, + {3005, "FB_ID"}, + {3006, "SRC_X"}, + {3007, "SRC_Y"}, + {3008, "SRC_W"}, + {3009, "SRC_H"}, + // Defines some optional properties we use for convenience. + {kTypePropId, "type"}, + {kInFormatsPropId, "IN_FORMATS"}, + }; + + uint32_t plane_id = kPlaneIdBase; + uint32_t property_id = kInFormatsBlobPropIdBase; + + for (size_t crtc_idx = 0; crtc_idx < crtc_states.size(); ++crtc_idx) { + crtc_properties[crtc_idx].id = kPrimaryCrtc + crtc_idx; + for (const auto& pair : crtc_property_names) { + crtc_properties[crtc_idx].properties.push_back( + {/* .id = */ pair.first, /* .value = */ 0}); + } + + std::vector<ui::MockDrmDevice::PlaneProperties> crtc_plane_properties( + crtc_states[crtc_idx].planes.size()); + for (size_t plane_idx = 0; + plane_idx < crtc_states[crtc_idx].planes.size(); ++plane_idx) { + crtc_plane_properties[plane_idx].id = plane_id++; + crtc_plane_properties[plane_idx].crtc_mask = 1 << crtc_idx; + + for (const auto& pair : plane_property_names) { + uint64_t value = 0; + if (pair.first == kTypePropId) { + value = plane_idx == 0 ? DRM_PLANE_TYPE_PRIMARY + : DRM_PLANE_TYPE_OVERLAY; + } else if (pair.first == kInFormatsPropId) { + value = property_id++; + drm_->SetPropertyBlob(ui::MockDrmDevice::AllocateInFormatsBlob( + value, crtc_states[crtc_idx].planes[plane_idx].formats, + std::vector<drm_format_modifier>())); + } + + crtc_plane_properties[plane_idx].properties.push_back( + {/* .id = */ pair.first, /* .value = */ value}); + } + } + + plane_properties.insert(plane_properties.end(), + crtc_plane_properties.begin(), + crtc_plane_properties.end()); + } + + std::map<uint32_t, std::string> property_names; + property_names.insert(crtc_property_names.begin(), + crtc_property_names.end()); + property_names.insert(connector_property_names.begin(), + connector_property_names.end()); + property_names.insert(plane_property_names.begin(), + plane_property_names.end()); + drm_->InitializeState(crtc_properties, connector_properties, + plane_properties, property_names, + /* use_atomic= */ true); + } + void SetUp() override { auto gbm = std::make_unique<ui::MockGbmDevice>(); drm_ = new ui::MockDrmDevice(std::move(gbm)); @@ -202,6 +307,24 @@ } TEST_F(ScreenManagerTest, CheckMirrorModeTransitions) { + std::vector<CrtcState> crtc_states = { + { + /* .planes = */ + { + {/* .formats = */ {DRM_FORMAT_XRGB8888}}, + {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}}, + }, + }, + { + /* .planes = */ + { + {/* .formats = */ {DRM_FORMAT_XRGB8888}}, + {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}}, + }, + }, + }; + InitializeDrmState(crtc_states); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), @@ -353,6 +476,24 @@ } TEST_F(ScreenManagerTest, CheckMirrorModeAfterBeginReEnabled) { + std::vector<CrtcState> crtc_states = { + { + /* .planes = */ + { + {/* .formats = */ {DRM_FORMAT_XRGB8888}}, + {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}}, + }, + }, + { + /* .planes = */ + { + {/* .formats = */ {DRM_FORMAT_XRGB8888}}, + {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}}, + }, + }, + }; + InitializeDrmState(crtc_states); + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); screen_manager_->ConfigureDisplayController( drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
diff --git a/ui/views/controls/table/table_header.cc b/ui/views/controls/table/table_header.cc index cc72fdb..31c7970 100644 --- a/ui/views/controls/table/table_header.cc +++ b/ui/views/controls/table/table_header.cc
@@ -170,6 +170,22 @@ return gfx::Size(1, kVerticalPadding * 2 + font_list_.GetHeight()); } +bool TableHeader::GetNeedsNotificationWhenVisibleBoundsChange() const { + return true; +} + +void TableHeader::OnVisibleBoundsChanged() { + // Ensure the TableView updates its virtual children's bounds, because that + // includes the bounds representing this TableHeader. + table_->UpdateVirtualAccessibilityChildrenBounds(); +} + +void TableHeader::AddedToWidget() { + // Ensure the TableView updates its virtual children's bounds, because that + // includes the bounds representing this TableHeader. + table_->UpdateVirtualAccessibilityChildrenBounds(); +} + gfx::NativeCursor TableHeader::GetCursor(const ui::MouseEvent& event) { return GetResizeColumn(GetMirroredXInView(event.x())) != -1 ? GetNativeColumnResizeCursor()
diff --git a/ui/views/controls/table/table_header.h b/ui/views/controls/table/table_header.h index 359bf68..83ffb09 100644 --- a/ui/views/controls/table/table_header.h +++ b/ui/views/controls/table/table_header.h
@@ -37,6 +37,9 @@ void OnPaint(gfx::Canvas* canvas) override; const char* GetClassName() const override; gfx::Size CalculatePreferredSize() const override; + bool GetNeedsNotificationWhenVisibleBoundsChange() const override; + void OnVisibleBoundsChanged() override; + void AddedToWidget() override; gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override; bool OnMousePressed(const ui::MouseEvent& event) override; bool OnMouseDragged(const ui::MouseEvent& event) override;
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc index cbd26898..f457255 100644 --- a/ui/views/controls/table/table_view.cc +++ b/ui/views/controls/table/table_view.cc
@@ -252,6 +252,7 @@ SetActiveVisibleColumnIndex(int{visible_columns_.size()} - 1); } } + ClearVirtualAccessibilityChildren(); UpdateVisibleColumnSizes(); PreferredSizeChanged(); SchedulePaint(); @@ -334,6 +335,7 @@ } PreferredSizeChanged(); SchedulePaint(); + UpdateVirtualAccessibilityChildrenBounds(); } int TableView::ModelToView(int model_index) const { @@ -420,6 +422,16 @@ return gfx::Size(width, GetRowCount() * row_height_); } +bool TableView::GetNeedsNotificationWhenVisibleBoundsChange() const { + return true; +} + +void TableView::OnVisibleBoundsChanged() { + // When our visible bounds change, we need to make sure we update the bounds + // of our AXVirtualView children. + UpdateVirtualAccessibilityChildrenBounds(); +} + bool TableView::OnKeyPressed(const ui::KeyEvent& event) { if (!HasFocus()) return false; @@ -1188,7 +1200,7 @@ } void TableView::UpdateVirtualAccessibilityChildren() { - GetViewAccessibility().RemoveAllVirtualChildViews(); + ClearVirtualAccessibilityChildren(); if (!GetRowCount() || visible_columns_.empty()) return; @@ -1200,8 +1212,6 @@ auto ax_header = std::make_unique<AXVirtualView>(); ui::AXNodeData& header_data = ax_header->GetCustomData(); header_data.role = ax::mojom::Role::kRow; - header_data.relative_bounds.bounds = - AdjustRectForAXRelativeBounds(header_->GetVisibleBounds()); for (size_t visible_column_index = 0; visible_column_index < visible_columns_.size(); @@ -1213,10 +1223,6 @@ ui::AXNodeData& cell_data = ax_cell->GetCustomData(); cell_data.role = ax::mojom::Role::kColumnHeader; cell_data.SetName(column.title); - gfx::Rect header_cell_bounds(visible_column.x, header_->y(), - visible_column.width, header_->height()); - cell_data.relative_bounds.bounds = - AdjustRectForAXRelativeBounds(header_cell_bounds); cell_data.AddIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex, static_cast<int32_t>(visible_column_index)); cell_data.AddIntAttribute(ax::mojom::IntAttribute::kTableCellColumnSpan, @@ -1264,16 +1270,15 @@ row_data.SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kSelect); row_data.AddIntAttribute(ax::mojom::IntAttribute::kTableRowIndex, static_cast<int32_t>(view_index)); - gfx::Rect row_bounds = GetRowBounds(view_index); - row_data.relative_bounds.bounds = AdjustRectForAXRelativeBounds(row_bounds); if (!single_selection_) row_data.AddState(ax::mojom::State::kMultiselectable); base::RepeatingCallback<void(ui::AXNodeData*)> row_callback = base::BindRepeating( - [](TableView* table, const int model_index, - const gfx::Rect& row_bounds, ui::AXNodeData* data) { + [](TableView* table, int model_index, ui::AXNodeData* data) { DCHECK(table); + gfx::Rect row_bounds = + table->GetRowBounds(table->ModelToView(model_index)); if (!table->GetVisibleBounds().Intersects(row_bounds)) data->AddState(ax::mojom::State::kInvisible); if (table->selection_model().IsSelected(model_index)) { @@ -1281,7 +1286,7 @@ true); } }, - base::Unretained(this), model_index, row_bounds); + base::Unretained(this), model_index); ax_row->SetPopulateDataCallback(std::move(row_callback)); for (size_t visible_column_index = 0; @@ -1301,9 +1306,6 @@ cell_data.AddAction(ax::mojom::Action::kScrollToMakeVisible); cell_data.AddAction(ax::mojom::Action::kSetSelection); } - gfx::Rect cell_bounds = GetCellBounds(view_index, visible_column_index); - cell_data.relative_bounds.bounds = - AdjustRectForAXRelativeBounds(cell_bounds); cell_data.AddIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, static_cast<int32_t>(view_index)); @@ -1331,10 +1333,11 @@ base::RepeatingCallback<void(ui::AXNodeData*)> cell_callback = base::BindRepeating( - [](TableView* table, const int model_index, - const size_t visible_column_index, - const gfx::Rect& cell_bounds, ui::AXNodeData* data) { + [](TableView* table, int model_index, size_t visible_column_index, + ui::AXNodeData* data) { DCHECK(table); + gfx::Rect cell_bounds = table->GetCellBounds( + table->ModelToView(model_index), visible_column_index); if (!table->GetVisibleBounds().Intersects(cell_bounds)) data->AddState(ax::mojom::State::kInvisible); if (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell && @@ -1346,8 +1349,7 @@ } } }, - base::Unretained(this), model_index, visible_column_index, - cell_bounds); + base::Unretained(this), model_index, visible_column_index); ax_cell->SetPopulateDataCallback(std::move(cell_callback)); ax_row->AddChildView(std::move(ax_cell)); @@ -1355,6 +1357,89 @@ GetViewAccessibility().AddVirtualChildView(std::move(ax_row)); } + + UpdateVirtualAccessibilityChildrenBounds(); +} + +void TableView::ClearVirtualAccessibilityChildren() { + GetViewAccessibility().RemoveAllVirtualChildViews(); +} + +void TableView::UpdateVirtualAccessibilityChildrenBounds() { + // The virtual children may be empty if the |model_| is in the process of + // updating (e.g. showing or hiding a column) but the virtual accessibility + // children haven't been updated yet to reflect the new model. + auto& virtual_children = GetViewAccessibility().virtual_children(); + if (virtual_children.empty()) + return; + + // Update the bounds for the header first, if applicable. + if (header_) { + auto& ax_row = virtual_children[0]; + ui::AXNodeData& row_data = ax_row->GetCustomData(); + DCHECK_EQ(ax_row->GetData().role, ax::mojom::Role::kRow); + row_data.relative_bounds.bounds = + gfx::RectF(CalculateHeaderRowAccessibilityBounds()); + + // Update the bounds for every child cell in this row. + for (size_t visible_column_index = 0; + visible_column_index < ax_row->children().size(); + visible_column_index++) { + ui::AXNodeData& cell_data = + ax_row->children()[visible_column_index]->GetCustomData(); + + DCHECK_EQ(cell_data.role, ax::mojom::Role::kColumnHeader); + cell_data.relative_bounds.bounds = gfx::RectF( + CalculateHeaderCellAccessibilityBounds(visible_column_index)); + } + } + + // Update the bounds for the table's content rows. + for (int row_index = 0; row_index < GetRowCount(); row_index++) { + auto& ax_row = virtual_children[header_ ? row_index + 1 : row_index]; + ui::AXNodeData& row_data = ax_row->GetCustomData(); + DCHECK_EQ(ax_row->GetData().role, ax::mojom::Role::kRow); + row_data.relative_bounds.bounds = + gfx::RectF(CalculateTableRowAccessibilityBounds(row_index)); + + // Update the bounds for every child cell in this row. + for (size_t visible_column_index = 0; + visible_column_index < ax_row->children().size(); + visible_column_index++) { + ui::AXNodeData& cell_data = + ax_row->children()[visible_column_index]->GetCustomData(); + + DCHECK_EQ(cell_data.role, ax::mojom::Role::kCell); + cell_data.relative_bounds.bounds = + gfx::RectF(CalculateTableCellAccessibilityBounds( + row_index, visible_column_index)); + } + } +} + +gfx::Rect TableView::CalculateHeaderRowAccessibilityBounds() const { + return AdjustRectForAXRelativeBounds(header_->GetVisibleBounds()); +} + +gfx::Rect TableView::CalculateHeaderCellAccessibilityBounds( + const int visible_column_index) const { + const VisibleColumn& visible_column = visible_columns_[visible_column_index]; + gfx::Rect header_cell_bounds(visible_column.x, header_->y(), + visible_column.width, header_->height()); + return AdjustRectForAXRelativeBounds(header_cell_bounds); +} + +gfx::Rect TableView::CalculateTableRowAccessibilityBounds( + const int row_index) const { + gfx::Rect row_bounds = GetRowBounds(row_index); + return AdjustRectForAXRelativeBounds(row_bounds); +} + +gfx::Rect TableView::CalculateTableCellAccessibilityBounds( + const int row_index, + const int visible_column_index) const { + gfx::Rect cell_bounds = GetCellBounds(row_index, visible_column_index); + return AdjustRectForAXRelativeBounds(cell_bounds); } void TableView::UpdateAccessibilityFocus() { @@ -1421,9 +1506,11 @@ return i->get(); } -gfx::RectF TableView::AdjustRectForAXRelativeBounds(gfx::Rect rect) const { - View::ConvertRectToScreen(this, &rect); - return gfx::RectF(rect); +gfx::Rect TableView::AdjustRectForAXRelativeBounds( + const gfx::Rect& rect) const { + gfx::Rect converted_rect = rect; + View::ConvertRectToScreen(this, &converted_rect); + return converted_rect; } DEFINE_ENUM_CONVERTERS(TableTypes,
diff --git a/ui/views/controls/table/table_view.h b/ui/views/controls/table/table_view.h index 25364ff..f7854c5d 100644 --- a/ui/views/controls/table/table_view.h +++ b/ui/views/controls/table/table_view.h
@@ -205,9 +205,18 @@ TableTypes GetTableType() const; + // Updates the relative bounds of the virtual accessibility children created + // in UpdateVirtualAccessibilityChildren(). This function is public so that + // the table's |header_| can trigger an update when its visible bounds are + // changed, because its accessibility information is also contained in the + // table's virtual accessibility children. + void UpdateVirtualAccessibilityChildrenBounds(); + // View overrides: void Layout() override; gfx::Size CalculatePreferredSize() const override; + bool GetNeedsNotificationWhenVisibleBoundsChange() const override; + void OnVisibleBoundsChanged() override; bool OnKeyPressed(const ui::KeyEvent& event) override; bool OnMousePressed(const ui::MouseEvent& event) override; void OnGestureEvent(ui::GestureEvent* event) override; @@ -343,6 +352,23 @@ // to assistive software. void UpdateVirtualAccessibilityChildren(); + // Clears the set of accessibility views set up in + // UpdateVirtualAccessibilityChildren(). Useful when the model is in the + // process of changing but the virtual accessibility children haven't been + // updated yet, e.g. showing or hiding a column via SetColumnVisibility(). + void ClearVirtualAccessibilityChildren(); + + // Helper functions used in UpdateVirtualAccessibilityChildrenBounds() for + // calculating the accessibility bounds for the header and table rows and + // cells. + gfx::Rect CalculateHeaderRowAccessibilityBounds() const; + gfx::Rect CalculateHeaderCellAccessibilityBounds( + const int visible_column_index) const; + gfx::Rect CalculateTableRowAccessibilityBounds(const int row_index) const; + gfx::Rect CalculateTableCellAccessibilityBounds( + const int row_index, + const int visible_column_index) const; + // Updates the internal accessibility state and fires the required // accessibility events to indicate to assistive software which row is active // and which cell is focused, if any. @@ -357,9 +383,10 @@ // |visible_column_index| indexes into |visible_columns_|. AXVirtualView* GetVirtualAccessibilityCell(int row, int visible_column_index); - // Returns |rect|, adjusted for use in AXRelativeBounds by converting it to - // gfx::RectF and translating it into screen coordinates. - gfx::RectF AdjustRectForAXRelativeBounds(gfx::Rect rect) const; + // Returns |rect|, adjusted for use in AXRelativeBounds by translating it into + // screen coordinates. The result must be converted to gfx::RectF when setting + // into AXRelativeBounds. + gfx::Rect AdjustRectForAXRelativeBounds(const gfx::Rect& rect) const; ui::TableModel* model_ = nullptr;
diff --git a/ui/views/controls/table/table_view_unittest.cc b/ui/views/controls/table/table_view_unittest.cc index 379fde81..eb8686e 100644 --- a/ui/views/controls/table/table_view_unittest.cc +++ b/ui/views/controls/table/table_view_unittest.cc
@@ -68,6 +68,39 @@ return table_->GetVirtualAccessibilityCell(row, visible_column_index); } + std::vector<std::vector<gfx::Rect>> GenerateExpectedBounds() { + // Generates the expected bounds for |table_|'s rows and cells. Each vector + // represents a row. The first entry in each child vector is the bounds for + // the entire row. The following entries in that vector are the bounds for + // each individual cell contained in that row. + auto expected_bounds = std::vector<std::vector<gfx::Rect>>(); + + // Generate the bounds for the header row and cells. + auto header_row = std::vector<gfx::Rect>(); + header_row.push_back(table_->CalculateHeaderRowAccessibilityBounds()); + for (size_t column_index = 0; column_index < visible_col_count(); + column_index++) { + header_row.push_back( + table_->CalculateHeaderCellAccessibilityBounds(column_index)); + } + expected_bounds.push_back(header_row); + + // Generate the bounds for the table rows and cells. + for (int row_index = 0; row_index < table_->GetRowCount(); row_index++) { + auto table_row = std::vector<gfx::Rect>(); + table_row.push_back( + table_->CalculateTableRowAccessibilityBounds(row_index)); + for (size_t column_index = 0; column_index < visible_col_count(); + column_index++) { + table_row.push_back(table_->CalculateTableCellAccessibilityBounds( + row_index, column_index)); + } + expected_bounds.push_back(table_row); + } + + return expected_bounds; + } + private: TableView* table_; @@ -333,6 +366,53 @@ generator.PressKey(code, flags); } + // Helper function for comparing the bounds of |table_|'s virtual + // accessibility child rows and cells with a set of expected bounds. + void VerifyTableAccChildrenBounds( + const ViewAccessibility& view_accessibility, + const std::vector<std::vector<gfx::Rect>>& expected_bounds) { + auto& virtual_children = view_accessibility.virtual_children(); + EXPECT_EQ(virtual_children.size(), expected_bounds.size()); + EXPECT_EQ((size_t)(table_->GetRowCount()) + 1U, expected_bounds.size()); + + for (size_t row_index = 0; row_index < virtual_children.size(); + row_index++) { + const auto& row = virtual_children[row_index]; + ASSERT_TRUE(row); + const ui::AXNodeData& row_data = row->GetData(); + EXPECT_EQ(ax::mojom::Role::kRow, row_data.role); + + ui::AXOffscreenResult offscreen_result = ui::AXOffscreenResult(); + gfx::Rect row_custom_bounds = row->GetBoundsRect( + ui::AXCoordinateSystem::kScreen, ui::AXClippingBehavior::kUnclipped, + &offscreen_result); + EXPECT_EQ(row_custom_bounds, expected_bounds[row_index][0]); + + EXPECT_EQ(row->children().size(), expected_bounds[row_index].size() - 1U); + EXPECT_EQ(row->children().size(), helper_->visible_col_count()); + for (size_t cell_index = 0; cell_index < row->children().size(); + cell_index++) { + const auto& cell = row->children()[cell_index]; + ASSERT_TRUE(cell); + const ui::AXNodeData& cell_data = cell->GetData(); + + if (row_index == 0) + EXPECT_EQ(ax::mojom::Role::kColumnHeader, cell_data.role); + else + EXPECT_EQ(ax::mojom::Role::kCell, cell_data.role); + + // Add 1 to get the cell's index into |expected_bounds| since the first + // entry is the row's bounds. + const int expected_bounds_index = cell_index + 1; + gfx::Rect cell_custom_bounds = cell->GetBoundsRect( + ui::AXCoordinateSystem::kScreen, ui::AXClippingBehavior::kUnclipped, + &offscreen_result); + EXPECT_EQ(cell_custom_bounds, + expected_bounds[row_index][expected_bounds_index]); + } + } + } + protected: virtual WidgetDelegate* GetWidgetDelegate(Widget* widget) { return nullptr; } @@ -404,6 +484,7 @@ EXPECT_EQ(ax::mojom::Role::kRow, row_data.role); EXPECT_EQ( i, row_data.GetIntAttribute(ax::mojom::IntAttribute::kTableRowIndex)); + ASSERT_FALSE(row_data.HasState(ax::mojom::State::kInvisible)); ASSERT_EQ(helper_->visible_col_count(), row->children().size()); j = 0; @@ -415,10 +496,43 @@ ax::mojom::IntAttribute::kTableCellRowIndex)); EXPECT_EQ(j++, cell_data.GetIntAttribute( ax::mojom::IntAttribute::kTableCellColumnIndex)); + ASSERT_FALSE(cell_data.HasState(ax::mojom::State::kInvisible)); } } } +// Verifies the bounding rect of each virtual accessibility child of the +// TableView (rows and cells) is updated appropriately as the table changes. For +// example, verifies that if a column is resized or hidden, the bounds are +// updated. +TEST_F(TableViewTest, UpdateVirtualAccessibilityChildrenBounds) { + // Verify the bounds are updated correctly when the TableView and its widget + // have been shown. Initially some widths would be 0 until the TableView's + // bounds are fully set up, so make sure the virtual children bounds have been + // updated and now match the expected bounds. + auto expected_bounds = helper_->GenerateExpectedBounds(); + VerifyTableAccChildrenBounds(table_->GetViewAccessibility(), expected_bounds); +} + +TEST_F(TableViewTest, UpdateVirtualAccessibilityChildrenBoundsWithResize) { + // Resize the first column 10 pixels smaller and check the bounds are updated. + int x = table_->GetVisibleColumn(0).width; + PressLeftMouseAt(helper_->header(), gfx::Point(x, 0)); + DragLeftMouseTo(helper_->header(), gfx::Point(x - 10, 0)); + + auto expected_bounds_after_resize = helper_->GenerateExpectedBounds(); + VerifyTableAccChildrenBounds(table_->GetViewAccessibility(), + expected_bounds_after_resize); +} + +TEST_F(TableViewTest, UpdateVirtualAccessibilityChildrenBoundsHideColumn) { + // Hide 1 column and check the bounds are updated. + table_->SetColumnVisibility(1, false); + auto expected_bounds_after_hiding = helper_->GenerateExpectedBounds(); + VerifyTableAccChildrenBounds(table_->GetViewAccessibility(), + expected_bounds_after_hiding); +} + TEST_F(TableViewTest, GetVirtualAccessibilityRow) { for (int i = 0; i < table_->GetRowCount(); ++i) { const AXVirtualView* row = helper_->GetVirtualAccessibilityRow(i);
diff --git a/weblayer/browser/android/metrics/uma_utils.cc b/weblayer/browser/android/metrics/uma_utils.cc index 71565db..5663a9ca 100644 --- a/weblayer/browser/android/metrics/uma_utils.cc +++ b/weblayer/browser/android/metrics/uma_utils.cc
@@ -15,10 +15,10 @@ namespace weblayer { -base::TimeTicks GetMainEntryPointTimeTicks() { +base::TimeTicks GetApplicationStartTime() { JNIEnv* env = base::android::AttachCurrentThread(); return base::TimeTicks::FromUptimeMillis( - Java_UmaUtils_getMainEntryPointTicks(env)); + Java_UmaUtils_getApplicationStartTime(env)); } } // namespace weblayer
diff --git a/weblayer/browser/android/metrics/uma_utils.h b/weblayer/browser/android/metrics/uma_utils.h index 7def1dd..b0b83bc1 100644 --- a/weblayer/browser/android/metrics/uma_utils.h +++ b/weblayer/browser/android/metrics/uma_utils.h
@@ -9,7 +9,7 @@ namespace weblayer { -base::TimeTicks GetMainEntryPointTimeTicks(); +base::TimeTicks GetApplicationStartTime(); } // namespace weblayer
diff --git a/weblayer/browser/browser_main_parts_impl.cc b/weblayer/browser/browser_main_parts_impl.cc index 8c890aa..5b01156 100644 --- a/weblayer/browser/browser_main_parts_impl.cc +++ b/weblayer/browser/browser_main_parts_impl.cc
@@ -110,7 +110,7 @@ #endif #if defined(OS_ANDROID) - startup_metric_utils::RecordMainEntryPointTime(GetMainEntryPointTimeTicks()); + startup_metric_utils::RecordApplicationStartTime(GetApplicationStartTime()); #endif }
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc index ec28ad05..d6c850ee 100644 --- a/weblayer/browser/content_browser_client_impl.cc +++ b/weblayer/browser/content_browser_client_impl.cc
@@ -181,25 +181,6 @@ switches::kWebLayerFakePermissions)) { command_line->AppendSwitch(switches::kWebLayerFakePermissions); } - - const std::string process_type = - command_line->GetSwitchValueASCII(switches::kProcessType); - if (process_type == switches::kRendererProcess) { - static const char* const kCommonSwitchNames[] = { - switches::kWebLayerTestMode, - }; - command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(), - kCommonSwitchNames, - base::size(kCommonSwitchNames)); - - const bool running_tests = - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kWebLayerTestMode); - if (running_tests) { - command_line->AppendSwitch( - switches::kEnableExperimentalWebPlatformFeatures); - } - } } std::string ContentBrowserClientImpl::GetApplicationLocale() {
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java b/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java index 0594554..f093df92 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java
@@ -30,7 +30,7 @@ } @CalledByNative - public static long getMainEntryPointTicks() { + public static long getApplicationStartTime() { return sApplicationStartTimeMs; } }
diff --git a/weblayer/public/common/switches.cc b/weblayer/public/common/switches.cc index 68bb83d..3cf247589 100644 --- a/weblayer/public/common/switches.cc +++ b/weblayer/public/common/switches.cc
@@ -6,10 +6,6 @@ namespace switches { -// Makes WebLayer turn on various test only features. This is used when running -// wpt. -const char kWebLayerTestMode[] = "run-web-tests"; - // Makes WebLayer Shell use the given path for its data directory. const char kWebLayerUserDataDir[] = "weblayer-user-data-dir";
diff --git a/weblayer/public/common/switches.h b/weblayer/public/common/switches.h index 7e1595a..05f3c69 100644 --- a/weblayer/public/common/switches.h +++ b/weblayer/public/common/switches.h
@@ -7,7 +7,6 @@ namespace switches { -extern const char kWebLayerTestMode[]; extern const char kWebLayerUserDataDir[]; extern const char kWebLayerFakePermissions[];
diff --git a/weblayer/renderer/content_renderer_client_impl.cc b/weblayer/renderer/content_renderer_client_impl.cc index b746b00d..831e661 100644 --- a/weblayer/renderer/content_renderer_client_impl.cc +++ b/weblayer/renderer/content_renderer_client_impl.cc
@@ -10,9 +10,7 @@ #include "components/autofill/content/renderer/password_autofill_agent.h" #include "content/public/renderer/render_thread.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_runtime_features.h" #include "weblayer/common/features.h" -#include "weblayer/public/common/switches.h" #include "weblayer/renderer/error_page_helper.h" #include "weblayer/renderer/weblayer_render_frame_observer.h" @@ -122,12 +120,4 @@ return nullptr; } -void ContentRendererClientImpl:: - SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() { - const bool running_tests = base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kWebLayerTestMode); - if (running_tests) - blink::WebRuntimeFeatures::EnableTestOnlyFeatures(true); -} - } // namespace weblayer
diff --git a/weblayer/renderer/content_renderer_client_impl.h b/weblayer/renderer/content_renderer_client_impl.h index 8b0dc94..8f5a650 100644 --- a/weblayer/renderer/content_renderer_client_impl.h +++ b/weblayer/renderer/content_renderer_client_impl.h
@@ -34,7 +34,6 @@ std::unique_ptr<content::URLLoaderThrottleProvider> CreateURLLoaderThrottleProvider( content::URLLoaderThrottleProviderType provider_type) override; - void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override; private: #if defined(OS_ANDROID)